diff --git a/.aws/testnet.json b/.aws/testnet.json
new file mode 100644
index 000000000..145bc4dc5
--- /dev/null
+++ b/.aws/testnet.json
@@ -0,0 +1,24 @@
+{
+ "executionRoleArn":"arn:aws:iam::094889878379:role/rif-gateways-ccbridge20220420234144997100000001",
+ "family":"rif-gateways-ccbridge",
+ "networkMode":"awsvpc",
+ "requiresCompatibilities":[
+ "FARGATE"
+ ],
+ "cpu":"2048",
+ "memory":"4096",
+ "containerDefinitions":[
+ {
+ "name":"rif-gateways-ccbridge-testnet",
+ "image":"094889878379.dkr.ecr.us-west-2.amazonaws.com/rif-gateways-ccbridge:latest",
+ "logConfiguration":{
+ "logDriver":"awslogs",
+ "options":{
+ "awslogs-region":"us-west-2",
+ "awslogs-group":"/ecs/rif-gateways-ccbridge",
+ "awslogs-stream-prefix":"testnet"
+ }
+ }
+ }
+ ]
+}
diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 000000000..2c3baf2fe
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,68 @@
+version: 2.1
+orbs:
+ coveralls: coveralls/coveralls@1.0.6
+jobs:
+ build:
+ working_directory: ~/repo
+ docker:
+ - image: circleci/node:lts
+ # The first ganache-cli container is meant to simulate a main chain, and the second one for a side chain (integration testing only)
+ - image: trufflesuite/ganache-cli
+ # The gas limit is 6700000 to avoid trying to deploy a contract larger than expected
+ command: ganache-cli -i 5777 --chainId 5777 -l 6700000 -k istanbul
+ - image: trufflesuite/ganache-cli
+ command: ganache-cli -i 5776 --chainId 5776 -p 8546 -l 6700000 -k istanbul
+ steps:
+ - checkout
+ # Download and cache dependencies
+ - restore_cache:
+ keys:
+ - v1-dependencies-{{ checksum "bridge/package.json" }}
+ # Fallback to using the latest cache if no exact match is found
+ - v1-dependencies-
+ - run:
+ name: install bridge dependencies
+ command: |
+ cd bridge
+ npm ci
+ - run:
+ name: install federator dependencies
+ command: |
+ cd federator
+ npm ci
+ - save_cache:
+ paths:
+ - bridge/node_modules
+ key: v1-dependencies-{{ checksum "bridge/package.json" }}
+ - run:
+ name: contracts lint
+ command: |
+ cd bridge
+ npm run lint
+ - run:
+ name: deploy contracts in development and mirror
+ command: |
+ cd bridge
+ npm run deployLocalIntegrationTest
+ - run:
+ name: federator integration tests
+ command: |
+ cd federator
+ npm run integrationTest
+ - run:
+ name: Heartbeat federator integration tests
+ command: |
+ cd federator
+ npm run integrationHeartbeatTest
+ - run:
+ name: federator unit tests
+ command: |
+ cd federator
+ npm test
+ - run:
+ name: bridge unit tests + coverage
+ command: |
+ cd bridge
+ npm run coverage
+ - coveralls/upload:
+ path_to_lcov: "./bridge/coverage/lcov.info"
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 000000000..51d40197e
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,5 @@
+./docs
+./ui
+./federator/test
+./federator/integrationTest
+./federator/node_modules
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 000000000..52031de51
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.sol linguist-language=Solidity
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 000000000..d3e073808
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,76 @@
+### Title of pull request
+
+The pull request should be described here
+
+### Description
+
+- Describe here your pull request modifications
+- It could be more than one thing
+
+### How to Test
+
+- Run both `ganache-cli`
+- Enter into the bridge directory and run all the tests
+
+#### Case 1
+
+1. Go to bridge directory
+```shell
+$~ cd bridge
+```
+
+2. Run all the tests
+```shell
+$~ npm run test
+```
+
+__Expected Result__
+- It should pass the test
+
+
+3. Run the first ganache-cli
+```shell
+$~ npm run ganache
+```
+
+4. Open another shell and run the ganache mirror
+```shell
+$~ npm run ganache-mirror
+```
+
+5. Go to the federator directory
+```shell
+$~ cd ../federator
+```
+
+6. Run the integration test
+```shell
+$~ npm run integrationTest
+```
+
+__Expected Result__
+- It should pass the test
+
+
+
+7. Run the integration test
+```shell
+$~ npm run integrationTest
+```
+__Expected Result__
+- It should pass the test
+
+
+#### Case N...
+
+### Checklist
+
+#### Bridge Directory `cd bridge`
+- [] Lint is clean `npm run lint`
+- [] Test is passing `npm run test`
+- [] Contracts are compiling `npm run compile`
+
+#### Federator Directory `cd federator`
+- [] Lint is clean `npm run lint`
+- [] Test is passing `npm run test`
+- [] Typescript is compiling `npm run build`
\ No newline at end of file
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 000000000..874ed3871
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,54 @@
+name: "CodeQL"
+
+on:
+ push:
+ branches: [master, ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [master]
+ schedule:
+ - cron: '0 9 * * 6'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+ with:
+ # We must fetch at least the immediate parents so that if this is
+ # a pull request then we can checkout the head.
+ fetch-depth: 2
+
+ # If this run was triggered by a pull request event, then checkout
+ # the head of the pull request instead of the merge commit.
+ - run: git checkout HEAD^2
+ if: ${{ github.event_name == 'pull_request' }}
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v1
+ # Override language selection by uncommenting this and choosing your languages
+ # with:
+ # languages: go, javascript, csharp, python, cpp, java
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v1
+
+ # ℹ️ Command-line programs to run using the OS shell.
+ # 📚 https://git.io/JvXDl
+
+ # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
+ # and modify them (or add more) to build your code if your project
+ # uses a compiled language
+
+ #- run: |
+ # make bootstrap
+ # make release
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v1
diff --git a/.github/workflows/testnet.yml b/.github/workflows/testnet.yml
new file mode 100644
index 000000000..cdef80de8
--- /dev/null
+++ b/.github/workflows/testnet.yml
@@ -0,0 +1,62 @@
+name: Deploy TestNet CC Bridge federator
+
+on:
+ release:
+ types: [published]
+
+env:
+ AWS_REGION: ${{ secrets.AWS_REGION }}
+ ECR_REPOSITORY: rif-gateways-ccbridge
+ ECS_SERVICE: ccbridge_services_testnet # set this to your Amazon ECS service name
+ ECS_CLUSTER: rif-gateways-ccbridge # set this to your Amazon ECS cluster name
+ ECS_TASK_DEFINITION: .aws/testnet.json # set this to the path to your Amazon ECS task definition
+ # file, e.g. .aws/task-definition.json
+ CONTAINER_NAME: rif-gateways-ccbridge-testnet # set this to the name of the container in the
+ # containerDefinitions section of your task definition
+
+jobs:
+ deploy:
+ name: Deploy
+ runs-on: ubuntu-latest
+ steps:
+
+ - name: Check out code
+ uses: actions/checkout@v2
+
+ - name: Configure AWS credentials
+ uses: aws-actions/configure-aws-credentials@v1
+ with:
+ aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ aws-region: ${{ secrets.AWS_REGION }}
+
+ - name: Login to Amazon ECR
+ id: login-ecr
+ uses: aws-actions/amazon-ecr-login@v1
+
+ - name: Build, tag, and push image to Amazon ECR
+ id: build-image
+ env:
+ ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
+ ECR_REPOSITORY: rif-gateways-ccbridge
+ IMAGE_TAG: ${{ github.sha }}
+ run: |
+ docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
+ docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
+ echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
+
+ - name: Fill in the new image ID in the Amazon ECS task definition
+ id: task-def
+ uses: aws-actions/amazon-ecs-render-task-definition@v1
+ with:
+ task-definition: ${{ env.ECS_TASK_DEFINITION }}
+ container-name: ${{ env.CONTAINER_NAME }}
+ image: ${{ steps.build-image.outputs.image }}
+
+ - name: Deploy Amazon ECS task definition
+ uses: aws-actions/amazon-ecs-deploy-task-definition@v1
+ with:
+ task-definition: ${{ steps.task-def.outputs.task-definition }}
+ service: ${{ env.ECS_SERVICE }}
+ cluster: ${{ env.ECS_CLUSTER }}
+ wait-for-service-stability: true
diff --git a/.gitignore b/.gitignore
index dd87e2d73..5c5434498 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,12 @@
node_modules
-build
+federator.log
+.DS_Store
+.idea
+.vscode
+
+# dotenv environment variables file
+.env
+.env.test
+.env.prod
+
+federator/built
diff --git a/COPYING.LESSER b/COPYING.LESSER
new file mode 100644
index 000000000..12c7aa21e
--- /dev/null
+++ b/COPYING.LESSER
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2023 Rootstock Ltd.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 000000000..08e23f623
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,21 @@
+FROM node:16-alpine
+
+RUN apk add --no-cache build-base git python3
+
+WORKDIR /home/node
+USER node
+
+COPY --chown=node:node ./federator/package*.json ./federator/
+WORKDIR ./federator
+RUN npm ci
+
+WORKDIR ../
+COPY --chown=node:node ./bridge/abi ./bridge/abi/
+COPY --chown=node:node ./federator/ ./federator/
+
+WORKDIR ./federator
+RUN (cd ./config/ && cp config.sample.js config.js) && \
+ npx tsc --build
+
+WORKDIR ./built/federator
+CMD ["node", "./src/main.js"]
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 000000000..b76e6a5a8
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2012-2021 Scott Chacon and others
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index cf091a3c5..858289e62 100644
--- a/README.md
+++ b/README.md
@@ -1,51 +1,64 @@
-# RSK Token Bridge
+# RSK <-> ETH Token Bridge
-Ethereum/RSK Token Bridge.
+Ethereum/RSK Bridge that allows to move ERC20 tokens from one chain to the other.
-## Components
+## Rationale
-The Token Bridge works between two Ethereum compatible Blockchain networks (from now on Mainchain and Sidechain). The original ERC20 Token Contract is deployed on the Mainchain and it does not require any modifications (it might pre-exists to the deployment of the RSK Token Bridge).
+Cross chain events are very important in the future of crypto. Exchanging tokens between networks allows the token holders to use them in their favorite chain without beeing restricted to the contract owner network choice. Moreover this also allows layer 2 solutions to use the same tokens on different chains, this concept together with stable coins creates a great way of payment with low volatility across networks.
-Two additional contracts are deployed on the Mainchain:
-* The Bridge Contract: acts as a Token Custodian of the Tokens on the Mainchain. It receives Tokens from the Mainchain and holds them until the Manager instructs it to release them.
-* The Manager Contract: controls the release of Tokens from the Mainchain to the Sidechain.
+## Overview
-On the Sidechain three contracts are deployed:
-* The Manager Contract: controls the release of Mirror Tokens from the Sidechain to the Mainchain.
-* The Bridge Contract: acts as a Token Custodian of the Mirror Tokens on the Sidechain. It receives Mirror Tokens from the Sidechan and holds them until the Manager instructs it to release them.
-* The Mirror Token Contract: a representation of the Mainchain token on the Sidecain. This Token is also an ERC20 Token, so it can be managed and used by the Token ecosystem as any other ERC20 Token.
+The smart contract on each network are connected by bridges, a bridge on one chain would receive and lock the ERC20 tokens, this action emits an event that will be served to the bridge on the other chain. This interoperability is achieved using a Federation that sends the event from one contract to the other, once the bridge on the other chain receives the event from the Federation, it mints the tokens on the mirror ERC20 contract.
+See the [FAQ](https://developers.rsk.co/tools/tokenbridge/faq/) to know more about how it works!
-## Transfer flows
+
+
+
-### Mainchain to Sidechain
+The bridges on each contract are upgradeable, this would enable a smooth transition to a more decentralized bridge in the future. Here's is a link to the first
+[POC of the trustless decentralized bridge](https://github.com/rsksmart/decentralized-tokenbridge)
-To transfer Tokens from the Mainchain to the Sidechain an account transfers Tokens to the Bridge. Since ERC20 Tokens emit transfer events there is no need for the Bridge to also emit such events. The Federation (a group of Oracles implemented as off-chain scripts) listens for the events emitted by the Tokens when the Bridge receives the transfer.
+## Usage
-For each transfer event that each Mainchain Federator listens it casts a vote to the Sidechain Manager to release the same amount of Mirror Tokens on the Sidechain. In this way the Bridge acts only as a Token Custodian, it holds the received tokens. The release of the Tokens is controlled by the Manager.
+You can use the ['Token Bridge Dapp'](https://tokenbridge.rsk.co/) together with [Nifty Wallet](https://chrome.google.com/webstore/detail/nifty-wallet/jbdaocneiiinmjbjlgalhcelgbejmnid) or [Metamask with custom network](https://github.com/rsksmart/rskj/wiki/Configure-Metamask-to-connect-with-RSK) to move tokens between networks. This is the [Dapp guide](https://developers.rsk.co/tools/tokenbridge/dappguide/) if you don't know how to use it.
+Or you can use a wallet with the abi of the contracts. See the ['interaction guide using MyCrypto'](https://developers.rsk.co/tools/tokenbridge/usingmycrypto/) for more information on how to use the bridge.
-The Sidechain Bridge has a preallocated amount of Mirror Tokens (similar to how the RSK Bridge works). Eventually we will include the required logic to dinamically allocate (mint / burn) Mirror Tokens.
+## Contracts deployed on RSK, Ethereum, RSK Testnet and Kovan
-When the Sidechain Manager has enough votes (N-out-of-M) for the Mainchain transfer it instructs the Sidechain Bridge to release the transferred amount of Mirror Tokens to the specified source account. The source account from the Mainchain could be the same as the destination account on the Sidechain or it can be mapped in the Mainchain Bridge to a different account.
+Here are the ['addresses'](./docs/ContractAddresses.md) of the deployed contracts in the different networks.
-To avoid undeserible side-effects due to a Blockchain reorganization the Federators only process transfer events that have enough confirmations (K confirmation blocks).
+## Report Security Vulnerabilities
-### Sidechain to Mainchain
+To report a vulnerability, please use the [vulnerability reporting guideline](./SECURITY.md) for details on how to do it.
-When an account from the Sidechain wants to transfer Mirror Tokens back to the Mainchain, it transfers them to the Sidechain Bridge. Similar to the Mainchain to Sidechain transfer, the Mirror Tokens emit events that are listened by the Federation (it might be the same group of Oracles as the ones in the Mainchain, but this is not mandatory).
+## Developers
-The Federation casts votes to the Mainchain Manager and when the Mainchain Manager has enough votes (N-out-of-M) it instructs the Mainchain Bridge to release the transferred amount of Tokens to the specified Mainchain account. As in the previous case, the source account from the Sidechain could be the same as the destination account of the Mainchain or it can be mapped in the Sidechain Bridge to a different account.
+### Contracts
-At the moment, the RSK Token Bridge is implemented as a Symmetric Bridge. Alternatives to this implementation are being evaluated.
+The smart contracts used by the bridge and the instructions to deploy them are in the ['bridge folder'](./bridge/README.md).
+The ABI to interact with the contracts are in the ['abi folder'](./bridge/abi)
-## References
+### Dapp
-- [Retrofitting a two-way peg between blockchains](https://people.cs.uchicago.edu/~teutsch/papers/dogethereum.pdf)
-- [Sentinel Bridge RSK](https://github.com/InfoCorp-Technologies/sentinel-bridge-rsk)
-- [Parity Bridge](https://github.com/paritytech/parity-bridge)
-- [Blockchain Interoperability — The Aion Transwarp Conduit (TWC)](https://blog.aion.network/blockchain-interoperability-the-aion-transwarp-conduit-twc-4f6ac2e79cec)
-- [Transwarp-Conduit: Interoperable Blockchain Application Framework](https://aion.network/media/TWC_Paper_Final.pdf)
-- [UI for TokenBridge, an interoperability solution between Ethereum networks for native and ERC tokens](https://github.com/poanetwork/bridge-ui)
-- [DAI Bridge POA Network](https://dai-bridge.poa.network/)
-- [POA Network partners with MakerDAO on xDai Chain, the first ever USD-Stable Blockchain](https://medium.com/poa-network/poa-network-partners-with-makerdao-on-xdai-chain-the-first-ever-usd-stable-blockchain-65a078c41e6a)
-- [How BancorX Works: From Ethereum to EOS and Back Again](https://blog.bancor.network/how-bancorx-works-from-ethereum-to-eos-and-back-again-649336ea1c4)
-- [How do Relay Tokens work?](https://support.bancor.network/hc/en-us/articles/360000471472-How-do-Relay-Tokens-work-)
+The dapp of the token bridge can be found in the repository ['tokenbirdge-ui'](https://github.com/rsksmart/tokenbridge-ui)
+
+
+### Federation
+
+A federation sends notification of events happening in the bridge of one chain to another chain. The federation is composed of oracles listening to the events created in one chain and sending it to the other chain. When a majority of the federators votes on an event, the bridge accepts the event as valid and releases the tokens on the other chain.
+See the ['federator'](./federator/README.md) for more information about federations.
+
+### Integration Test
+
+An integration test is prepared for contracts and federators. To properly run integration test, you need check network config in the `truffle-config.js` and `package.json` in `bridge` folder with your test chains' configuration before run `npm run deployIntegrationTest`.
+
+For testing purposes only, you can let `env.FEDERATOR_KEY` empty, which fulfills the role that a `FEDERATOR_KEY` key would have in production.
+Also, a `test.local.config.js` configuration is provided in `federator/config` for the same purpose, acting as the `config.js` file would in a productive environment.
+
+1. Check `mnemonic.key` in `bridge`
+1. Check `infura.key` in `bridge` (must contain your Infura's project ID in plain text)
+1. Check your `networkName` in `bridge/migrations/4_deploy_erc1820.js` when your test network does not have **ERC1820:Pseudo-introspection Registry Contract** deployed.
+
+Then
+1. run `npm run deployIntegrationTest` in `bridge`
+1. run `npm run integrationTest` in `federator`
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 000000000..8ef6025dd
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,143 @@
+# Rootstock's Security Process
+
+We're committed to conduct our security process in a professional and civil manner. Public shaming, under-reporting or misrepresentation of vulnerabilities will not be tolerated.
+
+## Responsible Disclosure
+
+For all security related issues, Rootstock has to main points of contact. Reach us at or refer to our [Bug Bounty Program.](https://www.rootstock.io/bounty-program/) **Do not open up a GitHub issue if the bug is a security vulnerability.**
+
+**Ensure the bug was not already reported** by searching on Github under [Issues](https://github.com/rsksmart/tokenbridge/issues).
+
+## Vulnerability Handling
+
+### Response Time
+
+Rootstock will make a best effort to meet the following response times for reported vulnerabilities:
+
+* Time to first response (from report submit) - 24 hours
+* Time to triage (from report submit) - 2 business days
+* Time to bounty (from triage) - 15 business days
+
+We’ll try to keep you informed about our progress throughout the process.
+
+### Disclouse Policy
+
+* Follow HackerOne's [disclosure guidelines](https://www.hackerone.com/disclosure-guidelines).
+* Public disclosure of a vulnerability makes it ineligible for a bounty. If the user reports the vulnerability to other security teams (e.g. Ethereum or ETC) but reports to Rootstock with considerable delay, then Rootstock may reduce or cancel the bounty.
+
+For more information check Rootstock bounty program policy at [HackerOne](https://hackerone.com/iovlabs)
+
+## Public Keys
+
+### Security
+
+```gpg
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2
+
+mQINBFoF+z0BEADJNtu4DjEqH3+TzdwNwPfRmHo7hhSBR08wnLfkWmsm3IxgEqdB
+wYU8rMNXpnsiToTjDnCYYacxQR5uUN4MbYvtnKqGbiapZ5EgCDoRMKYKhJwTuAjH
+ju9cPfblwuIG9eLJ7NJ9t/C+07JQQzDolPo3JBzXjeNDMS21YNqiUfHRCIKcTC45
+/ksfX0q5UG0KM0FgYiAYJer0OQp/A2KETzzweXdNTs+KXDuA1ChafQ/3x3efDG+D
+HekfQULToISKMq36Fh2icjMDY4I93iDXGa8xDoGYt1OIGuPS37XVdNjudlvsybgU
+8Y6vnw3xp9r5dP3Dvb43yYNXAiTErLiU6jkufUj1Jo85nwJDMSiaXwFfAeiiv1WO
+ThdRwrEOKYLVIAb0mhT1Gcqf4PC0nVX/RyPsF8OztgiJBAp/4jY/8POmGi7KdDKG
+Fa/r1eV/Tuk8yfh+GYq7LkdT92up5uUxPACCGvkP3+5vLu9R8ttO6DDl3eYGIpla
+mP4JTGaFWmVi/Fq+7u2JTZI3CpVsx7CBH5Loluof6Yp6ijqtrzDwGPsD6a/qqQpx
+hPwO0jYhrCFgRl369gkavlT4y2IodNw8D1Hx1MtIYLVwS7PD7XIcfLwsOl5I0Bc5
+SKbW4hJ8VPj/Qv+I5tDu1G/GbTmE5wSly7SbVMSvtSOUzIlbczONKi+mrQARAQAB
+tB9TZWMgQ2hhbm5lbCA8c2VjY2hhbm5lbEByc2suY28+iQI9BBMBCgAnBQJaBfs9
+AhsDBQkJZgGABQsJCAcDBRUKCQgLBRYCAwEAAh4BAheAAAoJEFjSJg1ZmGdY6tYP
+/A3P75RTZdl37JzHEWh6kfNJ6LdmCBTxbtwUxCmhKKKtgl1lSamtIkbiI6imY0Vk
+VCNxkHN56QjqK3ELRx7lwjXmKUNMe5Yql/5g86vpEznO/y6C5tv5W4k32dQwxrlV
+LUEwrfddQKts3TiUHzeGLjTdNk7ZV82427CgeNC/rsovQZ+mvWtjdhM0vq99vH+D
+T5cAMRlEparUgvKKfzSwznxrFcviPq+Za4HvOjTec8HP7tJfJNNzjyeXvlmHG10V
+euLOOr2mq7f2JTg7pKhtX94153XtvGt0HmqNi6k85kABTUKvtxWr1q4AVRFfrBwW
+1qorrOFcRpffpkumsLq/5FT4cEciVZzqUgfq9asyev5Qjtxj7tNlYiqXAsNfqhLp
+dGXiNcI+Kpk2Pe1eaOBH2QrE1Yg9aRQsq7Wkg7myyTktYpQg8t3s5JjEqIU66bLL
+it7OWPYjfV8bQ07r/64NZbNVyFF5qvAgI/cINTo27dfWQmELOXyymXQJLyEO1qHg
+hEFUoa3jnlC1Gpi7JyMHbEADb0a7zZf6TZyyeaPFG1bxcSB11BKm6NEfiQovccjq
+8E9wUZ1/BSC4YCvw9cmiHsZqKx5/KUxJlN9fYA0WCyQ7PWuc/8bAwEWlFUHDJdQ3
+BDxvpznL9u17Z3p+7+ASHiOcNiNqfAlNnffrrpqjimEZuQINBFoF/O8BEADH4/MA
+xV0moSw9tTcnTqq5/Pekueugukub7zgoxH8Yh82tKhpcl7sjOo4KaGzwjNHlzEUG
+KGyotaaPhTTxF3lqBfPPEA4EYkLfM3YBlOemI6642rapRQxHFptX1bEMGh+KE9rl
+FRZnN7cuUehbtTMpKwsPr69oMsrg8nF43migiNDa8hjfJ/0egBctovh0UprJLbap
+4Trqhiw5yshjE7wQ5tTJUJ/D+m7cJPrwaTE+mxJywYPp9fkzF/G/AV3K/IOK9LBW
+MWzUTD4aUx1Feji+xq6tgtrPwTwfM016ZHGVBE//7ZkrazUyap4FGjBSwCmWwukA
+NW8GHak7uq4qhTZ4u2raz7nBjkqK8hDr6HA5D+vW7UJGaJRRjBC6FYf45lbwTkVM
+VlogMWSCH36EPaQa3wilYqxDBxWPZVqroEO2RWOWwxWGtk/hUp2kwKKWqOH6lSZQ
+uBvrjPeZWEyfnVdv5AVlZhvb6vADpOYkSSROj7C2wCjKoOdxl+Axek6GhhkIkaIp
+1yK41YYnqq/FyFjeVQ82j1/zQp8oTcVhC9qGpQiUDeE85hMuhYSU7O1IaNuje2mn
+x5E79oICYtny1MO+LTfKf7OurlQbMZ/9/FgqnwacpLANrOCMWEdB8Spt4+Sk67dK
+e0f6OTkBp00azMlNUC+hIi/E7CFIumxLzpaW0QARAQABiQREBBgBCgAPBQJaBfzv
+AhsCBQkJZgGAAikJEFjSJg1ZmGdYwV0gBBkBCgAGBQJaBfzvAAoJEJOaLKTirVYF
+H/AP/iIgVYB0ooCSjNgLi3HNDj6i8HdVieqGBhhmQodXm1so8MvqZV74Q7hwr0zG
+zISA1BLFoQglVvTeytw+SlsHPIwqnaYugYD7eKuLdD+YUtCpdu1M863CMtYV8RSW
+xyGLYWHurVtVZ686kn7noIwce3SB75fzyozx30BSfaaal0fuCUbJqPMqBRoXJNi9
+pSHc6Vhss9QqLUeskoJaohCgVqk1GnCI+x5vCIfvscR3jFKqvm/FShuI8dvPQfyF
+C+DckmqM1pIrQ5/A8Owh+7F6odW77D4HLCVc7J1tJprPvYvoXrZPWBU2mTy84jn0
+63VQrE2yC+nGIYMBHMQUcOh/Laq5XeuQZoOYJWF7bBDuTiUlCnVjMouSf350jH58
+VRaoGCyDx7Ai40KNT29nR4LVBuJRt3nHczhqb6tHVYiXKv5NWmuJsn6lNsY6OrCo
+prfsXlVfX1Bad3p0srIHzliUK4jBFs4Dtfz9aCoI1Lw8WfBgNTxqptfxdudE2qDz
+OhYBq3Vp4NUYgKvBlFUhxofkMBNOoASkihgqguRvmsdhoBpQPRVLSGpFzExP95YC
+MsH6fVYERC6BCrE3D3fH3eMIe1OkBznYJNDZKduWlolWB/aLVBZTsMmAQjUWE9Zu
+6GxkQbqk6RjHMvty26bCHW/fqI4tCGxQ5f42jvNxm8InM22KxM4P/2aSqxVs9bXl
+80liZlIL1lMqp9QkghlP4A2hJgzMkNmeDzEsdZxbsNRcmARa7CTy0RZUjHiMZSU+
+LLWTVnrrt96oslbGE0laSwsMJL3DUJwIAyWQqIB9ppOLtnbU/gSjxhgdn1jdnFNl
+DyGYRM5Ys/qNfDE24NGCQjmKfgM6QhiKZgxnEOyMdXm/Kall8YG8g71jyfEGXbzS
+qCy815NSqepQ43gMs0DXfgVUORSSNJS8r6qQOzuWgoZ2T1hK3nJawhmH5AiWi4eR
+8HPgYZXPvwP0NIXrEFIW9QyOOJAR51u6GWLWVKDDH1MkFzXbUx3D8yu4groXuElB
+gkd6gzYB7gSngZF+DZsoD5tbhCO0GWbZKgpL7pjAeEgqsWrhhZFoYOT4rK2nn0lJ
+4aENQUgo+Bdn0zr9uSkE4yujzAXrIXLKX5eN3J+WPKxoO3W2NdyWySklwj5fszLO
+NH8lLEdJ895BIPt/0ZErAGC5l7eDUi0Pnk8CgWoSL8YSKHHAq2GVCgFcgw5uh6o6
+SuHccFq/TRXzkEgeTZ/n0LxbtKr5W4Qlly0Krgbt7ybf4gzLG1RbERYmVnndMWJ6
+CdwepVQE4Lc/SIZCNLd9uUbdgnkblcEtap4OxMBmYyKW3bCCpsvGdjVbKesFlSN+
+U2jfqj6/UEFtGoY/A0TiZcayn9felM7wuQINBFoF/WsBEACkQdxQFzhwz1YNm3Xr
+6vNGkxMg0kfZJxbUXuopuUbFWAg9RfIJ1BPk/wox/pwRnGm9RZUh/h1dXswAdM2X
+4Y8PWcfRb/FEnhGOr5VEF3pC0WPHSJ2K8Akfee/VBhnV8Nnv76LpMnC5C7AbwmUh
+0OHGMoXPDb8fG2GZWtZs/4g3LfPNNws1caLpsgQTa2jzatc93NFdH8ae915dPTY2
+y0FVXJn3hW0AGlTaOTktkNhfAaU8Ko1GhYBEDtD/klXZKhxhUgkK+nz94Z2DHbzI
+zBEAI9RPCoZFIFzmTTuAn8tyHWAc1tDXZRGIq4IfJa2mJsTDfiItOGaMQXXFBjFj
+e4K6ATA2En0Hr6dR3ybhN9bq9an0xzj22T5JEPhr2liwlKjEr2cZsKQhg8iawHNf
+cHYhCWrK1qlr6dw71BIdoRstNGMDkN8sE76oWMVSlJuJdWAvzQm9/ubcWg5LFQWZ
+LAomYp/WobteAzcMTRsC5F8LMxNp+CXJS8c/wwCX9h0GM2qP8mG9GjxEHIwugkKK
+CPsLvngJMe0oXkpndDIahPsjsVDMuN27zlpHIFtcwhQvdnPh2WnHDx3EMt8ol3Lh
+i7xmGqoHxl9DO5Idr797Ou+U1y9TtFs4jk/NJ99z+D6KwpCLT/WQ449SMnUanaOm
+Pe/8ocZ3PDnqmVcAW/bWkw1RBwARAQABiQIlBBgBCgAPBQJaBf1rAhsMBQkJZgGA
+AAoJEFjSJg1ZmGdYOIkP/1GUWKjzVPeMhh97gbllQrxqkmopOGQpyUqq9OPhhvih
+lm5hHg6qolf6cbW3yINFvUxL9ycJQUrV8ZCTQeOR0s5M+noHpui3i4tt3wmtE20D
+0AJolj2rd63Cn0mh5eGRyx1nMz3V/jAl2fgLUa/BIAa5lI08bZQIVJy0qKHaN3rH
+xU2Tp5MbKrDFG+WOrWYO8Ehw+h+U6G5+IWDQXThBID7J5CZ48KmVVSwVxh8OmTsi
+sTfetQ5Hr7oTid9gSu4gDmOuXo2Hg+sWpuACBZX9eyPTTYnts1c/85UctOonePTO
+pGV0OWGS72TmILQXH+ZmkKbvu1OGM7bIMM8uo5kaTEsN7sFv/LPgszlDj7peaFpP
+lCKsb2H0k1x6z0y5l5r7BBMMt+q7OHl4XO5PPoMk/ri4weDYRUP0LhZ5V/dwotbB
+Q4O9JAu7HAVFSbEsUgahhZGGx1ozwm1tEV5sjNVo0G+pFW933N/nquTi9PrIrSJn
+kXEAGI6Scd2wIl7Y7/ustYA8RDgpRuN65C/R/cETMqVa8noyZWrBLzi40y7PHMHR
+fbQUVf0+ULWR9BtmOvv+V770n5uWnK+VYAUpKhfF3d/BOybKXAlLzNTeSbkebzGg
+0zzL96O9QN+MTaejvVQUlwdggjhTO0SAzc4CyHy8XKzYfSx3fQxb4uZ0uPw2Zxap
+uQINBFoF/eIBEADI3zgxwZpyH+5E2XKSXaW855HBKUkpExWtiC7Fjb7vsBSo2kmO
+ZKEcP464MRC59j2n/vjoj5A1qVjkXFJcrdVNm7VcF+APsVDJCWscOp0HSLaf0iVM
+TxEoWKUUL6Q/IpepOcufcIQ51IX5SfQ3gMKAzJ3z0IQLm+Zz1oD+NCSscXVVIe9M
+zPxY/GKMkjIhdYNmYH5jvhXybhdt6H26z3s7w5K//7+mg+jvsac08wogetjx8V0Q
+Gp2d6Q/AW2HQX8YoMrBjZYuEMZRSydiU6K7KRS78mAzxuTLjPK9OvOsaTuFHvqFR
+AD/qXsyT9OLrpzPnTcoIfquH2ylk79M54jGR8J/JDhQk88lv7tkEVhQW9f+dhYDU
+MFwGZm4QxolmBZfMj5rU6dY+uigTNpKyDr0MS5cVptZiRvBZSMGPMhp0Yt48OLlt
+w+2/p/7FxhYkNpqjKCATdkS0yJJ2qW0dFWpzzOGNI4xwb/W+kaftW+kU/Sg8qwQl
+CdgjkxZ7CNPddomLNqdU5z0FeKwVMUnDHf5I08GnXAFx+/OYb2TIZXSKlSrHDDHA
++Pm3hqnzJP0r3yVVt0MHl7eln5aXew7zG2yBK4cm+YwAjfDhTLkwYTRC8ge8GDKf
+YyPqv38sDBsQCFTERGDPoZp5Smt9C3deYkgrqBR1iJZHNuM+7WL8J0ZjLwARAQAB
+iQIlBBgBCgAPBQJaBf3iAhsgBQkJZgGAAAoJEFjSJg1ZmGdYko0P/Rxk1TJCXaEj
+dX5WYYqITQE5iO5FWuuOpHf054S/yE9gcD5BGZSLakwummLVKEJyFlgZW3Tc2p9C
+5PyqukuEHLjep3UNYiQLX4rupeqovfEI8q3cJJrEa30svDmNO+kQYlPVemjsNo7l
+XmWm+LM281Ycg4ZYFpUIsDGupNFiQyLbKizXEICkhrBs8NaTCyp4yHJVuo75z/w5
+/p8HndVR4u62Qmxn06XZICjd8nQXK9bPen5OZ6O42yOL4/zCGJgQzrshMiBZwPUf
+Q6hjQJkgD/PttjL32SeIAGC6ca4uVR5MqPub1RDaIe6CZJ/Go8lZX+dxQzCJbdv+
+DcdNL7HHw9EVTR3wRdI7DwJbH1vJCEO1i1RTZBJd3sKhwHtdSXkdOwIWYgnUF2fx
+ermtX1AKDpAKkMumwMMvAFA6ntevmNmdc35LCCq5rMX4ClKVn5+0n5YeAdxH7teZ
+0FzlNBDmYtdeYWnMXut/ukHO2GWZyXkbfXXXQhezeUQaWuyCfsAuocqHvEtRYoVx
+iZ1WSLgU34q1rcX2abQsHUWRxZmBfKD6RZ15bvlIM99ne2/bDSBETz4KUCIa2WIV
+v0FjOkVKB3PSHj1q4fogldX0Yb55tUa3rX0Rb8QEKInQj8FFPd44XHclv9PTv0OL
+IfHtYt8huvu34FA85HR8wAOPiqvyJ7Oj
+=r7Yf
+-----END PGP PUBLIC KEY BLOCK-----
+```
diff --git a/bridge/.gitignore b/bridge/.gitignore
index 6106317db..aa5a812af 100644
--- a/bridge/.gitignore
+++ b/bridge/.gitignore
@@ -1,2 +1,58 @@
-mainconf.json
-sideconf.json
+infura.key
+mnemonic.key
+etherscan.key
+#Build
+/out
+/build
+
+#Truffle
+.openzeppelin/.session
+.openzeppelin/dev-*.json
+.openzeppelin/kovan.json
+.openzeppelin/mainnet.json
+coverage/
+coverage.json
+.coverage_contracts
+.coverage_artifacts
+deployed/development.json
+deployed/development_1.json
+deployed/mirrorDevelopment.json
+deployed/soliditycoverage.json
+
+#Hardhat files
+cache
+artifacts
+deployments/development
+
+# Waffle
+waffle_flatten
+
+# Coverage directory used by tools like istanbul
+coverage
+*.lcov
+
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+
+# Optional npm cache directory
+.npm
+
+# Optional REPL history
+.node_repl_history
+
+# Diagnostic reports (https://nodejs.org/api/report.html)
+report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Script files
+arguments.js
diff --git a/bridge/.nvmrc b/bridge/.nvmrc
new file mode 100644
index 000000000..19c7bdba7
--- /dev/null
+++ b/bridge/.nvmrc
@@ -0,0 +1 @@
+16
\ No newline at end of file
diff --git a/bridge/.prettierrc.json b/bridge/.prettierrc.json
new file mode 100644
index 000000000..99846c41a
--- /dev/null
+++ b/bridge/.prettierrc.json
@@ -0,0 +1,26 @@
+{
+ "overrides": [
+ {
+ "files": "*.sol",
+ "options": {
+ "printWidth": 80,
+ "tabWidth": 4,
+ "useTabs": false,
+ "singleQuote": false,
+ "bracketSpacing": false,
+ "explicitTypes": "always"
+ }
+ },
+ {
+ "files": "*.js",
+ "options": {
+ "parser": "json5",
+ "printWidth": 120,
+ "tabWidth": 2,
+ "useTabs": false,
+ "singleQuote": true,
+ "bracketSpacing": false
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/bridge/.solcover.js b/bridge/.solcover.js
new file mode 100644
index 000000000..8c2553bf1
--- /dev/null
+++ b/bridge/.solcover.js
@@ -0,0 +1,16 @@
+module.exports = {
+ skipFiles: [
+ 'test',
+ 'zeppelin',
+ 'Bridge/BridgeV3.sol',
+ 'Bridge/IBridgeV3.sol',
+ 'SideToken/SideTokenV1.sol',
+ 'Federation/FederationV2.sol',
+ 'AllowTokens/AllowTokensV0.sol',
+ 'SideTokenFactory/SideTokenFactoryV1.sol',
+ ],
+ providerOptions: {
+ network_id: 5888,
+ //vmErrorsOnRPCResponse: false
+ }
+};
\ No newline at end of file
diff --git a/bridge/.solhint.json b/bridge/.solhint.json
new file mode 100644
index 000000000..38ac4f8a7
--- /dev/null
+++ b/bridge/.solhint.json
@@ -0,0 +1,11 @@
+{
+ "extends": "solhint:recommended",
+ "rules": {
+ "func-order": "off",
+ "mark-callable-contracts": "off",
+ "compiler-version": "off",
+ "reason-string": ["warn", { "maxLength": 64 }],
+ "no-inline-assembly": "off",
+ "func-visibility": ["error", { "ignoreConstructors": true }]
+ }
+ }
\ No newline at end of file
diff --git a/bridge/.solhintignore b/bridge/.solhintignore
new file mode 100644
index 000000000..33451c7c0
--- /dev/null
+++ b/bridge/.solhintignore
@@ -0,0 +1,5 @@
+Migrations.sol
+MultiSigWallet.sol
+test
+zeppelin
+previous
\ No newline at end of file
diff --git a/bridge/README.md b/bridge/README.md
index 19a41f9d7..bfbb0c80d 100644
--- a/bridge/README.md
+++ b/bridge/README.md
@@ -1,32 +1,41 @@
# Token Bridge Contracts
-## Install Truffle
+## Contract coverage
+[](https://coveralls.io/github/rsksmart/tokenbridge)
+
+## Install dependencies
+Use node 16.
+Install node https://nodejs.org/es/
+Then install dependencies
```
-npm install -g truffle@4.1.14
+npm install
```
+
## Running test
```
-truffle test --network test
+npm run test
+npm run lint
+npm run coverage
```
## Configure networks
-Edit the truffle configuration file
+Edit the hardhat configuration file
```js
module.exports = {
- // See
- // to customize your Truffle configuration!met
+ // See https://hardhat.org/config/
+ // to customize your hardhat configuration
networks: {
development: {
host: "127.0.0.1",
port: 8545,
network_id: "*" // Match any network id
},
- regtest: {
+ rskregtest: {
host: "127.0.0.1",
port: 4444,
network_id: "*" // Match any network id
@@ -43,27 +52,30 @@ Launch the local network
ganache-cli --verbose
```
-A Windows command deploys the solution to mainchain and sidechain (both points
-to truffle development network, usually a ganache-cli instance)
+Deploy using hardhat to the desire network
```
-deploysymm
+npm run deploy --network
```
-Another Windows command deploys the solution to mainchain using truffle development network, and sidechain using
-truffle regtest network. Usually, there are differente nodes, ie two different ganache-cli instances.
+Examples
```
-deploysymm2
+npm run deploy --network development
+npm run deploy --network rskregtest
```
-TBD: Explain deploy of other configurations (RSK regtest, symmetric vs asymmetric deploy)
-
-## To Do
-
-- Prevent federator vote transactions that are not accepted/processed, filling storage space
-- Remove inverse account mapping (no use case)
-
+This will also generate the json files for that network with the addresses of the deployed contracts that will be called by the federator.
+#### Using HardHat
+After the deployments usign hardhat deploy, you will be able to verify all the deployed contracts using an script
+```shell
+$~ verify-script -n
+```
+> The network name is defined at `hardhat.config.js`
+## Contracts
+- All the contracts to be deployed from now on should use the [abidecoder v2](https://docs.soliditylang.org/en/v0.8.0/080-breaking-changes.html)
+- So, at the `.sol` contracts add the `pragma abicoder v2;` at the top, right after the pragma solidity version, like this:
+
diff --git a/bridge/abi/AllowTokens.json b/bridge/abi/AllowTokens.json
new file mode 100644
index 000000000..bbb483f42
--- /dev/null
+++ b/bridge/abi/AllowTokens.json
@@ -0,0 +1,947 @@
+[
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ }
+ ],
+ "name": "AllowedTokenRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "ConfirmationsChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ }
+ ],
+ "name": "SetToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_typeDescription",
+ "type": "string"
+ }
+ ],
+ "name": "TokenTypeAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "indexed": false,
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "TypeLimitsChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_lastDay",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_spentToday",
+ "type": "uint256"
+ }
+ ],
+ "name": "UpdateTokensTransfered",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_TYPES",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Secondary_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "description",
+ "type": "string"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "addTokenType",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "len",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "allowedTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "calcMaxWithdraw",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "maxWithdraw",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "smallAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ }
+ ],
+ "name": "getInfoAndLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokenInfo",
+ "name": "info",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limit",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypeDescriptions",
+ "outputs": [
+ {
+ "internalType": "string[]",
+ "name": "descriptions",
+ "type": "string[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypeDescriptionsLength",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypesLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits[]",
+ "name": "limits",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_primary",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "string",
+ "name": "description",
+ "type": "string"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TypeInfo[]",
+ "name": "typesInfo",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "isTokenAllowed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "largeAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "mediumAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "removeAllowedToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "setConfirmations",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokensAndType[]",
+ "name": "tokensAndTypes",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "setMultipleTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ }
+ ],
+ "name": "setToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "setTypeLimits",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "smallAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ }
+ ],
+ "name": "tokenInfo",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokenInfo",
+ "name": "",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "typeDescriptions",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "typeLimits",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "updateTokenTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ }
+]
diff --git a/bridge/abi/AllowTokensProxy.json b/bridge/abi/AllowTokensProxy.json
new file mode 100644
index 000000000..fb5a6db7f
--- /dev/null
+++ b/bridge/abi/AllowTokensProxy.json
@@ -0,0 +1,133 @@
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_admin",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+]
diff --git a/bridge/abi/AllowTokensV0.json b/bridge/abi/AllowTokensV0.json
new file mode 100644
index 000000000..b9d5e144f
--- /dev/null
+++ b/bridge/abi/AllowTokensV0.json
@@ -0,0 +1,378 @@
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ }
+ ],
+ "name": "AllowedTokenAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ }
+ ],
+ "name": "AllowedTokenRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "_enabled",
+ "type": "bool"
+ }
+ ],
+ "name": "AllowedTokenValidation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "dailyLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "DailyLimitChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_maxTokens",
+ "type": "uint256"
+ }
+ ],
+ "name": "MaxTokensAllowedChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_minTokens",
+ "type": "uint256"
+ }
+ ],
+ "name": "MinTokensAllowedChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "addAllowedToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "allowedTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ }
+ ],
+ "name": "calcMaxWithdraw",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_dailyLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeDailyLimit",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "dailyLimit",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "disableAllowedTokensValidation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "enableAllowedTokensValidation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getMaxTokensAllowed",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getMinTokensAllowed",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "isTokenAllowed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenToUse",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "isSideToken",
+ "type": "bool"
+ }
+ ],
+ "name": "isValidTokenTransfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isValidatingAllowedTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "removeAllowedToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "maxTokens",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMaxTokensAllowed",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "minTokens",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMinTokensAllowed",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/bridge/abi/Bridge.json b/bridge/abi/Bridge.json
new file mode 100644
index 000000000..d08800ff0
--- /dev/null
+++ b/bridge/abi/Bridge.json
@@ -0,0 +1,1721 @@
+[
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "AcceptedCrossTransfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "AllowTokensChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_reciever",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Claimed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "_userData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Cross",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "FederationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "FeePercentageChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_newSideTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_newSymbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_granularity",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_chainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "NewSideToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Paused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "SideTokenFactoryChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Unpaused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "Upgrading",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "WrappedCurrencyChanged",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "CLAIM_TYPEHASH",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Pausable_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__PauserRol_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "acceptTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "addPauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "allowTokens",
+ "outputs": [
+ {
+ "internalType": "contract IAllowTokens",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "changeAllowTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "changeFederation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "changeSideTokenFactory",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claim",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claimFallback",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_deadline",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_v",
+ "type": "uint8"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_r",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_s",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimGasless",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_originalTokenDecimals",
+ "type": "uint8"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenName",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.CreateSideTokenStruct[]",
+ "name": "createSideTokenStruct",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "createMultipleSideTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_originalTokenDecimals",
+ "type": "uint8"
+ },
+ {
+ "internalType": "string",
+ "name": "_tokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_tokenName",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deprecatedKnownTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deprecatedMappedTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deprecatedOriginalTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "deprecatedSymbolPrefix",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "domainSeparator",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "feePercentageDivider",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFederation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFeePercentage",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ }
+ ],
+ "name": "getOriginalTokenBySideToken",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.OriginalToken",
+ "name": "originalToken",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getTransactionDataHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasBeenClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasCrossed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initDomainSeparator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_federation",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_allowTokens",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_sideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionDataHashMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionDataHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionDataHashMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isPauser",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isUpgrading",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "originalToken",
+ "type": "address"
+ }
+ ],
+ "name": "knownToken",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "knownTokenByChain",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "nonces",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "originalTokenAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "originalTokenBySideToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "pause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "paused",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "tokenToUse",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "receiveTokensTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renouncePauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "senderAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "setFeePercentage",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ },
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.OriginalToken",
+ "name": "originalToken",
+ "type": "tuple"
+ }
+ ],
+ "name": "setOriginalTokenBySideTokenByChain",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "originalToken",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ }
+ ],
+ "name": "setSideTokenByOriginalAddressByChain",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "setUpgrading",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "setWrappedCurrency",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "originalToken",
+ "type": "address"
+ }
+ ],
+ "name": "sideTokenByOriginalToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "sideTokenByOriginalTokenByChain",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "sideTokenFactory",
+ "outputs": [
+ {
+ "internalType": "contract ISideTokenFactory",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "userData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "tokensReceived",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionsDataHashes",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unpause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "wrappedCurrency",
+ "outputs": [
+ {
+ "internalType": "contract IWrapped",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+]
diff --git a/bridge/abi/BridgeProxy.json b/bridge/abi/BridgeProxy.json
new file mode 100644
index 000000000..fb5a6db7f
--- /dev/null
+++ b/bridge/abi/BridgeProxy.json
@@ -0,0 +1,133 @@
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_admin",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+]
diff --git a/bridge/abi/BridgeV3.json b/bridge/abi/BridgeV3.json
new file mode 100644
index 000000000..33e492b1a
--- /dev/null
+++ b/bridge/abi/BridgeV3.json
@@ -0,0 +1,1305 @@
+[
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ }
+ ],
+ "name": "AcceptedCrossTransfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "AllowTokensChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_reciever",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ }
+ ],
+ "name": "Claimed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "_userData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Cross",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "FederationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "FeePercentageChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_newSideTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_newSymbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "NewSideToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Paused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "SideTokenFactoryChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Unpaused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "Upgrading",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "WrappedCurrencyChanged",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "CLAIM_TYPEHASH",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "DOMAIN_SEPARATOR",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Pausable_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__PauserRol_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "acceptTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "addPauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "allowTokens",
+ "outputs": [
+ {
+ "internalType": "contract IAllowTokens",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "changeAllowTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "changeFederation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "changeSideTokenFactory",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct IBridgeV3.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claim",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct IBridgeV3.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claimFallback",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct IBridgeV3.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_deadline",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_v",
+ "type": "uint8"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_r",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_s",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimGasless",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_originalTokenDecimals",
+ "type": "uint8"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenName",
+ "type": "string"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "feePercentageDivider",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFederation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFeePercentage",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "getTransactionDataHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasBeenClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasCrossed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initDomainSeparator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_federation",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_allowTokens",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_sideTokenFactory",
+ "type": "address"
+ },
+ {
+ "internalType": "string",
+ "name": "_symbolPrefix",
+ "type": "string"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isPauser",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isUpgrading",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "knownTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "mappedTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "nonces",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "originalTokenAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "originalTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "pause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "paused",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenToUse",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "receiveTokensTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renouncePauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "senderAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "setFeePercentage",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "setUpgrading",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "setWrappedCurrency",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "sideTokenFactory",
+ "outputs": [
+ {
+ "internalType": "contract ISideTokenFactory",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbolPrefix",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "userData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "tokensReceived",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionsDataHashes",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unpause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "wrappedCurrency",
+ "outputs": [
+ {
+ "internalType": "contract IWrapped",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+]
diff --git a/bridge/abi/ERC777.json b/bridge/abi/ERC777.json
new file mode 100644
index 000000000..83829d720
--- /dev/null
+++ b/bridge/abi/ERC777.json
@@ -0,0 +1,578 @@
+[
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "aName",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "aSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "address[]",
+ "name": "theDefaultOperators",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "tokenHolder",
+ "type": "address"
+ }
+ ],
+ "name": "AuthorizedOperator",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Burned",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Minted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "tokenHolder",
+ "type": "address"
+ }
+ ],
+ "name": "RevokedOperator",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Sent",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "holder",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ }
+ ],
+ "name": "authorizeOperator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenHolder",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "burn",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "defaultOperators",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "granularity",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "tokenHolder",
+ "type": "address"
+ }
+ ],
+ "name": "isOperatorFor",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "operatorBurn",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "operatorSend",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ }
+ ],
+ "name": "revokeOperator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "send",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "holder",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/bridge/abi/Federation.json b/bridge/abi/Federation.json
new file mode 100644
index 000000000..359b25f19
--- /dev/null
+++ b/bridge/abi/Federation.json
@@ -0,0 +1,798 @@
+[
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridge",
+ "type": "address"
+ }
+ ],
+ "name": "BridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Executed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "currentChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "currentBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "fedVersion",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256[]",
+ "name": "fedChainsIds",
+ "type": "uint256[]"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256[]",
+ "name": "fedChainsBlocks",
+ "type": "uint256[]"
+ },
+ {
+ "indexed": false,
+ "internalType": "string[]",
+ "name": "fedChainsInfo",
+ "type": "string[]"
+ }
+ ],
+ "name": "HeartBeat",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Voted",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_MEMBER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_newMember",
+ "type": "address"
+ }
+ ],
+ "name": "addMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridge",
+ "outputs": [
+ {
+ "internalType": "contract IBridge",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "fedVersion",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "fedChainsIds",
+ "type": "uint256[]"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "fedChainsBlocks",
+ "type": "uint256[]"
+ },
+ {
+ "internalType": "string[]",
+ "name": "fedChainsInfo",
+ "type": "string[]"
+ }
+ ],
+ "name": "emitHeartbeat",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getMembers",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getTransactionId",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_members",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isMember",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionIdMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionIdMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "members",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "processed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_oldMember",
+ "type": "address"
+ }
+ ],
+ "name": "removeMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ }
+ ],
+ "name": "setBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionWasProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "voteTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "votes",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
diff --git a/bridge/abi/FederationProxy.json b/bridge/abi/FederationProxy.json
new file mode 100644
index 000000000..fb5a6db7f
--- /dev/null
+++ b/bridge/abi/FederationProxy.json
@@ -0,0 +1,133 @@
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_admin",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+]
diff --git a/bridge/abi/FederationV2.json b/bridge/abi/FederationV2.json
new file mode 100644
index 000000000..c5914398f
--- /dev/null
+++ b/bridge/abi/FederationV2.json
@@ -0,0 +1,711 @@
+[
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridge",
+ "type": "address"
+ }
+ ],
+ "name": "BridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Executed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "HeartBeat",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Voted",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_MEMBER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_newMember",
+ "type": "address"
+ }
+ ],
+ "name": "addMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridge",
+ "outputs": [
+ {
+ "internalType": "contract IBridgeV3",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "emitHeartbeat",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getMembers",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "getTransactionId",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_members",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isMember",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "members",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "processed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_oldMember",
+ "type": "address"
+ }
+ ],
+ "name": "removeMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ }
+ ],
+ "name": "setBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionWasProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "voteTransaction",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "votes",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
diff --git a/bridge/abi/IERC20.json b/bridge/abi/IERC20.json
new file mode 100644
index 000000000..ea3bb351f
--- /dev/null
+++ b/bridge/abi/IERC20.json
@@ -0,0 +1,185 @@
+[
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/bridge/abi/MainToken.json b/bridge/abi/MainToken.json
new file mode 100644
index 000000000..ad13a0049
--- /dev/null
+++ b/bridge/abi/MainToken.json
@@ -0,0 +1,327 @@
+[
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "uint8",
+ "name": "decimals",
+ "type": "uint8"
+ },
+ {
+ "internalType": "uint256",
+ "name": "totalSupply",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "subtractedValue",
+ "type": "uint256"
+ }
+ ],
+ "name": "decreaseAllowance",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "addedValue",
+ "type": "uint256"
+ }
+ ],
+ "name": "increaseAllowance",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "name": "transferAndCall",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/bridge/abi/MultiSigWallet.json b/bridge/abi/MultiSigWallet.json
new file mode 100644
index 000000000..6fd15ca2b
--- /dev/null
+++ b/bridge/abi/MultiSigWallet.json
@@ -0,0 +1,545 @@
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_owners",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Confirmation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposit",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Execution",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "ExecutionFailure",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnerAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnerRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Revocation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Submission",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_OWNER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "addOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "confirmTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "confirmations",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "executeTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getConfirmationCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "count",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getConfirmations",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "_confirmations",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getOwners",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "pending",
+ "type": "bool"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "count",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "from",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "to",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "pending",
+ "type": "bool"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "name": "getTransactionIds",
+ "outputs": [
+ {
+ "internalType": "uint256[]",
+ "name": "_transactionIds",
+ "type": "uint256[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "isConfirmed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "owners",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "removeOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "replaceOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "revokeConfirmation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "destination",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "submitTransaction",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "transactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "transactions",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "destination",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+]
diff --git a/bridge/abi/ProxyAdmin.json b/bridge/abi/ProxyAdmin.json
new file mode 100644
index 000000000..77e96bbd8
--- /dev/null
+++ b/bridge/abi/ProxyAdmin.json
@@ -0,0 +1,164 @@
+[
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeProxyAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ }
+ ],
+ "name": "getProxyAdmin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ }
+ ],
+ "name": "getProxyImplementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgrade",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ }
+]
diff --git a/bridge/abi/SideToken.json b/bridge/abi/SideToken.json
new file mode 100644
index 000000000..2d242e7c6
--- /dev/null
+++ b/bridge/abi/SideToken.json
@@ -0,0 +1,772 @@
+[
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "_tokenName",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_tokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "address",
+ "name": "_minterAddr",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_newGranularity",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "tokenHolder",
+ "type": "address"
+ }
+ ],
+ "name": "AuthorizedOperator",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Burned",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Minted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "tokenHolder",
+ "type": "address"
+ }
+ ],
+ "name": "RevokedOperator",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Sent",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "PERMIT_TYPEHASH",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "holder",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ }
+ ],
+ "name": "authorizeOperator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenHolder",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "burn",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "defaultOperators",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "domainSeparator",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "granularity",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "tokenHolder",
+ "type": "address"
+ }
+ ],
+ "name": "isOperatorFor",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "userData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "mint",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "minter",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "nonces",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "operatorBurn",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "operatorSend",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "deadline",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint8",
+ "name": "v",
+ "type": "uint8"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "r",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "s",
+ "type": "bytes32"
+ }
+ ],
+ "name": "permit",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ }
+ ],
+ "name": "revokeOperator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "send",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "transferAndCall",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "success",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "holder",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/bridge/abi/SideTokenFactory.json b/bridge/abi/SideTokenFactory.json
new file mode 100644
index 000000000..0756323e1
--- /dev/null
+++ b/bridge/abi/SideTokenFactory.json
@@ -0,0 +1,95 @@
+[
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "SideTokenCreated",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/bridge/abi/SideTokenFactoryV1.json b/bridge/abi/SideTokenFactoryV1.json
new file mode 100644
index 000000000..61e4badab
--- /dev/null
+++ b/bridge/abi/SideTokenFactoryV1.json
@@ -0,0 +1,84 @@
+[
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ }
+ ],
+ "name": "CreatedSideToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [
+ {
+ "internalType": "contract SideTokenV1",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/bridge/abi/SideTokenV1.json b/bridge/abi/SideTokenV1.json
new file mode 100644
index 000000000..251910c72
--- /dev/null
+++ b/bridge/abi/SideTokenV1.json
@@ -0,0 +1,619 @@
+[
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "_tokenName",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_tokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "address",
+ "name": "_minterAddr",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "tokenHolder",
+ "type": "address"
+ }
+ ],
+ "name": "AuthorizedOperator",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Burned",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Minted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "tokenHolder",
+ "type": "address"
+ }
+ ],
+ "name": "RevokedOperator",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Sent",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "holder",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ }
+ ],
+ "name": "authorizeOperator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenHolder",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "burn",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "defaultOperators",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "granularity",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "tokenHolder",
+ "type": "address"
+ }
+ ],
+ "name": "isOperatorFor",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "userData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "mint",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "minter",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "operatorBurn",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ],
+ "name": "operatorSend",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ }
+ ],
+ "name": "revokeOperator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "send",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "holder",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/bridge/abi/TransparentUpgradeableProxy.json b/bridge/abi/TransparentUpgradeableProxy.json
new file mode 100644
index 000000000..f3d11ec46
--- /dev/null
+++ b/bridge/abi/TransparentUpgradeableProxy.json
@@ -0,0 +1,133 @@
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+]
diff --git a/bridge/contracts/AllowTokens/AllowTokens.sol b/bridge/contracts/AllowTokens/AllowTokens.sol
new file mode 100644
index 000000000..2dff30873
--- /dev/null
+++ b/bridge/contracts/AllowTokens/AllowTokens.sol
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "../zeppelin/math/SafeMath.sol";
+// Upgradables
+import "../zeppelin/upgradable/Initializable.sol";
+import "../zeppelin/upgradable/ownership/UpgradableOwnable.sol";
+import "../zeppelin/upgradable/ownership/UpgradableSecondary.sol";
+
+import "../interface/IAllowTokens.sol";
+
+contract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {
+ using SafeMath for uint256;
+
+ address constant private NULL_ADDRESS = address(0);
+ uint256 constant public MAX_TYPES = 250;
+ mapping (address => TokenInfo) public allowedTokens;
+ mapping (uint256 => Limits) public typeLimits;
+ uint256 public smallAmountConfirmations;
+ uint256 public mediumAmountConfirmations;
+ uint256 public largeAmountConfirmations;
+ string[] public typeDescriptions;
+
+ event SetToken(address indexed _tokenAddress, uint256 _typeId);
+ event AllowedTokenRemoved(address indexed _tokenAddress);
+ event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);
+ event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);
+ event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);
+ event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);
+
+ modifier notNull(address _address) {
+ require(_address != NULL_ADDRESS, "AllowTokens: Null Address");
+ _;
+ }
+
+ function initialize(
+ address _manager,
+ address _primary,
+ uint256 _smallAmountConfirmations,
+ uint256 _mediumAmountConfirmations,
+ uint256 _largeAmountConfirmations,
+ TypeInfo[] memory typesInfo) public initializer {
+ UpgradableOwnable.initialize(_manager);
+ UpgradableSecondary.__Secondary_init(_primary);
+ _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);
+ for(uint i = 0; i < typesInfo.length; i = i + 1) {
+ _addTokenType(typesInfo[i].description, typesInfo[i].limits);
+ }
+ }
+
+ function version() override external pure returns (string memory) {
+ return "v1";
+ }
+
+ function tokenInfo(address tokenAddress) public view returns(TokenInfo memory) {
+ return allowedTokens[tokenAddress];
+ }
+
+ function setTokenInfoByTokenAddress(address tokenAddress, TokenInfo memory info) internal {
+ require(isOwner() || _msgSender() == primary(), "AllowTokens: unauthorized sender");
+ allowedTokens[tokenAddress] = info;
+ }
+
+ function getInfoAndLimits(
+ address tokenAddress
+ ) public view override returns (
+ TokenInfo memory info,
+ Limits memory limit
+ ) {
+ info = tokenInfo(tokenAddress);
+ limit = typeLimits[info.typeId];
+ return (info, limit);
+ }
+
+ function calcMaxWithdraw(address token) public view override returns (uint256 maxWithdraw) {
+ (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);
+ return _calcMaxWithdraw(info, limits);
+ }
+
+ function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {
+ // solium-disable-next-line security/no-block-members
+ if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time
+ info.spentToday = 0;
+ }
+ if (limits.daily <= info.spentToday) {
+ return 0;
+ }
+ maxWithdraw = limits.daily - info.spentToday;
+ if (maxWithdraw > limits.max) {
+ maxWithdraw = limits.max;
+ }
+ return maxWithdraw;
+ }
+
+ function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {
+ (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);
+ require(isTokenAllowed(token), "AllowTokens: Not whitelisted");
+ require(amount >= limit.min, "AllowTokens: Lower than limit");
+
+ // solium-disable-next-line security/no-block-members
+ if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time
+ // solium-disable-next-line security/no-block-members
+ info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time
+ info.spentToday = 0;
+ }
+ uint maxWithdraw = _calcMaxWithdraw(info, limit);
+ require(amount <= maxWithdraw, "AllowTokens: Exceeded limit");
+ info.spentToday = info.spentToday.add(amount);
+ setTokenInfoByTokenAddress(token, info);
+
+ emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);
+ }
+
+ function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {
+ require(bytes(description).length > 0, "AllowTokens: Empty description");
+ len = typeDescriptions.length;
+ require(len + 1 <= MAX_TYPES, "AllowTokens: Reached MAX_TYPES");
+ typeDescriptions.push(description);
+ _setTypeLimits(len, limits);
+ emit TokenTypeAdded(len, description);
+ return len;
+ }
+
+ function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {
+ return _addTokenType(description, limits);
+ }
+
+ function _setTypeLimits(uint256 typeId, Limits memory limits) private {
+ require(typeId < typeDescriptions.length, "AllowTokens: bigger than typeDescriptions");
+ require(limits.max >= limits.min, "AllowTokens: maxTokens smaller than minTokens");
+ require(limits.daily >= limits.max, "AllowTokens: dailyLimit smaller than maxTokens");
+ require(limits.mediumAmount > limits.min, "AllowTokens: limits.mediumAmount smaller than min");
+ require(limits.largeAmount > limits.mediumAmount, "AllowTokens: limits.largeAmount smaller than mediumAmount");
+ typeLimits[typeId] = limits;
+ emit TypeLimitsChanged(typeId, limits);
+ }
+
+ function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {
+ _setTypeLimits(typeId, limits);
+ }
+
+ function getTypesLimits() external view override returns(Limits[] memory limits) {
+ limits = new Limits[](typeDescriptions.length);
+ for (uint256 i = 0; i < typeDescriptions.length; i++) {
+ limits[i] = typeLimits[i];
+ }
+ return limits;
+ }
+
+ function getTypeDescriptionsLength() external view override returns(uint256) {
+ return typeDescriptions.length;
+ }
+
+ function getTypeDescriptions() external view override returns(string[] memory descriptions) {
+ descriptions = new string[](typeDescriptions.length);
+ for (uint256 i = 0; i < typeDescriptions.length; i++) {
+ descriptions[i] = typeDescriptions[i];
+ }
+ return descriptions;
+ }
+
+ function isTokenAllowed(address token) public view notNull(token) override returns (bool) {
+ return tokenInfo(token).allowed;
+ }
+
+ function setToken(address token, uint256 typeId) override public notNull(token) {
+ require(isOwner() || _msgSender() == primary(), "AllowTokens: unauthorized sender");
+ require(typeId < typeDescriptions.length, "AllowTokens: typeId does not exist");
+ TokenInfo memory info = tokenInfo(token);
+ info.allowed = true;
+ info.typeId = typeId;
+ setTokenInfoByTokenAddress(token, info);
+ emit SetToken(token, typeId);
+ }
+
+ function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {
+ require(tokensAndTypes.length > 0, "AllowTokens: empty tokens");
+ for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {
+ setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);
+ }
+ }
+
+ function removeAllowedToken(address token) external notNull(token) onlyOwner {
+ TokenInfo memory info = tokenInfo(token);
+ require(info.allowed, "AllowTokens: Not Allowed");
+ info.allowed = false;
+ setTokenInfoByTokenAddress(token, info);
+ emit AllowedTokenRemoved(token);
+ }
+
+ function setConfirmations(
+ uint256 _smallAmountConfirmations,
+ uint256 _mediumAmountConfirmations,
+ uint256 _largeAmountConfirmations) external onlyOwner {
+ _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);
+ }
+
+ function _setConfirmations(
+ uint256 _smallAmountConfirmations,
+ uint256 _mediumAmountConfirmations,
+ uint256 _largeAmountConfirmations) private {
+ require(_smallAmountConfirmations <= _mediumAmountConfirmations, "AllowTokens: small bigger than medium confirmations");
+ require(_mediumAmountConfirmations <= _largeAmountConfirmations, "AllowTokens: medium bigger than large confirmations");
+ smallAmountConfirmations = _smallAmountConfirmations;
+ mediumAmountConfirmations = _mediumAmountConfirmations;
+ largeAmountConfirmations = _largeAmountConfirmations;
+ emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);
+ }
+
+ function getConfirmations() external view override
+ returns (
+ uint256 smallAmount,
+ uint256 mediumAmount,
+ uint256 largeAmount
+ ) {
+ return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);
+ }
+
+}
diff --git a/bridge/contracts/AllowTokens/AllowTokensV0.sol b/bridge/contracts/AllowTokens/AllowTokensV0.sol
new file mode 100644
index 000000000..f5e2b56ab
--- /dev/null
+++ b/bridge/contracts/AllowTokens/AllowTokensV0.sol
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../zeppelin/math/SafeMath.sol";
+import "../zeppelin/ownership/Ownable.sol";
+
+contract AllowTokensV0 is Ownable {
+ using SafeMath for uint256;
+
+ address constant private NULL_ADDRESS = address(0);
+
+ mapping (address => bool) public allowedTokens;
+ bool private validateAllowedTokens;
+ uint256 private maxTokensAllowed;
+ uint256 private minTokensAllowed;
+ uint256 public dailyLimit;
+
+ event AllowedTokenAdded(address indexed _tokenAddress);
+ event AllowedTokenRemoved(address indexed _tokenAddress);
+ event AllowedTokenValidation(bool _enabled);
+ event MaxTokensAllowedChanged(uint256 _maxTokens);
+ event MinTokensAllowedChanged(uint256 _minTokens);
+ event DailyLimitChanged(uint256 dailyLimit);
+
+ modifier notNull(address _address) {
+ require(_address != NULL_ADDRESS, "AllowTokens: Address cannot be empty");
+ _;
+ }
+
+ constructor(address _manager) {
+ transferOwnership(_manager);
+ validateAllowedTokens = true;
+ maxTokensAllowed = 10000 ether;
+ minTokensAllowed = 1 ether;
+ dailyLimit = 100000 ether;
+ }
+
+ function isValidatingAllowedTokens() external view returns(bool) {
+ return validateAllowedTokens;
+ }
+
+ function getMaxTokensAllowed() external view returns(uint256) {
+ return maxTokensAllowed;
+ }
+
+ function getMinTokensAllowed() external view returns(uint256) {
+ return minTokensAllowed;
+ }
+
+ function allowedTokenExist(address token) private view notNull(token) returns (bool) {
+ return allowedTokens[token];
+ }
+
+ function isTokenAllowed(address token) public view notNull(token) returns (bool) {
+ if (validateAllowedTokens) {
+ return allowedTokenExist(token);
+ }
+ return true;
+ }
+
+ function addAllowedToken(address token) external onlyOwner {
+ require(!allowedTokenExist(token), "AllowTokens: Token already exists in allowedTokens");
+ allowedTokens[token] = true;
+ emit AllowedTokenAdded(token);
+ }
+
+ function removeAllowedToken(address token) external onlyOwner {
+ require(allowedTokenExist(token), "AllowTokens: Token does not exis in allowedTokenst");
+ allowedTokens[token] = false;
+ emit AllowedTokenRemoved(token);
+ }
+
+ function enableAllowedTokensValidation() external onlyOwner {
+ validateAllowedTokens = true;
+ emit AllowedTokenValidation(validateAllowedTokens);
+ }
+
+ function disableAllowedTokensValidation() external onlyOwner {
+ // Before disabling Allowed Tokens Validations some kind of contract validation system
+ // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived
+ validateAllowedTokens = false;
+ emit AllowedTokenValidation(validateAllowedTokens);
+ }
+
+ function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {
+ require(maxTokens >= minTokensAllowed, "AllowTokens: Max Tokens should be equal or bigger than Min Token");
+ maxTokensAllowed = maxTokens;
+ emit MaxTokensAllowedChanged(maxTokensAllowed);
+ }
+
+ function setMinTokensAllowed(uint256 minTokens) external onlyOwner {
+ require(maxTokensAllowed >= minTokens, "AllowTokens: minTokens should be equal or smaller than maxTokens");
+ minTokensAllowed = minTokens;
+ emit MinTokensAllowedChanged(minTokensAllowed);
+ }
+
+ function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {
+ require(_dailyLimit >= maxTokensAllowed, "AllowTokens: dailyLimit should be equal or bigger than maxTokens");
+ dailyLimit = _dailyLimit;
+ emit DailyLimitChanged(_dailyLimit);
+ }
+
+ // solium-disable-next-line max-len
+ function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {
+ if(amount > maxTokensAllowed)
+ return false;
+ if(amount < minTokensAllowed)
+ return false;
+ if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)
+ return false;
+ if(!isSideToken && !isTokenAllowed(tokenToUse))
+ return false;
+ return true;
+ }
+
+ function calcMaxWithdraw(uint spentToday) external view returns (uint) {
+ uint maxWithrow = dailyLimit - spentToday;
+ if (dailyLimit < spentToday)
+ return 0;
+ if(maxWithrow > maxTokensAllowed)
+ maxWithrow = maxTokensAllowed;
+ return maxWithrow;
+ }
+
+}
diff --git a/bridge/contracts/Bridge.sol b/bridge/contracts/Bridge.sol
deleted file mode 100644
index 943f1437f..000000000
--- a/bridge/contracts/Bridge.sol
+++ /dev/null
@@ -1,61 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "./zeppelin/token/ERC20/ERC20.sol";
-import "./Transferable.sol";
-
-contract Bridge is Transferable {
- address public manager;
- ERC20 public token;
-
- mapping (address => address) mappedAddresses;
- mapping (address => address) mappedInverseAddresses;
-
- modifier onlyManager() {
- require(msg.sender == manager);
- _;
- }
-
- constructor(address _manager, ERC20 _token) public {
- manager = _manager;
- token = _token;
- }
-
- function acceptTransfer(address receiver, uint256 amount) public onlyManager returns(bool) {
- return token.transfer(receiver, amount);
- }
-
- function changeManager(address newmanager) public onlyManager {
- require(newmanager != address(0));
-
- manager = newmanager;
- }
-
- function tokenFallback(address from, uint256 amount, bytes data) public returns (bool) {
- require(msg.sender == address(token));
- return true;
- }
-
- function mapAddress(address to) public {
- mappedAddresses[msg.sender] = to;
- mappedInverseAddresses[to] = msg.sender;
- }
-
- function getMappedAddress(address account) public view returns (address) {
- address mapped = mappedAddresses[account];
-
- if (mapped == address(0))
- return account;
-
- return mapped;
- }
-
- function getMappedInverseAddress(address account) public view returns (address) {
- address mapped = mappedInverseAddresses[account];
-
- if (mapped == address(0))
- return account;
-
- return mapped;
- }
-}
-
diff --git a/bridge/contracts/Bridge/Bridge.sol b/bridge/contracts/Bridge/Bridge.sol
new file mode 100644
index 000000000..1e5d2e49f
--- /dev/null
+++ b/bridge/contracts/Bridge/Bridge.sol
@@ -0,0 +1,702 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "hardhat/console.sol";
+// Import base Initializable contract
+import "../zeppelin/upgradable/Initializable.sol";
+// Import interface and library from OpenZeppelin contracts
+import "../zeppelin/upgradable/utils/ReentrancyGuard.sol";
+import "../zeppelin/upgradable/lifecycle/UpgradablePausable.sol";
+import "../zeppelin/upgradable/ownership/UpgradableOwnable.sol";
+
+import "../zeppelin/introspection/IERC1820Registry.sol";
+import "../zeppelin/token/ERC777/IERC777Recipient.sol";
+import "../zeppelin/token/ERC20/IERC20.sol";
+import "../zeppelin/token/ERC20/SafeERC20.sol";
+import "../zeppelin/utils/Address.sol";
+import "../zeppelin/math/SafeMath.sol";
+import "../zeppelin/token/ERC777/IERC777.sol";
+
+import "../lib/LibEIP712.sol";
+import "../lib/LibUtils.sol";
+
+import "../interface/IBridge.sol";
+import "../interface/ISideToken.sol";
+import "../interface/ISideTokenFactory.sol";
+import "../interface/IAllowTokens.sol";
+import "../interface/IWrapped.sol";
+
+// solhint-disable-next-line max-states-count
+contract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {
+ using SafeMath for uint256;
+ using SafeERC20 for IERC20;
+ using Address for address;
+
+ address constant internal NULL_ADDRESS = address(0);
+ bytes32 constant internal NULL_HASH = bytes32(0);
+ IERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
+
+ address internal federation;
+ uint256 internal feePercentage;
+ string public deprecatedSymbolPrefix;
+ // domainSeparator replaces uint256 internal _depprecatedLastDay;
+ bytes32 public domainSeparator;
+ uint256 internal _deprecatedSpentToday;
+
+ mapping (address => address) public deprecatedMappedTokens; // OriginalToken => SideToken
+ mapping (address => address) public deprecatedOriginalTokens; // SideToken => OriginalToken
+ mapping (address => bool) public deprecatedKnownTokens; // OriginalToken => true
+
+ // claimed can use the same of bytes32
+ mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed
+
+ IAllowTokens public allowTokens;
+ ISideTokenFactory public sideTokenFactory;
+ //Bridge_v1 variables
+ bool public isUpgrading;
+ // Percentage with up to 2 decimals
+ uint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase
+ //Bridge_v2 variables
+ bytes32 constant internal _erc777Interface = keccak256("ERC777Token"); // solhint-disable-line const-name-snakecase
+ IWrapped public wrappedCurrency;
+ mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash
+ mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress
+ mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress
+
+ // keccak256("Claim(address to,uint256 amount,bytes32 transactionHash,uint256 originChainId,address relayer,uint256 fee,uint256 nonce,uint256 deadline)");
+ bytes32 public constant CLAIM_TYPEHASH = 0xaf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c;
+ mapping(address => uint) public nonces;
+
+ //Bridge_v3 variables multichain
+ mapping (uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain; // chainId => OriginalToken Address => SideToken Address
+ mapping (address => OriginalToken) public originalTokenBySideToken; // SideTokenAddress => struct {}
+ mapping (uint256 => mapping(address => bool)) public knownTokenByChain; // chainId => OriginalToken Address => Know
+
+ event AllowTokensChanged(address _newAllowTokens);
+ event FederationChanged(address _newFederation);
+ event SideTokenFactoryChanged(address _newSideTokenFactory);
+ event Upgrading(bool _isUpgrading);
+ event WrappedCurrencyChanged(address _wrappedCurrency);
+
+ function initialize(
+ address _manager,
+ address _federation,
+ address _allowTokens,
+ address _sideTokenFactory
+ ) public initializer {
+ UpgradableOwnable.initialize(_manager);
+ UpgradablePausable.__Pausable_init(_manager);
+ allowTokens = IAllowTokens(_allowTokens);
+ sideTokenFactory = ISideTokenFactory(_sideTokenFactory);
+ federation = _federation;
+ //keccak256("ERC777TokensRecipient")
+ ERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));
+ initDomainSeparator();
+ }
+
+ receive () external payable {
+ // The fallback function is needed to use WRBTC
+ require(_msgSender() == address(wrappedCurrency), "Bridge: not wrappedCurrency");
+ }
+
+ function version() override external pure returns (string memory) {
+ return "v4";
+ }
+
+ function initDomainSeparator() public {
+ domainSeparator = LibEIP712.hashEIP712Domain(
+ "RSK Token Bridge",
+ "1",
+ block.chainid,
+ address(this)
+ );
+ }
+
+ modifier whenNotUpgrading() {
+ require(!isUpgrading, "Bridge: Upgrading");
+ _;
+ }
+
+ function shouldBeCurrentChainId(uint256 chainId) internal view {
+ require(chainId == block.chainid, "Bridge: Not block.chainid");
+ }
+
+ function sideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {
+ address sideTokenAddr = sideTokenByOriginalTokenByChain[chainId][originalToken];
+
+ if (sideTokenAddr != NULL_ADDRESS) {
+ return sideTokenAddr;
+ }
+
+ // specification for retrocompatibility
+ return deprecatedMappedTokens[originalToken];
+ }
+
+ function setSideTokenByOriginalAddressByChain(uint256 chainId, address originalToken, address sideToken) public onlyOwner {
+ sideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;
+ }
+
+ function getOriginalTokenBySideToken(address sideToken) public view returns(OriginalToken memory originalToken) {
+ originalToken = originalTokenBySideToken[sideToken];
+ if (originalToken.tokenAddress != NULL_ADDRESS) {
+ return originalToken;
+ }
+
+ // specification for retrocompatibility
+ originalToken.originChainId = 1; // ethereum main chain id
+ originalToken.tokenAddress = deprecatedOriginalTokens[sideToken];
+ return originalToken;
+ }
+
+ function setOriginalTokenBySideTokenByChain(address sideToken, OriginalToken memory originalToken) public onlyOwner {
+ originalTokenBySideToken[sideToken] = originalToken;
+ }
+
+ function knownToken(uint256 chainId, address originalToken) public view returns(bool) {
+ bool knowToken = knownTokenByChain[chainId][originalToken];
+ if (knowToken) {
+ return knowToken;
+ }
+
+ // specification for retrocompatibility
+ return deprecatedKnownTokens[originalToken];
+ }
+
+ function _setKnownTokenByChain(uint256 chainId, address originalToken, bool knownTokenValue) internal {
+ knownTokenByChain[chainId][originalToken] = knownTokenValue;
+ }
+
+ function acceptTransfer(
+ address _originalTokenAddress,
+ address payable _from,
+ address payable _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex,
+ uint256 _originChainId,
+ uint256 _destinationChainId
+ ) external whenNotPaused nonReentrant override {
+ require(_msgSender() == federation, "Bridge: Not Federation");
+ checkChainId(_originChainId);
+ shouldBeCurrentChainId(_destinationChainId);
+ require(knownToken(_originChainId, _originalTokenAddress) ||
+ sideTokenByOriginalToken(_originChainId, _originalTokenAddress) != NULL_ADDRESS,
+ "Bridge: Unknown token"
+ );
+ require(_to != NULL_ADDRESS, "Bridge: Null To");
+ require(_amount > 0, "Bridge: Amount 0");
+ require(_blockHash != NULL_HASH, "Bridge: Null BlockHash");
+ require(_transactionHash != NULL_HASH, "Bridge: Null TxHash");
+ require(transactionsDataHashes[_transactionHash] == bytes32(0), "Bridge: Already accepted");
+
+ bytes32 _transactionDataHash = getTransactionDataHash(
+ _to,
+ _amount,
+ _blockHash,
+ _transactionHash,
+ _logIndex
+ );
+
+ bytes32 _transactionDataHashMultichain = getTransactionDataHash(
+ _to,
+ _amount,
+ _blockHash,
+ _transactionHash,
+ _logIndex,
+ _originChainId,
+ _destinationChainId
+ );
+ // Do not remove, claimed also has the previously processed using the older bridge version
+ // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41
+ require(!isClaimed(_transactionDataHash, _transactionDataHashMultichain), "Bridge: Already claimed");
+
+ transactionsDataHashes[_transactionHash] = _transactionDataHashMultichain;
+ originalTokenAddresses[_transactionHash] = _originalTokenAddress;
+ senderAddresses[_transactionHash] = _from;
+
+ emit AcceptedCrossTransfer(
+ _transactionHash,
+ _originalTokenAddress,
+ _to,
+ _from,
+ _amount,
+ _blockHash,
+ _logIndex,
+ _originChainId,
+ _destinationChainId
+ );
+ }
+
+ function checkChainId(uint256 chainId) internal pure {
+ require(chainId > 0, "Bridge: ChainId is 0");
+ }
+
+ function _createSideToken(
+ uint256 _typeId,
+ address _originalTokenAddress,
+ uint8 _originalTokenDecimals,
+ string calldata _tokenSymbol,
+ string calldata _tokenName,
+ uint256 _originChainId
+ ) internal {
+ require(_originalTokenAddress != NULL_ADDRESS, "Bridge: Null token");
+ checkChainId(_originChainId);
+ address sideToken = sideTokenByOriginalToken(_originChainId, _originalTokenAddress);
+ require(sideToken == NULL_ADDRESS, "Bridge: Already exists");
+
+ uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);
+
+ // Create side token
+ sideToken = sideTokenFactory.createSideToken(_tokenName, _tokenSymbol, granularity);
+
+ setSideTokenByOriginalAddressByChain(_originChainId, _originalTokenAddress, sideToken);
+
+ OriginalToken memory originalToken;
+ originalToken.originChainId = _originChainId;
+ originalToken.tokenAddress = _originalTokenAddress;
+ setOriginalTokenBySideTokenByChain(sideToken, originalToken);
+ allowTokens.setToken(sideToken, _typeId);
+
+ emit NewSideToken(sideToken, _originalTokenAddress, _tokenSymbol, granularity, _originChainId);
+ }
+
+ function createSideToken(
+ uint256 _typeId,
+ address _originalTokenAddress,
+ uint8 _originalTokenDecimals,
+ string calldata _tokenSymbol,
+ string calldata _tokenName,
+ uint256 _originChainId
+ ) external onlyOwner override {
+ _createSideToken(
+ _typeId,
+ _originalTokenAddress,
+ _originalTokenDecimals,
+ _tokenSymbol,
+ _tokenName,
+ _originChainId
+ );
+ }
+
+ function createMultipleSideTokens(
+ CreateSideTokenStruct[] calldata createSideTokenStruct
+ ) external onlyOwner {
+ for(uint256 i = 0; i < createSideTokenStruct.length; i++) {
+ _createSideToken(
+ createSideTokenStruct[i]._typeId,
+ createSideTokenStruct[i]._originalTokenAddress,
+ createSideTokenStruct[i]._originalTokenDecimals,
+ createSideTokenStruct[i]._originalTokenSymbol,
+ createSideTokenStruct[i]._originalTokenName,
+ createSideTokenStruct[i]._originChainId
+ );
+ }
+ }
+
+ function claim(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {
+ receivedAmount = _claim(
+ _claimData,
+ _claimData.to,
+ payable(address(0)),
+ 0
+ );
+ return receivedAmount;
+ }
+
+ function claimFallback(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {
+ require(_msgSender() == senderAddresses[_claimData.transactionHash],"Bridge: invalid sender");
+ receivedAmount = _claim(
+ _claimData,
+ _msgSender(),
+ payable(address(0)),
+ 0
+ );
+ return receivedAmount;
+ }
+
+ function getDigest(
+ ClaimData memory _claimData,
+ address payable _relayer,
+ uint256 _fee,
+ uint256 _deadline
+ ) internal returns (bytes32) {
+ return LibEIP712.hashEIP712Message(
+ domainSeparator,
+ keccak256(
+ abi.encode(
+ CLAIM_TYPEHASH,
+ _claimData.to,
+ _claimData.amount,
+ _claimData.transactionHash,
+ _claimData.originChainId,
+ _relayer,
+ _fee,
+ nonces[_claimData.to]++,
+ _deadline
+ )
+ )
+ );
+ }
+
+ // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol
+ function claimGasless(
+ ClaimData calldata _claimData,
+ address payable _relayer,
+ uint256 _fee,
+ uint256 _deadline,
+ uint8 _v,
+ bytes32 _r,
+ bytes32 _s
+ ) external override returns (uint256 receivedAmount) {
+ require(_deadline >= block.timestamp, "Bridge: EXPIRED"); // solhint-disable-line not-rely-on-time
+
+ bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);
+ address recoveredAddress = ecrecover(digest, _v, _r, _s);
+ require(_claimData.to != address(0) && recoveredAddress == _claimData.to, "Bridge: INVALID_SIGNATURE");
+
+ return _claim(
+ _claimData,
+ _claimData.to,
+ _relayer,
+ _fee
+ );
+ }
+
+ function isClaimed(bytes32 transactionDataHash, bytes32 transactionDataHashMultichain) public view returns(bool) {
+ return claimed[transactionDataHash] || claimed[transactionDataHashMultichain];
+ }
+
+ function isClaimed(ClaimData calldata _claimData, bytes32 transactionDataHashMultichain) public view returns(bool) {
+ bytes32 transactionDataHash = getTransactionDataHash(
+ _claimData.to,
+ _claimData.amount,
+ _claimData.blockHash,
+ _claimData.transactionHash,
+ _claimData.logIndex
+ );
+
+ return claimed[transactionDataHash] || claimed[transactionDataHashMultichain];
+ }
+
+ function _claim(
+ ClaimData calldata _claimData,
+ address payable _reciever,
+ address payable _relayer,
+ uint256 _fee
+ ) internal nonReentrant returns (uint256 receivedAmount) {
+ address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];
+ require(originalTokenAddress != NULL_ADDRESS, "Bridge: Tx not crossed");
+
+ bytes32 transactionDataHash = getTransactionDataHash(
+ _claimData.to,
+ _claimData.amount,
+ _claimData.blockHash,
+ _claimData.transactionHash,
+ _claimData.logIndex,
+ _claimData.originChainId,
+ block.chainid
+ );
+
+ require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, "Bridge: Wrong transactionDataHash");
+ require(!isClaimed(_claimData, transactionDataHash), "Bridge: Already claimed");
+ claimed[transactionDataHash] = true;
+
+ receivedAmount = _claimCross(
+ _claimData.originChainId,
+ originalTokenAddress,
+ _reciever,
+ _claimData.amount,
+ _relayer,
+ _fee
+ );
+
+ emitClaimed(_claimData, originalTokenAddress, _reciever, _relayer, _fee);
+ return receivedAmount;
+ }
+
+ function emitClaimed(
+ ClaimData calldata _claimData,
+ address _originalTokenAddress,
+ address payable _reciever,
+ address payable _relayer,
+ uint256 _fee
+ ) internal {
+ emit Claimed(
+ _claimData.transactionHash,
+ _originalTokenAddress,
+ _claimData.to,
+ senderAddresses[_claimData.transactionHash],
+ _claimData.amount,
+ _claimData.blockHash,
+ _claimData.logIndex,
+ _reciever,
+ _relayer,
+ _fee,
+ _claimData.originChainId,
+ block.chainid
+ );
+ }
+
+ function _claimCross(
+ uint256 _originalChainId,
+ address _originalTokenAddress,
+ address payable _reciever,
+ uint256 _amount,
+ address payable _relayer,
+ uint256 _fee
+ ) internal returns (uint256) {
+ checkChainId(_originalChainId);
+ if (knownToken(_originalChainId, _originalTokenAddress)) {
+ return _claimCrossBackToToken(
+ _originalTokenAddress,
+ _reciever,
+ _amount,
+ _relayer,
+ _fee
+ );
+ }
+
+ return _claimCrossToSideToken(
+ sideTokenByOriginalToken(_originalChainId, _originalTokenAddress),
+ _reciever,
+ _amount,
+ _relayer,
+ _fee
+ );
+ }
+
+ function _claimCrossToSideToken(
+ address _sideToken,
+ address payable _receiver,
+ uint256 _amount,
+ address payable _relayer,
+ uint256 _fee
+ ) internal returns (uint256 receivedAmount) {
+ require(_sideToken != NULL_ADDRESS, "Bridge: side token is null");
+ uint256 granularity = IERC777(_sideToken).granularity();
+ uint256 formattedAmount = _amount.mul(granularity);
+ require(_fee <= formattedAmount, "Bridge: fee too high");
+ receivedAmount = formattedAmount.sub(_fee);
+ ISideToken(_sideToken).mint(_receiver, receivedAmount, "", "");
+ if (_fee > 0) {
+ ISideToken(_sideToken).mint(_relayer, _fee, "", "relayer fee");
+ }
+ return receivedAmount;
+ }
+
+ function _claimCrossBackToToken(
+ address _originalTokenAddress,
+ address payable _receiver,
+ uint256 _amount,
+ address payable _relayer,
+ uint256 _fee
+ ) internal returns (uint256 receivedAmount) {
+ uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);
+ //As side tokens are ERC777 they will always have 18 decimals
+ uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));
+ require(_fee <= formattedAmount, "Bridge: fee too high");
+ receivedAmount = formattedAmount.sub(_fee);
+ if (address(wrappedCurrency) == _originalTokenAddress) {
+ wrappedCurrency.withdraw(formattedAmount);
+ _receiver.transfer(receivedAmount);
+ if(_fee > 0) {
+ _relayer.transfer(_fee);
+ }
+ } else {
+ IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);
+ if(_fee > 0) {
+ IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);
+ }
+ }
+ return receivedAmount;
+ }
+
+ /**
+ * ERC-20 tokens approve and transferFrom pattern
+ * See https://eips.ethereum.org/EIPS/eip-20#transferfrom
+ */
+ function receiveTokensTo(uint256 destinationChainId, address tokenToUse, address to, uint256 amount) external override {
+ address sender = _msgSender();
+ //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them
+ IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);
+ crossTokens(tokenToUse, sender, to, amount, "", destinationChainId);
+ }
+
+ /**
+ * Use network currency and cross it.
+ */
+ function depositTo(uint256 chainId, address to) external payable override {
+ address sender = _msgSender();
+ require(address(wrappedCurrency) != NULL_ADDRESS, "Bridge: wrappedCurrency empty");
+ wrappedCurrency.deposit{ value: msg.value }();
+ crossTokens(address(wrappedCurrency), sender, to, msg.value, "", chainId);
+ }
+
+ /**
+ * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction
+ * See https://eips.ethereum.org/EIPS/eip-777#motivation for details
+ * @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination
+ * const userData = web3.eth.abi.encodeParameters(
+ * ["address", "uint256"],
+ * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]
+ * );
+ * or you also can send only the destination chain id, and the receiver would be the same as the from parameter
+ * const userData = web3.eth.abi.encodeParameters(["uint256"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);
+ */
+ function tokensReceived(
+ address operator,
+ address from,
+ address to,
+ uint amount,
+ bytes calldata userData, // [address,uint256] user addrest receiver, destinationChainId || [uint256] same as from, destinationChainId
+ bytes calldata
+ ) external override(IBridge, IERC777Recipient) {
+ //Hook from ERC777address
+ if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom
+ require(to == address(this), "Bridge: Not to this address");
+ address tokenToUse = _msgSender();
+ require(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, "Bridge: Not ERC777 token");
+ require(userData.length >= 32, "Bridge: user data with at least the destinationChainId");
+ require(userData.length == 64 || !from.isContract(), "Bridge: Specify receiver address in data");
+ address receiver = userData.length == 32 ? from : LibUtils.toAddress(userData, 12);
+ uint256 destinationChainId = LibUtils.toUint256(userData, userData.length - 32);
+ crossTokens(tokenToUse, from, receiver, amount, userData, destinationChainId);
+ }
+
+ function crossTokens(
+ address tokenToUse,
+ address from,
+ address to,
+ uint256 amount,
+ bytes memory userData,
+ uint256 destinationChainId
+ ) internal whenNotUpgrading whenNotPaused nonReentrant {
+ require(block.chainid != destinationChainId, "Bridge: destination chain id equal current chain id");
+ checkChainId(destinationChainId);
+ _setKnownTokenByChain(destinationChainId, tokenToUse, true);
+ uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);
+ uint256 amountMinusFees = amount.sub(fee);
+ uint8 decimals = LibUtils.getDecimals(tokenToUse);
+ uint formattedAmount = amount;
+ if (decimals != 18) {
+ formattedAmount = amount.mul(uint256(10)**(18-decimals));
+ }
+ // We consider the amount before fees converted to 18 decimals to check the limits
+ // updateTokenTransfer revert if token not allowed
+ allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);
+
+ OriginalToken memory sideToken = getOriginalTokenBySideToken(tokenToUse);
+ if (sideToken.tokenAddress != NULL_ADDRESS) {
+ // Side Token Crossing back
+ { // Created scope to avoid stack too deep
+ uint256 granularity = LibUtils.getGranularity(tokenToUse);
+ uint256 modulo = amountMinusFees.mod(granularity);
+ fee = fee.add(modulo);
+ amountMinusFees = amountMinusFees.sub(modulo);
+ IERC777(tokenToUse).burn(amountMinusFees, userData);
+ }
+ emit Cross(
+ sideToken.tokenAddress,
+ to,
+ destinationChainId,
+ from,
+ block.chainid,
+ amountMinusFees,
+ userData
+ );
+ } else {
+ emit Cross(
+ tokenToUse,
+ to,
+ destinationChainId,
+ from,
+ block.chainid,
+ amountMinusFees,
+ userData
+ );
+ }
+
+ if (fee > 0) {
+ //Send the payment to the MultiSig of the Federation
+ IERC20(tokenToUse).safeTransfer(owner(), fee);
+ }
+ }
+
+ // function for retrocompatibility
+ function getTransactionDataHash(
+ address _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex
+ ) internal pure returns(bytes32) {
+ return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));
+ }
+
+ function getTransactionDataHash(
+ address _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex,
+ uint256 _originChainId,
+ uint256 _destinationChainId
+ ) public pure override returns(bytes32) {
+ return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex, _originChainId, _destinationChainId));
+ }
+
+ function setFeePercentage(uint amount) external onlyOwner {
+ require(amount < (feePercentageDivider/10), "Bridge: bigger than 10%");
+ feePercentage = amount;
+ emit FeePercentageChanged(feePercentage);
+ }
+
+ function getFeePercentage() external view override returns(uint) {
+ return feePercentage;
+ }
+
+ function changeFederation(address newFederation) external onlyOwner {
+ require(newFederation != NULL_ADDRESS, "Bridge: Federation is empty");
+ federation = newFederation;
+ emit FederationChanged(federation);
+ }
+
+ function changeAllowTokens(address newAllowTokens) external onlyOwner {
+ require(newAllowTokens != NULL_ADDRESS, "Bridge: AllowTokens is empty");
+ allowTokens = IAllowTokens(newAllowTokens);
+ emit AllowTokensChanged(newAllowTokens);
+ }
+
+ function getFederation() external view returns(address) {
+ return federation;
+ }
+
+ function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {
+ require(newSideTokenFactory != NULL_ADDRESS, "Bridge: SideTokenFactory is empty");
+ sideTokenFactory = ISideTokenFactory(newSideTokenFactory);
+ emit SideTokenFactoryChanged(newSideTokenFactory);
+ }
+
+ function setUpgrading(bool _isUpgrading) external onlyOwner {
+ isUpgrading = _isUpgrading;
+ emit Upgrading(isUpgrading);
+ }
+
+ function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {
+ require(_wrappedCurrency != NULL_ADDRESS, "Bridge: wrapp is empty");
+ wrappedCurrency = IWrapped(_wrappedCurrency);
+ emit WrappedCurrencyChanged(_wrappedCurrency);
+ }
+
+ function hasCrossed(bytes32 transactionHash) public view returns (bool) {
+ return transactionsDataHashes[transactionHash] != bytes32(0);
+ }
+
+ function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {
+ return claimed[transactionsDataHashes[transactionHash]];
+ }
+
+}
diff --git a/bridge/contracts/Bridge/BridgeV3.sol b/bridge/contracts/Bridge/BridgeV3.sol
new file mode 100644
index 000000000..d5dbc4116
--- /dev/null
+++ b/bridge/contracts/Bridge/BridgeV3.sol
@@ -0,0 +1,503 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+// import "hardhat/console.sol";
+// Import base Initializable contract
+import "../zeppelin/upgradable/Initializable.sol";
+// Import interface and library from OpenZeppelin contracts
+import "../zeppelin/upgradable/utils/ReentrancyGuard.sol";
+import "../zeppelin/upgradable/lifecycle/UpgradablePausable.sol";
+import "../zeppelin/upgradable/ownership/UpgradableOwnable.sol";
+
+import "../zeppelin/introspection/IERC1820Registry.sol";
+import "../zeppelin/token/ERC777/IERC777Recipient.sol";
+import "../zeppelin/token/ERC20/IERC20.sol";
+import "../zeppelin/token/ERC20/SafeERC20.sol";
+import "../zeppelin/utils/Address.sol";
+import "../zeppelin/math/SafeMath.sol";
+import "../zeppelin/token/ERC777/IERC777.sol";
+
+import "../lib/LibEIP712.sol";
+import "../lib/LibUtils.sol";
+
+import "./IBridgeV3.sol";
+import "../interface/ISideToken.sol";
+import "../interface/ISideTokenFactory.sol";
+import "../interface/IAllowTokens.sol";
+import "../interface/IWrapped.sol";
+
+
+contract BridgeV3 is Initializable, IBridgeV3, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {
+ using SafeMath for uint256;
+ using SafeERC20 for IERC20;
+ using Address for address;
+
+ address constant internal NULL_ADDRESS = address(0);
+ bytes32 constant internal NULL_HASH = bytes32(0);
+ IERC1820Registry constant internal erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
+
+ address internal federation;
+ uint256 internal feePercentage;
+ string public symbolPrefix;
+ bytes32 public DOMAIN_SEPARATOR; // replaces uint256 internal _depprecatedLastDay;
+ uint256 internal _deprecatedSpentToday;
+
+ mapping (address => address) public mappedTokens; // OirignalToken => SideToken
+ mapping (address => address) public originalTokens; // SideToken => OriginalToken
+ mapping (address => bool) public knownTokens; // OriginalToken => true
+ mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed
+ IAllowTokens public allowTokens;
+ ISideTokenFactory public sideTokenFactory;
+ //Bridge_v1 variables
+ bool public isUpgrading;
+ uint256 constant public feePercentageDivider = 10000; // Porcentage with up to 2 decimals
+ //Bridge_v3 variables
+ bytes32 constant internal _erc777Interface = keccak256("ERC777Token");
+ IWrapped public wrappedCurrency;
+ mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash
+ mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress
+ mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress
+
+ // keccak256("Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)");
+ bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;
+ mapping(address => uint) public nonces;
+
+ event AllowTokensChanged(address _newAllowTokens);
+ event FederationChanged(address _newFederation);
+ event SideTokenFactoryChanged(address _newSideTokenFactory);
+ event Upgrading(bool _isUpgrading);
+ event WrappedCurrencyChanged(address _wrappedCurrency);
+
+ function initialize(
+ address _manager,
+ address _federation,
+ address _allowTokens,
+ address _sideTokenFactory,
+ string memory _symbolPrefix
+ ) public initializer {
+ UpgradableOwnable.initialize(_manager);
+ UpgradablePausable.__Pausable_init(_manager);
+ symbolPrefix = _symbolPrefix;
+ allowTokens = IAllowTokens(_allowTokens);
+ sideTokenFactory = ISideTokenFactory(_sideTokenFactory);
+ federation = _federation;
+ //keccak256("ERC777TokensRecipient")
+ erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));
+ initDomainSeparator();
+ }
+
+ receive () external payable {
+ // The fallback function is needed to use WRBTC
+ require(_msgSender() == address(wrappedCurrency), "Bridge: not wrappedCurrency");
+ }
+
+ function version() override external pure returns (string memory) {
+ return "v3";
+ }
+
+ function initDomainSeparator() public {
+ uint chainId;
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ chainId := chainid()
+ }
+ DOMAIN_SEPARATOR = LibEIP712.hashEIP712Domain(
+ "RSK Token Bridge",
+ "1",
+ chainId,
+ address(this)
+ );
+ }
+
+ modifier whenNotUpgrading() {
+ require(!isUpgrading, "Bridge: Upgrading");
+ _;
+ }
+
+ function acceptTransfer(
+ address _originalTokenAddress,
+ address payable _from,
+ address payable _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex
+ ) external whenNotPaused nonReentrant override {
+ require(_msgSender() == federation, "Bridge: Not Federation");
+ require(knownTokens[_originalTokenAddress] ||
+ mappedTokens[_originalTokenAddress] != NULL_ADDRESS,
+ "Bridge: Unknown token"
+ );
+ require(_to != NULL_ADDRESS, "Bridge: Null To");
+ require(_amount > 0, "Bridge: Amount 0");
+ require(_blockHash != NULL_HASH, "Bridge: Null BlockHash");
+ require(_transactionHash != NULL_HASH, "Bridge: Null TxHash");
+ require(transactionsDataHashes[_transactionHash] == bytes32(0), "Bridge: Already accepted");
+
+ bytes32 _transactionDataHash = getTransactionDataHash(
+ _to,
+ _amount,
+ _blockHash,
+ _transactionHash,
+ _logIndex
+ );
+ // Do not remove, claimed also has the previously processed using the older bridge version
+ // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41
+ require(!claimed[_transactionDataHash], "Bridge: Already claimed");
+
+ transactionsDataHashes[_transactionHash] = _transactionDataHash;
+ originalTokenAddresses[_transactionHash] = _originalTokenAddress;
+ senderAddresses[_transactionHash] = _from;
+
+ emit AcceptedCrossTransfer(
+ _transactionHash,
+ _originalTokenAddress,
+ _to,
+ _from,
+ _amount,
+ _blockHash,
+ _logIndex
+ );
+ }
+
+
+ function createSideToken(
+ uint256 _typeId,
+ address _originalTokenAddress,
+ uint8 _originalTokenDecimals,
+ string calldata _originalTokenSymbol,
+ string calldata _originalTokenName
+ ) external onlyOwner {
+ require(_originalTokenAddress != NULL_ADDRESS, "Bridge: Null token");
+ address sideToken = mappedTokens[_originalTokenAddress];
+ require(sideToken == NULL_ADDRESS, "Bridge: Already exists");
+ uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);
+ string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));
+
+ // Create side token
+ sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);
+
+ mappedTokens[_originalTokenAddress] = sideToken;
+ originalTokens[sideToken] = _originalTokenAddress;
+ allowTokens.setToken(sideToken, _typeId);
+
+ emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);
+ }
+
+ function claim(ClaimData calldata _claimData)
+ external override returns (uint256 receivedAmount) {
+
+ receivedAmount = _claim(
+ _claimData,
+ _claimData.to,
+ payable(address(0)),
+ 0
+ );
+ return receivedAmount;
+ }
+
+ function claimFallback(ClaimData calldata _claimData)
+ external override returns (uint256 receivedAmount) {
+ require(_msgSender() == senderAddresses[_claimData.transactionHash],"Bridge: invalid sender");
+ receivedAmount = _claim(
+ _claimData,
+ _msgSender(),
+ payable(address(0)),
+ 0
+ );
+ return receivedAmount;
+ }
+
+ function getDigest(
+ ClaimData memory _claimData,
+ address payable _relayer,
+ uint256 _fee,
+ uint256 _deadline
+ ) internal returns (bytes32) {
+ return LibEIP712.hashEIP712Message(
+ DOMAIN_SEPARATOR,
+ keccak256(
+ abi.encode(
+ CLAIM_TYPEHASH,
+ _claimData.to,
+ _claimData.amount,
+ _claimData.transactionHash,
+ _relayer,
+ _fee,
+ nonces[_claimData.to]++,
+ _deadline
+ )
+ )
+ );
+ }
+
+ // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol
+ function claimGasless(
+ ClaimData calldata _claimData,
+ address payable _relayer,
+ uint256 _fee,
+ uint256 _deadline,
+ uint8 _v,
+ bytes32 _r,
+ bytes32 _s
+ ) external override returns (uint256 receivedAmount) {
+ require(_deadline >= block.timestamp, "Bridge: EXPIRED");
+
+ bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);
+ address recoveredAddress = ecrecover(digest, _v, _r, _s);
+ require(_claimData.to != address(0) && recoveredAddress == _claimData.to, "Bridge: INVALID_SIGNATURE");
+
+ receivedAmount = _claim(
+ _claimData,
+ _claimData.to,
+ _relayer,
+ _fee
+ );
+ return receivedAmount;
+ }
+
+ function _claim(
+ ClaimData calldata _claimData,
+ address payable _reciever,
+ address payable _relayer,
+ uint256 _fee
+ ) internal nonReentrant returns (uint256 receivedAmount) {
+ address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];
+ require(originalTokenAddress != NULL_ADDRESS, "Bridge: Tx not crossed");
+
+ bytes32 transactionDataHash = getTransactionDataHash(
+ _claimData.to,
+ _claimData.amount,
+ _claimData.blockHash,
+ _claimData.transactionHash,
+ _claimData.logIndex
+ );
+ require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, "Bridge: Wrong transactionDataHash");
+ require(!claimed[transactionDataHash], "Bridge: Already claimed");
+
+ claimed[transactionDataHash] = true;
+ if (knownTokens[originalTokenAddress]) {
+ receivedAmount =_claimCrossBackToToken(
+ originalTokenAddress,
+ _reciever,
+ _claimData.amount,
+ _relayer,
+ _fee
+ );
+ } else {
+ receivedAmount =_claimCrossToSideToken(
+ originalTokenAddress,
+ _reciever,
+ _claimData.amount,
+ _relayer,
+ _fee
+ );
+ }
+ emit Claimed(
+ _claimData.transactionHash,
+ originalTokenAddress,
+ _claimData.to,
+ senderAddresses[_claimData.transactionHash],
+ _claimData.amount,
+ _claimData.blockHash,
+ _claimData.logIndex,
+ _reciever,
+ _relayer,
+ _fee
+ );
+ return receivedAmount;
+ }
+
+ function _claimCrossToSideToken(
+ address _originalTokenAddress,
+ address payable _receiver,
+ uint256 _amount,
+ address payable _relayer,
+ uint256 _fee
+ ) internal returns (uint256 receivedAmount) {
+ address sideToken = mappedTokens[_originalTokenAddress];
+ uint256 granularity = IERC777(sideToken).granularity();
+ uint256 formattedAmount = _amount.mul(granularity);
+ require(_fee <= formattedAmount, "Bridge: fee too high");
+ receivedAmount = formattedAmount - _fee;
+ ISideToken(sideToken).mint(_receiver, receivedAmount, "", "");
+ if(_fee > 0) {
+ ISideToken(sideToken).mint(_relayer, _fee, "", "relayer fee");
+ }
+ return receivedAmount;
+ }
+
+ function _claimCrossBackToToken(
+ address _originalTokenAddress,
+ address payable _receiver,
+ uint256 _amount,
+ address payable _relayer,
+ uint256 _fee
+ ) internal returns (uint256 receivedAmount) {
+ uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);
+ //As side tokens are ERC777 they will always have 18 decimals
+ uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));
+ require(_fee <= formattedAmount, "Bridge: fee too high");
+ receivedAmount = formattedAmount - _fee;
+ if(address(wrappedCurrency) == _originalTokenAddress) {
+ wrappedCurrency.withdraw(formattedAmount);
+ _receiver.transfer(receivedAmount);
+ if(_fee > 0) {
+ _relayer.transfer(_fee);
+ }
+ } else {
+ IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);
+ if(_fee > 0) {
+ IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);
+ }
+ }
+ return receivedAmount;
+ }
+
+ /**
+ * ERC-20 tokens approve and transferFrom pattern
+ * See https://eips.ethereum.org/EIPS/eip-20#transferfrom
+ */
+ function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {
+ address sender = _msgSender();
+ //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them
+ IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);
+ crossTokens(tokenToUse, sender, to, amount, "");
+ }
+
+ /**
+ * Use network currency and cross it.
+ */
+ function depositTo(address to) override external payable {
+ address sender = _msgSender();
+ require(address(wrappedCurrency) != NULL_ADDRESS, "Bridge: wrappedCurrency empty");
+ wrappedCurrency.deposit{ value: msg.value }();
+ crossTokens(address(wrappedCurrency), sender, to, msg.value, "");
+ }
+
+ /**
+ * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction
+ * See https://eips.ethereum.org/EIPS/eip-777#motivation for details
+ */
+ function tokensReceived (
+ address operator,
+ address from,
+ address to,
+ uint amount,
+ bytes calldata userData,
+ bytes calldata
+ ) external override(IBridgeV3, IERC777Recipient){
+ //Hook from ERC777address
+ if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom
+ require(to == address(this), "Bridge: Not to this address");
+ address tokenToUse = _msgSender();
+ require(erc1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, "Bridge: Not ERC777 token");
+ require(userData.length != 0 || !from.isContract(), "Bridge: Specify receiver address in data");
+ address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);
+ crossTokens(tokenToUse, from, receiver, amount, userData);
+ }
+
+ function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)
+ internal whenNotUpgrading whenNotPaused nonReentrant {
+ knownTokens[tokenToUse] = true;
+ uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);
+ uint256 amountMinusFees = amount.sub(fee);
+ uint8 decimals = LibUtils.getDecimals(tokenToUse);
+ uint formattedAmount = amount;
+ if(decimals != 18) {
+ formattedAmount = amount.mul(uint256(10)**(18-decimals));
+ }
+ // We consider the amount before fees converted to 18 decimals to check the limits
+ // updateTokenTransfer revert if token not allowed
+ allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);
+ address originalTokenAddress = tokenToUse;
+ if (originalTokens[tokenToUse] != NULL_ADDRESS) {
+ //Side Token Crossing
+ originalTokenAddress = originalTokens[tokenToUse];
+ uint256 granularity = LibUtils.getGranularity(tokenToUse);
+ uint256 modulo = amountMinusFees.mod(granularity);
+ fee = fee.add(modulo);
+ amountMinusFees = amountMinusFees.sub(modulo);
+ IERC777(tokenToUse).burn(amountMinusFees, userData);
+ }
+
+ emit Cross(
+ originalTokenAddress,
+ from,
+ to,
+ amountMinusFees,
+ userData
+ );
+
+ if (fee > 0) {
+ //Send the payment to the MultiSig of the Federation
+ IERC20(tokenToUse).safeTransfer(owner(), fee);
+ }
+ }
+
+ function getTransactionDataHash(
+ address _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex
+ )
+ public pure override returns(bytes32)
+ {
+ return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));
+ }
+
+ function setFeePercentage(uint amount) external onlyOwner {
+ require(amount < (feePercentageDivider/10), "Bridge: bigger than 10%");
+ feePercentage = amount;
+ emit FeePercentageChanged(feePercentage);
+ }
+
+ function getFeePercentage() external view override returns(uint) {
+ return feePercentage;
+ }
+
+ function changeFederation(address newFederation) external onlyOwner {
+ require(newFederation != NULL_ADDRESS, "Bridge: Federation is empty");
+ federation = newFederation;
+ emit FederationChanged(federation);
+ }
+
+
+ function changeAllowTokens(address newAllowTokens) external onlyOwner {
+ require(newAllowTokens != NULL_ADDRESS, "Bridge: AllowTokens is empty");
+ allowTokens = IAllowTokens(newAllowTokens);
+ emit AllowTokensChanged(newAllowTokens);
+ }
+
+ function getFederation() external view returns(address) {
+ return federation;
+ }
+
+ function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {
+ require(newSideTokenFactory != NULL_ADDRESS, "Bridge: SideTokenFactory is empty");
+ sideTokenFactory = ISideTokenFactory(newSideTokenFactory);
+ emit SideTokenFactoryChanged(newSideTokenFactory);
+ }
+
+ function setUpgrading(bool _isUpgrading) external onlyOwner {
+ isUpgrading = _isUpgrading;
+ emit Upgrading(isUpgrading);
+ }
+
+ function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {
+ require(_wrappedCurrency != NULL_ADDRESS, "Bridge: wrapp is empty");
+ wrappedCurrency = IWrapped(_wrappedCurrency);
+ emit WrappedCurrencyChanged(_wrappedCurrency);
+ }
+
+ function hasCrossed(bytes32 transactionHash) public view returns (bool) {
+ return transactionsDataHashes[transactionHash] != bytes32(0);
+ }
+
+ function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {
+ return claimed[transactionsDataHashes[transactionHash]];
+ }
+
+}
\ No newline at end of file
diff --git a/bridge/contracts/Bridge/IBridgeV3.sol b/bridge/contracts/Bridge/IBridgeV3.sol
new file mode 100644
index 000000000..6f267988e
--- /dev/null
+++ b/bridge/contracts/Bridge/IBridgeV3.sol
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+interface IBridgeV3 {
+
+ struct ClaimData {
+ address payable to;
+ uint256 amount;
+ bytes32 blockHash;
+ bytes32 transactionHash;
+ uint32 logIndex;
+ }
+
+ function version() external pure returns (string memory);
+
+ function getFeePercentage() external view returns(uint);
+
+ /**
+ * ERC-20 tokens approve and transferFrom pattern
+ * See https://eips.ethereum.org/EIPS/eip-20#transferfrom
+ */
+ function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;
+
+ /**
+ * Use network currency and cross it.
+ */
+ function depositTo(address to) external payable;
+
+ /**
+ * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction
+ * See https://eips.ethereum.org/EIPS/eip-777#motivation for details
+ */
+ function tokensReceived (
+ address operator,
+ address from,
+ address to,
+ uint amount,
+ bytes calldata userData,
+ bytes calldata operatorData
+ ) external;
+
+ /**
+ * Accepts the transaction from the other chain that was voted and sent by the Federation contract
+ */
+ function acceptTransfer(
+ address _originalTokenAddress,
+ address payable _from,
+ address payable _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex
+ ) external;
+
+ /**
+ * Claims the crossed transaction using the hash, this sends the funds to the address indicated in
+ */
+ function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);
+
+ function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);
+
+ function claimGasless(
+ ClaimData calldata _claimData,
+ address payable _relayer,
+ uint256 _fee,
+ uint256 _deadline,
+ uint8 _v,
+ bytes32 _r,
+ bytes32 _s
+ ) external returns (uint256 receivedAmount);
+
+ function getTransactionDataHash(
+ address _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex
+ ) external returns(bytes32);
+
+ event Cross(
+ address indexed _tokenAddress,
+ address indexed _from,
+ address indexed _to,
+ uint256 _amount,
+ bytes _userData
+ );
+ event NewSideToken(
+ address indexed _newSideTokenAddress,
+ address indexed _originalTokenAddress,
+ string _newSymbol,
+ uint256 _granularity
+ );
+ event AcceptedCrossTransfer(
+ bytes32 indexed _transactionHash,
+ address indexed _originalTokenAddress,
+ address indexed _to,
+ address _from,
+ uint256 _amount,
+ bytes32 _blockHash,
+ uint256 _logIndex
+ );
+ event FeePercentageChanged(uint256 _amount);
+ event Claimed(
+ bytes32 indexed _transactionHash,
+ address indexed _originalTokenAddress,
+ address indexed _to,
+ address _sender,
+ uint256 _amount,
+ bytes32 _blockHash,
+ uint256 _logIndex,
+ address _reciever,
+ address _relayer,
+ uint256 _fee
+ );
+}
\ No newline at end of file
diff --git a/bridge/contracts/FederatedManager.sol b/bridge/contracts/FederatedManager.sol
deleted file mode 100644
index 70e99c8b2..000000000
--- a/bridge/contracts/FederatedManager.sol
+++ /dev/null
@@ -1,222 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "./Transferable.sol";
-
-contract FederatedManager {
- address owner;
- address[] public members;
-
- mapping(bytes32 => address[]) votes;
- mapping(bytes32 => bool) processed;
-
- mapping(address => uint) public lastBlockNumber;
- mapping(address => bytes32) public lastBlockHash;
-
- mapping(address => address[]) newMemberVotes;
- mapping(address => address[]) oldMemberVotes;
-
- mapping(address => address[]) managersVotes;
-
- Transferable public transferable;
-
- modifier onlyOwner() {
- require(msg.sender == owner);
- _;
- }
-
- modifier onlyMember() {
- require(isMember(msg.sender));
- _;
- }
-
- constructor(address[] _members) public {
- members = _members;
- owner = msg.sender;
- }
-
- function setTransferable(Transferable _transferable) public onlyOwner {
- require(transferable == address(0));
- transferable = _transferable;
- }
-
- function isMember(address _account) public view returns(bool) {
- uint n = members.length;
-
- for (uint16 k = 0; k < n; k++)
- if (members[k] == _account)
- return true;
-
- return false;
- }
-
- function voteTransaction(uint _blockNumber, bytes32 _blockHash, bytes32 _transactionHash, address _receiver, uint _amount)
- public onlyMember
- {
- bytes32 voteId = getTransactionVoteId(_blockNumber, _blockHash, _transactionHash, _receiver, _amount);
-
- if (processed[voteId])
- return;
-
- address[] storage transactionVotes = votes[voteId];
- uint n = transactionVotes.length;
-
- for (uint16 k = 0; k < n; k++)
- if (transactionVotes[k] == msg.sender)
- return;
-
- transactionVotes.push(msg.sender);
-
- if (_blockNumber > lastBlockNumber[msg.sender]) {
- lastBlockHash[msg.sender] = _blockHash;
- lastBlockNumber[msg.sender] = _blockNumber;
- }
-
- if (transactionVotes.length < members.length / 2 + 1)
- return;
-
- if (transferable.acceptTransfer(_receiver, _amount)) {
- delete votes[voteId];
- processed[voteId] = true;
- }
- }
-
- function transactionVotes(uint _blockNumber, bytes32 _blockHash, bytes32 _transactionHash, address _receiver, uint _amount)
- public view returns(address[])
- {
- bytes32 voteId = getTransactionVoteId(_blockNumber, _blockHash, _transactionHash, _receiver, _amount);
-
- return votes[voteId];
- }
-
- function transactionNoVotes(uint _blockNumber, bytes32 _blockHash, bytes32 _transactionHash, address _receiver, uint _amount)
- public view returns(uint)
- {
- bytes32 voteId = getTransactionVoteId(_blockNumber, _blockHash, _transactionHash, _receiver, _amount);
-
- return votes[voteId].length;
- }
-
- function transactionWasProcessed(uint _blockNumber, bytes32 _blockHash, bytes32 _transactionHash, address _receiver, uint _amount)
- public view returns(bool)
- {
- bytes32 voteId = getTransactionVoteId(_blockNumber, _blockHash, _transactionHash, _receiver, _amount);
-
- return processed[voteId];
- }
-
- function getTransactionVoteId(uint _blockNumber, bytes32 _blockHash, bytes32 _transactionHash, address _receiver, uint _amount)
- public pure returns(bytes32)
- {
- return keccak256(abi.encodePacked(_blockNumber, _blockHash, _transactionHash, _receiver, _amount));
- }
-
- function voteAddMember(address _newMember) public onlyMember
- {
- if (isMember(_newMember))
- return;
-
- address[] storage memberVotes = newMemberVotes[_newMember];
- uint nvotes = memberVotes.length;
-
- for (uint k = 0; k < nvotes; k++)
- if (memberVotes[k] == msg.sender)
- return;
-
- memberVotes.push(msg.sender);
-
- if (memberVotes.length < members.length / 2 + 1)
- return;
-
- members.push(_newMember);
- delete newMemberVotes[_newMember];
- }
-
- function addMemberVotes(address _newMember)
- public view returns(address[])
- {
- return newMemberVotes[_newMember];
- }
-
- function addMemberNoVotes(address _newMember)
- public view returns(uint)
- {
- return newMemberVotes[_newMember].length;
- }
-
- function voteRemoveMember(address _oldMember) public onlyMember
- {
- if (!isMember(_oldMember))
- return;
-
- address[] storage memberVotes = oldMemberVotes[_oldMember];
- uint nvotes = memberVotes.length;
-
- for (uint k = 0; k < nvotes; k++)
- if (memberVotes[k] == msg.sender)
- return;
-
- memberVotes.push(msg.sender);
-
- if (memberVotes.length < members.length / 2 + 1)
- return;
-
- uint nmembers = members.length;
-
- for (uint j = 0; j < nmembers; j++) {
- if (members[j] == _oldMember) {
- if (j < nmembers - 1)
- members[j] = members[nmembers - 1];
-
- members.length--;
- }
- }
-
- delete oldMemberVotes[_oldMember];
- }
-
- function removeMemberVotes(address _oldMember)
- public view returns(address[])
- {
- return oldMemberVotes[_oldMember];
- }
-
- function removeMemberNoVotes(address _oldMember)
- public view returns(uint)
- {
- return oldMemberVotes[_oldMember].length;
- }
-
- function voteNewManager(address _newManager) public onlyMember
- {
- if (_newManager == address(this))
- return;
-
- address[] storage managerVotes = managersVotes[_newManager];
- uint nvotes = managerVotes.length;
-
- for (uint k = 0; k < nvotes; k++)
- if (managerVotes[k] == msg.sender)
- return;
-
- managerVotes.push(msg.sender);
-
- if (managerVotes.length < members.length / 2 + 1)
- return;
-
- transferable.changeManager(_newManager);
- delete managersVotes[_newManager];
- }
-
- function newManagerVotes(address _newManager)
- public view returns(address[])
- {
- return managersVotes[_newManager];
- }
-
- function newManagerNoVotes(address _newManager)
- public view returns(uint)
- {
- return managersVotes[_newManager].length;
- }
-}
-
diff --git a/bridge/contracts/Federation/Federation.sol b/bridge/contracts/Federation/Federation.sol
new file mode 100644
index 000000000..9799d49a6
--- /dev/null
+++ b/bridge/contracts/Federation/Federation.sol
@@ -0,0 +1,397 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// Upgradables
+import "../zeppelin/upgradable/Initializable.sol";
+import "../zeppelin/upgradable/ownership/UpgradableOwnable.sol";
+
+import "../interface/IBridge.sol";
+import "../interface/IFederation.sol";
+contract Federation is Initializable, UpgradableOwnable, IFederation {
+ uint constant public MAX_MEMBER_COUNT = 50;
+ address constant private NULL_ADDRESS = address(0);
+
+ IBridge public bridge;
+ address[] public members;
+
+ /**
+ @notice The minimum amount of votes to approve a transaction
+ @dev It should have at least the required amount of members
+ */
+ uint public required;
+
+ /**
+ @notice All the addresses that are members of the federation
+ @dev The address should be a member to vote in transactions
+ */
+ mapping (address => bool) public isMember;
+
+ /**
+ (bytes32) transactionId = keccak256(
+ abi.encodePacked(
+ originalTokenAddress,
+ sender,
+ receiver,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex
+ )
+ ) => (
+ (address) members => (bool) voted
+ )
+ @notice Votes by members by the transaction ID
+ @dev the members should approve the transaction by 50% + 1
+ */
+ mapping (bytes32 => mapping (address => bool)) public votes;
+
+ /**
+ (bytes32) transactionId => (bool) voted
+ @notice Check if that transaction was already processed
+ */
+ mapping(bytes32 => bool) public processed;
+
+ modifier onlyMember() {
+ require(isMember[_msgSender()], "Federation: Not Federator");
+ _;
+ }
+
+ modifier validRequirement(uint membersCount, uint _required) {
+ require(_required <= membersCount && _required != 0 && membersCount != 0, "Federation: Invalid requirements");
+ _;
+ }
+
+ function initialize(
+ address[] calldata _members,
+ uint _required,
+ address _bridge,
+ address owner
+ ) public validRequirement(_members.length, _required) initializer {
+ UpgradableOwnable.initialize(owner);
+ require(_members.length <= MAX_MEMBER_COUNT, "Federation: Too many members");
+ members = _members;
+ for (uint i = 0; i < _members.length; i++) {
+ require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, "Federation: Invalid members");
+ isMember[_members[i]] = true;
+ emit MemberAddition(_members[i]);
+ }
+ required = _required;
+ emit RequirementChange(required);
+ _setBridge(_bridge);
+ }
+
+ /**
+ @notice Current version of the contract
+ @return version in v{Number}
+ */
+ function version() external pure override returns (string memory) {
+ return "v3";
+ }
+
+ /**
+ @notice Sets a new bridge contract
+ @dev Emits BridgeChanged event
+ @param _bridge the new bridge contract address that should implement the IBridge interface
+ */
+ function setBridge(address _bridge) external onlyOwner override {
+ _setBridge(_bridge);
+ }
+
+ function _setBridge(address _bridge) internal {
+ require(_bridge != NULL_ADDRESS, "Federation: Empty bridge");
+ bridge = IBridge(_bridge);
+ emit BridgeChanged(_bridge);
+ }
+
+ function validateTransaction(bytes32 transactionId, bytes32 transactionIdMultichain) internal view returns(bool) {
+ uint256 minimumVotes = getMinimalNumberOfVotes();
+ uint256 amountVotes = 0;
+
+ for (uint256 i = 0; i < members.length; i++) {
+ if (votes[transactionIdMultichain][members[i]]) {
+ amountVotes += 1;
+ } else if (votes[transactionId][members[i]]) {
+ amountVotes += 1;
+ }
+
+ if (amountVotes >= minimumVotes && amountVotes >= required) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ function getMinimalNumberOfVotes() internal view returns(uint256) {
+ return members.length / 2 + 1;
+ }
+
+ function isProcessed(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {
+ return processed[transactionIdMultichain] || processed[transactionId];
+ }
+
+ function isVoted(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {
+ return votes[transactionIdMultichain][_msgSender()] || votes[transactionId][_msgSender()];
+ }
+
+ function shouldBeCurrentChainId(uint256 chainId) internal view {
+ require(chainId == block.chainid, "Federation: Not block.chainid");
+ }
+
+ /**
+ @notice Vote in a transaction, if it has enough votes it accepts the transfer
+ @param originalTokenAddress The address of the token in the origin (main) chain
+ @param sender The address who solicited the cross token
+ @param receiver Who is going to receive the token in the opposite chain
+ @param value Amount
+ @param blockHash The block hash in which the transaction with the cross event occurred
+ @param transactionHash The transaction in which the cross event occurred
+ @param logIndex Index of the event in the logs
+ @param originChainId Is chainId of the original chain
+ @param destinationChainId Is chainId of the destination chain
+ */
+ function voteTransaction(
+ address originalTokenAddress,
+ address payable sender,
+ address payable receiver,
+ uint256 value,
+ bytes32 blockHash,
+ bytes32 transactionHash,
+ uint32 logIndex,
+ uint256 originChainId,
+ uint256 destinationChainId
+ ) external onlyMember override {
+ shouldBeCurrentChainId(destinationChainId);
+ bytes32 transactionId = keccak256(
+ abi.encodePacked(
+ originalTokenAddress,
+ sender,
+ receiver,
+ value,
+ blockHash,
+ transactionHash,
+ logIndex
+ )
+ );
+
+ bytes32 transactionIdMultichain = getTransactionId(
+ originalTokenAddress,
+ sender,
+ receiver,
+ value,
+ blockHash,
+ transactionHash,
+ logIndex,
+ originChainId,
+ destinationChainId
+ );
+
+ if (isProcessed(transactionId, transactionIdMultichain))
+ return;
+
+ if (isVoted(transactionId, transactionIdMultichain))
+ return;
+
+ votes[transactionIdMultichain][_msgSender()] = true;
+ emit Voted(
+ _msgSender(),
+ transactionHash,
+ transactionIdMultichain,
+ originalTokenAddress,
+ sender,
+ receiver,
+ value,
+ blockHash,
+ logIndex,
+ originChainId,
+ destinationChainId
+ );
+
+ if (validateTransaction(transactionId, transactionIdMultichain)) {
+ processed[transactionIdMultichain] = true;
+
+ acceptTransfer(
+ originalTokenAddress,
+ sender,
+ receiver,
+ value,
+ blockHash,
+ transactionHash,
+ logIndex,
+
+ originChainId,
+ destinationChainId
+ );
+
+ emit Executed(
+ _msgSender(),
+ transactionHash,
+ transactionIdMultichain,
+ originalTokenAddress,
+ sender,
+ receiver,
+ value,
+ blockHash,
+ logIndex,
+ originChainId,
+ destinationChainId
+ );
+ }
+ }
+
+ function acceptTransfer(
+ address originalTokenAddress,
+ address payable sender,
+ address payable receiver,
+ uint256 value,
+ bytes32 blockHash,
+ bytes32 transactionHash,
+ uint32 logIndex,
+ uint256 originChainId,
+ uint256 destinationChainId
+ ) internal {
+ bridge.acceptTransfer(
+ originalTokenAddress,
+ sender,
+ receiver,
+ value,
+ blockHash,
+ transactionHash,
+ logIndex,
+ originChainId,
+ destinationChainId
+ );
+ }
+
+ /**
+ @notice Get the amount of approved votes for that transactionId
+ @param transactionId The transaction hashed from getTransactionId function
+ */
+ function getTransactionCount(bytes32 transactionId) public view returns(uint) {
+ uint count = 0;
+ for (uint i = 0; i < members.length; i++) {
+ if (votes[transactionId][members[i]])
+ count += 1;
+ }
+ return count;
+ }
+
+ function hasVoted(bytes32 transactionId) external view returns(bool) {
+ return votes[transactionId][_msgSender()];
+ }
+
+ function transactionWasProcessed(bytes32 transactionId) external view returns(bool) {
+ return processed[transactionId];
+ }
+
+ /**
+ @notice Gets the hash of transaction from the following parameters encoded and keccaked
+ @dev It encodes and applies keccak256 to the parameters received in the same order
+ @param originalTokenAddress The address of the token in the origin (main) chain
+ @param sender The address who solicited the cross token
+ @param receiver Who is going to receive the token in the opposite chain
+ @param amount Could be the amount or the tokenId
+ @param blockHash The block hash in which the transaction with the cross event occurred
+ @param transactionHash The transaction in which the cross event occurred
+ @param logIndex Index of the event in the logs
+ @param originChainId Is chainId of the original chain
+ @param destinationChainId Is chainId of the destination chain
+ @return The hash generated by the parameters.
+ */
+ function getTransactionId(
+ address originalTokenAddress,
+ address sender,
+ address receiver,
+ uint256 amount,
+ bytes32 blockHash,
+ bytes32 transactionHash,
+ uint32 logIndex,
+ uint256 originChainId,
+ uint256 destinationChainId
+ ) public pure returns(bytes32) {
+ return keccak256(
+ abi.encodePacked(
+ originalTokenAddress,
+ sender,
+ receiver,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ originChainId,
+ destinationChainId
+ )
+ );
+ }
+
+ function addMember(address _newMember) external onlyOwner override {
+ require(_newMember != NULL_ADDRESS, "Federation: Empty member");
+ require(!isMember[_newMember], "Federation: Member already exists");
+ require(members.length < MAX_MEMBER_COUNT, "Federation: Max members reached");
+
+ isMember[_newMember] = true;
+ members.push(_newMember);
+ emit MemberAddition(_newMember);
+ }
+
+ function removeMember(address _oldMember) external onlyOwner override {
+ require(_oldMember != NULL_ADDRESS, "Federation: Empty member");
+ require(isMember[_oldMember], "Federation: Member doesn't exists");
+ require(members.length > 1, "Federation: Can't remove all the members");
+ require(members.length - 1 >= required, "Federation: Can't have less than required members");
+
+ isMember[_oldMember] = false;
+ for (uint i = 0; i < members.length - 1; i++) {
+ if (members[i] == _oldMember) {
+ members[i] = members[members.length - 1];
+ break;
+ }
+ }
+ members.pop(); // remove an element from the end of the array.
+ emit MemberRemoval(_oldMember);
+ }
+
+ /**
+ @notice Return all the current members of the federation
+ @return Current members
+ */
+ function getMembers() external view override returns (address[] memory) {
+ return members;
+ }
+
+ /**
+ @notice Changes the number of required members to vote and approve an transaction
+ @dev Emits the RequirementChange event
+ @param _required the number of minimum members to approve an transaction, it has to be bigger than 1
+ */
+ function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {
+ require(_required >= 2, "Federation: Requires at least 2");
+ required = _required;
+ emit RequirementChange(_required);
+ }
+
+ /**
+ @notice It emits an HeartBeat like an health check
+ @dev Emits HeartBeat event
+ */
+ function emitHeartbeat(
+ string calldata fedVersion,
+ uint256[] calldata fedChainsIds,
+ uint256[] calldata fedChainsBlocks,
+ string[] calldata fedChainsInfo
+ ) external onlyMember override {
+ require(fedChainsIds.length == fedChainsBlocks.length &&
+ fedChainsIds.length == fedChainsInfo.length, "Federation: Length missmatch");
+ emit HeartBeat(
+ _msgSender(),
+ block.chainid,
+ block.number,
+ fedVersion,
+ fedChainsIds,
+ fedChainsBlocks,
+ fedChainsInfo
+ );
+ }
+}
diff --git a/bridge/contracts/Federation/FederationV2.sol b/bridge/contracts/Federation/FederationV2.sol
new file mode 100644
index 000000000..09ef3bdcf
--- /dev/null
+++ b/bridge/contracts/Federation/FederationV2.sol
@@ -0,0 +1,265 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+// Upgradables
+import "../zeppelin/upgradable/Initializable.sol";
+import "../zeppelin/upgradable/ownership/UpgradableOwnable.sol";
+
+import "../Bridge/IBridgeV3.sol";
+
+contract FederationV2 is Initializable, UpgradableOwnable {
+ uint constant public MAX_MEMBER_COUNT = 50;
+ address constant private NULL_ADDRESS = address(0);
+
+ IBridgeV3 public bridge;
+ address[] public members;
+ uint public required;
+
+ mapping (address => bool) public isMember;
+ mapping (bytes32 => mapping (address => bool)) public votes;
+ mapping(bytes32 => bool) public processed;
+
+ event Executed(
+ address indexed federator,
+ bytes32 indexed transactionHash,
+ bytes32 indexed transactionId,
+ address originalTokenAddress,
+ address sender,
+ address receiver,
+ uint256 amount,
+ bytes32 blockHash,
+ uint32 logIndex
+ );
+ event MemberAddition(address indexed member);
+ event MemberRemoval(address indexed member);
+ event RequirementChange(uint required);
+ event BridgeChanged(address bridge);
+ event Voted(
+ address indexed federator,
+ bytes32 indexed transactionHash,
+ bytes32 indexed transactionId,
+ address originalTokenAddress,
+ address sender,
+ address receiver,
+ uint256 amount,
+ bytes32 blockHash,
+ uint32 logIndex
+ );
+ event HeartBeat(
+ address indexed sender,
+ uint256 fedRskBlock,
+ uint256 fedEthBlock,
+ string federatorVersion,
+ string nodeRskInfo,
+ string nodeEthInfo
+ );
+
+ modifier onlyMember() {
+ require(isMember[_msgSender()], "Federation: Not Federator");
+ _;
+ }
+
+ modifier validRequirement(uint membersCount, uint _required) {
+ // solium-disable-next-line max-len
+ require(_required <= membersCount && _required != 0 && membersCount != 0, "Federation: Invalid requirements");
+ _;
+ }
+
+ function initialize(address[] memory _members, uint _required, address _bridge, address owner)
+ validRequirement(_members.length, _required) public initializer {
+ UpgradableOwnable.initialize(owner);
+ require(_members.length <= MAX_MEMBER_COUNT, "Federation: Too many members");
+ members = _members;
+ for (uint i = 0; i < _members.length; i++) {
+ require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, "Federation: Invalid members");
+ isMember[_members[i]] = true;
+ emit MemberAddition(_members[i]);
+ }
+ required = _required;
+ emit RequirementChange(required);
+ _setBridge(_bridge);
+ }
+
+ function version() external pure returns (string memory) {
+ return "v2";
+ }
+
+ function setBridge(address _bridge) external onlyOwner {
+ _setBridge(_bridge);
+ }
+
+ function _setBridge(address _bridge) internal {
+ require(_bridge != NULL_ADDRESS, "Federation: Empty bridge");
+ bridge = IBridgeV3(_bridge);
+ emit BridgeChanged(_bridge);
+ }
+
+ function voteTransaction(
+ address originalTokenAddress,
+ address payable sender,
+ address payable receiver,
+ uint256 amount,
+ bytes32 blockHash,
+ bytes32 transactionHash,
+ uint32 logIndex
+ )
+ public onlyMember returns(bool)
+ {
+ bytes32 transactionId = getTransactionId(
+ originalTokenAddress,
+ sender,
+ receiver,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex
+ );
+ if (processed[transactionId])
+ return true;
+
+ if (votes[transactionId][_msgSender()])
+ return true;
+
+ votes[transactionId][_msgSender()] = true;
+ emit Voted(
+ _msgSender(),
+ transactionHash,
+ transactionId,
+ originalTokenAddress,
+ sender,
+ receiver,
+ amount,
+ blockHash,
+ logIndex
+ );
+
+ uint transactionCount = getTransactionCount(transactionId);
+ if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {
+ processed[transactionId] = true;
+ bridge.acceptTransfer(
+ originalTokenAddress,
+ sender,
+ receiver,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex
+ );
+ emit Executed(
+ _msgSender(),
+ transactionHash,
+ transactionId,
+ originalTokenAddress,
+ sender,
+ receiver,
+ amount,
+ blockHash,
+ logIndex
+ );
+ return true;
+ }
+
+ return true;
+ }
+
+ function getTransactionCount(bytes32 transactionId) public view returns(uint) {
+ uint count = 0;
+ for (uint i = 0; i < members.length; i++) {
+ if (votes[transactionId][members[i]])
+ count += 1;
+ }
+ return count;
+ }
+
+ function hasVoted(bytes32 transactionId) external view returns(bool)
+ {
+ return votes[transactionId][_msgSender()];
+ }
+
+ function transactionWasProcessed(bytes32 transactionId) external view returns(bool)
+ {
+ return processed[transactionId];
+ }
+
+ function getTransactionId(
+ address originalTokenAddress,
+ address sender,
+ address receiver,
+ uint256 amount,
+ bytes32 blockHash,
+ bytes32 transactionHash,
+ uint32 logIndex
+ ) public pure returns(bytes32)
+ {
+ return keccak256(
+ abi.encodePacked(
+ originalTokenAddress,
+ sender,
+ receiver,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex
+ )
+ );
+ }
+
+ function addMember(address _newMember) external onlyOwner
+ {
+ require(_newMember != NULL_ADDRESS, "Federation: Empty member");
+ require(!isMember[_newMember], "Federation: Member already exists");
+ require(members.length < MAX_MEMBER_COUNT, "Federation: Max members reached");
+
+ isMember[_newMember] = true;
+ members.push(_newMember);
+ emit MemberAddition(_newMember);
+ }
+
+ function removeMember(address _oldMember) external onlyOwner
+ {
+ require(_oldMember != NULL_ADDRESS, "Federation: Empty member");
+ require(isMember[_oldMember], "Federation: Member doesn't exists");
+ require(members.length > 1, "Federation: Can't remove all the members");
+ require(members.length - 1 >= required, "Federation: Can't have less than required members");
+
+ isMember[_oldMember] = false;
+ for (uint i = 0; i < members.length - 1; i++) {
+ if (members[i] == _oldMember) {
+ members[i] = members[members.length - 1];
+ break;
+ }
+ }
+ members.pop(); // remove an element from the end of the array.
+ emit MemberRemoval(_oldMember);
+ }
+
+ function getMembers() external view returns (address[] memory)
+ {
+ return members;
+ }
+
+ function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)
+ {
+ require(_required >= 2, "Federation: Requires at least 2");
+ required = _required;
+ emit RequirementChange(_required);
+ }
+
+ function emitHeartbeat(
+ uint256 fedRskBlock,
+ uint256 fedEthBlock,
+ string calldata federatorVersion,
+ string calldata nodeRskInfo,
+ string calldata nodeEthInfo
+ ) external onlyMember {
+ emit HeartBeat(
+ _msgSender(),
+ fedRskBlock,
+ fedEthBlock,
+ federatorVersion,
+ nodeRskInfo,
+ nodeEthInfo
+ );
+ }
+}
\ No newline at end of file
diff --git a/bridge/contracts/MainToken.sol b/bridge/contracts/MainToken.sol
deleted file mode 100644
index e57446b08..000000000
--- a/bridge/contracts/MainToken.sol
+++ /dev/null
@@ -1,15 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "./zeppelin/token/ERC20/DetailedERC20.sol";
-import "./zeppelin/token/ERC20/StandardToken.sol";
-
-contract MainToken is DetailedERC20, StandardToken {
- constructor(string _name, string _symbol, uint8 _decimals,
- uint _totalSupply)
- DetailedERC20(_name, _symbol, _decimals)
- public {
- totalSupply_ = _totalSupply;
- balances[msg.sender] = _totalSupply;
- }
-}
-
diff --git a/bridge/contracts/Migrations.sol b/bridge/contracts/Migrations.sol
deleted file mode 100644
index c4efb65e2..000000000
--- a/bridge/contracts/Migrations.sol
+++ /dev/null
@@ -1,23 +0,0 @@
-pragma solidity ^0.4.23;
-
-contract Migrations {
- address public owner;
- uint public last_completed_migration;
-
- constructor() public {
- owner = msg.sender;
- }
-
- modifier restricted() {
- if (msg.sender == owner) _;
- }
-
- function setCompleted(uint completed) public restricted {
- last_completed_migration = completed;
- }
-
- function upgrade(address new_address) public restricted {
- Migrations upgraded = Migrations(new_address);
- upgraded.setCompleted(last_completed_migration);
- }
-}
diff --git a/bridge/contracts/MultiSigWallet.sol b/bridge/contracts/MultiSigWallet.sol
new file mode 100644
index 000000000..b6fac4ad7
--- /dev/null
+++ b/bridge/contracts/MultiSigWallet.sol
@@ -0,0 +1,396 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.
+/// @author Stefan George -
+contract MultiSigWallet {
+
+ /*
+ * Events
+ */
+ event Confirmation(address indexed sender, uint indexed transactionId);
+ event Revocation(address indexed sender, uint indexed transactionId);
+ event Submission(uint indexed transactionId);
+ event Execution(uint indexed transactionId);
+ event ExecutionFailure(uint indexed transactionId);
+ event Deposit(address indexed sender, uint value);
+ event OwnerAddition(address indexed owner);
+ event OwnerRemoval(address indexed owner);
+ event RequirementChange(uint required);
+
+ /*
+ * views
+ */
+ uint constant public MAX_OWNER_COUNT = 50;
+
+ /*
+ * Storage
+ */
+ mapping (uint => Transaction) public transactions;
+ mapping (uint => mapping (address => bool)) public confirmations;
+ mapping (address => bool) public isOwner;
+ address[] public owners;
+ uint public required;
+ uint public transactionCount;
+
+ struct Transaction {
+ address destination;
+ uint value;
+ bytes data;
+ bool executed;
+ }
+
+ /*
+ * Modifiers
+ */
+ modifier onlyWallet() {
+ require(msg.sender == address(this), "Only wallet allowed");
+ _;
+ }
+
+ modifier ownerDoesNotExist(address owner) {
+ require(!isOwner[owner], "The owner already exists");
+ _;
+ }
+
+ modifier ownerExists(address owner) {
+ require(isOwner[owner], "The owner does not exist");
+ _;
+ }
+
+ modifier transactionExists(uint transactionId) {
+ require(transactions[transactionId].destination != address(0), "Transaction does not exist");
+ _;
+ }
+
+ modifier confirmed(uint transactionId, address owner) {
+ require(confirmations[transactionId][owner], "Transaction is not confirmed by owner");
+ _;
+ }
+
+ modifier notConfirmed(uint transactionId, address owner) {
+ require(!confirmations[transactionId][owner], "Transaction is already confirmed by owner");
+ _;
+ }
+
+ modifier notExecuted(uint transactionId) {
+ require(!transactions[transactionId].executed, "Transaction was already executed");
+ _;
+ }
+
+ modifier notNull(address _address) {
+ require(_address != address(0), "Address cannot be empty");
+ _;
+ }
+
+ modifier validRequirement(uint ownerCount, uint _required) {
+ // solium-disable-next-line max-len
+ require(ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && _required != 0 && ownerCount != 0, "Required value is invalid for the current owners count");
+ _;
+ }
+
+ /// @dev Fallback function allows to deposit ether.
+ receive ()
+ external
+ payable
+ {
+ if (msg.value > 0)
+ emit Deposit(msg.sender, msg.value);
+ }
+
+ /*
+ * Public functions
+ */
+ /// @dev Contract constructor sets initial owners and required number of confirmations.
+ /// @param _owners List of initial owners.
+ /// @param _required Number of required confirmations.
+ constructor(address[] memory _owners, uint _required)
+ validRequirement(_owners.length, _required)
+ {
+ for (uint i = 0; i < _owners.length; i++) {
+ require(!isOwner[_owners[i]] && _owners[i] != address(0), "Owners addresses are invalid");
+ isOwner[_owners[i]] = true;
+ }
+ owners = _owners;
+ required = _required;
+ }
+
+ /// @dev Allows to add a new owner. Transaction has to be sent by wallet.
+ /// @param owner Address of new owner.
+ function addOwner(address owner)
+ public
+ onlyWallet
+ ownerDoesNotExist(owner)
+ notNull(owner)
+ validRequirement(owners.length + 1, required)
+ {
+ isOwner[owner] = true;
+ owners.push(owner);
+ emit OwnerAddition(owner);
+ }
+
+ /// @dev Allows to remove an owner. Transaction has to be sent by wallet.
+ /// @param owner Address of owner.
+ function removeOwner(address owner)
+ public
+ onlyWallet
+ ownerExists(owner)
+ {
+ isOwner[owner] = false;
+ for (uint i = 0; i < owners.length - 1; i++)
+ if (owners[i] == owner) {
+ owners[i] = owners[owners.length - 1];
+ break;
+ }
+ owners.pop(); // remove an element from the end of the array.
+ if (required > owners.length)
+ changeRequirement(owners.length);
+ emit OwnerRemoval(owner);
+ }
+
+ /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.
+ /// @param owner Address of owner to be replaced.
+ /// @param newOwner Address of new owner.
+ function replaceOwner(address owner, address newOwner)
+ public
+ onlyWallet
+ ownerExists(owner)
+ ownerDoesNotExist(newOwner)
+ {
+ for (uint i = 0; i < owners.length; i++)
+ if (owners[i] == owner) {
+ owners[i] = newOwner;
+ break;
+ }
+ isOwner[owner] = false;
+ isOwner[newOwner] = true;
+ emit OwnerRemoval(owner);
+ emit OwnerAddition(newOwner);
+ }
+
+ /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.
+ /// @param _required Number of required confirmations.
+ function changeRequirement(uint _required)
+ public
+ onlyWallet
+ validRequirement(owners.length, _required)
+ {
+ required = _required;
+ emit RequirementChange(_required);
+ }
+
+ /// @dev Allows an owner to submit and confirm a transaction.
+ /// @param destination Transaction target address.
+ /// @param value Transaction ether value.
+ /// @param data Transaction data payload.
+ /// @return transactionId Returns transaction ID.
+ function submitTransaction(address destination, uint value, bytes memory data)
+ public
+ returns (uint transactionId)
+ {
+ transactionId = addTransaction(destination, value, data);
+ confirmTransaction(transactionId);
+ }
+
+ /// @dev Allows an owner to confirm a transaction.
+ /// @param transactionId Transaction ID.
+ function confirmTransaction(uint transactionId)
+ public
+ ownerExists(msg.sender)
+ transactionExists(transactionId)
+ notConfirmed(transactionId, msg.sender)
+ {
+ confirmations[transactionId][msg.sender] = true;
+ emit Confirmation(msg.sender, transactionId);
+ executeTransaction(transactionId);
+ }
+
+ /// @dev Allows an owner to revoke a confirmation for a transaction.
+ /// @param transactionId Transaction ID.
+ function revokeConfirmation(uint transactionId)
+ public
+ ownerExists(msg.sender)
+ confirmed(transactionId, msg.sender)
+ notExecuted(transactionId)
+ {
+ confirmations[transactionId][msg.sender] = false;
+ emit Revocation(msg.sender, transactionId);
+ }
+
+ /// @dev Allows anyone to execute a confirmed transaction.
+ /// @param transactionId Transaction ID.
+ function executeTransaction(uint transactionId)
+ public
+ ownerExists(msg.sender)
+ confirmed(transactionId, msg.sender)
+ notExecuted(transactionId)
+ {
+ if (isConfirmed(transactionId)) {
+ Transaction storage txn = transactions[transactionId];
+ txn.executed = true;
+ if (external_call(txn.destination, txn.value, txn.data.length, txn.data))
+ emit Execution(transactionId);
+ else {
+ emit ExecutionFailure(transactionId);
+ txn.executed = false;
+ }
+ }
+ }
+
+ // call has been separated into its own function in order to take advantage
+ // of the Solidity's code generator to produce a loop that copies tx.data into memory.
+ function external_call(address destination, uint value, uint dataLength, bytes memory data) internal returns (bool) {
+ bool result;
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ let x := mload(0x40) // "Allocate" memory for output (0x40 is where "free memory" pointer is stored by convention)
+ let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that
+ result := call(
+ sub(gas(), 34710), // 34710 is the value that solidity is currently emitting
+ // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +
+ // callNewAccountGas (25000, in case the destination address does not exist and needs creating)
+ destination,
+ value,
+ d,
+ dataLength, // Size of the input (in bytes) - this is what fixes the padding problem
+ x,
+ 0 // Output is ignored, therefore the output size is zero
+ )
+ }
+ return result;
+ }
+
+ /// @dev Returns the confirmation status of a transaction.
+ /// @param transactionId Transaction ID.
+ /// @return Confirmation status.
+ function isConfirmed(uint transactionId)
+ public
+ view
+ returns (bool)
+ {
+ uint count = 0;
+ for (uint i = 0; i < owners.length; i++) {
+ if (confirmations[transactionId][owners[i]])
+ count += 1;
+ if (count == required)
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * Internal functions
+ */
+ /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.
+ /// @param destination Transaction target address.
+ /// @param value Transaction ether value.
+ /// @param data Transaction data payload.
+ /// @return transactionId Returns transaction ID.
+ function addTransaction(address destination, uint value, bytes memory data)
+ internal
+ notNull(destination)
+ returns (uint transactionId)
+ {
+ transactionId = transactionCount;
+ transactions[transactionId] = Transaction({
+ destination: destination,
+ value: value,
+ data: data,
+ executed: false
+ });
+ transactionCount += 1;
+ emit Submission(transactionId);
+ }
+
+ /*
+ * Web3 call functions
+ */
+ /// @dev Returns number of confirmations of a transaction.
+ /// @param transactionId Transaction ID.
+ /// @return count Number of confirmations.
+ function getConfirmationCount(uint transactionId)
+ public
+ view
+ returns (uint count)
+ {
+ for (uint i = 0; i < owners.length; i++) {
+ if (confirmations[transactionId][owners[i]]) {
+ count += 1;
+ }
+ }
+ }
+
+ /// @dev Returns total number of transactions after filers are applied.
+ /// @param pending Include pending transactions.
+ /// @param executed Include executed transactions.
+ /// @return count Total number of transactions after filters are applied.
+ function getTransactionCount(bool pending, bool executed)
+ public
+ view
+ returns (uint count)
+ {
+ for (uint i = 0; i < transactionCount; i++) {
+ if ( pending && !transactions[i].executed || executed && transactions[i].executed) {
+ count += 1;
+ }
+ }
+ }
+
+ /// @dev Returns list of owners.
+ /// @return List of owner addresses.
+ function getOwners()
+ public
+ view
+ returns (address[] memory)
+ {
+ return owners;
+ }
+
+ /// @dev Returns array with owner addresses, which confirmed transaction.
+ /// @param transactionId Transaction ID.
+ /// @return _confirmations Returns array of owner addresses.
+ function getConfirmations(uint transactionId)
+ public
+ view
+ returns (address[] memory _confirmations)
+ {
+ address[] memory confirmationsTemp = new address[](owners.length);
+ uint count = 0;
+ uint i;
+ for (i = 0; i < owners.length; i++)
+ if (confirmations[transactionId][owners[i]]) {
+ confirmationsTemp[count] = owners[i];
+ count += 1;
+ }
+ _confirmations = new address[](count);
+ for (i = 0; i < count; i++)
+ _confirmations[i] = confirmationsTemp[i];
+ }
+
+ /// @dev Returns list of transaction IDs in defined range.
+ /// @param from Index start position of transaction array.
+ /// @param to Index end position of transaction array.
+ /// @param pending Include pending transactions.
+ /// @param executed Include executed transactions.
+ /// @return _transactionIds Returns array of transaction IDs.
+ function getTransactionIds(uint from, uint to, bool pending, bool executed)
+ public
+ view
+ returns (uint[] memory _transactionIds)
+ {
+ uint[] memory transactionIdsTemp = new uint[](transactionCount);
+ uint count = 0;
+ uint i;
+ for (i = 0; i < transactionCount; i++)
+ if ( pending && !transactions[i].executed || executed && transactions[i].executed)
+ {
+ transactionIdsTemp[count] = i;
+ count += 1;
+ }
+ _transactionIds = new uint[](to - from);
+ for (i = from; i < to; i++)
+ _transactionIds[i - from] = transactionIdsTemp[i];
+ }
+}
\ No newline at end of file
diff --git a/bridge/contracts/Proxies.sol b/bridge/contracts/Proxies.sol
new file mode 100644
index 000000000..0864c6409
--- /dev/null
+++ b/bridge/contracts/Proxies.sol
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol";
+
+contract BridgeProxy is TransparentUpgradeableProxy {
+ // solhint-disable-next-line no-empty-blocks
+ constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}
+}
+
+contract AllowTokensProxy is TransparentUpgradeableProxy {
+ // solhint-disable-next-line no-empty-blocks
+ constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}
+}
+
+contract FederationProxy is TransparentUpgradeableProxy {
+ // solhint-disable-next-line no-empty-blocks
+ constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}
+}
\ No newline at end of file
diff --git a/bridge/contracts/SideToken.sol b/bridge/contracts/SideToken.sol
deleted file mode 100644
index 2e35da0de..000000000
--- a/bridge/contracts/SideToken.sol
+++ /dev/null
@@ -1,47 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "./zeppelin/token/ERC20/DetailedERC20.sol";
-import "./zeppelin/token/ERC20/StandardToken.sol";
-import "./Transferable.sol";
-
-contract SideToken is DetailedERC20, StandardToken, Transferable {
- address public manager;
-
- modifier onlyManager() {
- require(msg.sender == manager);
- _;
- }
-
- constructor(string _name, string _symbol, uint8 _decimals, address _manager)
- DetailedERC20(_name, _symbol, _decimals)
- public {
- manager = _manager;
- }
-
- function changeManager(address newmanager) public onlyManager {
- require(newmanager != address(0));
-
- manager = newmanager;
- }
-
- function acceptTransfer(address receiver, uint256 amount) public onlyManager returns(bool) {
- totalSupply_ += amount;
- balances[receiver] += amount;
-
- emit Transfer(manager, receiver, amount);
-
- return true;
- }
-
- function transfer(address receiver, uint amount) public returns(bool) {
- bool result = super.transfer(receiver, amount);
-
- if (result && receiver == manager) {
- balances[manager] -= amount;
- totalSupply_ -= amount;
- }
-
- return result;
- }
-}
-
diff --git a/bridge/contracts/SideToken/SideToken.sol b/bridge/contracts/SideToken/SideToken.sol
new file mode 100644
index 000000000..a22ae270f
--- /dev/null
+++ b/bridge/contracts/SideToken/SideToken.sol
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "../zeppelin/token/ERC777/ERC777.sol";
+import "../interface/IERC677Receiver.sol";
+import "../interface/ISideToken.sol";
+import "../lib/LibEIP712.sol";
+
+contract SideToken is ISideToken, ERC777 {
+ using SafeMath for uint256;
+
+ address public minter;
+ uint256 private _granularity;
+
+ // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md
+ bytes32 public domainSeparator;
+ // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
+ bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
+ mapping(address => uint) public nonces;
+
+ // ERC677 Transfer Event
+ event Transfer(address,address,uint256,bytes);
+
+ constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)
+ ERC777(_tokenName, _tokenSymbol, new address[](0)) {
+ require(_minterAddr != address(0), "SideToken: Empty Minter");
+ require(_newGranularity >= 1, "SideToken: Granularity < 1");
+ minter = _minterAddr;
+ _granularity = _newGranularity;
+
+ domainSeparator = LibEIP712.hashEIP712Domain(
+ name(),
+ "1",
+ block.chainid,
+ address(this)
+ );
+ }
+
+ modifier onlyMinter() {
+ require(_msgSender() == minter, "SideToken: Caller is not the minter");
+ _;
+ }
+
+ function mint(
+ address account,
+ uint256 amount,
+ bytes calldata userData,
+ bytes calldata operatorData
+ )
+ external onlyMinter override
+ {
+ _mint(_msgSender(), account, amount, userData, operatorData);
+ }
+
+ /**
+ * @dev ERC677 transfer token with additional data if the recipient is a contact.
+ * @param recipient The address to transfer to.
+ * @param amount The amount to be transferred.
+ * @param data The extra data to be passed to the receiving contract.
+ */
+ function transferAndCall(address recipient, uint amount, bytes calldata data)
+ external returns (bool success)
+ {
+ address from = _msgSender();
+
+ _send(from, from, recipient, amount, data, "", false);
+ emit Transfer(from, recipient, amount, data);
+ IERC677Receiver(recipient).onTokenTransfer(from, amount, data);
+ return true;
+ }
+
+ function granularity() public view override returns (uint256) {
+ return _granularity;
+ }
+
+ // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md
+ function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {
+ require(deadline >= block.timestamp, "SideToken: EXPIRED"); // solhint-disable-line not-rely-on-time
+ bytes32 digest = LibEIP712.hashEIP712Message(
+ domainSeparator,
+ keccak256(
+ abi.encode(
+ PERMIT_TYPEHASH,
+ owner,
+ spender,
+ value,
+ nonces[owner]++,
+ deadline
+ )
+ )
+ );
+ address recoveredAddress = ecrecover(digest, v, r, s);
+ require(recoveredAddress != address(0) && recoveredAddress == owner, "SideToken: INVALID_SIGNATURE");
+ _approve(owner, spender, value);
+ }
+
+}
\ No newline at end of file
diff --git a/bridge/contracts/SideToken/SideTokenV1.sol b/bridge/contracts/SideToken/SideTokenV1.sol
new file mode 100644
index 000000000..037b37bd3
--- /dev/null
+++ b/bridge/contracts/SideToken/SideTokenV1.sol
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../zeppelin/token/ERC777/ERC777.sol";
+
+contract SideTokenV1 is ERC777 {
+ address public minter;
+
+ constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)
+ ERC777(_tokenName, _tokenSymbol, new address[](0)) {
+ require(_minterAddr != address(0), "SideToken: Minter address is null");
+ minter = _minterAddr;
+ }
+
+ modifier onlyMinter() {
+ require(_msgSender() == minter, "SideToken: Caller is not the minter");
+ _;
+ }
+ function mint(
+ address account,
+ uint256 amount,
+ bytes calldata userData,
+ bytes calldata operatorData
+ )
+ external onlyMinter
+ {
+ _mint(_msgSender(), account, amount, userData, operatorData);
+ }
+
+}
\ No newline at end of file
diff --git a/bridge/contracts/SideTokenFactory/SideTokenFactory.sol b/bridge/contracts/SideTokenFactory/SideTokenFactory.sol
new file mode 100644
index 000000000..80ee87f7d
--- /dev/null
+++ b/bridge/contracts/SideTokenFactory/SideTokenFactory.sol
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "../zeppelin/ownership/Secondary.sol";
+import "../interface/ISideTokenFactory.sol";
+import "../SideToken/SideToken.sol";
+
+contract SideTokenFactory is ISideTokenFactory, Secondary {
+
+ function createSideToken(string calldata name, string calldata symbol, uint256 granularity)
+ external onlyPrimary override returns(address) {
+ address sideToken = address(new SideToken(name, symbol, primary(), granularity));
+ emit SideTokenCreated(sideToken, symbol, granularity);
+ return sideToken;
+ }
+}
\ No newline at end of file
diff --git a/bridge/contracts/SideTokenFactory/SideTokenFactoryV1.sol b/bridge/contracts/SideTokenFactory/SideTokenFactoryV1.sol
new file mode 100644
index 000000000..3e9c5e92d
--- /dev/null
+++ b/bridge/contracts/SideTokenFactory/SideTokenFactoryV1.sol
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../zeppelin/ownership/Secondary.sol";
+import "../SideToken/SideTokenV1.sol";
+
+contract SideTokenFactoryV1 is Secondary {
+ event CreatedSideToken(address sideToken, string symbol);
+
+ function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {
+ SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());
+ emit CreatedSideToken(address(sideToken), symbol);
+ return sideToken;
+ }
+}
\ No newline at end of file
diff --git a/bridge/contracts/Transferable.sol b/bridge/contracts/Transferable.sol
deleted file mode 100644
index 62d5a4dfb..000000000
--- a/bridge/contracts/Transferable.sol
+++ /dev/null
@@ -1,6 +0,0 @@
-pragma solidity ^0.4.24;
-
-contract Transferable {
- function acceptTransfer(address account, uint256 value) public returns(bool);
- function changeManager(address newmanager) public;
-}
diff --git a/bridge/contracts/interface/IAllowTokens.sol b/bridge/contracts/interface/IAllowTokens.sol
new file mode 100644
index 000000000..da89e89b1
--- /dev/null
+++ b/bridge/contracts/interface/IAllowTokens.sol
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+interface IAllowTokens {
+
+ struct Limits {
+ uint256 min;
+ uint256 max;
+ uint256 daily;
+ uint256 mediumAmount;
+ uint256 largeAmount;
+ }
+
+ struct TokenInfo {
+ bool allowed;
+ uint256 typeId;
+ uint256 spentToday;
+ uint256 lastDay;
+ }
+
+ struct TypeInfo {
+ string description;
+ Limits limits;
+ }
+
+ struct TokensAndType {
+ address token;
+ uint256 typeId;
+ }
+
+ function version() external pure returns (string memory);
+
+ function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);
+
+ function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);
+
+ function getTypesLimits() external view returns(Limits[] memory limits);
+
+ function getTypeDescriptionsLength() external view returns(uint256);
+
+ function getTypeDescriptions() external view returns(string[] memory descriptions);
+
+ function setToken(address token, uint256 typeId) external;
+
+ function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);
+
+ function isTokenAllowed(address token) external view returns (bool);
+
+ function updateTokenTransfer(address token, uint256 amount) external;
+}
\ No newline at end of file
diff --git a/bridge/contracts/interface/IBridge.sol b/bridge/contracts/interface/IBridge.sol
new file mode 100644
index 000000000..dd2b00ab0
--- /dev/null
+++ b/bridge/contracts/interface/IBridge.sol
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+interface IBridge {
+
+ struct ClaimData {
+ address payable to;
+ uint256 amount;
+ bytes32 blockHash;
+ bytes32 transactionHash;
+ uint32 logIndex;
+ uint256 originChainId;
+ }
+
+ struct OriginalToken {
+ address tokenAddress;
+ uint256 originChainId;
+ }
+
+ struct CreateSideTokenStruct {
+ uint256 _typeId;
+ address _originalTokenAddress;
+ uint8 _originalTokenDecimals;
+ string _originalTokenSymbol;
+ string _originalTokenName;
+ uint256 _originChainId;
+ }
+
+ function version() external pure returns (string memory);
+
+ function getFeePercentage() external view returns(uint);
+
+ /**
+ * ERC-20 tokens approve and transferFrom pattern
+ * See https://eips.ethereum.org/EIPS/eip-20#transferfrom
+ */
+ function receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;
+
+ /**
+ * Use network currency and cross it.
+ */
+ function depositTo(uint256 chainId, address to) external payable;
+
+ /**
+ * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction
+ * See https://eips.ethereum.org/EIPS/eip-777#motivation for details
+ * @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination
+ * const userData = web3.eth.abi.encodeParameters(
+ * ["address", "uint256"],
+ * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]
+ * );
+ * or you also can send only the destination chain id, and the receiver would be the same as the from parameter
+ * const userData = web3.eth.abi.encodeParameters(["uint256"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);
+ */
+ function tokensReceived (
+ address operator,
+ address from,
+ address to,
+ uint amount,
+ bytes calldata userData,
+ bytes calldata operatorData
+ ) external;
+
+ /**
+ * Accepts the transaction from the other chain that was voted and sent by the Federation contract
+ */
+ function acceptTransfer(
+ address _originalTokenAddress,
+ address payable _from,
+ address payable _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex,
+ uint256 _originChainId,
+ uint256 _destinationChainId
+ ) external;
+
+ /**
+ * Claims the crossed transaction using the hash, this sends the funds to the address indicated in
+ */
+ function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);
+
+ function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);
+
+ function claimGasless(
+ ClaimData calldata _claimData,
+ address payable _relayer,
+ uint256 _fee,
+ uint256 _deadline,
+ uint8 _v,
+ bytes32 _r,
+ bytes32 _s
+ ) external returns (uint256 receivedAmount);
+
+ function createSideToken(
+ uint256 _typeId,
+ address _originalTokenAddress,
+ uint8 _originalTokenDecimals,
+ string calldata _originalTokenSymbol,
+ string calldata _originalTokenName,
+ uint256 _chainId
+ ) external;
+
+ function createMultipleSideTokens(
+ CreateSideTokenStruct[] calldata createSideTokenStruct
+ ) external;
+
+ function getTransactionDataHash(
+ address _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex,
+ uint256 _originChainId,
+ uint256 _destinationChainId
+ ) external returns(bytes32);
+
+ event Cross(
+ address indexed _tokenAddress,
+ address indexed _to,
+ uint256 indexed _destinationChainId,
+ address _from,
+ uint256 _originChainId,
+ uint256 _amount,
+ bytes _userData
+ );
+
+ event NewSideToken(
+ address indexed _newSideTokenAddress,
+ address indexed _originalTokenAddress,
+ string _newSymbol,
+ uint256 _granularity,
+ uint256 _chainId
+ );
+ event AcceptedCrossTransfer(
+ bytes32 indexed _transactionHash,
+ address indexed _originalTokenAddress,
+ address indexed _to,
+ address _from,
+ uint256 _amount,
+ bytes32 _blockHash,
+ uint256 _logIndex,
+ uint256 _originChainId,
+ uint256 _destinationChainId
+ );
+ event FeePercentageChanged(uint256 _amount);
+ event Claimed(
+ bytes32 indexed _transactionHash,
+ address indexed _originalTokenAddress,
+ address indexed _to,
+ address _sender,
+ uint256 _amount,
+ bytes32 _blockHash,
+ uint256 _logIndex,
+ address _reciever,
+ address _relayer,
+ uint256 _fee,
+ uint256 _destinationChainId,
+ uint256 _originChainId
+ );
+}
\ No newline at end of file
diff --git a/bridge/contracts/interface/IERC1271.sol b/bridge/contracts/interface/IERC1271.sol
new file mode 100644
index 000000000..e20d0d195
--- /dev/null
+++ b/bridge/contracts/interface/IERC1271.sol
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+pragma solidity >=0.5.0;
+
+/// @title Interface for verifying contract-based account signatures
+/// @notice Interface that verifies provided signature for the data
+/// @dev Interface defined by EIP-1271
+interface IERC1271 {
+ /// @notice Returns whether the provided signature is valid for the provided data
+ /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.
+ /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).
+ /// MUST allow external calls.
+ /// @param hash Hash of the data to be signed
+ /// @param signature Signature byte array associated with _data
+ /// @return magicValue The bytes4 magic value 0x1626ba7e
+ function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
+}
\ No newline at end of file
diff --git a/bridge/contracts/interface/IERC677Receiver.sol b/bridge/contracts/interface/IERC677Receiver.sol
new file mode 100644
index 000000000..87ab42eb7
--- /dev/null
+++ b/bridge/contracts/interface/IERC677Receiver.sol
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+interface IERC677Receiver {
+ function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;
+}
\ No newline at end of file
diff --git a/bridge/contracts/interface/IFederation.sol b/bridge/contracts/interface/IFederation.sol
new file mode 100644
index 000000000..3bf0d0750
--- /dev/null
+++ b/bridge/contracts/interface/IFederation.sol
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+interface IFederation {
+
+ /**
+ @notice Current version of the contract
+ @return version in v{Number}
+ */
+ function version() external pure returns (string memory);
+
+ /**
+ @notice Sets a new bridge contract
+ @param _bridge the new bridge contract address that should implement the IBridge interface
+ */
+ function setBridge(address _bridge) external;
+
+ /**
+ @notice Vote in a transaction, if it has enough votes it accepts the transfer
+ @param originalTokenAddress The address of the token in the origin (main) chain
+ @param sender The address who solicited the cross token
+ @param receiver Who is going to receive the token in the opposite chain
+ @param value Amount
+ @param blockHash The block hash in which the transaction with the cross event occurred
+ @param transactionHash The transaction in which the cross event occurred
+ @param logIndex Index of the event in the logs
+ @param originChainId Is chainId of the original chain
+ @param destinationChainId Is chainId of the destination chain
+ */
+ function voteTransaction(
+ address originalTokenAddress,
+ address payable sender,
+ address payable receiver,
+ uint256 value,
+ bytes32 blockHash,
+ bytes32 transactionHash,
+ uint32 logIndex,
+ uint256 originChainId,
+ uint256 destinationChainId
+ ) external;
+
+ /**
+ @notice Add a new member to the federation
+ @param _newMember address of the new member
+ */
+ function addMember(address _newMember) external;
+
+ /**
+ @notice Remove a member of the federation
+ @param _oldMember address of the member to be removed from federation
+ */
+ function removeMember(address _oldMember) external;
+
+ /**
+ @notice Return all the current members of the federation
+ @return Current members
+ */
+ function getMembers() external view returns (address[] memory);
+
+ /**
+ @notice Changes the number of required members to vote and approve an transaction
+ @param _required the number of minimum members to approve an transaction, it has to be bigger than 1
+ */
+ function changeRequirement(uint _required) external;
+
+ /**
+ @notice It emmits an HeartBeat like an healthy check
+ */
+ function emitHeartbeat(
+ string calldata federatorVersion,
+ uint256[] calldata fedChainsIds,
+ uint256[] calldata fedChainsBlocks,
+ string[] calldata fedChainsInfo
+ ) external;
+
+ event Executed(
+ address indexed federator,
+ bytes32 indexed transactionHash,
+ bytes32 indexed transactionId,
+ address originalTokenAddress,
+ address sender,
+ address receiver,
+ uint256 amount,
+ bytes32 blockHash,
+ uint32 logIndex,
+ uint256 originChainId,
+ uint256 destinationChainId
+ );
+ event MemberAddition(address indexed member);
+ event MemberRemoval(address indexed member);
+ event RequirementChange(uint required);
+ event BridgeChanged(address bridge);
+ event Voted(
+ address indexed federator,
+ bytes32 indexed transactionHash,
+ bytes32 indexed transactionId,
+ address originalTokenAddress,
+ address sender,
+ address receiver,
+ uint256 amount,
+ bytes32 blockHash,
+ uint32 logIndex,
+ uint256 originChainId,
+ uint256 destinationChainId
+ );
+ event HeartBeat(
+ address indexed sender,
+ uint256 currentChainId,
+ uint256 currentBlock,
+ string fedVersion,
+ uint256[] fedChainsIds,
+ uint256[] fedChainsBlocks,
+ string[] fedChainsInfo
+ );
+
+}
diff --git a/bridge/contracts/interface/ISideToken.sol b/bridge/contracts/interface/ISideToken.sol
new file mode 100644
index 000000000..4b50c39ec
--- /dev/null
+++ b/bridge/contracts/interface/ISideToken.sol
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+interface ISideToken {
+ function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;
+}
\ No newline at end of file
diff --git a/bridge/contracts/interface/ISideTokenFactory.sol b/bridge/contracts/interface/ISideTokenFactory.sol
new file mode 100644
index 000000000..dee84fde8
--- /dev/null
+++ b/bridge/contracts/interface/ISideTokenFactory.sol
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+interface ISideTokenFactory {
+
+ function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);
+
+ event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);
+}
\ No newline at end of file
diff --git a/bridge/contracts/interface/IWrapped.sol b/bridge/contracts/interface/IWrapped.sol
new file mode 100644
index 000000000..62887a7b1
--- /dev/null
+++ b/bridge/contracts/interface/IWrapped.sol
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+interface IWrapped {
+ function balanceOf(address) external returns(uint);
+
+ function deposit() external payable;
+
+ function withdraw(uint wad) external;
+
+ function totalSupply() external view returns (uint);
+
+ function approve(address guy, uint wad) external returns (bool);
+
+ function transfer(address dst, uint wad) external returns (bool);
+
+ function transferFrom(address src, address dst, uint wad)
+ external
+ returns (bool);
+}
\ No newline at end of file
diff --git a/bridge/contracts/lib/LibEIP712.sol b/bridge/contracts/lib/LibEIP712.sol
new file mode 100644
index 000000000..c74caedac
--- /dev/null
+++ b/bridge/contracts/lib/LibEIP712.sol
@@ -0,0 +1,99 @@
+//SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol
+library LibEIP712 {
+
+ // Hash of the EIP712 Domain Separator Schema
+ // keccak256(abi.encodePacked(
+ // "EIP712Domain(",
+ // "string name,",
+ // "string version,",
+ // "uint256 chainId,",
+ // "address verifyingContract",
+ // ")"
+ // ))
+ bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;
+
+ /// @dev Calculates a EIP712 domain separator.
+ /// @param name The EIP712 domain name.
+ /// @param version The EIP712 domain version.
+ /// @param verifyingContract The EIP712 verifying contract.
+ /// @return result EIP712 domain separator.
+ function hashEIP712Domain(
+ string memory name,
+ string memory version,
+ uint256 chainId,
+ address verifyingContract
+ )
+ internal
+ pure
+ returns (bytes32 result)
+ {
+ bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;
+
+ // Assembly for more efficient computing:
+ // keccak256(abi.encodePacked(
+ // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,
+ // keccak256(bytes(name)),
+ // keccak256(bytes(version)),
+ // chainId,
+ // uint256(verifyingContract)
+ // ))
+
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ // Calculate hashes of dynamic data
+ let nameHash := keccak256(add(name, 32), mload(name))
+ let versionHash := keccak256(add(version, 32), mload(version))
+
+ // Load free memory pointer
+ let memPtr := mload(64)
+
+ // Store params in memory
+ mstore(memPtr, schemaHash)
+ mstore(add(memPtr, 32), nameHash)
+ mstore(add(memPtr, 64), versionHash)
+ mstore(add(memPtr, 96), chainId)
+ mstore(add(memPtr, 128), verifyingContract)
+
+ // Compute hash
+ result := keccak256(memPtr, 160)
+ }
+ return result;
+ }
+
+ /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.
+ /// @param eip712DomainHash Hash of the domain domain separator data, computed
+ /// with getDomainHash().
+ /// @param hashStruct The EIP712 hash struct.
+ /// @return result EIP712 hash applied to the given EIP712 Domain.
+ function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)
+ internal
+ pure
+ returns (bytes32 result)
+ {
+ // Assembly for more efficient computing:
+ // keccak256(abi.encodePacked(
+ // EIP191_HEADER,
+ // EIP712_DOMAIN_HASH,
+ // hashStruct
+ // ));
+
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ // Load free memory pointer
+ let memPtr := mload(64)
+
+ mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header
+ mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash
+ mstore(add(memPtr, 34), hashStruct) // Hash of struct
+
+ // Compute hash
+ result := keccak256(memPtr, 66)
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/bridge/contracts/lib/LibUtils.sol b/bridge/contracts/lib/LibUtils.sol
new file mode 100644
index 000000000..5c5993098
--- /dev/null
+++ b/bridge/contracts/lib/LibUtils.sol
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+library LibUtils {
+
+ function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {
+ require(decimals <= 18, "LibUtils: Decimals not <= 18");
+ return uint256(10)**(18-decimals);
+ }
+
+ function getDecimals(address tokenToUse) internal view returns (uint8) {
+ //support decimals as uint256 or uint8
+ (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature("decimals()"));
+ require(success, "LibUtils: No decimals");
+ // uint: enc(X) is the big-endian encoding of X,
+ //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.
+ return uint8(abi.decode(data, (uint256)));
+ }
+
+ function getGranularity(address tokenToUse) internal view returns (uint256) {
+ //support granularity if ERC777
+ (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature("granularity()"));
+ require(success, "LibUtils: No granularity");
+
+ return abi.decode(data, (uint256));
+ }
+
+ function bytesToAddress(bytes memory bys) internal pure returns (address addr) {
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ addr := mload(add(bys,20))
+ }
+ }
+
+ function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
+ require(_bytes.length >= _start + 20, "LibUtils: toAddress_outOfBounds");
+ address tempAddress;
+
+ assembly {
+ tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
+ }
+
+ return tempAddress;
+ }
+
+ function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
+ require(_bytes.length >= _start + 16, "LibUtils: toUint128_outOfBounds");
+ uint128 tempUint;
+
+ assembly {
+ tempUint := mload(add(add(_bytes, 0x10), _start))
+ }
+
+ return tempUint;
+ }
+
+ function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
+ require(_bytes.length >= _start + 32, "LibUtils: toUint256_outOfBounds");
+ uint256 tempUint;
+
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ tempUint := mload(add(add(_bytes, 0x20), _start))
+ }
+
+ return tempUint;
+ }
+}
diff --git a/bridge/contracts/test/AlternativeERC20Detailed.sol b/bridge/contracts/test/AlternativeERC20Detailed.sol
new file mode 100644
index 000000000..6384530d9
--- /dev/null
+++ b/bridge/contracts/test/AlternativeERC20Detailed.sol
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../zeppelin/token/ERC20/ERC20.sol";
+
+contract AlternativeERC20Detailed is ERC20 {
+ string private _name;
+ bytes32 private _symbol;
+ uint256 private _decimals;
+
+ constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)
+ {
+ _name = aName;
+ _symbol = aSymbol;
+ _decimals = someDecimals;
+ _mint(msg.sender, aTotalSupply);
+ }
+
+ function name() public view returns (string memory) {
+ return _name;
+ }
+
+ function symbol() public view returns (bytes32) {
+ return _symbol;
+ }
+
+ function decimals() public view returns (uint256) {
+ return _decimals;
+ }
+}
\ No newline at end of file
diff --git a/bridge/contracts/test/LibUtilsHarness.sol b/bridge/contracts/test/LibUtilsHarness.sol
new file mode 100644
index 000000000..475fad2cc
--- /dev/null
+++ b/bridge/contracts/test/LibUtilsHarness.sol
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../lib/LibUtils.sol";
+
+contract LibUtilsHarness {
+
+ function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {
+ return LibUtils.decimalsToGranularity(decimals);
+ }
+
+ function getDecimals(address tokenToUse) external view returns (uint8) {
+ return LibUtils.getDecimals(tokenToUse);
+ }
+
+ function getGranularity(address tokenToUse) external view returns (uint256) {
+ return LibUtils.getGranularity(tokenToUse);
+ }
+
+ function bytesToAddress(bytes memory bys) external pure returns (address addr) {
+ return LibUtils.bytesToAddress(bys);
+ }
+
+ function toUint128(bytes memory _bytes, uint256 _start) external pure returns (uint128) {
+ return LibUtils.toUint128(_bytes, _start);
+ }
+
+}
diff --git a/bridge/contracts/test/MainToken.sol b/bridge/contracts/test/MainToken.sol
new file mode 100644
index 000000000..336d919a9
--- /dev/null
+++ b/bridge/contracts/test/MainToken.sol
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../zeppelin/token/ERC20/ERC20Detailed.sol";
+import "../zeppelin/token/ERC20/ERC20.sol";
+
+contract MainToken is ERC20Detailed, ERC20 {
+ constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)
+ ERC20Detailed(name, symbol, decimals)
+ {
+ _mint(msg.sender, totalSupply);
+ }
+
+ /**
+ * ERC-677's only method implementation
+ * See https://github.com/ethereum/EIPs/issues/677 for details
+ */
+ function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {
+ bool result = transfer(_to, _value);
+ if (!result) return false;
+
+ ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);
+ receiver.tokenFallback(msg.sender, _value, _data);
+
+ // IMPORTANT: the ERC-677 specification does not say
+ // anything about the use of the receiver contract's
+ // tokenFallback method return value. Given
+ // its return type matches with this method's return
+ // type, returning it could be a possibility.
+ // We here take the more conservative approach and
+ // ignore the return value, returning true
+ // to signal a succesful transfer despite tokenFallback's
+ // return value -- fact being tokens are transferred
+ // in any case.
+ return true;
+ }
+}
+
+interface ERC677TransferReceiver {
+ function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);
+}
\ No newline at end of file
diff --git a/bridge/contracts/test/WRBTC.sol b/bridge/contracts/test/WRBTC.sol
new file mode 100644
index 000000000..c6eb1fc26
--- /dev/null
+++ b/bridge/contracts/test/WRBTC.sol
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../interface/IWrapped.sol";
+
+contract WRBTC is IWrapped {
+ string public name = "Wrapped RBTC";
+ string public symbol = "WRBTC";
+ uint8 public decimals = 18;
+
+ event Approval(address indexed src, address indexed guy, uint wad);
+ event Transfer(address indexed src, address indexed dst, uint wad);
+ event Deposit(address indexed dst, uint wad);
+ event Withdrawal(address indexed src, uint wad);
+
+ mapping (address => uint) override public balanceOf;
+ mapping (address => mapping (address => uint)) public allowance;
+
+ receive () external payable {
+ deposit();
+ }
+ function deposit() override public payable {
+ balanceOf[msg.sender] += msg.value;
+ emit Deposit(msg.sender, msg.value);
+ }
+ function withdraw(uint wad) override public {
+ require(balanceOf[msg.sender] >= wad, "WRBTC: Balance less than wad");
+ balanceOf[msg.sender] -= wad;
+ (bool success, ) = msg.sender.call{value:wad, gas:23000}("");
+ require(success, "WRBTC: transfer fail");
+ emit Withdrawal(msg.sender, wad);
+ }
+
+ function totalSupply() override public view returns (uint) {
+ return address(this).balance;
+ }
+
+ function approve(address guy, uint wad) override public returns (bool) {
+ allowance[msg.sender][guy] = wad;
+ emit Approval(msg.sender, guy, wad);
+ return true;
+ }
+
+ function transfer(address dst, uint wad) override public returns (bool) {
+ return transferFrom(msg.sender, dst, wad);
+ }
+
+ function transferFrom(address src, address dst, uint wad)
+ override public
+ returns (bool)
+ {
+ require(balanceOf[src] >= wad, "WRBTC: Balance less than wad");
+
+ if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {
+ require(allowance[src][msg.sender] >= wad, "WRBTC: Allowance less than wad");
+ allowance[src][msg.sender] -= wad;
+ }
+
+ balanceOf[src] -= wad;
+ balanceOf[dst] += wad;
+
+ emit Transfer(src, dst, wad);
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/bridge/contracts/test/mockERC677Reciever.sol b/bridge/contracts/test/mockERC677Reciever.sol
new file mode 100644
index 000000000..a20aa7a79
--- /dev/null
+++ b/bridge/contracts/test/mockERC677Reciever.sol
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../zeppelin/token/ERC20/ERC20Detailed.sol";
+import "../zeppelin/token/ERC20/ERC20.sol";
+import "../interface/IERC677Receiver.sol";
+
+contract mockERC677Receiver is IERC677Receiver {
+ event Success(address _sender, uint _value, bytes _data);
+ /**
+ * ERC-677's only method implementation
+ * See https://github.com/ethereum/EIPs/issues/677 for details
+ */
+ function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {
+ emit Success(_sender, _value, _data);
+ }
+}
\ No newline at end of file
diff --git a/bridge/contracts/test/mockERC777Recipient.sol b/bridge/contracts/test/mockERC777Recipient.sol
new file mode 100644
index 000000000..d4136bbf0
--- /dev/null
+++ b/bridge/contracts/test/mockERC777Recipient.sol
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../zeppelin/token/ERC777/IERC777Recipient.sol";
+import "../zeppelin/introspection/IERC1820Registry.sol";
+
+contract mockERC777Recipient is IERC777Recipient {
+ IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
+
+ constructor() {
+ _erc1820.setInterfaceImplementer(address(this), keccak256("ERC777TokensRecipient"), address(this));
+ }
+
+ event Success(
+ address operator,
+ address from,
+ address to,
+ uint amount,
+ bytes userData,
+ bytes operatorData);
+
+ /**
+ * ERC-677's only method implementation
+ * See https://github.com/ethereum/EIPs/issues/677 for details
+ */
+ function tokensReceived(
+ address operator,
+ address from,
+ address to,
+ uint amount,
+ bytes calldata userData,
+ bytes calldata operatorData
+ ) override external {
+ emit Success(operator, from, to, amount, userData, operatorData);
+ }
+}
\ No newline at end of file
diff --git a/bridge/contracts/test/mockReceiveTokensCall.sol b/bridge/contracts/test/mockReceiveTokensCall.sol
new file mode 100644
index 000000000..fb6213c22
--- /dev/null
+++ b/bridge/contracts/test/mockReceiveTokensCall.sol
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../interface/IBridge.sol";
+import "../zeppelin/token/ERC20/IERC20.sol";
+import "../zeppelin/token/ERC777/IERC777.sol";
+import "../zeppelin/token/ERC777/IERC777Recipient.sol";
+import "../zeppelin/introspection/IERC1820Registry.sol";
+
+contract mockReceiveTokensCall is IERC777Recipient {
+ address public bridge;
+ IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
+
+ constructor(address _bridge) {
+ bridge = _bridge;
+ //keccak256("ERC777TokensRecipient")
+ erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));
+ }
+
+ function callReceiveTokens(address tokenToUse, address receiver, uint256 amount, uint256 destinationChainId) external {
+ IERC20(tokenToUse).approve(bridge, amount);
+ IBridge(bridge).receiveTokensTo(destinationChainId, tokenToUse, receiver, amount);
+ }
+
+ function callDepositTo(address receiver, uint256 destinationChainId) external payable {
+ IBridge(bridge).depositTo{ value: msg.value }(destinationChainId, receiver);
+ }
+
+ function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {
+ IERC777(tokenToUse).send(bridge, amount, data);
+ }
+
+ // Mandatory for IERC777Recipient
+ function tokensReceived(
+ address,
+ address,
+ address,
+ uint,
+ bytes calldata,
+ bytes calldata
+ ) override external view {
+ this;
+ }
+}
\ No newline at end of file
diff --git a/bridge/contracts/test/nftbridge/OpenSea721.sol b/bridge/contracts/test/nftbridge/OpenSea721.sol
new file mode 100644
index 000000000..bd1d5dc50
--- /dev/null
+++ b/bridge/contracts/test/nftbridge/OpenSea721.sol
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol
+// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol
+import "../../zeppelin/token/ERC721/ERC721.sol";
+import "../../zeppelin/ownership/Ownable.sol";
+import "../../zeppelin/math/SafeMath.sol";
+import "../../zeppelin/utils/Strings.sol";
+import "./OpenSeaEIP712Base.sol";
+
+
+/**
+ * @title OpenSea721
+ * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.
+ */
+contract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {
+ using SafeMath for uint256;
+
+ uint256 private _currentTokenId = 0;
+
+ constructor(
+ string memory _name,
+ string memory _symbol
+ ) ERC721(_name, _symbol) {
+ _initializeEIP712(_name);
+ }
+
+ function baseTokenURI() public pure returns (string memory) {
+ return "https://creatures-api.opensea.io/api/creature/";
+ }
+
+ function contractURI() public pure returns (string memory) {
+ return "https://creatures-api.opensea.io/contract/opensea-creatures";
+ }
+
+ /**
+ * @dev Mints a token to an address with a tokenURI.
+ * @param _to address of the future owner of the token
+ */
+ function mintTo(address _to) public onlyOwner {
+ uint256 newTokenId = _getNextTokenId();
+ _mint(_to, newTokenId);
+ _incrementTokenId();
+ }
+
+ /**
+ * @dev calculates the next token ID based on value of _currentTokenId
+ * @return uint256 for the next token ID
+ */
+ function _getNextTokenId() private view returns (uint256) {
+ return _currentTokenId.add(1);
+ }
+
+ /**
+ * @dev increments the value of _currentTokenId
+ */
+ function _incrementTokenId() private {
+ _currentTokenId++;
+ }
+
+ function tokenURI(uint256 _tokenId) override public pure returns (string memory) {
+ return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));
+ }
+
+}
\ No newline at end of file
diff --git a/bridge/contracts/test/nftbridge/OpenSeaEIP712Base.sol b/bridge/contracts/test/nftbridge/OpenSeaEIP712Base.sol
new file mode 100644
index 000000000..f5c7362b3
--- /dev/null
+++ b/bridge/contracts/test/nftbridge/OpenSeaEIP712Base.sol
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../../zeppelin/upgradable/Initializable.sol";
+
+contract OpenSeaEIP712Base is Initializable {
+ struct EIP712Domain {
+ string name;
+ string version;
+ address verifyingContract;
+ bytes32 salt;
+ }
+
+ string constant public ERC712_VERSION = "1";
+
+ bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(
+ bytes(
+ "EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)"
+ )
+ );
+ bytes32 internal domainSeperator;
+
+ // supposed to be called once while initializing.
+ // one of the contracts that inherits this contract follows proxy pattern
+ // so it is not possible to do this in a constructor
+ function _initializeEIP712(
+ string memory name
+ )
+ internal
+ initializer
+ {
+ _setDomainSeperator(name);
+ }
+
+ function _setDomainSeperator(string memory name) internal {
+ domainSeperator = keccak256(
+ abi.encode(
+ EIP712_DOMAIN_TYPEHASH,
+ keccak256(bytes(name)),
+ keccak256(bytes(ERC712_VERSION)),
+ address(this),
+ bytes32(block.chainid)
+ )
+ );
+ }
+
+ function getDomainSeperator() public view returns (bytes32) {
+ return domainSeperator;
+ }
+
+ /**
+ * Accept message hash and returns hash message in EIP712 compatible form
+ * So that it can be used to recover signer from signature signed using EIP712 formatted data
+ * https://eips.ethereum.org/EIPS/eip-712
+ * "\\x19" makes the encoding deterministic
+ * "\\x01" is the version byte to make it compatible to EIP-191
+ */
+ function toTypedMessageHash(bytes32 messageHash)
+ internal
+ view
+ returns (bytes32)
+ {
+ return
+ keccak256(
+ abi.encodePacked("\x19\x01", getDomainSeperator(), messageHash)
+ );
+ }
+}
diff --git a/bridge/contracts/test/nftbridge/TestTokenCreator.sol b/bridge/contracts/test/nftbridge/TestTokenCreator.sol
new file mode 100644
index 000000000..b27568182
--- /dev/null
+++ b/bridge/contracts/test/nftbridge/TestTokenCreator.sol
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+
+contract TestTokenCreator {
+ address public _owner;
+
+ constructor() {
+ _owner = msg.sender;
+ }
+
+ function creator() public view returns (address) {
+ return _owner;
+ }
+}
diff --git a/bridge/contracts/zeppelin/GSN/Context.sol b/bridge/contracts/zeppelin/GSN/Context.sol
new file mode 100644
index 000000000..61b1db8ed
--- /dev/null
+++ b/bridge/contracts/zeppelin/GSN/Context.sol
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/*
+ * @dev Provides information about the current execution context, including the
+ * sender of the transaction and its data. While these are generally available
+ * via msg.sender and msg.data, they should not be accessed in such a direct
+ * manner, since when dealing with GSN meta-transactions the account sending and
+ * paying for execution may not be the actual sender (as far as an application
+ * is concerned).
+ *
+ * This contract is only required for intermediate, library-like contracts.
+ */
+abstract contract Context {
+
+ function _msgSender() internal view returns (address payable) {
+ return payable(msg.sender);
+ }
+
+ function _msgData() internal view returns (bytes memory) {
+ this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
+ return msg.data;
+ }
+}
diff --git a/bridge/contracts/zeppelin/LICENSE b/bridge/contracts/zeppelin/LICENSE
new file mode 100644
index 000000000..c5e7ce02f
--- /dev/null
+++ b/bridge/contracts/zeppelin/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2016-2019 zOS Global Limited
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/bridge/contracts/zeppelin/README.md b/bridge/contracts/zeppelin/README.md
new file mode 100644
index 000000000..2dd0b7d5b
--- /dev/null
+++ b/bridge/contracts/zeppelin/README.md
@@ -0,0 +1,63 @@
+#
+
+[](https://www.npmjs.org/package/openzeppelin-solidity)
+[](https://travis-ci.com/OpenZeppelin/openzeppelin-solidity)
+[](https://coveralls.io/github/OpenZeppelin/openzeppelin-solidity?branch=master)
+
+**OpenZeppelin is a library for secure smart contract development.** It provides implementations of standards like ERC20 and ERC721 which you can deploy as-is or extend to suit your needs, as well as Solidity components to build custom contracts and more complex decentralized systems.
+
+## Install
+
+```
+npm install openzeppelin-solidity
+```
+
+OpenZeppelin features a stable API, which means your contracts won't break unexpectedly when upgrading to a newer minor version. You can read ṫhe details in our [API Stability](https://forum.zeppelin.solutions/t/api-stability/138) document.
+
+## Usage
+
+To write your custom contracts, import ours and extend them through inheritance.
+
+```solidity
+pragma solidity ^0.5.0;
+
+import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol';
+import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Mintable.sol';
+
+contract MyNFT is ERC721Full, ERC721Mintable {
+ constructor() ERC721Full("MyNFT", "MNFT") {
+ }
+}
+```
+
+> You need an ethereum development framework for the above import statements to work! Check out these guides for [Truffle], [Embark] or [Buidler].
+
+On our site you will find a few [guides] to learn about the different parts of OpenZeppelin, as well as [documentation for the API][API docs]. Keep in mind that the API docs are work in progress, and don’t hesitate to ask questions in [our forum][forum].
+
+## Security
+
+OpenZeppelin the project is maintained by [Zeppelin] the company, and developed following our high standards for code quality and security. OpenZeppelin is meant to provide tested and community-audited code, but please use common sense when doing anything that deals with real money! We take no responsibility for your implementation decisions and any security problems you might experience.
+
+The core development principles and strategies that OpenZeppelin is based on include: security in depth, simple and modular code, clarity-driven naming conventions, comprehensive unit testing, pre-and-post-condition sanity checks, code consistency, and regular audits.
+
+The latest audit was done on October 2018 on version 2.0.0.
+
+Please report any security issues you find to security@openzeppelin.org.
+
+## Contribute
+
+OpenZeppelin exists thanks to its contributors. There are many ways you can participate and help build high quality software. Check out the [contribution guide]!
+
+## License
+
+OpenZeppelin is released under the [MIT License](LICENSE).
+
+
+[API docs]: https://openzeppelin.org/api/docs/token_ERC721_ERC721BasicToken.html
+[guides]: https://openzeppelin.org/api/docs/get-started.html
+[forum]: https://forum.zeppelin.solutions
+[Zeppelin]: https://zeppelin.solutions
+[contribution guide]: CONTRIBUTING.md
+[Truffle]: https://truffleframework.com/docs/truffle/quickstart
+[Embark]: https://embark.status.im/docs/quick_start.html
+[Buidler]: https://buidler.dev/guides/#getting-started
diff --git a/bridge/contracts/zeppelin/access/Roles.sol b/bridge/contracts/zeppelin/access/Roles.sol
new file mode 100644
index 000000000..b42c67127
--- /dev/null
+++ b/bridge/contracts/zeppelin/access/Roles.sol
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @title Roles
+ * @dev Library for managing addresses assigned to a Role.
+ */
+library Roles {
+ struct Role {
+ mapping (address => bool) bearer;
+ }
+
+ /**
+ * @dev Give an account access to this role.
+ */
+ function add(Role storage role, address account) internal {
+ require(!has(role, account), "Roles: account already has role");
+ role.bearer[account] = true;
+ }
+
+ /**
+ * @dev Remove an account's access to this role.
+ */
+ function remove(Role storage role, address account) internal {
+ require(has(role, account), "Roles: account doesn't have role");
+ role.bearer[account] = false;
+ }
+
+ /**
+ * @dev Check if an account has this role.
+ * @return bool
+ */
+ function has(Role storage role, address account) internal view returns (bool) {
+ require(account != address(0), "Roles: account is the zero address");
+ return role.bearer[account];
+ }
+}
diff --git a/bridge/contracts/zeppelin/access/roles/MinterRole.sol b/bridge/contracts/zeppelin/access/roles/MinterRole.sol
new file mode 100644
index 000000000..14fb2742d
--- /dev/null
+++ b/bridge/contracts/zeppelin/access/roles/MinterRole.sol
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "../../GSN/Context.sol";
+import "../Roles.sol";
+
+abstract contract MinterRole is Context {
+ using Roles for Roles.Role;
+
+ event MinterAdded(address indexed account);
+ event MinterRemoved(address indexed account);
+
+ Roles.Role private _minters;
+
+ constructor () {
+ _addMinter(_msgSender());
+ }
+
+ modifier onlyMinter() {
+ require(isMinter(_msgSender()), "MinterRole: caller doesn't have the role");
+ _;
+ }
+
+ function isMinter(address account) public view returns (bool) {
+ return _minters.has(account);
+ }
+
+ function addMinter(address account) public onlyMinter {
+ _addMinter(account);
+ }
+
+ function renounceMinter() public {
+ _removeMinter(_msgSender());
+ }
+
+ function _addMinter(address account) internal {
+ _minters.add(account);
+ emit MinterAdded(account);
+ }
+
+ function _removeMinter(address account) internal {
+ _minters.remove(account);
+ emit MinterRemoved(account);
+ }
+}
diff --git a/bridge/contracts/zeppelin/access/roles/PauserRole.sol b/bridge/contracts/zeppelin/access/roles/PauserRole.sol
new file mode 100644
index 000000000..aeed3f7aa
--- /dev/null
+++ b/bridge/contracts/zeppelin/access/roles/PauserRole.sol
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "../../GSN/Context.sol";
+import "../Roles.sol";
+
+abstract contract PauserRole is Context {
+ using Roles for Roles.Role;
+
+ event PauserAdded(address indexed account);
+ event PauserRemoved(address indexed account);
+
+ Roles.Role private _pausers;
+
+ constructor () {
+ _addPauser(_msgSender());
+ }
+
+ modifier onlyPauser() {
+ require(isPauser(_msgSender()), "PauserRole: caller doesn't have the role");
+ _;
+ }
+
+ function isPauser(address account) public view returns (bool) {
+ return _pausers.has(account);
+ }
+
+ function addPauser(address account) public onlyPauser {
+ _addPauser(account);
+ }
+
+ function renouncePauser() public {
+ _removePauser(_msgSender());
+ }
+
+ function _addPauser(address account) internal {
+ _pausers.add(account);
+ emit PauserAdded(account);
+ }
+
+ function _removePauser(address account) internal {
+ _pausers.remove(account);
+ emit PauserRemoved(account);
+ }
+}
diff --git a/bridge/contracts/zeppelin/introspection/ERC165.sol b/bridge/contracts/zeppelin/introspection/ERC165.sol
new file mode 100644
index 000000000..cb120911a
--- /dev/null
+++ b/bridge/contracts/zeppelin/introspection/ERC165.sol
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "./IERC165.sol";
+
+/**
+ * @dev Implementation of the {IERC165} interface.
+ *
+ * Contracts may inherit from this and call {_registerInterface} to declare
+ * their support of an interface.
+ */
+abstract contract ERC165 is IERC165 {
+ /*
+ * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
+ */
+ bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
+
+ /**
+ * @dev Mapping of interface ids to whether or not it's supported.
+ */
+ mapping(bytes4 => bool) private _supportedInterfaces;
+
+ constructor () {
+ // Derived contracts need only register support for their own interfaces,
+ // we register support for ERC165 itself here
+ _registerInterface(_INTERFACE_ID_ERC165);
+ }
+
+ /**
+ * @dev See {IERC165-supportsInterface}.
+ *
+ * Time complexity O(1), guaranteed to always use less than 30 000 gas.
+ */
+ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
+ return _supportedInterfaces[interfaceId];
+ }
+
+ /**
+ * @dev Registers the contract as an implementer of the interface defined by
+ * `interfaceId`. Support of the actual ERC165 interface is automatic and
+ * registering its interface id is not required.
+ *
+ * See {IERC165-supportsInterface}.
+ *
+ * Requirements:
+ *
+ * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
+ */
+ function _registerInterface(bytes4 interfaceId) internal virtual {
+ require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
+ _supportedInterfaces[interfaceId] = true;
+ }
+}
diff --git a/bridge/contracts/zeppelin/introspection/ERC165Checker.sol b/bridge/contracts/zeppelin/introspection/ERC165Checker.sol
new file mode 100644
index 000000000..8f5ff744a
--- /dev/null
+++ b/bridge/contracts/zeppelin/introspection/ERC165Checker.sol
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+/**
+ * @dev Library used to query support of an interface declared via {IERC165}.
+ *
+ * Note that these functions return the actual result of the query: they do not
+ * `revert` if an interface is not supported. It is up to the caller to decide
+ * what to do in these cases.
+ */
+library ERC165Checker {
+ // As per the EIP-165 spec, no interface should ever match 0xffffffff
+ bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;
+
+ /*
+ * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
+ */
+ bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
+
+ /**
+ * @dev Returns true if `account` supports the {IERC165} interface,
+ */
+ function supportsERC165(address account) internal view returns (bool) {
+ // Any contract that implements ERC165 must explicitly indicate support of
+ // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
+ return _supportsERC165Interface(account, _INTERFACE_ID_ERC165) &&
+ !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);
+ }
+
+ /**
+ * @dev Returns true if `account` supports the interface defined by
+ * `interfaceId`. Support for {IERC165} itself is queried automatically.
+ *
+ * See {IERC165-supportsInterface}.
+ */
+ function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
+ // query support of both ERC165 as per the spec and support of _interfaceId
+ return supportsERC165(account) &&
+ _supportsERC165Interface(account, interfaceId);
+ }
+
+ /**
+ * @dev Returns a boolean array where each value corresponds to the
+ * interfaces passed in and whether they're supported or not. This allows
+ * you to batch check interfaces for a contract where your expectation
+ * is that some interfaces may not be supported.
+ *
+ * See {IERC165-supportsInterface}.
+ *
+ * _Available since v3.4._
+ */
+ function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool[] memory) {
+ // an array of booleans corresponding to interfaceIds and whether they're supported or not
+ bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);
+
+ // query support of ERC165 itself
+ if (supportsERC165(account)) {
+ // query support of each interface in interfaceIds
+ for (uint256 i = 0; i < interfaceIds.length; i++) {
+ interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);
+ }
+ }
+
+ return interfaceIdsSupported;
+ }
+
+ /**
+ * @dev Returns true if `account` supports all the interfaces defined in
+ * `interfaceIds`. Support for {IERC165} itself is queried automatically.
+ *
+ * Batch-querying can lead to gas savings by skipping repeated checks for
+ * {IERC165} support.
+ *
+ * See {IERC165-supportsInterface}.
+ */
+ function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
+ // query support of ERC165 itself
+ if (!supportsERC165(account)) {
+ return false;
+ }
+
+ // query support of each interface in _interfaceIds
+ for (uint256 i = 0; i < interfaceIds.length; i++) {
+ if (!_supportsERC165Interface(account, interfaceIds[i])) {
+ return false;
+ }
+ }
+
+ // all interfaces supported
+ return true;
+ }
+
+ /**
+ * @notice Query if a contract implements an interface, does not check ERC165 support
+ * @param account The address of the contract to query for support of an interface
+ * @param interfaceId The interface identifier, as specified in ERC-165
+ * @return true if the contract at account indicates support of the interface with
+ * identifier interfaceId, false otherwise
+ * @dev Assumes that account contains a contract that supports ERC165, otherwise
+ * the behavior of this method is undefined. This precondition can be checked
+ * with {supportsERC165}.
+ * Interface identification is specified in ERC-165.
+ */
+ function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {
+ // success determines whether the staticcall succeeded and result determines
+ // whether the contract at account indicates support of _interfaceId
+ (bool success, bool result) = _callERC165SupportsInterface(account, interfaceId);
+
+ return (success && result);
+ }
+
+ /**
+ * @notice Calls the function with selector 0x01ffc9a7 (ERC165) and suppresses throw
+ * @param account The address of the contract to query for support of an interface
+ * @param interfaceId The interface identifier, as specified in ERC-165
+ * @return success true if the STATICCALL succeeded, false otherwise
+ * @return result true if the STATICCALL succeeded and the contract at account
+ * indicates support of the interface with identifier interfaceId, false otherwise
+ */
+ function _callERC165SupportsInterface(address account, bytes4 interfaceId)
+ private
+ view
+ returns (bool, bool)
+ {
+ bytes memory encodedParams = abi.encodeWithSelector(_INTERFACE_ID_ERC165, interfaceId);
+ (bool success, bytes memory result) = account.staticcall{ gas: 30000 }(encodedParams);
+ if (result.length < 32) return (false, false);
+ return (success, abi.decode(result, (bool)));
+ }
+}
diff --git a/bridge/contracts/zeppelin/introspection/IERC165.sol b/bridge/contracts/zeppelin/introspection/IERC165.sol
new file mode 100644
index 000000000..01c9c0864
--- /dev/null
+++ b/bridge/contracts/zeppelin/introspection/IERC165.sol
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+/**
+ * @dev Interface of the ERC165 standard, as defined in the
+ * https://eips.ethereum.org/EIPS/eip-165[EIP].
+ *
+ * Implementers can declare support of contract interfaces, which can then be
+ * queried by others ({ERC165Checker}).
+ *
+ * For an implementation, see {ERC165}.
+ */
+interface IERC165 {
+ /**
+ * @dev Returns true if this contract implements the interface defined by
+ * `interfaceId`. See the corresponding
+ * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
+ * to learn more about how these ids are created.
+ *
+ * This function call must use less than 30 000 gas.
+ */
+ function supportsInterface(bytes4 interfaceId) external view returns (bool);
+}
diff --git a/bridge/contracts/zeppelin/introspection/IERC1820Implementer.sol b/bridge/contracts/zeppelin/introspection/IERC1820Implementer.sol
new file mode 100644
index 000000000..16b0d9a05
--- /dev/null
+++ b/bridge/contracts/zeppelin/introspection/IERC1820Implementer.sol
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface for an ERC1820 implementer, as defined in the
+ * https://eips.ethereum.org/EIPS/eip-1820#interface-implementation-erc1820implementerinterface[EIP].
+ * Used by contracts that will be registered as implementers in the
+ * {IERC1820Registry}.
+ */
+interface IERC1820Implementer {
+ /**
+ * @dev Returns a special value (`ERC1820_ACCEPT_MAGIC`) if this contract
+ * implements `_interfaceHash` for `_account`.
+ *
+ * See {IERC1820Registry-setInterfaceImplementer}.
+ */
+ function canImplementInterfaceForAddress(bytes32 _interfaceHash, address _account) external view returns (bytes32);
+}
diff --git a/bridge/contracts/zeppelin/introspection/IERC1820Registry.sol b/bridge/contracts/zeppelin/introspection/IERC1820Registry.sol
new file mode 100644
index 000000000..bbc7c82aa
--- /dev/null
+++ b/bridge/contracts/zeppelin/introspection/IERC1820Registry.sol
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface of the global ERC1820 Registry, as defined in the
+ * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register
+ * implementers for interfaces in this registry, as well as query support.
+ *
+ * Implementers may be shared by multiple accounts, and can also implement more
+ * than a single interface for each account. Contracts can implement interfaces
+ * for themselves, but externally-owned accounts (EOA) must delegate this to a
+ * contract.
+ *
+ * {IERC165} interfaces can also be queried via the registry.
+ *
+ * For an in-depth explanation and source code analysis, see the EIP text.
+ */
+interface IERC1820Registry {
+ /**
+ * @dev Sets `newManager` as the manager for `account`. A manager of an
+ * account is able to set interface implementers for it.
+ *
+ * By default, each account is its own manager. Passing a value of `0x0` in
+ * `newManager` will reset the manager to this initial state.
+ *
+ * Emits a {ManagerChanged} event.
+ *
+ * Requirements:
+ *
+ * - the caller must be the current manager for `account`.
+ */
+ function setManager(address account, address newManager) external;
+
+ /**
+ * @dev Returns the manager for `account`.
+ *
+ * See {setManager}.
+ */
+ function getManager(address account) external view returns (address);
+
+ /**
+ * @dev Sets the `implementer` contract as `account`'s implementer for
+ * `interfaceHash`.
+ *
+ * `account` being the zero address is an alias for the caller's address.
+ * The zero address can also be used in `implementer` to remove an old one.
+ *
+ * See {interfaceHash} to learn how these are created.
+ *
+ * Emits an {InterfaceImplementerSet} event.
+ *
+ * Requirements:
+ *
+ * - the caller must be the current manager for `_account`.
+ * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not
+ * end in 28 zeroes).
+ * - `_implementer` must implement {IERC1820Implementer} and return true when
+ * queried for support, unless `implementer` is the caller. See
+ * {IERC1820Implementer-canImplementInterfaceForAddress}.
+ */
+ function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;
+
+ /**
+ * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such
+ * implementer is registered, returns the zero address.
+ *
+ * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28
+ * zeroes), `_account` will be queried for support of it.
+ *
+ * `account` being the zero address is an alias for the caller's address.
+ */
+ function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);
+
+ /**
+ * @dev Returns the interface hash for an `interfaceName`, as defined in the
+ * corresponding
+ * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].
+ */
+ function interfaceHash(string calldata interfaceName) external pure returns (bytes32);
+
+ /**
+ * @notice Updates the cache with whether the contract implements an ERC165 interface or not.
+ * @param account Address of the contract for which to update the cache.
+ * @param interfaceId ERC165 interface for which to update the cache.
+ */
+ function updateERC165Cache(address account, bytes4 interfaceId) external;
+
+ /**
+ * @notice Checks whether a contract implements an ERC165 interface or not.
+ * If the result is not cached a direct lookup on the contract address is performed.
+ * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling
+ * {updateERC165Cache} with the contract address.
+ * @param account Address of the contract to check.
+ * @param interfaceId ERC165 interface to check.
+ * @return True if `account` implements `interfaceId`, false otherwise.
+ */
+ function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);
+
+ /**
+ * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.
+ * @param account Address of the contract to check.
+ * @param interfaceId ERC165 interface to check.
+ * @return True if `account` implements `interfaceId`, false otherwise.
+ */
+ function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);
+
+ event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);
+
+ event ManagerChanged(address indexed account, address indexed newManager);
+}
diff --git a/bridge/contracts/zeppelin/introspection/README.md b/bridge/contracts/zeppelin/introspection/README.md
new file mode 100644
index 000000000..239b9c4aa
--- /dev/null
+++ b/bridge/contracts/zeppelin/introspection/README.md
@@ -0,0 +1,23 @@
+---
+sections:
+ - title: Local
+ contracts:
+ - IERC165
+ - ERC165
+ - ERC165Checker
+ - title: Global
+ contracts:
+ - IERC1820Registry
+ - IERC1820Implementer
+ - ERC1820Implementer
+---
+
+This set of interfaces and contracts deal with [type introspection](https://en.wikipedia.org/wiki/Type_introspection) of contracts, that is, examining which functions can be called on them. This is usually referred to as a contract's _interface_.
+
+Ethereum contracts have no native concept of an interface, so applications must usually simply trust they are not making an incorrect call. For trusted setups this is a non-issue, but often unknown and untrusted third-party addresses need to be interacted with. There may even not be any direct calls to them! (e.g. `ERC20` tokens may be sent to a contract that lacks a way to transfer them out of it, locking them forever). In these cases, a contract _declaring_ its interface can be very helpful in preventing errors.
+
+There are two main ways to approach this.
+ - Locally, where a contract implements `IERC165` and declares an interface, and a second one queries it directly via `ERC165Checker`.
+ - Globally, where a global and unique registry (`IERC1820Registry`) is used to register implementers of a certain interface (`IERC1820Implementer`). It is then the registry that is queried, which allows for more complex setups, like contracts implementing interfaces for externally-owned accounts.
+
+Note that, in all cases, accounts simply _declare_ their interfaces, but they are not required to actually implement them. This mechanism can therefore be used to both prevent errors and allow for complex interactions (see `ERC777`), but it must not be relied on for security.
diff --git a/bridge/contracts/zeppelin/lifecycle/Destructible.sol b/bridge/contracts/zeppelin/lifecycle/Destructible.sol
deleted file mode 100644
index c10630d88..000000000
--- a/bridge/contracts/zeppelin/lifecycle/Destructible.sol
+++ /dev/null
@@ -1,22 +0,0 @@
-pragma solidity ^0.4.24;
-
-
-import "../ownership/Ownable.sol";
-
-
-/**
- * @title Destructible
- * @dev Base contract that can be destroyed by owner. All funds in contract will be sent to the owner.
- */
-contract Destructible is Ownable {
- /**
- * @dev Transfers the current balance to the owner and terminates the contract.
- */
- function destroy() public onlyOwner {
- selfdestruct(owner);
- }
-
- function destroyAndSend(address _recipient) public onlyOwner {
- selfdestruct(_recipient);
- }
-}
diff --git a/bridge/contracts/zeppelin/lifecycle/Pausable.sol b/bridge/contracts/zeppelin/lifecycle/Pausable.sol
new file mode 100644
index 000000000..43c08998b
--- /dev/null
+++ b/bridge/contracts/zeppelin/lifecycle/Pausable.sol
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "../GSN/Context.sol";
+import "../access/roles/PauserRole.sol";
+
+/**
+ * @dev Contract module which allows children to implement an emergency stop
+ * mechanism that can be triggered by an authorized account.
+ *
+ * This module is used through inheritance. It will make available the
+ * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
+ * the functions of your contract. Note that they will not be pausable by
+ * simply including this module, only once the modifiers are put in place.
+ */
+abstract contract Pausable is Context, PauserRole {
+ /**
+ * @dev Emitted when the pause is triggered by a pauser (`account`).
+ */
+ event Paused(address account);
+
+ /**
+ * @dev Emitted when the pause is lifted by a pauser (`account`).
+ */
+ event Unpaused(address account);
+
+ bool private _paused;
+
+ /**
+ * @dev Initializes the contract in unpaused state. Assigns the Pauser role
+ * to the deployer.
+ */
+ constructor () {
+ _paused = false;
+ }
+
+ /**
+ * @dev Returns true if the contract is paused, and false otherwise.
+ */
+ function paused() public view returns (bool) {
+ return _paused;
+ }
+
+ /**
+ * @dev Modifier to make a function callable only when the contract is not paused.
+ */
+ modifier whenNotPaused() {
+ require(!_paused, "Pausable: paused");
+ _;
+ }
+
+ /**
+ * @dev Modifier to make a function callable only when the contract is paused.
+ */
+ modifier whenPaused() {
+ require(_paused, "Pausable: not paused");
+ _;
+ }
+
+ /**
+ * @dev Called by a pauser to pause, triggers stopped state.
+ */
+ function pause() public onlyPauser whenNotPaused {
+ _paused = true;
+ emit Paused(_msgSender());
+ }
+
+ /**
+ * @dev Called by a pauser to unpause, returns to normal state.
+ */
+ function unpause() public onlyPauser whenPaused {
+ _paused = false;
+ emit Unpaused(_msgSender());
+ }
+}
diff --git a/bridge/contracts/zeppelin/lifecycle/TokenDestructible.sol b/bridge/contracts/zeppelin/lifecycle/TokenDestructible.sol
deleted file mode 100644
index 0a43590a0..000000000
--- a/bridge/contracts/zeppelin/lifecycle/TokenDestructible.sol
+++ /dev/null
@@ -1,36 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "../ownership/Ownable.sol";
-import "../token/ERC20/ERC20Basic.sol";
-
-
-/**
- * @title TokenDestructible:
- * @author Remco Bloemen
- * @dev Base contract that can be destroyed by owner. All funds in contract including
- * listed tokens will be sent to the owner.
- */
-contract TokenDestructible is Ownable {
-
- constructor() public payable { }
-
- /**
- * @notice Terminate contract and refund to owner
- * @param _tokens List of addresses of ERC20 or ERC20Basic token contracts to
- refund.
- * @notice The called token contracts could try to re-enter this contract. Only
- supply token contracts you trust.
- */
- function destroy(address[] _tokens) public onlyOwner {
-
- // Transfer tokens to owner
- for (uint256 i = 0; i < _tokens.length; i++) {
- ERC20Basic token = ERC20Basic(_tokens[i]);
- uint256 balance = token.balanceOf(this);
- token.transfer(owner, balance);
- }
-
- // Transfer Eth to owner and terminate contract
- selfdestruct(owner);
- }
-}
diff --git a/bridge/contracts/zeppelin/math/Math.sol b/bridge/contracts/zeppelin/math/Math.sol
deleted file mode 100644
index 3928eb9d5..000000000
--- a/bridge/contracts/zeppelin/math/Math.sol
+++ /dev/null
@@ -1,24 +0,0 @@
-pragma solidity ^0.4.24;
-
-
-/**
- * @title Math
- * @dev Assorted math operations
- */
-library Math {
- function max64(uint64 _a, uint64 _b) internal pure returns (uint64) {
- return _a >= _b ? _a : _b;
- }
-
- function min64(uint64 _a, uint64 _b) internal pure returns (uint64) {
- return _a < _b ? _a : _b;
- }
-
- function max256(uint256 _a, uint256 _b) internal pure returns (uint256) {
- return _a >= _b ? _a : _b;
- }
-
- function min256(uint256 _a, uint256 _b) internal pure returns (uint256) {
- return _a < _b ? _a : _b;
- }
-}
diff --git a/bridge/contracts/zeppelin/math/SafeMath.sol b/bridge/contracts/zeppelin/math/SafeMath.sol
index 58a8da1c3..b0d676806 100644
--- a/bridge/contracts/zeppelin/math/SafeMath.sol
+++ b/bridge/contracts/zeppelin/math/SafeMath.sol
@@ -1,52 +1,159 @@
-pragma solidity ^0.4.24;
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+pragma abicoder v2;
/**
- * @title SafeMath
- * @dev Math operations with safety checks that throw on error
+ * @dev Wrappers over Solidity's arithmetic operations with added overflow
+ * checks.
+ *
+ * Arithmetic operations in Solidity wrap on overflow. This can easily result
+ * in bugs, because programmers usually assume that an overflow raises an
+ * error, which is the standard behavior in high level programming languages.
+ * `SafeMath` restores this intuition by reverting the transaction when an
+ * operation overflows.
+ *
+ * Using this library instead of the unchecked operations eliminates an entire
+ * class of bugs, so it's recommended to use it always.
*/
library SafeMath {
+ /**
+ * @dev Returns the addition of two unsigned integers, reverting on
+ * overflow.
+ *
+ * Counterpart to Solidity's `+` operator.
+ *
+ * Requirements:
+ * - Addition cannot overflow.
+ */
+ function add(uint256 a, uint256 b) internal pure returns (uint256) {
+ uint256 c = a + b;
+ require(c >= a, "SafeMath: addition overflow");
- /**
- * @dev Multiplies two numbers, throws on overflow.
- */
- function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
- // Gas optimization: this is cheaper than asserting 'a' not being zero, but the
- // benefit is lost if 'b' is also tested.
- // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
- if (_a == 0) {
- return 0;
- }
-
- c = _a * _b;
- assert(c / _a == _b);
- return c;
- }
-
- /**
- * @dev Integer division of two numbers, truncating the quotient.
- */
- function div(uint256 _a, uint256 _b) internal pure returns (uint256) {
- // assert(_b > 0); // Solidity automatically throws when dividing by 0
- // uint256 c = _a / _b;
- // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold
- return _a / _b;
- }
-
- /**
- * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
- */
- function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
- assert(_b <= _a);
- return _a - _b;
- }
-
- /**
- * @dev Adds two numbers, throws on overflow.
- */
- function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
- c = _a + _b;
- assert(c >= _a);
- return c;
- }
+ return c;
+ }
+
+ /**
+ * @dev Returns the subtraction of two unsigned integers, reverting on
+ * overflow (when the result is negative).
+ *
+ * Counterpart to Solidity's `-` operator.
+ *
+ * Requirements:
+ * - Subtraction cannot overflow.
+ */
+ function sub(uint256 a, uint256 b) internal pure returns (uint256) {
+ return sub(a, b, "SafeMath: subtraction overflow");
+ }
+
+ /**
+ * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
+ * overflow (when the result is negative).
+ *
+ * Counterpart to Solidity's `-` operator.
+ *
+ * Requirements:
+ * - Subtraction cannot overflow.
+ *
+ * _Available since v2.4.0._
+ */
+ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
+ require(b <= a, errorMessage);
+ uint256 c = a - b;
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the multiplication of two unsigned integers, reverting on
+ * overflow.
+ *
+ * Counterpart to Solidity's `*` operator.
+ *
+ * Requirements:
+ * - Multiplication cannot overflow.
+ */
+ function mul(uint256 a, uint256 b) internal pure returns (uint256) {
+ // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
+ // benefit is lost if 'b' is also tested.
+ // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
+ if (a == 0) {
+ return 0;
+ }
+
+ uint256 c = a * b;
+ require(c / a == b, "SafeMath: multiplication overflow");
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the integer division of two unsigned integers. Reverts on
+ * division by zero. The result is rounded towards zero.
+ *
+ * Counterpart to Solidity's `/` operator. Note: this function uses a
+ * `revert` opcode (which leaves remaining gas untouched) while Solidity
+ * uses an invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ */
+ function div(uint256 a, uint256 b) internal pure returns (uint256) {
+ return div(a, b, "SafeMath: division by zero");
+ }
+
+ /**
+ * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
+ * division by zero. The result is rounded towards zero.
+ *
+ * Counterpart to Solidity's `/` operator. Note: this function uses a
+ * `revert` opcode (which leaves remaining gas untouched) while Solidity
+ * uses an invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ *
+ * _Available since v2.4.0._
+ */
+ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
+ // Solidity only automatically asserts when dividing by 0
+ require(b > 0, errorMessage);
+ uint256 c = a / b;
+ // assert(a == b * c + a % b); // There is no case in which this doesn't hold
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
+ * Reverts when dividing by zero.
+ *
+ * Counterpart to Solidity's `%` operator. This function uses a `revert`
+ * opcode (which leaves remaining gas untouched) while Solidity uses an
+ * invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ */
+ function mod(uint256 a, uint256 b) internal pure returns (uint256) {
+ return mod(a, b, "SafeMath: modulo by zero");
+ }
+
+ /**
+ * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
+ * Reverts with custom message when dividing by zero.
+ *
+ * Counterpart to Solidity's `%` operator. This function uses a `revert`
+ * opcode (which leaves remaining gas untouched) while Solidity uses an
+ * invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ *
+ * _Available since v2.4.0._
+ */
+ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
+ require(b != 0, errorMessage);
+ return a % b;
+ }
}
diff --git a/bridge/contracts/zeppelin/ownership/Claimable.sol b/bridge/contracts/zeppelin/ownership/Claimable.sol
deleted file mode 100644
index 9027c11f5..000000000
--- a/bridge/contracts/zeppelin/ownership/Claimable.sol
+++ /dev/null
@@ -1,39 +0,0 @@
-pragma solidity ^0.4.24;
-
-
-import "./Ownable.sol";
-
-
-/**
- * @title Claimable
- * @dev Extension for the Ownable contract, where the ownership needs to be claimed.
- * This allows the new owner to accept the transfer.
- */
-contract Claimable is Ownable {
- address public pendingOwner;
-
- /**
- * @dev Modifier throws if called by any account other than the pendingOwner.
- */
- modifier onlyPendingOwner() {
- require(msg.sender == pendingOwner);
- _;
- }
-
- /**
- * @dev Allows the current owner to set the pendingOwner address.
- * @param newOwner The address to transfer ownership to.
- */
- function transferOwnership(address newOwner) public onlyOwner {
- pendingOwner = newOwner;
- }
-
- /**
- * @dev Allows the pendingOwner address to finalize the transfer.
- */
- function claimOwnership() public onlyPendingOwner {
- emit OwnershipTransferred(owner, pendingOwner);
- owner = pendingOwner;
- pendingOwner = address(0);
- }
-}
diff --git a/bridge/contracts/zeppelin/ownership/Contactable.sol b/bridge/contracts/zeppelin/ownership/Contactable.sol
deleted file mode 100644
index 9ed32cbbb..000000000
--- a/bridge/contracts/zeppelin/ownership/Contactable.sol
+++ /dev/null
@@ -1,22 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "./Ownable.sol";
-
-
-/**
- * @title Contactable token
- * @dev Basic version of a contactable contract, allowing the owner to provide a string with their
- * contact information.
- */
-contract Contactable is Ownable {
-
- string public contactInformation;
-
- /**
- * @dev Allows the owner to set a string with their contact information.
- * @param _info The contact information to attach to the contract.
- */
- function setContactInformation(string _info) public onlyOwner {
- contactInformation = _info;
- }
-}
diff --git a/bridge/contracts/zeppelin/ownership/DelayedClaimable.sol b/bridge/contracts/zeppelin/ownership/DelayedClaimable.sol
deleted file mode 100644
index a9c0857f8..000000000
--- a/bridge/contracts/zeppelin/ownership/DelayedClaimable.sol
+++ /dev/null
@@ -1,40 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "./Claimable.sol";
-
-
-/**
- * @title DelayedClaimable
- * @dev Extension for the Claimable contract, where the ownership needs to be claimed before/after
- * a certain block number.
- */
-contract DelayedClaimable is Claimable {
-
- uint256 public end;
- uint256 public start;
-
- /**
- * @dev Used to specify the time period during which a pending
- * owner can claim ownership.
- * @param _start The earliest time ownership can be claimed.
- * @param _end The latest time ownership can be claimed.
- */
- function setLimits(uint256 _start, uint256 _end) public onlyOwner {
- require(_start <= _end);
- end = _end;
- start = _start;
- }
-
- /**
- * @dev Allows the pendingOwner address to finalize the transfer, as long as it is called within
- * the specified start and end time.
- */
- function claimOwnership() public onlyPendingOwner {
- require((block.number <= end) && (block.number >= start));
- emit OwnershipTransferred(owner, pendingOwner);
- owner = pendingOwner;
- pendingOwner = address(0);
- end = 0;
- }
-
-}
diff --git a/bridge/contracts/zeppelin/ownership/HasNoContracts.sol b/bridge/contracts/zeppelin/ownership/HasNoContracts.sol
deleted file mode 100644
index f73cc6e58..000000000
--- a/bridge/contracts/zeppelin/ownership/HasNoContracts.sol
+++ /dev/null
@@ -1,22 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "./Ownable.sol";
-
-
-/**
- * @title Contracts that should not own Contracts
- * @author Remco Bloemen
- * @dev Should contracts (anything Ownable) end up being owned by this contract, it allows the owner
- * of this contract to reclaim ownership of the contracts.
- */
-contract HasNoContracts is Ownable {
-
- /**
- * @dev Reclaim ownership of Ownable contracts
- * @param _contractAddr The address of the Ownable to be reclaimed.
- */
- function reclaimContract(address _contractAddr) external onlyOwner {
- Ownable contractInst = Ownable(_contractAddr);
- contractInst.transferOwnership(owner);
- }
-}
diff --git a/bridge/contracts/zeppelin/ownership/HasNoEther.sol b/bridge/contracts/zeppelin/ownership/HasNoEther.sol
deleted file mode 100644
index cdccd4f5a..000000000
--- a/bridge/contracts/zeppelin/ownership/HasNoEther.sol
+++ /dev/null
@@ -1,41 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "./Ownable.sol";
-
-
-/**
- * @title Contracts that should not own Ether
- * @author Remco Bloemen
- * @dev This tries to block incoming ether to prevent accidental loss of Ether. Should Ether end up
- * in the contract, it will allow the owner to reclaim this Ether.
- * @notice Ether can still be sent to this contract by:
- * calling functions labeled `payable`
- * `selfdestruct(contract_address)`
- * mining directly to the contract address
- */
-contract HasNoEther is Ownable {
-
- /**
- * @dev Constructor that rejects incoming Ether
- * The `payable` flag is added so we can access `msg.value` without compiler warning. If we
- * leave out payable, then Solidity will allow inheriting contracts to implement a payable
- * constructor. By doing it this way we prevent a payable constructor from working. Alternatively
- * we could use assembly to access msg.value.
- */
- constructor() public payable {
- require(msg.value == 0);
- }
-
- /**
- * @dev Disallows direct send by setting a default function without the `payable` flag.
- */
- function() external {
- }
-
- /**
- * @dev Transfer all Ether held by the contract to the owner.
- */
- function reclaimEther() external onlyOwner {
- owner.transfer(address(this).balance);
- }
-}
diff --git a/bridge/contracts/zeppelin/ownership/Ownable.sol b/bridge/contracts/zeppelin/ownership/Ownable.sol
index 1fbf571bf..595e40e18 100644
--- a/bridge/contracts/zeppelin/ownership/Ownable.sol
+++ b/bridge/contracts/zeppelin/ownership/Ownable.sol
@@ -1,64 +1,79 @@
-pragma solidity ^0.4.24;
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+import "../GSN/Context.sol";
/**
- * @title Ownable
- * @dev The Ownable contract has an owner address, and provides basic authorization control
- * functions, this simplifies the implementation of "user permissions".
+ * @dev Contract module which provides a basic access control mechanism, where
+ * there is an account (an owner) that can be granted exclusive access to
+ * specific functions.
+ *
+ * This module is used through inheritance. It will make available the modifier
+ * `onlyOwner`, which can be applied to your functions to restrict their use to
+ * the owner.
*/
-contract Ownable {
- address public owner;
+abstract contract Ownable is Context {
+ address private _owner;
+ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
- event OwnershipRenounced(address indexed previousOwner);
- event OwnershipTransferred(
- address indexed previousOwner,
- address indexed newOwner
- );
+ /**
+ * @dev Initializes the contract setting the deployer as the initial owner.
+ */
+ constructor () {
+ _owner = _msgSender();
+ emit OwnershipTransferred(address(0), _owner);
+ }
+ /**
+ * @dev Returns the address of the current owner.
+ */
+ function owner() public view returns (address) {
+ return _owner;
+ }
- /**
- * @dev The Ownable constructor sets the original `owner` of the contract to the sender
- * account.
- */
- constructor() public {
- owner = msg.sender;
- }
+ /**
+ * @dev Throws if called by any account other than the owner.
+ */
+ modifier onlyOwner() {
+ require(isOwner(), "Ownable: caller is not the owner");
+ _;
+ }
- /**
- * @dev Throws if called by any account other than the owner.
- */
- modifier onlyOwner() {
- require(msg.sender == owner);
- _;
- }
+ /**
+ * @dev Returns true if the caller is the current owner.
+ */
+ function isOwner() public view returns (bool) {
+ return _msgSender() == _owner;
+ }
- /**
- * @dev Allows the current owner to relinquish control of the contract.
- * @notice Renouncing to ownership will leave the contract without an owner.
- * It will not be possible to call the functions with the `onlyOwner`
- * modifier anymore.
- */
- function renounceOwnership() public onlyOwner {
- emit OwnershipRenounced(owner);
- owner = address(0);
- }
+ /**
+ * @dev Leaves the contract without owner. It will not be possible to call
+ * `onlyOwner` functions anymore. Can only be called by the current owner.
+ *
+ * NOTE: Renouncing ownership will leave the contract without an owner,
+ * thereby removing any functionality that is only available to the owner.
+ */
+ function renounceOwnership() public onlyOwner {
+ emit OwnershipTransferred(_owner, address(0));
+ _owner = address(0);
+ }
- /**
- * @dev Allows the current owner to transfer control of the contract to a newOwner.
- * @param _newOwner The address to transfer ownership to.
- */
- function transferOwnership(address _newOwner) public onlyOwner {
- _transferOwnership(_newOwner);
- }
+ /**
+ * @dev Transfers ownership of the contract to a new account (`newOwner`).
+ * Can only be called by the current owner.
+ */
+ function transferOwnership(address newOwner) public onlyOwner {
+ _transferOwnership(newOwner);
+ }
- /**
- * @dev Transfers control of the contract to a newOwner.
- * @param _newOwner The address to transfer ownership to.
- */
- function _transferOwnership(address _newOwner) internal {
- require(_newOwner != address(0));
- emit OwnershipTransferred(owner, _newOwner);
- owner = _newOwner;
- }
+ /**
+ * @dev Transfers ownership of the contract to a new account (`newOwner`).
+ */
+ function _transferOwnership(address newOwner) internal {
+ require(newOwner != address(0), "Ownable: new owner is the zero address");
+ emit OwnershipTransferred(_owner, newOwner);
+ _owner = newOwner;
+ }
}
diff --git a/bridge/contracts/zeppelin/ownership/Secondary.sol b/bridge/contracts/zeppelin/ownership/Secondary.sol
new file mode 100644
index 000000000..a52f08661
--- /dev/null
+++ b/bridge/contracts/zeppelin/ownership/Secondary.sol
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "../GSN/Context.sol";
+/**
+ * @dev A Secondary contract can only be used by its primary account (the one that created it).
+ */
+abstract contract Secondary is Context {
+ address private _primary;
+
+ /**
+ * @dev Emitted when the primary contract changes.
+ */
+ event PrimaryTransferred(
+ address recipient
+ );
+
+ /**
+ * @dev Sets the primary account to the one that is creating the Secondary contract.
+ */
+ constructor () {
+ _primary = _msgSender();
+ emit PrimaryTransferred(_primary);
+ }
+
+ /**
+ * @dev Reverts if called from any account other than the primary.
+ */
+ modifier onlyPrimary() {
+ require(_msgSender() == _primary, "Secondary: caller is not the primary account");
+ _;
+ }
+
+ /**
+ * @return the address of the primary.
+ */
+ function primary() public view returns (address) {
+ return _primary;
+ }
+
+ /**
+ * @dev Transfers contract to a new primary.
+ * @param recipient The address of new primary.
+ */
+ function transferPrimary(address recipient) public onlyPrimary {
+ require(recipient != address(0), "Secondary: new primary is the zero address");
+ _primary = recipient;
+ emit PrimaryTransferred(_primary);
+ }
+}
diff --git a/bridge/contracts/zeppelin/token/ERC1155/ERC1155.sol b/bridge/contracts/zeppelin/token/ERC1155/ERC1155.sol
new file mode 100644
index 000000000..585e6a17e
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC1155/ERC1155.sol
@@ -0,0 +1,414 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "./IERC1155.sol";
+import "./IERC1155MetadataURI.sol";
+import "./IERC1155Receiver.sol";
+import "../../GSN/Context.sol";
+import "../../introspection/ERC165.sol";
+import "../../math/SafeMath.sol";
+import "../../utils/Address.sol";
+
+/**
+ *
+ * @dev Implementation of the basic standard multi-token.
+ * See https://eips.ethereum.org/EIPS/eip-1155
+ * Originally based on code by Enjin: https://github.com/enjin/erc-1155
+ *
+ * _Available since v3.1._
+ */
+contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
+ using SafeMath for uint256;
+ using Address for address;
+
+ // Mapping from token ID to account balances
+ mapping (uint256 => mapping(address => uint256)) private _balances;
+
+ // Mapping from account to operator approvals
+ mapping (address => mapping(address => bool)) private _operatorApprovals;
+
+ // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
+ string private _uri;
+
+ /*
+ * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e
+ * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4
+ * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
+ * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
+ * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a
+ * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6
+ *
+ * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^
+ * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26
+ */
+ bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;
+
+ /*
+ * bytes4(keccak256('uri(uint256)')) == 0x0e89341c
+ */
+ bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;
+
+ /**
+ * @dev See {_setURI}.
+ */
+ constructor (string memory uri_) {
+ _setURI(uri_);
+
+ // register the supported interfaces to conform to ERC1155 via ERC165
+ _registerInterface(_INTERFACE_ID_ERC1155);
+
+ // register the supported interfaces to conform to ERC1155MetadataURI via ERC165
+ _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);
+ }
+
+ /**
+ * @dev See {IERC1155MetadataURI-uri}.
+ *
+ * This implementation returns the same URI for *all* token types. It relies
+ * on the token type ID substitution mechanism
+ * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
+ *
+ * Clients calling this function must replace the `\{id\}` substring with the
+ * actual token type ID.
+ */
+ function uri(uint256) external view virtual override returns (string memory) {
+ return _uri;
+ }
+
+ /**
+ * @dev See {IERC1155-balanceOf}.
+ *
+ * Requirements:
+ *
+ * - `account` cannot be the zero address.
+ */
+ function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
+ require(account != address(0), "ERC1155: balance query for the zero address");
+ return _balances[id][account];
+ }
+
+ /**
+ * @dev See {IERC1155-balanceOfBatch}.
+ *
+ * Requirements:
+ *
+ * - `accounts` and `ids` must have the same length.
+ */
+ function balanceOfBatch(
+ address[] memory accounts,
+ uint256[] memory ids
+ )
+ public
+ view
+ virtual
+ override
+ returns (uint256[] memory)
+ {
+ require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
+
+ uint256[] memory batchBalances = new uint256[](accounts.length);
+
+ for (uint256 i = 0; i < accounts.length; ++i) {
+ batchBalances[i] = balanceOf(accounts[i], ids[i]);
+ }
+
+ return batchBalances;
+ }
+
+ /**
+ * @dev See {IERC1155-setApprovalForAll}.
+ */
+ function setApprovalForAll(address operator, bool approved) public virtual override {
+ require(_msgSender() != operator, "ERC1155: setting approval status for self");
+
+ _operatorApprovals[_msgSender()][operator] = approved;
+ emit ApprovalForAll(_msgSender(), operator, approved);
+ }
+
+ /**
+ * @dev See {IERC1155-isApprovedForAll}.
+ */
+ function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
+ return _operatorApprovals[account][operator];
+ }
+
+ /**
+ * @dev See {IERC1155-safeTransferFrom}.
+ */
+ function safeTransferFrom(
+ address from,
+ address to,
+ uint256 id,
+ uint256 amount,
+ bytes memory data
+ )
+ public
+ virtual
+ override
+ {
+ require(to != address(0), "ERC1155: transfer to the zero address");
+ require(
+ from == _msgSender() || isApprovedForAll(from, _msgSender()),
+ "ERC1155: caller is not owner nor approved"
+ );
+
+ address operator = _msgSender();
+
+ _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
+
+ _balances[id][from] = _balances[id][from].sub(amount, "ERC1155: insufficient balance for transfer");
+ _balances[id][to] = _balances[id][to].add(amount);
+
+ emit TransferSingle(operator, from, to, id, amount);
+
+ _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
+ }
+
+ /**
+ * @dev See {IERC1155-safeBatchTransferFrom}.
+ */
+ function safeBatchTransferFrom(
+ address from,
+ address to,
+ uint256[] memory ids,
+ uint256[] memory amounts,
+ bytes memory data
+ )
+ public
+ virtual
+ override
+ {
+ require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
+ require(to != address(0), "ERC1155: transfer to the zero address");
+ require(
+ from == _msgSender() || isApprovedForAll(from, _msgSender()),
+ "ERC1155: transfer caller is not owner nor approved"
+ );
+
+ address operator = _msgSender();
+
+ _beforeTokenTransfer(operator, from, to, ids, amounts, data);
+
+ for (uint256 i = 0; i < ids.length; ++i) {
+ uint256 id = ids[i];
+ uint256 amount = amounts[i];
+
+ _balances[id][from] = _balances[id][from].sub(
+ amount,
+ "ERC1155: insufficient balance for transfer"
+ );
+ _balances[id][to] = _balances[id][to].add(amount);
+ }
+
+ emit TransferBatch(operator, from, to, ids, amounts);
+
+ _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
+ }
+
+ /**
+ * @dev Sets a new URI for all token types, by relying on the token type ID
+ * substitution mechanism
+ * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
+ *
+ * By this mechanism, any occurrence of the `\{id\}` substring in either the
+ * URI or any of the amounts in the JSON file at said URI will be replaced by
+ * clients with the token type ID.
+ *
+ * For example, the `https://token-cdn-domain/\{id\}.json` URI would be
+ * interpreted by clients as
+ * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
+ * for token type ID 0x4cce0.
+ *
+ * See {uri}.
+ *
+ * Because these URIs cannot be meaningfully represented by the {URI} event,
+ * this function emits no events.
+ */
+ function _setURI(string memory newuri) internal virtual {
+ _uri = newuri;
+ }
+
+ /**
+ * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.
+ *
+ * Emits a {TransferSingle} event.
+ *
+ * Requirements:
+ *
+ * - `account` cannot be the zero address.
+ * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
+ * acceptance magic value.
+ */
+ function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {
+ require(account != address(0), "ERC1155: mint to the zero address");
+
+ address operator = _msgSender();
+
+ _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);
+
+ _balances[id][account] = _balances[id][account].add(amount);
+ emit TransferSingle(operator, address(0), account, id, amount);
+
+ _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);
+ }
+
+ /**
+ * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
+ *
+ * Requirements:
+ *
+ * - `ids` and `amounts` must have the same length.
+ * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
+ * acceptance magic value.
+ */
+ function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {
+ require(to != address(0), "ERC1155: mint to the zero address");
+ require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
+
+ address operator = _msgSender();
+
+ _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
+
+ for (uint i = 0; i < ids.length; i++) {
+ _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);
+ }
+
+ emit TransferBatch(operator, address(0), to, ids, amounts);
+
+ _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
+ }
+
+ /**
+ * @dev Destroys `amount` tokens of token type `id` from `account`
+ *
+ * Requirements:
+ *
+ * - `account` cannot be the zero address.
+ * - `account` must have at least `amount` tokens of token type `id`.
+ */
+ function _burn(address account, uint256 id, uint256 amount) internal virtual {
+ require(account != address(0), "ERC1155: burn from the zero address");
+
+ address operator = _msgSender();
+
+ _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
+
+ _balances[id][account] = _balances[id][account].sub(
+ amount,
+ "ERC1155: burn amount exceeds balance"
+ );
+
+ emit TransferSingle(operator, account, address(0), id, amount);
+ }
+
+ /**
+ * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
+ *
+ * Requirements:
+ *
+ * - `ids` and `amounts` must have the same length.
+ */
+ function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {
+ require(account != address(0), "ERC1155: burn from the zero address");
+ require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
+
+ address operator = _msgSender();
+
+ _beforeTokenTransfer(operator, account, address(0), ids, amounts, "");
+
+ for (uint i = 0; i < ids.length; i++) {
+ _balances[ids[i]][account] = _balances[ids[i]][account].sub(
+ amounts[i],
+ "ERC1155: burn amount exceeds balance"
+ );
+ }
+
+ emit TransferBatch(operator, account, address(0), ids, amounts);
+ }
+
+ /**
+ * @dev Hook that is called before any token transfer. This includes minting
+ * and burning, as well as batched variants.
+ *
+ * The same hook is called on both single and batched variants. For single
+ * transfers, the length of the `id` and `amount` arrays will be 1.
+ *
+ * Calling conditions (for each `id` and `amount` pair):
+ *
+ * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
+ * of token type `id` will be transferred to `to`.
+ * - When `from` is zero, `amount` tokens of token type `id` will be minted
+ * for `to`.
+ * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
+ * will be burned.
+ * - `from` and `to` are never both zero.
+ * - `ids` and `amounts` have the same, non-zero length.
+ *
+ * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
+ */
+ function _beforeTokenTransfer(
+ address operator,
+ address from,
+ address to,
+ uint256[] memory ids,
+ uint256[] memory amounts,
+ bytes memory data
+ )
+ internal
+ virtual
+ { }
+
+ function _doSafeTransferAcceptanceCheck(
+ address operator,
+ address from,
+ address to,
+ uint256 id,
+ uint256 amount,
+ bytes memory data
+ )
+ private
+ {
+ if (to.isContract()) {
+ try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
+ if (response != IERC1155Receiver(to).onERC1155Received.selector) {
+ revert("ERC1155: ERC1155Receiver rejected tokens");
+ }
+ } catch Error(string memory reason) {
+ revert(reason);
+ } catch {
+ revert("ERC1155: transfer to non ERC1155Receiver implementer");
+ }
+ }
+ }
+
+ function _doSafeBatchTransferAcceptanceCheck(
+ address operator,
+ address from,
+ address to,
+ uint256[] memory ids,
+ uint256[] memory amounts,
+ bytes memory data
+ )
+ private
+ {
+ if (to.isContract()) {
+ try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {
+ if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {
+ revert("ERC1155: ERC1155Receiver rejected tokens");
+ }
+ } catch Error(string memory reason) {
+ revert(reason);
+ } catch {
+ revert("ERC1155: transfer to non ERC1155Receiver implementer");
+ }
+ }
+ }
+
+ function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
+ uint256[] memory array = new uint256[](1);
+ array[0] = element;
+
+ return array;
+ }
+}
diff --git a/bridge/contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol b/bridge/contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol
new file mode 100644
index 000000000..d95b43853
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "./ERC1155.sol";
+
+/**
+ * @dev Extension of {ERC1155} that allows token holders to destroy both their
+ * own tokens and those that they have been approved to use.
+ *
+ * _Available since v3.1._
+ */
+abstract contract ERC1155Burnable is ERC1155 {
+ function burn(address account, uint256 id, uint256 value) public virtual {
+ require(
+ account == _msgSender() || isApprovedForAll(account, _msgSender()),
+ "ERC1155: caller is not owner nor approved"
+ );
+
+ _burn(account, id, value);
+ }
+
+ function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {
+ require(
+ account == _msgSender() || isApprovedForAll(account, _msgSender()),
+ "ERC1155: caller is not owner nor approved"
+ );
+
+ _burnBatch(account, ids, values);
+ }
+}
diff --git a/bridge/contracts/zeppelin/token/ERC1155/ERC1155Holder.sol b/bridge/contracts/zeppelin/token/ERC1155/ERC1155Holder.sol
new file mode 100644
index 000000000..4468f65cc
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC1155/ERC1155Holder.sol
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "./ERC1155Receiver.sol";
+
+/**
+ * @dev _Available since v3.1._
+ */
+contract ERC1155Holder is ERC1155Receiver {
+ function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {
+ return this.onERC1155Received.selector;
+ }
+
+ function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {
+ return this.onERC1155BatchReceived.selector;
+ }
+}
diff --git a/bridge/contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol b/bridge/contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol
new file mode 100644
index 000000000..e435ff8e5
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "./ERC1155.sol";
+import "../../lifecycle/Pausable.sol";
+
+/**
+ * @dev ERC1155 token with pausable token transfers, minting and burning.
+ *
+ * Useful for scenarios such as preventing trades until the end of an evaluation
+ * period, or having an emergency switch for freezing all token transfers in the
+ * event of a large bug.
+ *
+ * _Available since v3.1._
+ */
+abstract contract ERC1155Pausable is ERC1155, Pausable {
+ /**
+ * @dev See {ERC1155-_beforeTokenTransfer}.
+ *
+ * Requirements:
+ *
+ * - the contract must not be paused.
+ */
+ function _beforeTokenTransfer(
+ address operator,
+ address from,
+ address to,
+ uint256[] memory ids,
+ uint256[] memory amounts,
+ bytes memory data
+ )
+ internal
+ virtual
+ override
+ {
+ super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
+
+ require(!paused(), "ERC1155Pausable: token transfer while paused");
+ }
+}
diff --git a/bridge/contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol b/bridge/contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol
new file mode 100644
index 000000000..f3e870270
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "./IERC1155Receiver.sol";
+import "../../introspection/ERC165.sol";
+
+/**
+ * @dev _Available since v3.1._
+ */
+abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
+ constructor() {
+ _registerInterface(
+ ERC1155Receiver(address(0)).onERC1155Received.selector ^
+ ERC1155Receiver(address(0)).onERC1155BatchReceived.selector
+ );
+ }
+}
diff --git a/bridge/contracts/zeppelin/token/ERC1155/IERC1155.sol b/bridge/contracts/zeppelin/token/ERC1155/IERC1155.sol
new file mode 100644
index 000000000..673196332
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC1155/IERC1155.sol
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../../introspection/IERC165.sol";
+
+/**
+ * @dev Required interface of an ERC1155 compliant contract, as defined in the
+ * https://eips.ethereum.org/EIPS/eip-1155[EIP].
+ *
+ * _Available since v3.1._
+ */
+interface IERC1155 is IERC165 {
+ /**
+ * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
+ */
+ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
+
+ /**
+ * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
+ * transfers.
+ */
+ event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);
+
+ /**
+ * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
+ * `approved`.
+ */
+ event ApprovalForAll(address indexed account, address indexed operator, bool approved);
+
+ /**
+ * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
+ *
+ * If an {URI} event was emitted for `id`, the standard
+ * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
+ * returned by {IERC1155MetadataURI-uri}.
+ */
+ event URI(string value, uint256 indexed id);
+
+ /**
+ * @dev Returns the amount of tokens of token type `id` owned by `account`.
+ *
+ * Requirements:
+ *
+ * - `account` cannot be the zero address.
+ */
+ function balanceOf(address account, uint256 id) external view returns (uint256);
+
+ /**
+ * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
+ *
+ * Requirements:
+ *
+ * - `accounts` and `ids` must have the same length.
+ */
+ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);
+
+ /**
+ * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
+ *
+ * Emits an {ApprovalForAll} event.
+ *
+ * Requirements:
+ *
+ * - `operator` cannot be the caller.
+ */
+ function setApprovalForAll(address operator, bool approved) external;
+
+ /**
+ * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
+ *
+ * See {setApprovalForAll}.
+ */
+ function isApprovedForAll(address account, address operator) external view returns (bool);
+
+ /**
+ * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
+ *
+ * Emits a {TransferSingle} event.
+ *
+ * Requirements:
+ *
+ * - `to` cannot be the zero address.
+ * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
+ * - `from` must have a balance of tokens of type `id` of at least `amount`.
+ * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
+ * acceptance magic value.
+ */
+ function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
+
+ /**
+ * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
+ *
+ * Emits a {TransferBatch} event.
+ *
+ * Requirements:
+ *
+ * - `ids` and `amounts` must have the same length.
+ * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
+ * acceptance magic value.
+ */
+ function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
+}
diff --git a/bridge/contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol b/bridge/contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol
new file mode 100644
index 000000000..f636cc2d8
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "./IERC1155.sol";
+
+/**
+ * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
+ * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
+ *
+ * _Available since v3.1._
+ */
+interface IERC1155MetadataURI is IERC1155 {
+ /**
+ * @dev Returns the URI for token type `id`.
+ *
+ * If the `\{id\}` substring is present in the URI, it must be replaced by
+ * clients with the actual token type ID.
+ */
+ function uri(uint256 id) external view returns (string memory);
+}
diff --git a/bridge/contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol b/bridge/contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol
new file mode 100644
index 000000000..07c441e22
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../../introspection/IERC165.sol";
+
+/**
+ * _Available since v3.1._
+ */
+interface IERC1155Receiver is IERC165 {
+
+ /**
+ @dev Handles the receipt of a single ERC1155 token type. This function is
+ called at the end of a `safeTransferFrom` after the balance has been updated.
+ To accept the transfer, this must return
+ `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
+ (i.e. 0xf23a6e61, or its own function selector).
+ @param operator The address which initiated the transfer (i.e. msg.sender)
+ @param from The address which previously owned the token
+ @param id The ID of the token being transferred
+ @param value The amount of tokens being transferred
+ @param data Additional data with no specified format
+ @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
+ */
+ function onERC1155Received(
+ address operator,
+ address from,
+ uint256 id,
+ uint256 value,
+ bytes calldata data
+ )
+ external
+ returns(bytes4);
+
+ /**
+ @dev Handles the receipt of a multiple ERC1155 token types. This function
+ is called at the end of a `safeBatchTransferFrom` after the balances have
+ been updated. To accept the transfer(s), this must return
+ `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
+ (i.e. 0xbc197c81, or its own function selector).
+ @param operator The address which initiated the batch transfer (i.e. msg.sender)
+ @param from The address which previously owned the token
+ @param ids An array containing ids of each token being transferred (order and length must match values array)
+ @param values An array containing amounts of each token being transferred (order and length must match ids array)
+ @param data Additional data with no specified format
+ @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
+ */
+ function onERC1155BatchReceived(
+ address operator,
+ address from,
+ uint256[] calldata ids,
+ uint256[] calldata values,
+ bytes calldata data
+ )
+ external
+ returns(bytes4);
+}
diff --git a/bridge/contracts/zeppelin/token/ERC1155/README.adoc b/bridge/contracts/zeppelin/token/ERC1155/README.adoc
new file mode 100644
index 000000000..e80474695
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC1155/README.adoc
@@ -0,0 +1,37 @@
+= ERC 1155
+
+[.readme-notice]
+NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc1155
+
+This set of interfaces and contracts are all related to the https://eips.ethereum.org/EIPS/eip-1155[ERC1155 Multi Token Standard].
+
+The EIP consists of three interfaces which fulfill different roles, found here as {IERC1155}, {IERC1155MetadataURI} and {IERC1155Receiver}.
+
+{ERC1155} implements the mandatory {IERC1155} interface, as well as the optional extension {IERC1155MetadataURI}, by relying on the substitution mechanism to use the same URI for all token types, dramatically reducing gas costs.
+
+Additionally there are multiple custom extensions, including:
+
+* designation of addresses that can pause token transfers for all users ({ERC1155Pausable}).
+* destruction of own tokens ({ERC1155Burnable}).
+
+NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC1155 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc1155.adoc#Presets[ERC1155 Presets] (such as {ERC1155PresetMinterPauser}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts.
+
+== Core
+
+{{IERC1155}}
+
+{{IERC1155MetadataURI}}
+
+{{ERC1155}}
+
+{{IERC1155Receiver}}
+
+== Extensions
+
+{{ERC1155Pausable}}
+
+{{ERC1155Burnable}}
+
+== Convenience
+
+{{ERC1155Holder}}
diff --git a/bridge/contracts/zeppelin/token/ERC20/BasicToken.sol b/bridge/contracts/zeppelin/token/ERC20/BasicToken.sol
deleted file mode 100644
index b40f10ece..000000000
--- a/bridge/contracts/zeppelin/token/ERC20/BasicToken.sol
+++ /dev/null
@@ -1,50 +0,0 @@
-pragma solidity ^0.4.24;
-
-
-import "./ERC20Basic.sol";
-import "../../math/SafeMath.sol";
-
-
-/**
- * @title Basic token
- * @dev Basic version of StandardToken, with no allowances.
- */
-contract BasicToken is ERC20Basic {
- using SafeMath for uint256;
-
- mapping(address => uint256) internal balances;
-
- uint256 internal totalSupply_;
-
- /**
- * @dev Total number of tokens in existence
- */
- function totalSupply() public view returns (uint256) {
- return totalSupply_;
- }
-
- /**
- * @dev Transfer token for a specified address
- * @param _to The address to transfer to.
- * @param _value The amount to be transferred.
- */
- function transfer(address _to, uint256 _value) public returns (bool) {
- require(_value <= balances[msg.sender]);
- require(_to != address(0));
-
- balances[msg.sender] = balances[msg.sender].sub(_value);
- balances[_to] = balances[_to].add(_value);
- emit Transfer(msg.sender, _to, _value);
- return true;
- }
-
- /**
- * @dev Gets the balance of the specified address.
- * @param _owner The address to query the the balance of.
- * @return An uint256 representing the amount owned by the passed address.
- */
- function balanceOf(address _owner) public view returns (uint256) {
- return balances[_owner];
- }
-
-}
diff --git a/bridge/contracts/zeppelin/token/ERC20/DetailedERC20.sol b/bridge/contracts/zeppelin/token/ERC20/DetailedERC20.sol
deleted file mode 100644
index 20ba0f60c..000000000
--- a/bridge/contracts/zeppelin/token/ERC20/DetailedERC20.sol
+++ /dev/null
@@ -1,22 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "./ERC20.sol";
-
-
-/**
- * @title DetailedERC20 token
- * @dev The decimals are only for visualization purposes.
- * All the operations are done using the smallest and indivisible token unit,
- * just as on Ethereum all the operations are done in wei.
- */
-contract DetailedERC20 is ERC20 {
- string public name;
- string public symbol;
- uint8 public decimals;
-
- constructor(string _name, string _symbol, uint8 _decimals) public {
- name = _name;
- symbol = _symbol;
- decimals = _decimals;
- }
-}
diff --git a/bridge/contracts/zeppelin/token/ERC20/ERC20.sol b/bridge/contracts/zeppelin/token/ERC20/ERC20.sol
index 04e90d86c..031d25081 100644
--- a/bridge/contracts/zeppelin/token/ERC20/ERC20.sol
+++ b/bridge/contracts/zeppelin/token/ERC20/ERC20.sol
@@ -1,23 +1,233 @@
-pragma solidity ^0.4.24;
+// SPDX-License-Identifier: MIT
-import "./ERC20Basic.sol";
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+import "../../GSN/Context.sol";
+import "./IERC20.sol";
+import "../../math/SafeMath.sol";
/**
- * @title ERC20 interface
- * @dev see https://github.com/ethereum/EIPs/issues/20
+ * @dev Implementation of the {IERC20} interface.
+ *
+ * This implementation is agnostic to the way tokens are created. This means
+ * that a supply mechanism has to be added in a derived contract using {_mint}.
+ * For a generic mechanism see {ERC20Mintable}.
+ *
+ * TIP: For a detailed writeup see our guide
+ * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
+ * to implement supply mechanisms].
+ *
+ * We have followed general OpenZeppelin guidelines: functions revert instead
+ * of returning `false` on failure. This behavior is nonetheless conventional
+ * and does not conflict with the expectations of ERC20 applications.
+ *
+ * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
+ * This allows applications to reconstruct the allowance for all accounts just
+ * by listening to said events. Other implementations of the EIP may not emit
+ * these events, as it isn't required by the specification.
+ *
+ * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
+ * functions have been added to mitigate the well-known issues around setting
+ * allowances. See {IERC20-approve}.
*/
-contract ERC20 is ERC20Basic {
- function allowance(address _owner, address _spender)
- public view returns (uint256);
-
- function transferFrom(address _from, address _to, uint256 _value)
- public returns (bool);
-
- function approve(address _spender, uint256 _value) public returns (bool);
- event Approval(
- address indexed owner,
- address indexed spender,
- uint256 value
- );
+contract ERC20 is Context, IERC20 {
+ using SafeMath for uint256;
+
+ mapping (address => uint256) private _balances;
+
+ mapping (address => mapping (address => uint256)) private _allowances;
+
+ uint256 private _totalSupply;
+
+ /**
+ * @dev See {IERC20-totalSupply}.
+ */
+ function totalSupply() override public view returns (uint256) {
+ return _totalSupply;
+ }
+
+ /**
+ * @dev See {IERC20-balanceOf}.
+ */
+ function balanceOf(address account) override public view returns (uint256) {
+ return _balances[account];
+ }
+
+ /**
+ * @dev See {IERC20-transfer}.
+ *
+ * Requirements:
+ *
+ * - `recipient` cannot be the zero address.
+ * - the caller must have a balance of at least `amount`.
+ */
+ function transfer(address recipient, uint256 amount) override public returns (bool) {
+ _transfer(_msgSender(), recipient, amount);
+ return true;
+ }
+
+ /**
+ * @dev See {IERC20-allowance}.
+ */
+ function allowance(address owner, address spender) override public view returns (uint256) {
+ return _allowances[owner][spender];
+ }
+
+ /**
+ * @dev See {IERC20-approve}.
+ *
+ * Requirements:
+ *
+ * - `spender` cannot be the zero address.
+ */
+ function approve(address spender, uint256 amount) override public returns (bool) {
+ _approve(_msgSender(), spender, amount);
+ return true;
+ }
+
+ /**
+ * @dev See {IERC20-transferFrom}.
+ *
+ * Emits an {Approval} event indicating the updated allowance. This is not
+ * required by the EIP. See the note at the beginning of {ERC20};
+ *
+ * Requirements:
+ * - `sender` and `recipient` cannot be the zero address.
+ * - `sender` must have a balance of at least `amount`.
+ * - the caller must have allowance for `sender`'s tokens of at least
+ * `amount`.
+ */
+ function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {
+ _transfer(sender, recipient, amount);
+ _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
+ return true;
+ }
+
+ /**
+ * @dev Atomically increases the allowance granted to `spender` by the caller.
+ *
+ * This is an alternative to {approve} that can be used as a mitigation for
+ * problems described in {IERC20-approve}.
+ *
+ * Emits an {Approval} event indicating the updated allowance.
+ *
+ * Requirements:
+ *
+ * - `spender` cannot be the zero address.
+ */
+ function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
+ _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
+ return true;
+ }
+
+ /**
+ * @dev Atomically decreases the allowance granted to `spender` by the caller.
+ *
+ * This is an alternative to {approve} that can be used as a mitigation for
+ * problems described in {IERC20-approve}.
+ *
+ * Emits an {Approval} event indicating the updated allowance.
+ *
+ * Requirements:
+ *
+ * - `spender` cannot be the zero address.
+ * - `spender` must have allowance for the caller of at least
+ * `subtractedValue`.
+ */
+ function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
+ _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
+ return true;
+ }
+
+ /**
+ * @dev Moves tokens `amount` from `sender` to `recipient`.
+ *
+ * This is internal function is equivalent to {transfer}, and can be used to
+ * e.g. implement automatic token fees, slashing mechanisms, etc.
+ *
+ * Emits a {Transfer} event.
+ *
+ * Requirements:
+ *
+ * - `sender` cannot be the zero address.
+ * - `recipient` cannot be the zero address.
+ * - `sender` must have a balance of at least `amount`.
+ */
+ function _transfer(address sender, address recipient, uint256 amount) internal {
+ require(sender != address(0), "ERC20: transfer from zero address");
+ require(recipient != address(0), "ERC20: transfer to zero address");
+
+ _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
+ _balances[recipient] = _balances[recipient].add(amount);
+ emit Transfer(sender, recipient, amount);
+ }
+
+ /** @dev Creates `amount` tokens and assigns them to `account`, increasing
+ * the total supply.
+ *
+ * Emits a {Transfer} event with `from` set to the zero address.
+ *
+ * Requirements
+ *
+ * - `to` cannot be the zero address.
+ */
+ function _mint(address account, uint256 amount) internal {
+ require(account != address(0), "ERC20: mint to zero address");
+
+ _totalSupply = _totalSupply.add(amount);
+ _balances[account] = _balances[account].add(amount);
+ emit Transfer(address(0), account, amount);
+ }
+
+ /**
+ * @dev Destroys `amount` tokens from `account`, reducing the
+ * total supply.
+ *
+ * Emits a {Transfer} event with `to` set to the zero address.
+ *
+ * Requirements
+ *
+ * - `account` cannot be the zero address.
+ * - `account` must have at least `amount` tokens.
+ */
+ function _burn(address account, uint256 amount) internal {
+ require(account != address(0), "ERC20: burn from zero address");
+
+ _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
+ _totalSupply = _totalSupply.sub(amount);
+ emit Transfer(account, address(0), amount);
+ }
+
+ /**
+ * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
+ *
+ * This is internal function is equivalent to `approve`, and can be used to
+ * e.g. set automatic allowances for certain subsystems, etc.
+ *
+ * Emits an {Approval} event.
+ *
+ * Requirements:
+ *
+ * - `owner` cannot be the zero address.
+ * - `spender` cannot be the zero address.
+ */
+ function _approve(address owner, address spender, uint256 amount) internal {
+ require(owner != address(0), "ERC20: approve from zero address");
+ require(spender != address(0), "ERC20: approve to zero address");
+
+ _allowances[owner][spender] = amount;
+ emit Approval(owner, spender, amount);
+ }
+
+ /**
+ * @dev Destroys `amount` tokens from `account`.`amount` is then deducted
+ * from the caller's allowance.
+ *
+ * See {_burn} and {_approve}.
+ */
+ function _burnFrom(address account, uint256 amount) internal {
+ _burn(account, amount);
+ _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance"));
+ }
}
diff --git a/bridge/contracts/zeppelin/token/ERC20/ERC20Basic.sol b/bridge/contracts/zeppelin/token/ERC20/ERC20Basic.sol
deleted file mode 100644
index 1b2d94255..000000000
--- a/bridge/contracts/zeppelin/token/ERC20/ERC20Basic.sol
+++ /dev/null
@@ -1,14 +0,0 @@
-pragma solidity ^0.4.24;
-
-
-/**
- * @title ERC20Basic
- * @dev Simpler version of ERC20 interface
- * See https://github.com/ethereum/EIPs/issues/179
- */
-contract ERC20Basic {
- function totalSupply() public view returns (uint256);
- function balanceOf(address _who) public view returns (uint256);
- function transfer(address _to, uint256 _value) public returns (bool);
- event Transfer(address indexed from, address indexed to, uint256 value);
-}
diff --git a/bridge/contracts/zeppelin/token/ERC20/ERC20Detailed.sol b/bridge/contracts/zeppelin/token/ERC20/ERC20Detailed.sol
new file mode 100644
index 000000000..4f3781d25
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC20/ERC20Detailed.sol
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "./IERC20.sol";
+
+/**
+ * @dev Optional functions from the ERC20 standard.
+ */
+abstract contract ERC20Detailed is IERC20 {
+ string private _name;
+ string private _symbol;
+ uint8 private _decimals;
+
+ /**
+ * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of
+ * these values are immutable: they can only be set once during
+ * construction.
+ */
+ constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {
+ _name = aName;
+ _symbol = aSymbol;
+ _decimals = theDecimals;
+ }
+
+ /**
+ * @dev Returns the name of the token.
+ */
+ function name() public view returns (string memory) {
+ return _name;
+ }
+
+ /**
+ * @dev Returns the symbol of the token, usually a shorter version of the
+ * name.
+ */
+ function symbol() public view returns (string memory) {
+ return _symbol;
+ }
+
+ /**
+ * @dev Returns the number of decimals used to get its user representation.
+ * For example, if `decimals` equals `2`, a balance of `505` tokens should
+ * be displayed to a user as `5,05` (`505 / 10 ** 2`).
+ *
+ * Tokens usually opt for a value of 18, imitating the relationship between
+ * Ether and Wei.
+ *
+ * NOTE: This information is only used for _display_ purposes: it in
+ * no way affects any of the arithmetic of the contract, including
+ * {IERC20-balanceOf} and {IERC20-transfer}.
+ */
+ function decimals() public view returns (uint8) {
+ return _decimals;
+ }
+}
diff --git a/bridge/contracts/zeppelin/token/ERC20/IERC20.sol b/bridge/contracts/zeppelin/token/ERC20/IERC20.sol
new file mode 100644
index 000000000..2026fedb4
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC20/IERC20.sol
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
+ * the optional functions; to access them see {ERC20Detailed}.
+ */
+interface IERC20 {
+ /**
+ * @dev Returns the amount of tokens in existence.
+ */
+ function totalSupply() external view returns (uint256);
+
+ /**
+ * @dev Returns the amount of tokens owned by `account`.
+ */
+ function balanceOf(address account) external view returns (uint256);
+
+ /**
+ * @dev Moves `amount` tokens from the caller's account to `recipient`.
+ *
+ * Returns a boolean value indicating whether the operation succeeded.
+ *
+ * Emits a {Transfer} event.
+ */
+ function transfer(address recipient, uint256 amount) external returns (bool);
+
+ /**
+ * @dev Returns the remaining number of tokens that `spender` will be
+ * allowed to spend on behalf of `owner` through {transferFrom}. This is
+ * zero by default.
+ *
+ * This value changes when {approve} or {transferFrom} are called.
+ */
+ function allowance(address owner, address spender) external view returns (uint256);
+
+ /**
+ * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
+ *
+ * Returns a boolean value indicating whether the operation succeeded.
+ *
+ * IMPORTANT: Beware that changing an allowance with this method brings the risk
+ * that someone may use both the old and the new allowance by unfortunate
+ * transaction ordering. One possible solution to mitigate this race
+ * condition is to first reduce the spender's allowance to 0 and set the
+ * desired value afterwards:
+ * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
+ *
+ * Emits an {Approval} event.
+ */
+ function approve(address spender, uint256 amount) external returns (bool);
+
+ /**
+ * @dev Moves `amount` tokens from `sender` to `recipient` using the
+ * allowance mechanism. `amount` is then deducted from the caller's
+ * allowance.
+ *
+ * Returns a boolean value indicating whether the operation succeeded.
+ *
+ * Emits a {Transfer} event.
+ */
+ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
+
+ /**
+ * @dev Emitted when `value` tokens are moved from one account (`from`) to
+ * another (`to`).
+ *
+ * Note that `value` may be zero.
+ */
+ event Transfer(address indexed from, address indexed to, uint256 value);
+
+ /**
+ * @dev Emitted when the allowance of a `spender` for an `owner` is set by
+ * a call to {approve}. `value` is the new allowance.
+ */
+ event Approval(address indexed owner, address indexed spender, uint256 value);
+}
diff --git a/bridge/contracts/zeppelin/token/ERC20/MintableToken.sol b/bridge/contracts/zeppelin/token/ERC20/MintableToken.sol
deleted file mode 100644
index 1821058ff..000000000
--- a/bridge/contracts/zeppelin/token/ERC20/MintableToken.sol
+++ /dev/null
@@ -1,60 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "./StandardToken.sol";
-import "../../ownership/Ownable.sol";
-
-
-/**
- * @title Mintable token
- * @dev Simple ERC20 Token example, with mintable token creation
- * Based on code by TokenMarketNet: https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol
- */
-contract MintableToken is StandardToken, Ownable {
- event Mint(address indexed to, uint256 amount);
- event MintFinished();
-
- bool public mintingFinished = false;
-
-
- modifier canMint() {
- require(!mintingFinished);
- _;
- }
-
- modifier hasMintPermission() {
- require(msg.sender == owner);
- _;
- }
-
- /**
- * @dev Function to mint tokens
- * @param _to The address that will receive the minted tokens.
- * @param _amount The amount of tokens to mint.
- * @return A boolean that indicates if the operation was successful.
- */
- function mint(
- address _to,
- uint256 _amount
- )
- public
- hasMintPermission
- canMint
- returns (bool)
- {
- totalSupply_ = totalSupply_.add(_amount);
- balances[_to] = balances[_to].add(_amount);
- emit Mint(_to, _amount);
- emit Transfer(address(0), _to, _amount);
- return true;
- }
-
- /**
- * @dev Function to stop minting new tokens.
- * @return True if the operation was successful.
- */
- function finishMinting() public onlyOwner canMint returns (bool) {
- mintingFinished = true;
- emit MintFinished();
- return true;
- }
-}
diff --git a/bridge/contracts/zeppelin/token/ERC20/README.md b/bridge/contracts/zeppelin/token/ERC20/README.md
new file mode 100644
index 000000000..8ad614cbc
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC20/README.md
@@ -0,0 +1,35 @@
+---
+sections:
+ - title: Core
+ contracts:
+ - IERC20
+ - ERC20
+ - ERC20Detailed
+ - title: Extensions
+ contracts:
+ - ERC20Mintable
+ - ERC20Burnable
+ - ERC20Pausable
+ - ERC20Capped
+ - title: Utilities
+ contracts:
+ - SafeERC20
+ - TokenTimelock
+---
+
+This set of interfaces, contracts, and utilities are all related to the [ERC20 Token Standard](https://eips.ethereum.org/EIPS/eip-20).
+
+*For a walkthrough on how to create an ERC20 token read our [ERC20 guide](../../tokens.md#constructing-a-nice-erc20-token).*
+
+There a few core contracts that implement the behavior specified in the EIP: `IERC20`, `ERC20`, `ERC20Detailed`.
+
+Additionally there are multiple extensions, including:
+- designation of addresses that can create token supply (`ERC20Mintable`), with an optional maximum cap (`ERC20Capped`),
+- destruction of own tokens (`ERC20Burnable`),
+- designation of addresses that can pause token operations for all users (`ERC20Pausable`).
+
+Finally, there are some utilities to interact with ERC20 contracts in various ways.
+- `SafeERC20` is a wrapper around the interface that eliminates the need to handle boolean return values.
+- `TokenTimelock` can hold tokens for a beneficiary until a specified time.
+
+> This page is incomplete. We're working to improve it for the next release. Stay tuned!
diff --git a/bridge/contracts/zeppelin/token/ERC20/SafeERC20.sol b/bridge/contracts/zeppelin/token/ERC20/SafeERC20.sol
index 206d19f74..19fe473fd 100644
--- a/bridge/contracts/zeppelin/token/ERC20/SafeERC20.sol
+++ b/bridge/contracts/zeppelin/token/ERC20/SafeERC20.sol
@@ -1,44 +1,78 @@
-pragma solidity ^0.4.24;
+// SPDX-License-Identifier: MIT
-import "./ERC20Basic.sol";
-import "./ERC20.sol";
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+import "./IERC20.sol";
+import "../../math/SafeMath.sol";
+import "../../utils/Address.sol";
/**
* @title SafeERC20
- * @dev Wrappers around ERC20 operations that throw on failure.
+ * @dev Wrappers around ERC20 operations that throw on failure (when the token
+ * contract returns false). Tokens that return no value (and instead revert or
+ * throw on failure) are also supported, non-reverting calls are assumed to be
+ * successful.
* To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
- function safeTransfer(
- ERC20Basic _token,
- address _to,
- uint256 _value
- )
- internal
- {
- require(_token.transfer(_to, _value));
- }
-
- function safeTransferFrom(
- ERC20 _token,
- address _from,
- address _to,
- uint256 _value
- )
- internal
- {
- require(_token.transferFrom(_from, _to, _value));
- }
-
- function safeApprove(
- ERC20 _token,
- address _spender,
- uint256 _value
- )
- internal
- {
- require(_token.approve(_spender, _value));
- }
+ using SafeMath for uint256;
+ using Address for address;
+
+ function safeTransfer(IERC20 token, address to, uint256 value) internal {
+ callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
+ }
+
+ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
+ callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
+ }
+
+ function safeApprove(IERC20 token, address spender, uint256 value) internal {
+ // safeApprove should only be called when setting an initial allowance,
+ // or when resetting it to zero. To increase and decrease it, use
+ // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
+ // solhint-disable-next-line max-line-length
+ require((value == 0) || (token.allowance(address(this), spender) == 0),
+ "SafeERC20: approve non-zero to non-zero allowance"
+ );
+ callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
+ }
+
+ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
+ uint256 newAllowance = token.allowance(address(this), spender).add(value);
+ callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
+ }
+
+ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
+ uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
+ callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
+ }
+
+ /**
+ * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
+ * on the return value: the return value is optional (but if data is returned, it must not be false).
+ * @param token The token targeted by the call.
+ * @param data The call data (encoded using abi.encode or one of its variants).
+ */
+ function callOptionalReturn(IERC20 token, bytes memory data) private {
+ // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
+ // we're implementing it ourselves.
+
+ // A Solidity high level call has three parts:
+ // 1. The target address is checked to verify it contains contract code
+ // 2. The call itself is made, and success asserted
+ // 3. The return value is decoded, which in turn checks the size of the returned data.
+ // solhint-disable-next-line max-line-length
+ require(address(token).isContract(), "SafeERC20: call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = address(token).call(data);
+ require(success, "SafeERC20: low-level call failed");
+
+ if (returndata.length > 0) { // Return data is optional
+ // solhint-disable-next-line max-line-length
+ require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
+ }
+ }
}
diff --git a/bridge/contracts/zeppelin/token/ERC20/StandardToken.sol b/bridge/contracts/zeppelin/token/ERC20/StandardToken.sol
deleted file mode 100644
index ff09e12ea..000000000
--- a/bridge/contracts/zeppelin/token/ERC20/StandardToken.sol
+++ /dev/null
@@ -1,124 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "./BasicToken.sol";
-import "./ERC20.sol";
-
-
-/**
- * @title Standard ERC20 token
- *
- * @dev Implementation of the basic standard token.
- * https://github.com/ethereum/EIPs/issues/20
- * Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
- */
-contract StandardToken is ERC20, BasicToken {
-
- mapping (address => mapping (address => uint256)) internal allowed;
-
-
- /**
- * @dev Transfer tokens from one address to another
- * @param _from address The address which you want to send tokens from
- * @param _to address The address which you want to transfer to
- * @param _value uint256 the amount of tokens to be transferred
- */
- function transferFrom(
- address _from,
- address _to,
- uint256 _value
- )
- public
- returns (bool)
- {
- require(_value <= balances[_from]);
- require(_value <= allowed[_from][msg.sender]);
- require(_to != address(0));
-
- balances[_from] = balances[_from].sub(_value);
- balances[_to] = balances[_to].add(_value);
- allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
- emit Transfer(_from, _to, _value);
- return true;
- }
-
- /**
- * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
- * Beware that changing an allowance with this method brings the risk that someone may use both the old
- * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
- * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
- * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
- * @param _spender The address which will spend the funds.
- * @param _value The amount of tokens to be spent.
- */
- function approve(address _spender, uint256 _value) public returns (bool) {
- allowed[msg.sender][_spender] = _value;
- emit Approval(msg.sender, _spender, _value);
- return true;
- }
-
- /**
- * @dev Function to check the amount of tokens that an owner allowed to a spender.
- * @param _owner address The address which owns the funds.
- * @param _spender address The address which will spend the funds.
- * @return A uint256 specifying the amount of tokens still available for the spender.
- */
- function allowance(
- address _owner,
- address _spender
- )
- public
- view
- returns (uint256)
- {
- return allowed[_owner][_spender];
- }
-
- /**
- * @dev Increase the amount of tokens that an owner allowed to a spender.
- * approve should be called when allowed[_spender] == 0. To increment
- * allowed value is better to use this function to avoid 2 calls (and wait until
- * the first transaction is mined)
- * From MonolithDAO Token.sol
- * @param _spender The address which will spend the funds.
- * @param _addedValue The amount of tokens to increase the allowance by.
- */
- function increaseApproval(
- address _spender,
- uint256 _addedValue
- )
- public
- returns (bool)
- {
- allowed[msg.sender][_spender] = (
- allowed[msg.sender][_spender].add(_addedValue));
- emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
- return true;
- }
-
- /**
- * @dev Decrease the amount of tokens that an owner allowed to a spender.
- * approve should be called when allowed[_spender] == 0. To decrement
- * allowed value is better to use this function to avoid 2 calls (and wait until
- * the first transaction is mined)
- * From MonolithDAO Token.sol
- * @param _spender The address which will spend the funds.
- * @param _subtractedValue The amount of tokens to decrease the allowance by.
- */
- function decreaseApproval(
- address _spender,
- uint256 _subtractedValue
- )
- public
- returns (bool)
- {
- uint256 oldValue = allowed[msg.sender][_spender];
- if (_subtractedValue >= oldValue) {
- allowed[msg.sender][_spender] = 0;
- } else {
- allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
- }
- emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
- return true;
- }
-
-}
diff --git a/bridge/contracts/zeppelin/token/ERC20/TokenVesting.sol b/bridge/contracts/zeppelin/token/ERC20/TokenVesting.sol
deleted file mode 100644
index 66a917558..000000000
--- a/bridge/contracts/zeppelin/token/ERC20/TokenVesting.sol
+++ /dev/null
@@ -1,126 +0,0 @@
-/* solium-disable security/no-block-members */
-
-pragma solidity ^0.4.24;
-
-import "./ERC20Basic.sol";
-import "./SafeERC20.sol";
-import "../../ownership/Ownable.sol";
-import "../../math/SafeMath.sol";
-
-
-/**
- * @title TokenVesting
- * @dev A token holder contract that can release its token balance gradually like a
- * typical vesting scheme, with a cliff and vesting period. Optionally revocable by the
- * owner.
- */
-contract TokenVesting is Ownable {
- using SafeMath for uint256;
- using SafeERC20 for ERC20Basic;
-
- event Released(uint256 amount);
- event Revoked();
-
- // beneficiary of tokens after they are released
- address public beneficiary;
-
- uint256 public cliff;
- uint256 public start;
- uint256 public duration;
-
- bool public revocable;
-
- mapping (address => uint256) public released;
- mapping (address => bool) public revoked;
-
- /**
- * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
- * _beneficiary, gradually in a linear fashion until _start + _duration. By then all
- * of the balance will have vested.
- * @param _beneficiary address of the beneficiary to whom vested tokens are transferred
- * @param _cliff duration in seconds of the cliff in which tokens will begin to vest
- * @param _start the time (as Unix time) at which point vesting starts
- * @param _duration duration in seconds of the period in which the tokens will vest
- * @param _revocable whether the vesting is revocable or not
- */
- constructor(
- address _beneficiary,
- uint256 _start,
- uint256 _cliff,
- uint256 _duration,
- bool _revocable
- )
- public
- {
- require(_beneficiary != address(0));
- require(_cliff <= _duration);
-
- beneficiary = _beneficiary;
- revocable = _revocable;
- duration = _duration;
- cliff = _start.add(_cliff);
- start = _start;
- }
-
- /**
- * @notice Transfers vested tokens to beneficiary.
- * @param _token ERC20 token which is being vested
- */
- function release(ERC20Basic _token) public {
- uint256 unreleased = releasableAmount(_token);
-
- require(unreleased > 0);
-
- released[_token] = released[_token].add(unreleased);
-
- _token.safeTransfer(beneficiary, unreleased);
-
- emit Released(unreleased);
- }
-
- /**
- * @notice Allows the owner to revoke the vesting. Tokens already vested
- * remain in the contract, the rest are returned to the owner.
- * @param _token ERC20 token which is being vested
- */
- function revoke(ERC20Basic _token) public onlyOwner {
- require(revocable);
- require(!revoked[_token]);
-
- uint256 balance = _token.balanceOf(address(this));
-
- uint256 unreleased = releasableAmount(_token);
- uint256 refund = balance.sub(unreleased);
-
- revoked[_token] = true;
-
- _token.safeTransfer(owner, refund);
-
- emit Revoked();
- }
-
- /**
- * @dev Calculates the amount that has already vested but hasn't been released yet.
- * @param _token ERC20 token which is being vested
- */
- function releasableAmount(ERC20Basic _token) public view returns (uint256) {
- return vestedAmount(_token).sub(released[_token]);
- }
-
- /**
- * @dev Calculates the amount that has already vested.
- * @param _token ERC20 token which is being vested
- */
- function vestedAmount(ERC20Basic _token) public view returns (uint256) {
- uint256 currentBalance = _token.balanceOf(address(this));
- uint256 totalBalance = currentBalance.add(released[_token]);
-
- if (block.timestamp < cliff) {
- return 0;
- } else if (block.timestamp >= start.add(duration) || revoked[_token]) {
- return totalBalance;
- } else {
- return totalBalance.mul(block.timestamp.sub(start)).div(duration);
- }
- }
-}
diff --git a/bridge/contracts/zeppelin/token/ERC721/ERC721.sol b/bridge/contracts/zeppelin/token/ERC721/ERC721.sol
new file mode 100644
index 000000000..13d031fb7
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC721/ERC721.sol
@@ -0,0 +1,473 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../../GSN/Context.sol";
+import "./IERC721.sol";
+import "./IERC721Metadata.sol";
+import "./IERC721Enumerable.sol";
+import "./IERC721Receiver.sol";
+import "../../introspection/ERC165.sol";
+import "../../math/SafeMath.sol";
+import "../../utils/Address.sol";
+import "../../utils/EnumerableSet.sol";
+import "../../utils/EnumerableMap.sol";
+import "../../utils/Strings.sol";
+
+/**
+ * @title ERC721 Non-Fungible Token Standard basic implementation
+ * @dev see https://eips.ethereum.org/EIPS/eip-721
+ */
+contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {
+ using SafeMath for uint256;
+ using Address for address;
+ using EnumerableSet for EnumerableSet.UintSet;
+ using EnumerableMap for EnumerableMap.UintToAddressMap;
+ using Strings for uint256;
+
+ // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
+ // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
+ bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
+
+ // Mapping from holder address to their (enumerable) set of owned tokens
+ mapping (address => EnumerableSet.UintSet) private _holderTokens;
+
+ // Enumerable mapping from token ids to their owners
+ EnumerableMap.UintToAddressMap private _tokenOwners;
+
+ // Mapping from token ID to approved address
+ mapping (uint256 => address) private _tokenApprovals;
+
+ // Mapping from owner to operator approvals
+ mapping (address => mapping (address => bool)) private _operatorApprovals;
+
+ // Token name
+ string private _name;
+
+ // Token symbol
+ string private _symbol;
+
+ // Optional mapping for token URIs
+ mapping (uint256 => string) private _tokenURIs;
+
+ // Base URI
+ string private _baseURI;
+
+ /*
+ * bytes4(keccak256('balanceOf(address)')) == 0x70a08231
+ * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
+ * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
+ * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
+ * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
+ * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
+ * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
+ * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
+ * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
+ *
+ * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
+ * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
+ */
+ bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
+
+ /*
+ * bytes4(keccak256('name()')) == 0x06fdde03
+ * bytes4(keccak256('symbol()')) == 0x95d89b41
+ * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
+ *
+ * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
+ */
+ bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
+
+ /*
+ * bytes4(keccak256('totalSupply()')) == 0x18160ddd
+ * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
+ * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
+ *
+ * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
+ */
+ bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;
+
+ /**
+ * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
+ */
+ constructor (string memory name_, string memory symbol_) {
+ _name = name_;
+ _symbol = symbol_;
+
+ // register the supported interfaces to conform to ERC721 via ERC165
+ _registerInterface(_INTERFACE_ID_ERC721);
+ _registerInterface(_INTERFACE_ID_ERC721_METADATA);
+ _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
+ }
+
+ /**
+ * @dev See {IERC721-balanceOf}.
+ */
+ function balanceOf(address owner) public view virtual override returns (uint256) {
+ require(owner != address(0), "ERC721: balance query for the zero address");
+ return _holderTokens[owner].length();
+ }
+
+ /**
+ * @dev See {IERC721-ownerOf}.
+ */
+ function ownerOf(uint256 tokenId) public view virtual override returns (address) {
+ return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token");
+ }
+
+ /**
+ * @dev See {IERC721Metadata-name}.
+ */
+ function name() public view virtual override returns (string memory) {
+ return _name;
+ }
+
+ /**
+ * @dev See {IERC721Metadata-symbol}.
+ */
+ function symbol() public view virtual override returns (string memory) {
+ return _symbol;
+ }
+
+ /**
+ * @dev See {IERC721Metadata-tokenURI}.
+ */
+ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
+ require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
+
+ string memory _tokenURI = _tokenURIs[tokenId];
+ string memory base = baseURI();
+
+ // If there is no base URI, return the token URI.
+ if (bytes(base).length == 0) {
+ return _tokenURI;
+ }
+ // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
+ if (bytes(_tokenURI).length > 0) {
+ return string(abi.encodePacked(base, _tokenURI));
+ }
+ // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
+ return string(abi.encodePacked(base, tokenId.toString()));
+ }
+
+ /**
+ * @dev Returns the base URI set via {_setBaseURI}. This will be
+ * automatically added as a prefix in {tokenURI} to each token's URI, or
+ * to the token ID if no specific URI is set for that token ID.
+ */
+ function baseURI() public view virtual returns (string memory) {
+ return _baseURI;
+ }
+
+ /**
+ * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
+ */
+ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
+ return _holderTokens[owner].at(index);
+ }
+
+ /**
+ * @dev See {IERC721Enumerable-totalSupply}.
+ */
+ function totalSupply() public view virtual override returns (uint256) {
+ // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds
+ return _tokenOwners.length();
+ }
+
+ /**
+ * @dev See {IERC721Enumerable-tokenByIndex}.
+ */
+ function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
+ (uint256 tokenId, ) = _tokenOwners.at(index);
+ return tokenId;
+ }
+
+ /**
+ * @dev See {IERC721-approve}.
+ */
+ function approve(address to, uint256 tokenId) public virtual override {
+ address owner = ERC721.ownerOf(tokenId);
+ require(to != owner, "ERC721: approval to current owner");
+
+ require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),
+ "ERC721: approve caller is not owner nor approved for all"
+ );
+
+ _approve(to, tokenId);
+ }
+
+ /**
+ * @dev See {IERC721-getApproved}.
+ */
+ function getApproved(uint256 tokenId) public view virtual override returns (address) {
+ require(_exists(tokenId), "ERC721: approved query for nonexistent token");
+
+ return _tokenApprovals[tokenId];
+ }
+
+ /**
+ * @dev See {IERC721-setApprovalForAll}.
+ */
+ function setApprovalForAll(address operator, bool approved) public virtual override {
+ require(operator != _msgSender(), "ERC721: approve to caller");
+
+ _operatorApprovals[_msgSender()][operator] = approved;
+ emit ApprovalForAll(_msgSender(), operator, approved);
+ }
+
+ /**
+ * @dev See {IERC721-isApprovedForAll}.
+ */
+ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
+ return _operatorApprovals[owner][operator];
+ }
+
+ /**
+ * @dev See {IERC721-transferFrom}.
+ */
+ function transferFrom(address from, address to, uint256 tokenId) public virtual override {
+ //solhint-disable-next-line max-line-length
+ require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
+
+ _transfer(from, to, tokenId);
+ }
+
+ /**
+ * @dev See {IERC721-safeTransferFrom}.
+ */
+ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
+ safeTransferFrom(from, to, tokenId, "");
+ }
+
+ /**
+ * @dev See {IERC721-safeTransferFrom}.
+ */
+ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
+ require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
+ _safeTransfer(from, to, tokenId, _data);
+ }
+
+ /**
+ * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
+ * are aware of the ERC721 protocol to prevent tokens from being forever locked.
+ *
+ * `_data` is additional data, it has no specified format and it is sent in call to `to`.
+ *
+ * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
+ * implement alternative mechanisms to perform token transfer, such as signature-based.
+ *
+ * Requirements:
+ *
+ * - `from` cannot be the zero address.
+ * - `to` cannot be the zero address.
+ * - `tokenId` token must exist and be owned by `from`.
+ * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
+ *
+ * Emits a {Transfer} event.
+ */
+ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
+ _transfer(from, to, tokenId);
+ require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
+ }
+
+ /**
+ * @dev Returns whether `tokenId` exists.
+ *
+ * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
+ *
+ * Tokens start existing when they are minted (`_mint`),
+ * and stop existing when they are burned (`_burn`).
+ */
+ function _exists(uint256 tokenId) internal view virtual returns (bool) {
+ return _tokenOwners.contains(tokenId);
+ }
+
+ /**
+ * @dev Returns whether `spender` is allowed to manage `tokenId`.
+ *
+ * Requirements:
+ *
+ * - `tokenId` must exist.
+ */
+ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
+ require(_exists(tokenId), "ERC721: operator query for nonexistent token");
+ address owner = ERC721.ownerOf(tokenId);
+ return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));
+ }
+
+ /**
+ * @dev Safely mints `tokenId` and transfers it to `to`.
+ *
+ * Requirements:
+ d*
+ * - `tokenId` must not exist.
+ * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
+ *
+ * Emits a {Transfer} event.
+ */
+ function _safeMint(address to, uint256 tokenId) internal virtual {
+ _safeMint(to, tokenId, "");
+ }
+
+ /**
+ * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
+ * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
+ */
+ function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
+ _mint(to, tokenId);
+ require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
+ }
+
+ /**
+ * @dev Mints `tokenId` and transfers it to `to`.
+ *
+ * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
+ *
+ * Requirements:
+ *
+ * - `tokenId` must not exist.
+ * - `to` cannot be the zero address.
+ *
+ * Emits a {Transfer} event.
+ */
+ function _mint(address to, uint256 tokenId) internal virtual {
+ require(to != address(0), "ERC721: mint to the zero address");
+ require(!_exists(tokenId), "ERC721: token already minted");
+
+ _beforeTokenTransfer(address(0), to, tokenId);
+
+ _holderTokens[to].add(tokenId);
+
+ _tokenOwners.set(tokenId, to);
+
+ emit Transfer(address(0), to, tokenId);
+ }
+
+ /**
+ * @dev Destroys `tokenId`.
+ * The approval is cleared when the token is burned.
+ *
+ * Requirements:
+ *
+ * - `tokenId` must exist.
+ *
+ * Emits a {Transfer} event.
+ */
+ function _burn(uint256 tokenId) internal virtual {
+ address owner = ERC721.ownerOf(tokenId); // internal owner
+
+ _beforeTokenTransfer(owner, address(0), tokenId);
+
+ // Clear approvals
+ _approve(address(0), tokenId);
+
+ // Clear metadata (if any)
+ if (bytes(_tokenURIs[tokenId]).length != 0) {
+ delete _tokenURIs[tokenId];
+ }
+
+ _holderTokens[owner].remove(tokenId);
+
+ _tokenOwners.remove(tokenId);
+
+ emit Transfer(owner, address(0), tokenId);
+ }
+
+ /**
+ * @dev Transfers `tokenId` from `from` to `to`.
+ * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
+ *
+ * Requirements:
+ *
+ * - `to` cannot be the zero address.
+ * - `tokenId` token must be owned by `from`.
+ *
+ * Emits a {Transfer} event.
+ */
+ function _transfer(address from, address to, uint256 tokenId) internal virtual {
+ require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); // internal owner
+ require(to != address(0), "ERC721: transfer to the zero address");
+
+ _beforeTokenTransfer(from, to, tokenId);
+
+ // Clear approvals from the previous owner
+ _approve(address(0), tokenId);
+
+ _holderTokens[from].remove(tokenId);
+ _holderTokens[to].add(tokenId);
+
+ _tokenOwners.set(tokenId, to);
+
+ emit Transfer(from, to, tokenId);
+ }
+
+ /**
+ * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
+ *
+ * Requirements:
+ *
+ * - `tokenId` must exist.
+ */
+ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
+ require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
+ _tokenURIs[tokenId] = _tokenURI;
+ }
+
+ /**
+ * @dev Internal function to set the base URI for all token IDs. It is
+ * automatically added as a prefix to the value returned in {tokenURI},
+ * or to the token ID if {tokenURI} is empty.
+ */
+ function _setBaseURI(string memory baseURI_) internal virtual {
+ _baseURI = baseURI_;
+ }
+
+ /**
+ * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
+ * The call is not executed if the target address is not a contract.
+ *
+ * @param from address representing the previous owner of the given token ID
+ * @param to target address that will receive the tokens
+ * @param tokenId uint256 ID of the token to be transferred
+ * @param _data bytes optional data to send along with the call
+ * @return bool whether the call correctly returned the expected magic value
+ */
+ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
+ private returns (bool)
+ {
+ if (!to.isContract()) {
+ return true;
+ }
+ bytes memory returndata = to.functionCall(abi.encodeWithSelector(
+ IERC721Receiver(to).onERC721Received.selector,
+ _msgSender(),
+ from,
+ tokenId,
+ _data
+ ), "ERC721: transfer to non ERC721Receiver implementer");
+ bytes4 retval = abi.decode(returndata, (bytes4));
+ return (retval == _ERC721_RECEIVED);
+ }
+
+ function _approve(address to, uint256 tokenId) private {
+ _tokenApprovals[tokenId] = to;
+ emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner
+ }
+
+ /**
+ * @dev Hook that is called before any token transfer. This includes minting
+ * and burning.
+ *
+ * Calling conditions:
+ *
+ * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
+ * transferred to `to`.
+ * - When `from` is zero, `tokenId` will be minted for `to`.
+ * - When `to` is zero, ``from``'s `tokenId` will be burned.
+ * - `from` cannot be the zero address.
+ * - `to` cannot be the zero address.
+ *
+ * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
+ */
+ function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }
+}
diff --git a/bridge/contracts/zeppelin/token/ERC721/ERC721Burnable.sol b/bridge/contracts/zeppelin/token/ERC721/ERC721Burnable.sol
new file mode 100644
index 000000000..c9fa8c872
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC721/ERC721Burnable.sol
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../../GSN/Context.sol";
+import "./ERC721.sol";
+
+/**
+ * @title ERC721 Burnable Token
+ * @dev ERC721 Token that can be irreversibly burned (destroyed).
+ */
+abstract contract ERC721Burnable is Context, ERC721 {
+ /**
+ * @dev Burns `tokenId`. See {ERC721-_burn}.
+ *
+ * Requirements:
+ *
+ * - The caller must own `tokenId` or be an approved operator.
+ */
+ function burn(uint256 tokenId) public virtual {
+ //solhint-disable-next-line max-line-length
+ require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
+ _burn(tokenId);
+ }
+}
diff --git a/bridge/contracts/zeppelin/token/ERC721/ERC721Holder.sol b/bridge/contracts/zeppelin/token/ERC721/ERC721Holder.sol
new file mode 100644
index 000000000..6e4858a6b
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC721/ERC721Holder.sol
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "./IERC721Receiver.sol";
+
+ /**
+ * @dev Implementation of the {IERC721Receiver} interface.
+ *
+ * Accepts all token transfers.
+ * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.
+ */
+contract ERC721Holder is IERC721Receiver {
+
+ /**
+ * @dev See {IERC721Receiver-onERC721Received}.
+ *
+ * Always returns `IERC721Receiver.onERC721Received.selector`.
+ */
+ function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {
+ return this.onERC721Received.selector;
+ }
+}
diff --git a/bridge/contracts/zeppelin/token/ERC721/ERC721Pausable.sol b/bridge/contracts/zeppelin/token/ERC721/ERC721Pausable.sol
new file mode 100644
index 000000000..f18585674
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC721/ERC721Pausable.sol
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "./ERC721.sol";
+import "../../lifecycle/Pausable.sol";
+
+/**
+ * @dev ERC721 token with pausable token transfers, minting and burning.
+ *
+ * Useful for scenarios such as preventing trades until the end of an evaluation
+ * period, or having an emergency switch for freezing all token transfers in the
+ * event of a large bug.
+ */
+abstract contract ERC721Pausable is ERC721, Pausable {
+ /**
+ * @dev See {ERC721-_beforeTokenTransfer}.
+ *
+ * Requirements:
+ *
+ * - the contract must not be paused.
+ */
+ function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {
+ super._beforeTokenTransfer(from, to, tokenId);
+
+ require(!paused(), "ERC721Pausable: token transfer while paused");
+ }
+}
diff --git a/bridge/contracts/zeppelin/token/ERC721/IERC721.sol b/bridge/contracts/zeppelin/token/ERC721/IERC721.sol
new file mode 100644
index 000000000..4afa6dc52
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC721/IERC721.sol
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "../../introspection/IERC165.sol";
+
+/**
+ * @dev Required interface of an ERC721 compliant contract.
+ */
+interface IERC721 is IERC165 {
+ /**
+ * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
+ */
+ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
+
+ /**
+ * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
+ */
+ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
+
+ /**
+ * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
+ */
+ event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
+
+ /**
+ * @dev Returns the number of tokens in ``owner``'s account.
+ */
+ function balanceOf(address owner) external view returns (uint256 balance);
+
+ /**
+ * @dev Returns the owner of the `tokenId` token.
+ *
+ * Requirements:
+ *
+ * - `tokenId` must exist.
+ */
+ function ownerOf(uint256 tokenId) external view returns (address owner);
+
+ /**
+ * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
+ * are aware of the ERC721 protocol to prevent tokens from being forever locked.
+ *
+ * Requirements:
+ *
+ * - `from` cannot be the zero address.
+ * - `to` cannot be the zero address.
+ * - `tokenId` token must exist and be owned by `from`.
+ * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
+ * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
+ *
+ * Emits a {Transfer} event.
+ */
+ function safeTransferFrom(address from, address to, uint256 tokenId) external;
+
+ /**
+ * @dev Transfers `tokenId` token from `from` to `to`.
+ *
+ * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
+ *
+ * Requirements:
+ *
+ * - `from` cannot be the zero address.
+ * - `to` cannot be the zero address.
+ * - `tokenId` token must be owned by `from`.
+ * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
+ *
+ * Emits a {Transfer} event.
+ */
+ function transferFrom(address from, address to, uint256 tokenId) external;
+
+ /**
+ * @dev Gives permission to `to` to transfer `tokenId` token to another account.
+ * The approval is cleared when the token is transferred.
+ *
+ * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
+ *
+ * Requirements:
+ *
+ * - The caller must own the token or be an approved operator.
+ * - `tokenId` must exist.
+ *
+ * Emits an {Approval} event.
+ */
+ function approve(address to, uint256 tokenId) external;
+
+ /**
+ * @dev Returns the account approved for `tokenId` token.
+ *
+ * Requirements:
+ *
+ * - `tokenId` must exist.
+ */
+ function getApproved(uint256 tokenId) external view returns (address operator);
+
+ /**
+ * @dev Approve or remove `operator` as an operator for the caller.
+ * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
+ *
+ * Requirements:
+ *
+ * - The `operator` cannot be the caller.
+ *
+ * Emits an {ApprovalForAll} event.
+ */
+ function setApprovalForAll(address operator, bool _approved) external;
+
+ /**
+ * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
+ *
+ * See {setApprovalForAll}
+ */
+ function isApprovedForAll(address owner, address operator) external view returns (bool);
+
+ /**
+ * @dev Safely transfers `tokenId` token from `from` to `to`.
+ *
+ * Requirements:
+ *
+ * - `from` cannot be the zero address.
+ * - `to` cannot be the zero address.
+ * - `tokenId` token must exist and be owned by `from`.
+ * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
+ * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
+ *
+ * Emits a {Transfer} event.
+ */
+ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
+}
diff --git a/bridge/contracts/zeppelin/token/ERC721/IERC721Enumerable.sol b/bridge/contracts/zeppelin/token/ERC721/IERC721Enumerable.sol
new file mode 100644
index 000000000..2cb478965
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC721/IERC721Enumerable.sol
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "./IERC721.sol";
+
+/**
+ * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
+ * @dev See https://eips.ethereum.org/EIPS/eip-721
+ */
+interface IERC721Enumerable is IERC721 {
+
+ /**
+ * @dev Returns the total amount of tokens stored by the contract.
+ */
+ function totalSupply() external view returns (uint256);
+
+ /**
+ * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
+ * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
+ */
+ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);
+
+ /**
+ * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
+ * Use along with {totalSupply} to enumerate all tokens.
+ */
+ function tokenByIndex(uint256 index) external view returns (uint256);
+}
diff --git a/bridge/contracts/zeppelin/token/ERC721/IERC721Metadata.sol b/bridge/contracts/zeppelin/token/ERC721/IERC721Metadata.sol
new file mode 100644
index 000000000..24f02f838
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC721/IERC721Metadata.sol
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+import "./IERC721.sol";
+
+/**
+ * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
+ * @dev See https://eips.ethereum.org/EIPS/eip-721
+ */
+interface IERC721Metadata is IERC721 {
+
+ /**
+ * @dev Returns the token collection name.
+ */
+ function name() external view returns (string memory);
+
+ /**
+ * @dev Returns the token collection symbol.
+ */
+ function symbol() external view returns (string memory);
+
+ /**
+ * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
+ */
+ function tokenURI(uint256 tokenId) external view returns (string memory);
+}
diff --git a/bridge/contracts/zeppelin/token/ERC721/IERC721Receiver.sol b/bridge/contracts/zeppelin/token/ERC721/IERC721Receiver.sol
new file mode 100644
index 000000000..081f4ab8d
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC721/IERC721Receiver.sol
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+/**
+ * @title ERC721 token receiver interface
+ * @dev Interface for any contract that wants to support safeTransfers
+ * from ERC721 asset contracts.
+ */
+interface IERC721Receiver {
+ /**
+ * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
+ * by `operator` from `from`, this function is called.
+ *
+ * It must return its Solidity selector to confirm the token transfer.
+ * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
+ *
+ * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
+ */
+ function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
+}
diff --git a/bridge/contracts/zeppelin/token/ERC721/README.adoc b/bridge/contracts/zeppelin/token/ERC721/README.adoc
new file mode 100644
index 000000000..5f584eee1
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC721/README.adoc
@@ -0,0 +1,42 @@
+= ERC 721
+
+[.readme-notice]
+NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc721
+
+This set of interfaces, contracts, and utilities are all related to the https://eips.ethereum.org/EIPS/eip-721[ERC721 Non-Fungible Token Standard].
+
+TIP: For a walk through on how to create an ERC721 token read our xref:ROOT:erc721.adoc[ERC721 guide].
+
+The EIP consists of three interfaces, found here as {IERC721}, {IERC721Metadata}, and {IERC721Enumerable}. Only the first one is required in a contract to be ERC721 compliant. However, all three are implemented in {ERC721}.
+
+Additionally, {IERC721Receiver} can be used to prevent tokens from becoming forever locked in contracts. Imagine sending an in-game item to an exchange address that can't send it back!. When using <>, the token contract checks to see that the receiver is an {IERC721Receiver}, which implies that it knows how to handle {ERC721} tokens. If you're writing a contract that needs to receive {ERC721} tokens, you'll want to include this interface.
+
+Additionally there are multiple custom extensions, including:
+
+* designation of addresses that can pause token transfers for all users ({ERC721Pausable}).
+* destruction of own tokens ({ERC721Burnable}).
+
+NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC721 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc721.adoc#Presets[ERC721 Presets] (such as {ERC721PresetMinterPauserAutoId}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts.
+
+
+== Core
+
+{{IERC721}}
+
+{{IERC721Metadata}}
+
+{{IERC721Enumerable}}
+
+{{ERC721}}
+
+{{IERC721Receiver}}
+
+== Extensions
+
+{{ERC721Pausable}}
+
+{{ERC721Burnable}}
+
+== Convenience
+
+{{ERC721Holder}}
diff --git a/bridge/contracts/zeppelin/token/ERC777/ERC777.sol b/bridge/contracts/zeppelin/token/ERC777/ERC777.sol
new file mode 100644
index 000000000..18f3f71e6
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC777/ERC777.sol
@@ -0,0 +1,481 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "../../GSN/Context.sol";
+import "./IERC777.sol";
+import "./IERC777Recipient.sol";
+import "./IERC777Sender.sol";
+import "../../token/ERC20/IERC20.sol";
+import "../../math/SafeMath.sol";
+import "../../utils/Address.sol";
+import "../../introspection/IERC1820Registry.sol";
+
+/**
+ * @dev Implementation of the {IERC777} interface.
+ *
+ * This implementation is agnostic to the way tokens are created. This means
+ * that a supply mechanism has to be added in a derived contract using {_mint}.
+ *
+ * Support for ERC20 is included in this contract, as specified by the EIP: both
+ * the ERC777 and ERC20 interfaces can be safely used when interacting with it.
+ * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token
+ * movements.
+ *
+ * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there
+ * are no special restrictions in the amount of tokens that created, moved, or
+ * destroyed. This makes integration with ERC20 applications seamless.
+ */
+contract ERC777 is Context, IERC777, IERC20 {
+ using SafeMath for uint256;
+ using Address for address;
+
+ IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
+
+ mapping(address => uint256) private _balances;
+
+ uint256 private _totalSupply;
+
+ string private _name;
+ string private _symbol;
+
+ // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.
+ // See https://github.com/ethereum/solidity/issues/4024.
+
+ // keccak256("ERC777TokensSender")
+ bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =
+ 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;
+
+ // keccak256("ERC777TokensRecipient")
+ bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =
+ 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;
+
+ // This isn't ever read from - it's only used to respond to the defaultOperators query.
+ address[] private _defaultOperatorsArray;
+
+ // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).
+ mapping(address => bool) private _defaultOperators;
+
+ // For each account, a mapping of its operators and revoked default operators.
+ mapping(address => mapping(address => bool)) private _operators;
+ mapping(address => mapping(address => bool)) private _revokedDefaultOperators;
+
+ // ERC20-allowances
+ mapping (address => mapping (address => uint256)) private _allowances;
+
+ /**
+ * @dev `defaultOperators` may be an empty array.
+ */
+ constructor(
+ string memory aName,
+ string memory aSymbol,
+ address[] memory theDefaultOperators
+ ) {
+ _name = aName;
+ _symbol = aSymbol;
+
+ _defaultOperatorsArray = theDefaultOperators;
+ for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {
+ _defaultOperators[_defaultOperatorsArray[i]] = true;
+ }
+
+ // register interfaces
+ _erc1820.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this));
+ _erc1820.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this));
+ }
+
+ /**
+ * @dev See {IERC777-name}.
+ */
+ function name() public view override(IERC777) returns (string memory) {
+ return _name;
+ }
+
+ /**
+ * @dev See {IERC777-symbol}.
+ */
+ function symbol() public view override(IERC777) returns (string memory) {
+ return _symbol;
+ }
+
+ /**
+ * @dev See {ERC20Detailed-decimals}.
+ *
+ * Always returns 18, as per the
+ * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).
+ */
+ function decimals() public pure override returns (uint8) {
+ return 18;
+ }
+
+ /**
+ * @dev See {IERC777-granularity}.
+ *
+ * This implementation always returns `1`.
+ */
+ function granularity() public view virtual override(IERC777) returns (uint256) {
+ return 1;
+ }
+
+ /**
+ * @dev See {IERC777-totalSupply}.
+ */
+ function totalSupply() public view override(IERC20, IERC777) returns (uint256) {
+ return _totalSupply;
+ }
+
+ /**
+ * @dev Returns the amount of tokens owned by an account (`tokenHolder`).
+ */
+ function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {
+ return _balances[tokenHolder];
+ }
+
+ /**
+ * @dev See {IERC777-send}.
+ *
+ * Also emits a {Transfer} event for ERC20 compatibility.
+ */
+ function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {
+ _send(_msgSender(), _msgSender(), recipient, amount, data, "", true);
+ }
+
+ /**
+ * @dev See {IERC20-transfer}.
+ *
+ * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}
+ * interface if it is a contract.
+ *
+ * Also emits a {Sent} event.
+ */
+ function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {
+ require(recipient != address(0), "ERC777: transfer to zero address");
+
+ address from = _msgSender();
+
+ _callTokensToSend(from, from, recipient, amount, "", "");
+
+ _move(from, from, recipient, amount, "", "");
+
+ _callTokensReceived(from, from, recipient, amount, "", "", false);
+
+ return true;
+ }
+
+ /**
+ * @dev See {IERC777-burn}.
+ *
+ * Also emits a {Transfer} event for ERC20 compatibility.
+ */
+ function burn(uint256 amount, bytes calldata data) external override(IERC777) {
+ _burn(_msgSender(), _msgSender(), amount, data, "");
+ }
+
+ /**
+ * @dev See {IERC777-isOperatorFor}.
+ */
+ function isOperatorFor(
+ address operator,
+ address tokenHolder
+ ) public view override(IERC777) returns (bool) {
+ return operator == tokenHolder ||
+ (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||
+ _operators[tokenHolder][operator];
+ }
+
+ /**
+ * @dev See {IERC777-authorizeOperator}.
+ */
+ function authorizeOperator(address operator) external override(IERC777) {
+ require(_msgSender() != operator, "ERC777: authorizing self as operator");
+
+ if (_defaultOperators[operator]) {
+ delete _revokedDefaultOperators[_msgSender()][operator];
+ } else {
+ _operators[_msgSender()][operator] = true;
+ }
+
+ emit AuthorizedOperator(operator, _msgSender());
+ }
+
+ /**
+ * @dev See {IERC777-revokeOperator}.
+ */
+ function revokeOperator(address operator) external override(IERC777) {
+ require(operator != _msgSender(), "ERC777: revoking self as operator");
+
+ if (_defaultOperators[operator]) {
+ _revokedDefaultOperators[_msgSender()][operator] = true;
+ } else {
+ delete _operators[_msgSender()][operator];
+ }
+
+ emit RevokedOperator(operator, _msgSender());
+ }
+
+ /**
+ * @dev See {IERC777-defaultOperators}.
+ */
+ function defaultOperators() public view override(IERC777) returns (address[] memory) {
+ return _defaultOperatorsArray;
+ }
+
+ /**
+ * @dev See {IERC777-operatorSend}.
+ *
+ * Emits {Sent} and {Transfer} events.
+ */
+ function operatorSend(
+ address sender,
+ address recipient,
+ uint256 amount,
+ bytes calldata data,
+ bytes calldata operatorData
+ )
+ external override(IERC777)
+ {
+ require(isOperatorFor(_msgSender(), sender), "ERC777: caller is not an operator");
+ _send(_msgSender(), sender, recipient, amount, data, operatorData, true);
+ }
+
+ /**
+ * @dev See {IERC777-operatorBurn}.
+ *
+ * Emits {Burned} and {Transfer} events.
+ */
+ function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)
+ external override(IERC777) {
+ require(isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator");
+ _burn(_msgSender(), account, amount, data, operatorData);
+ }
+
+ /**
+ * @dev See {IERC20-allowance}.
+ *
+ * Note that operator and allowance concepts are orthogonal: operators may
+ * not have allowance, and accounts with allowance may not be operators
+ * themselves.
+ */
+ function allowance(address holder, address spender)
+ public view override(IERC20) returns (uint256) {
+ return _allowances[holder][spender];
+ }
+
+ /**
+ * @dev See {IERC20-approve}.
+ *
+ * Note that accounts cannot have allowance issued by their operators.
+ */
+ function approve(address spender, uint256 value) external override(IERC20) returns (bool) {
+ address holder = _msgSender();
+ _approve(holder, spender, value);
+ return true;
+ }
+
+ /**
+ * @dev See {IERC20-transferFrom}.
+ *
+ * Note that operator and allowance concepts are orthogonal: operators cannot
+ * call `transferFrom` (unless they have allowance), and accounts with
+ * allowance cannot call `operatorSend` (unless they are operators).
+ *
+ * Emits {Sent}, {Transfer} and {Approval} events.
+ */
+ function transferFrom(address holder, address recipient, uint256 amount)
+ external override(IERC20) returns (bool) {
+ require(recipient != address(0), "ERC777: transfer to zero address");
+ require(holder != address(0), "ERC777: transfer from zero address");
+
+ address spender = _msgSender();
+
+ _callTokensToSend(spender, holder, recipient, amount, "", "");
+
+ _move(spender, holder, recipient, amount, "", "");
+ _approve(holder, spender, _allowances[holder][spender].sub(amount, "ERC777: transfer amount exceeds allowance"));
+
+ _callTokensReceived(spender, holder, recipient, amount, "", "", false);
+
+ return true;
+ }
+
+ /**
+ * @dev Creates `amount` tokens and assigns them to `account`, increasing
+ * the total supply.
+ *
+ * If a send hook is registered for `account`, the corresponding function
+ * will be called with `operator`, `data` and `operatorData`.
+ *
+ * See {IERC777Sender} and {IERC777Recipient}.
+ *
+ * Emits {Minted} and {Transfer} events.
+ *
+ * Requirements
+ *
+ * - `account` cannot be the zero address.
+ * - if `account` is a contract, it must implement the {IERC777Recipient}
+ * interface.
+ */
+ function _mint(
+ address operator,
+ address account,
+ uint256 amount,
+ bytes memory userData,
+ bytes memory operatorData
+ )
+ internal
+ {
+ require(account != address(0), "ERC777: mint to zero address");
+
+ // Update state variables
+ _totalSupply = _totalSupply.add(amount);
+ _balances[account] = _balances[account].add(amount);
+
+ _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);
+
+ emit Minted(operator, account, amount, userData, operatorData);
+ emit Transfer(address(0), account, amount);
+ }
+
+ /**
+ * @dev Send tokens
+ * @param operator address operator requesting the transfer
+ * @param from address token holder address
+ * @param to address recipient address
+ * @param amount uint256 amount of tokens to transfer
+ * @param userData bytes extra information provided by the token holder (if any)
+ * @param operatorData bytes extra information provided by the operator (if any)
+ * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
+ */
+ function _send(
+ address operator,
+ address from,
+ address to,
+ uint256 amount,
+ bytes memory userData,
+ bytes memory operatorData,
+ bool requireReceptionAck
+ )
+ internal
+ {
+ require(from != address(0), "ERC777: send from zero address");
+ require(to != address(0), "ERC777: send to zero address");
+
+ _callTokensToSend(operator, from, to, amount, userData, operatorData);
+
+ _move(operator, from, to, amount, userData, operatorData);
+
+ _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);
+ }
+
+ /**
+ * @dev Burn tokens
+ * @param operator address operator requesting the operation
+ * @param from address token holder address
+ * @param amount uint256 amount of tokens to burn
+ * @param data bytes extra information provided by the token holder
+ * @param operatorData bytes extra information provided by the operator (if any)
+ */
+ function _burn(
+ address operator,
+ address from,
+ uint256 amount,
+ bytes memory data,
+ bytes memory operatorData
+ )
+ internal
+ {
+ require(from != address(0), "ERC777: burn from zero address");
+
+ _callTokensToSend(operator, from, address(0), amount, data, operatorData);
+
+ // Update state variables
+ _balances[from] = _balances[from].sub(amount, "ERC777: burn amount exceeds balance");
+ _totalSupply = _totalSupply.sub(amount);
+
+ emit Burned(operator, from, amount, data, operatorData);
+ emit Transfer(from, address(0), amount);
+ }
+
+ function _move(
+ address operator,
+ address from,
+ address to,
+ uint256 amount,
+ bytes memory userData,
+ bytes memory operatorData
+ )
+ internal
+ {
+ _balances[from] = _balances[from].sub(amount, "ERC777: transfer amount exceeds balance");
+ _balances[to] = _balances[to].add(amount);
+
+ emit Sent(operator, from, to, amount, userData, operatorData);
+ emit Transfer(from, to, amount);
+ }
+
+ function _approve(address holder, address spender, uint256 value) internal {
+ // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is
+ // currently unnecessary.
+ //require(holder != address(0), "ERC777: approve from the zero address");
+ require(spender != address(0), "ERC777: approve to zero address");
+
+ _allowances[holder][spender] = value;
+ emit Approval(holder, spender, value);
+ }
+
+ /**
+ * @dev Call from.tokensToSend() if the interface is registered
+ * @param operator address operator requesting the transfer
+ * @param from address token holder address
+ * @param to address recipient address
+ * @param amount uint256 amount of tokens to transfer
+ * @param userData bytes extra information provided by the token holder (if any)
+ * @param operatorData bytes extra information provided by the operator (if any)
+ */
+ function _callTokensToSend(
+ address operator,
+ address from,
+ address to,
+ uint256 amount,
+ bytes memory userData,
+ bytes memory operatorData
+ )
+ internal
+ {
+ address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);
+ if (implementer != address(0)) {
+ IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);
+ }
+ }
+
+ /**
+ * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but
+ * tokensReceived() was not registered for the recipient
+ * @param operator address operator requesting the transfer
+ * @param from address token holder address
+ * @param to address recipient address
+ * @param amount uint256 amount of tokens to transfer
+ * @param userData bytes extra information provided by the token holder (if any)
+ * @param operatorData bytes extra information provided by the operator (if any)
+ * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
+ */
+ function _callTokensReceived(
+ address operator,
+ address from,
+ address to,
+ uint256 amount,
+ bytes memory userData,
+ bytes memory operatorData,
+ bool requireReceptionAck
+ )
+ private
+ {
+ address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);
+ if (implementer != address(0)) {
+ IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);
+ } else if (requireReceptionAck) {
+ require(!to.isContract(), "ERC777: token recipient contract has no implementer for ERC777TokensRecipient");
+ }
+ }
+}
diff --git a/bridge/contracts/zeppelin/token/ERC777/IERC777.sol b/bridge/contracts/zeppelin/token/ERC777/IERC777.sol
new file mode 100644
index 000000000..47eae2b6a
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC777/IERC777.sol
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface of the ERC777Token standard as defined in the EIP.
+ *
+ * This contract uses the
+ * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let
+ * token holders and recipients react to token movements by using setting implementers
+ * for the associated interfaces in said registry. See `IERC1820Registry` and
+ * `ERC1820Implementer`.
+ */
+interface IERC777 {
+ /**
+ * @dev Returns the name of the token.
+ */
+ function name() external view returns (string memory);
+
+ /**
+ * @dev Returns the symbol of the token, usually a shorter version of the
+ * name.
+ */
+ function symbol() external view returns (string memory);
+
+ /**
+ * @dev Returns the smallest part of the token that is not divisible. This
+ * means all token operations (creation, movement and destruction) must have
+ * amounts that are a multiple of this number.
+ *
+ * For most token contracts, this value will equal 1.
+ */
+ function granularity() external view returns (uint256);
+
+ /**
+ * @dev Returns the amount of tokens in existence.
+ */
+ function totalSupply() external view returns (uint256);
+
+ /**
+ * @dev Returns the amount of tokens owned by an account (`owner`).
+ */
+ function balanceOf(address owner) external view returns (uint256);
+
+ /**
+ * @dev Moves `amount` tokens from the caller's account to `recipient`.
+ *
+ * If send or receive hooks are registered for the caller and `recipient`,
+ * the corresponding functions will be called with `data` and empty
+ * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.
+ *
+ * Emits a `Sent` event.
+ *
+ * Requirements
+ *
+ * - the caller must have at least `amount` tokens.
+ * - `recipient` cannot be the zero address.
+ * - if `recipient` is a contract, it must implement the `tokensReceived`
+ * interface.
+ */
+ function send(address recipient, uint256 amount, bytes calldata data) external;
+
+ /**
+ * @dev Destroys `amount` tokens from the caller's account, reducing the
+ * total supply.
+ *
+ * If a send hook is registered for the caller, the corresponding function
+ * will be called with `data` and empty `operatorData`. See `IERC777Sender`.
+ *
+ * Emits a `Burned` event.
+ *
+ * Requirements
+ *
+ * - the caller must have at least `amount` tokens.
+ */
+ function burn(uint256 amount, bytes calldata data) external;
+
+ /**
+ * @dev Returns true if an account is an operator of `tokenHolder`.
+ * Operators can send and burn tokens on behalf of their owners. All
+ * accounts are their own operator.
+ *
+ * See `operatorSend` and `operatorBurn`.
+ */
+ function isOperatorFor(address operator, address tokenHolder) external view returns (bool);
+
+ /**
+ * @dev Make an account an operator of the caller.
+ *
+ * See `isOperatorFor`.
+ *
+ * Emits an `AuthorizedOperator` event.
+ *
+ * Requirements
+ *
+ * - `operator` cannot be calling address.
+ */
+ function authorizeOperator(address operator) external;
+
+ /**
+ * @dev Make an account an operator of the caller.
+ *
+ * See `isOperatorFor` and `defaultOperators`.
+ *
+ * Emits a `RevokedOperator` event.
+ *
+ * Requirements
+ *
+ * - `operator` cannot be calling address.
+ */
+ function revokeOperator(address operator) external;
+
+ /**
+ * @dev Returns the list of default operators. These accounts are operators
+ * for all token holders, even if `authorizeOperator` was never called on
+ * them.
+ *
+ * This list is immutable, but individual holders may revoke these via
+ * `revokeOperator`, in which case `isOperatorFor` will return false.
+ */
+ function defaultOperators() external view returns (address[] memory);
+
+ /**
+ * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must
+ * be an operator of `sender`.
+ *
+ * If send or receive hooks are registered for `sender` and `recipient`,
+ * the corresponding functions will be called with `data` and
+ * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.
+ *
+ * Emits a `Sent` event.
+ *
+ * Requirements
+ *
+ * - `sender` cannot be the zero address.
+ * - `sender` must have at least `amount` tokens.
+ * - the caller must be an operator for `sender`.
+ * - `recipient` cannot be the zero address.
+ * - if `recipient` is a contract, it must implement the `tokensReceived`
+ * interface.
+ */
+ function operatorSend(
+ address sender,
+ address recipient,
+ uint256 amount,
+ bytes calldata data,
+ bytes calldata operatorData
+ ) external;
+
+ /**
+ * @dev Destoys `amount` tokens from `account`, reducing the total supply.
+ * The caller must be an operator of `account`.
+ *
+ * If a send hook is registered for `account`, the corresponding function
+ * will be called with `data` and `operatorData`. See `IERC777Sender`.
+ *
+ * Emits a `Burned` event.
+ *
+ * Requirements
+ *
+ * - `account` cannot be the zero address.
+ * - `account` must have at least `amount` tokens.
+ * - the caller must be an operator for `account`.
+ */
+ function operatorBurn(
+ address account,
+ uint256 amount,
+ bytes calldata data,
+ bytes calldata operatorData
+ ) external;
+
+ event Sent(
+ address indexed operator,
+ address indexed from,
+ address indexed to,
+ uint256 amount,
+ bytes data,
+ bytes operatorData
+ );
+
+ function decimals() external returns (uint8);
+
+ event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
+
+ event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);
+
+ event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
+
+ event RevokedOperator(address indexed operator, address indexed tokenHolder);
+}
diff --git a/bridge/contracts/zeppelin/token/ERC777/IERC777Recipient.sol b/bridge/contracts/zeppelin/token/ERC777/IERC777Recipient.sol
new file mode 100644
index 000000000..32af25dcd
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC777/IERC777Recipient.sol
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.
+ *
+ * Accounts can be notified of `IERC777` tokens being sent to them by having a
+ * contract implement this interface (contract holders can be their own
+ * implementer) and registering it on the
+ * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).
+ *
+ * See `IERC1820Registry` and `ERC1820Implementer`.
+ */
+interface IERC777Recipient {
+ /**
+ * @dev Called by an `IERC777` token contract whenever tokens are being
+ * moved or created into a registered account (`to`). The type of operation
+ * is conveyed by `from` being the zero address or not.
+ *
+ * This call occurs _after_ the token contract's state is updated, so
+ * `IERC777.balanceOf`, etc., can be used to query the post-operation state.
+ *
+ * This function may revert to prevent the operation from being executed.
+ */
+ function tokensReceived(
+ address operator,
+ address from,
+ address to,
+ uint amount,
+ bytes calldata userData,
+ bytes calldata operatorData
+ ) external;
+}
diff --git a/bridge/contracts/zeppelin/token/ERC777/IERC777Sender.sol b/bridge/contracts/zeppelin/token/ERC777/IERC777Sender.sol
new file mode 100644
index 000000000..ebd6d5b91
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC777/IERC777Sender.sol
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface of the ERC777TokensSender standard as defined in the EIP.
+ *
+ * `IERC777` Token holders can be notified of operations performed on their
+ * tokens by having a contract implement this interface (contract holders can be
+ * their own implementer) and registering it on the
+ * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).
+ *
+ * See `IERC1820Registry` and `ERC1820Implementer`.
+ */
+interface IERC777Sender {
+ /**
+ * @dev Called by an `IERC777` token contract whenever a registered holder's
+ * (`from`) tokens are about to be moved or destroyed. The type of operation
+ * is conveyed by `to` being the zero address or not.
+ *
+ * This call occurs _before_ the token contract's state is updated, so
+ * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.
+ *
+ * This function may revert to prevent the operation from being executed.
+ */
+ function tokensToSend(
+ address operator,
+ address from,
+ address to,
+ uint amount,
+ bytes calldata userData,
+ bytes calldata operatorData
+ ) external;
+}
diff --git a/bridge/contracts/zeppelin/token/ERC777/README.md b/bridge/contracts/zeppelin/token/ERC777/README.md
new file mode 100644
index 000000000..dba6bc7f1
--- /dev/null
+++ b/bridge/contracts/zeppelin/token/ERC777/README.md
@@ -0,0 +1,17 @@
+---
+sections:
+ - title: Core
+ contracts:
+ - IERC777
+ - ERC777
+ - title: Hooks
+ contracts:
+ - IERC777Sender
+ - IERC777Recipient
+---
+
+This set of interfaces and contracts are all related to the [ERC777 token standard](https://eips.ethereum.org/EIPS/eip-777).
+
+The token behavior itself is implemented in the core contracts: `IERC777`, `ERC777`.
+
+Additionally there are interfaces used to develop contracts that react to token movements: `IERC777Sender`, `IERC777Recipient`.
diff --git a/bridge/contracts/zeppelin/upgradable/ARCHITECTURE.md b/bridge/contracts/zeppelin/upgradable/ARCHITECTURE.md
new file mode 100644
index 000000000..bfb6cff8d
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/ARCHITECTURE.md
@@ -0,0 +1,27 @@
+## Architecture
+
+The following provides visibility into how OpenZeppelin's contracts are organized:
+
+- **access** - Smart contracts that enable functionality that can be used for selective restrictions and basic authorization control functions.
+- **crowdsale** - A collection of smart contracts used to manage token crowdsales that allow investors to purchase tokens with ETH. Includes a base contract which implements fundamental crowdsale functionality in its simplest form. The base contract can be extended in order to satisfy your crowdsale’s specific requirements.
+ - **distribution** - Includes extensions of the base crowdsale contract which can be used to customize the completion of a crowdsale.
+ - **emission** - Includes extensions of the base crowdsale contract which can be used to mint and manage how tokens are issued to purchasers.
+ - **price** - Includes extensions of the crowdsale contract that can be used to manage changes in token prices.
+ - **validation** - Includes extensions of the crowdsale contract that can be used to enforce restraints and limit access to token purchases.
+- **examples** - A collection of simple smart contracts that demonstrate how to add new features to base contracts through multiple inheritance.
+- **introspection** - An interface that can be used to make a contract comply with the ERC-165 standard as well as a contract that implements ERC-165 using a lookup table.
+- **lifecycle** - A collection of base contracts used to manage the existence and behavior of your contracts and their funds.
+- **math** - Libraries with safety checks on operations that throw on errors.
+- **mocks** - A collection of abstract contracts that are primarily used for unit testing. They also serve as good usage examples and demonstrate how to combine contracts with inheritance when developing your own custom applications.
+- **ownership** - A collection of smart contracts that can be used to manage contract and token ownership
+- **payment** - A collection of smart contracts that can be used to manage payments through escrow arrangements, withdrawals, and claims. Includes support for both single payees and multiple payees.
+- **proposals** - A collection of smart contracts that reflect community Ethereum Improvement Proposals (EIPs). These contracts are under development and standardization. They are not recommended for production, but they are useful for experimentation with pending EIP standards. Go [here](https://github.com/OpenZeppelin/openzeppelin-solidity/wiki/ERC-Process) for more information.
+
+- **token** - A collection of approved ERC standard tokens -- their interfaces and implementations.
+ - **ERC20** - A standard interface for fungible tokens:
+ - *Interfaces* - Includes the ERC-20 token standard basic interface. I.e., what the contract’s ABI can represent.
+ - *Implementations* - Includes ERC-20 token implementations that include all required and some optional ERC-20 functionality.
+ - **ERC721** - A standard interface for non-fungible tokens
+ - *Interfaces* - Includes the ERC-721 token standard basic interface. I.e., what the contract’s ABI can represent.
+ - *Implementations* - Includes ERC-721 token implementations that include all required and some optional ERC-721 functionality.
+
diff --git a/bridge/contracts/zeppelin/upgradable/Initializable.sol b/bridge/contracts/zeppelin/upgradable/Initializable.sol
new file mode 100644
index 000000000..17c61c74e
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/Initializable.sol
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @title Initializable
+ *
+ * @dev Helper contract to support initializer functions. To use it, replace
+ * the constructor with a function that has the `initializer` modifier.
+ * WARNING: Unlike constructors, initializer functions must be manually
+ * invoked. This applies both to deploying an Initializable contract, as well
+ * as extending an Initializable contract via inheritance.
+ * WARNING: When used with inheritance, manual care must be taken to not invoke
+ * a parent initializer twice, or ensure that all initializers are idempotent,
+ * because this is not dealt with automatically as with constructors.
+ */
+contract Initializable {
+
+ /**
+ * @dev Indicates that the contract has been initialized.
+ */
+ bool private initialized;
+
+ /**
+ * @dev Indicates that the contract is in the process of being initialized.
+ */
+ bool private initializing;
+
+ /**
+ * @dev Modifier to use in the initializer function of a contract.
+ */
+ modifier initializer() {
+ require(initializing || !initialized, "Contract instance is already initialized");
+
+ bool isTopLevelCall = !initializing;
+ if (isTopLevelCall) {
+ initializing = true;
+ initialized = true;
+ }
+
+ _;
+
+ if (isTopLevelCall) {
+ initializing = false;
+ }
+ }
+
+ // Reserved storage space to allow for layout changes in the future.
+ uint256[50] private ______gap;
+}
\ No newline at end of file
diff --git a/bridge/contracts/zeppelin/upgradable/LICENSE b/bridge/contracts/zeppelin/upgradable/LICENSE
new file mode 100644
index 000000000..c5e7ce02f
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2016-2019 zOS Global Limited
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/bridge/contracts/zeppelin/upgradable/README.md b/bridge/contracts/zeppelin/upgradable/README.md
new file mode 100644
index 000000000..3ede2e0f0
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/README.md
@@ -0,0 +1,113 @@
+#
+
+## OpenZeppelin Contracts Ethereum Package
+
+[](https://www.npmjs.org/package/@openzeppelin/contracts-ethereum-package)
+[](https://circleci.com/gh/OpenZeppelin/openzeppelin-contracts-ethereum-package)
+
+**OpenZeppelin Contracts is a library for secure smart contract development.** It provides implementations of standards like ERC20 and ERC721 which you can deploy as-is or extend to suit your needs, as well as Solidity components to build custom contracts and more complex decentralized systems.
+
+This fork of OpenZeppelin is set up as a **reusable Ethereum Package**. It is deployed to the kovan, rinkeby, and ropsten test networks, as well as to the main Ethereum network. You can reuse any of the pre-deployed on-chain contracts by simply linking to them using the [OpenZeppelin SDK](https://github.com/openzeppelin/openzeppelin-sdk), or reuse their Solidity source code as with the [vanilla version of OpenZeppelin Contracts](https://github.com/OpenZeppelin/openzeppelin-contracts).
+
+## Differences with openzeppelin-contracts
+
+This package contains the same contracts as the vanilla [openzeppelin-contracts](https://github.com/openZeppelin/openzeppelin-contracts). The main difference is that _all contracts in this package are potentially upgradeable_: you will notice that no contracts have constructors defined, but use [initializer functions](https://docs.zeppelinos.org/docs/writing_contracts.html#initializers) instead. Also, this package is set up as an Ethereum package, and provides a small set of pre-deployed logic contracts that can be used directly via the OpenZeppelin SDK, without needing to deploy them again.
+
+All in all, **you should use this package instead of openzeppelin-solidity if you are managing your project via the OpenZeppelin CLI**.
+
+## Install
+
+```
+npm install @openzeppelin/contracts-ethereum-package
+```
+
+## Deployed logic contracts
+
+- [StandaloneERC20](contracts/token/ERC20/StandaloneERC20.sol): ERC20 token implementation, optionally mintable and pausable.
+- [StandaloneERC721](contracts/token/ERC721/StandaloneERC721.sol): ERC721 non-fungible token implementation with metadata and enumerable extensions, optionally mintable and pausable.
+- [TokenVesting](contracts/drafts/TokenVesting.sol): tToken holder contract that can release its token balance gradually like a typical vesting scheme, with a cliff and vesting period, optionally revocable.
+- [PaymentSplitter](contracts/payment/PaymentSplitter.sol): Splits payments among a group of addresses proportionately to some number of shares they own.
+
+## Using via the OpenZeppelin CLI
+
+You can easily create upgradeable instances of any of the logic contracts listed above using the OpenZeppelin CLI. This will rely on the pre-deployed instances in mainnet, kovan, ropsten, or rinkeby, greatly reducing your gas deployment costs. To do this, just [create a new OpenZeppelin SDK project](https://docs.zeppelinos.org/docs/deploying.html) and [link to this package](https://docs.zeppelinos.org/docs/linking.html).
+
+```bash
+$ npm install -g @openzeppelin/cli
+$ openzeppelin init
+$ openzeppelin link @openzeppelin/contracts-ethereum-package
+> Installing...
+$ openzeppelin create @openzeppelin/contracts-ethereum-package/StandaloneERC20
+> Creating...
+```
+
+To create an instance of a contract, use the `openzeppelin create` command. As an example, you can run the following to create an upgradeable ERC20 named MyToken, with symbol TKN and 8 decimals, and an initial supply of 100 tokens assigned to the address HOLDER, with a MINTER and a PAUSER. Remember to replace $HOLDER, $MINTER, and $PAUSER with actual addresses when you run this command; you can specify more than one (or none at all) minters and pausers.
+
+```
+$ openzeppelin create
+? Pick a contract to instantiate: @openzeppelin/contracts-ethereum-package/StandaloneERC20
+? Pick a network: development
+✓ Deploying @openzeppelin/contracts-ethereum-package dependency to network
+? Do you want to call a function on the instance after creating it?: Yes
+? Select which function: * initialize(name: string, symbol: string, decimals: uint8, initialSupply: uint256, initialHolder: address, minters: address[], pausers: address[])
+? name (string): MyToken
+? symbol (string): MYT
+? decimals (uint8): 18
+? initialSupply (uint256): 100e18
+? initialHolder (address): 0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1
+? minters (address[]):
+? pausers (address[]):
+✓ Setting everything up to create contract instances
+✓ Instance created at 0x2612Af3A521c2df9EAF28422Ca335b04AdF3ac66
+```
+
+OpenZeppelin will create an upgradeable ERC20 instance and keep track of its address in the `.openzeppelin/rinkeby.json` file. Should you update your version of the openzeppelin contracts ethereum package later down the road, you can simply run `openzeppelin update` to upgrade all your ERC20 instances to the latest version.
+
+You can also deploy a ERC721 token by choosing the `StandaloneERC721` contract when running `openzeppelin create`. Refer to the `initialize` function of each of the predeployed logic contracts to see which parameters are required for initialization.
+
+## Extending contracts
+
+If you prefer to write your custom contracts, import the ones from this package and extend them through inheritance. Note that **you must use this package and not `@openzeppelin/contracts` if you are [writing upgradeable contracts](https://docs.zeppelinos.org/docs/writing_contracts.html)**.
+
+```solidity
+pragma solidity ^0.5.0;
+
+import '@openzeppelin/upgrades/contracts/Initializable.sol';
+import '@openzeppelin/contracts-ethereum-package/contracts/token/ERC721/ERC721Full.sol';
+import '@openzeppelin/contracts-ethereum-package/contracts/token/ERC721/ERC721Mintable.sol';
+
+contract MyNFT is Initializable, ERC721Full, ERC721Mintable {
+ function initialize() public initializer {
+ ERC721.initialize();
+ ERC721Enumerable.initialize();
+ ERC721Metadata.initialize("MyNFT", "MNFT");
+ ERC721Mintable.initialize(msg.sender);
+ }
+}
+```
+
+On our site you will find a few [guides] to learn about the different parts of OpenZeppelin, as well as [documentation for the API][API docs]. Keep in mind that the API docs are work in progress, and don’t hesitate to ask questions in [our forum][forum].
+
+## Security
+
+OpenZeppelin Contracts is maintained by [OpenZeppelin](https://openzeppelin.com) the company, and developed following our high standards for code quality and security. OpenZeppelin Contracts is meant to provide tested and community-audited code, but please use common sense when doing anything that deals with real money! We take no responsibility for your implementation decisions and any security problems you might experience.
+
+The core development principles and strategies that OpenZeppelin Contracts is based on include: security in depth, simple and modular code, clarity-driven naming conventions, comprehensive unit testing, pre-and-post-condition sanity checks, code consistency, and regular audits.
+
+The latest audit was done on October 2018 on version 2.0.0.
+
+Please report any security issues you find to security@openzeppelin.org.
+
+## Contribute
+
+OpenZeppelin exists thanks to its contributors. There are many ways you can participate and help build high quality software. Check out the [contribution guide]!
+
+## License
+
+OpenZeppelin is released under the [MIT License](LICENSE).
+
+[API docs]: https://docs.openzeppelin.org/v2.8.0/api/token/erc20
+[guides]: https://docs.openzeppelin.org/v2.8.0/get-started
+[forum]: https://forum.zeppelin.solutions
+[Zeppelin]: https://zeppelin.solutions
+[contribution guide]: CONTRIBUTING.md
diff --git a/bridge/contracts/zeppelin/upgradable/access/README.md b/bridge/contracts/zeppelin/upgradable/access/README.md
new file mode 100644
index 000000000..e39860b62
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/access/README.md
@@ -0,0 +1,9 @@
+---
+sections:
+ - title: Library
+ contracts:
+ - Roles
+ - subdirectory: roles
+---
+
+> This page is incomplete. We're working to improve it for the next release. Stay tuned!
diff --git a/bridge/contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol b/bridge/contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol
new file mode 100644
index 000000000..a5dc48673
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "../../Initializable.sol";
+
+import "../../../GSN/Context.sol";
+import "../../../access/Roles.sol";
+
+contract UpgradablePauserRole is Initializable, Context {
+ using Roles for Roles.Role;
+
+ event PauserAdded(address indexed account);
+ event PauserRemoved(address indexed account);
+
+ Roles.Role private _pausers;
+
+ function __PauserRol_init(address sender) public initializer {
+ if (!isPauser(sender)) {
+ _addPauser(sender);
+ }
+ }
+
+ modifier onlyPauser() {
+ require(isPauser(_msgSender()), "PauserRole: caller doesn't have the role");
+ _;
+ }
+
+ function isPauser(address account) public view returns (bool) {
+ return _pausers.has(account);
+ }
+
+ function addPauser(address account) public onlyPauser {
+ _addPauser(account);
+ }
+
+ function renouncePauser() public {
+ _removePauser(_msgSender());
+ }
+
+ function _addPauser(address account) internal {
+ _pausers.add(account);
+ emit PauserAdded(account);
+ }
+
+ function _removePauser(address account) internal {
+ _pausers.remove(account);
+ emit PauserRemoved(account);
+ }
+}
diff --git a/bridge/contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol b/bridge/contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol
new file mode 100644
index 000000000..380bb4f84
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "../Initializable.sol";
+
+import "../../GSN/Context.sol";
+import "../access/roles/UpgradablePauserRole.sol";
+
+/**
+ * @dev Contract module which allows children to implement an emergency stop
+ * mechanism that can be triggered by an authorized account.
+ *
+ * This module is used through inheritance. It will make available the
+ * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
+ * the functions of your contract. Note that they will not be pausable by
+ * simply including this module, only once the modifiers are put in place.
+ */
+contract UpgradablePausable is Initializable, Context, UpgradablePauserRole {
+ /**
+ * @dev Emitted when the pause is triggered by a pauser (`account`).
+ */
+ event Paused(address account);
+
+ /**
+ * @dev Emitted when the pause is lifted by a pauser (`account`).
+ */
+ event Unpaused(address account);
+
+ bool private _paused;
+
+ /**
+ * @dev Initializes the contract in unpaused state. Assigns the Pauser role
+ * to the deployer.
+ */
+ function __Pausable_init(address sender) public initializer {
+ UpgradablePauserRole.__PauserRol_init(sender);
+
+ _paused = false;
+ }
+
+ /**
+ * @dev Returns true if the contract is paused, and false otherwise.
+ */
+ function paused() public view returns (bool) {
+ return _paused;
+ }
+
+ /**
+ * @dev Modifier to make a function callable only when the contract is not paused.
+ */
+ modifier whenNotPaused() {
+ require(!_paused, "Pausable: paused");
+ _;
+ }
+
+ /**
+ * @dev Modifier to make a function callable only when the contract is paused.
+ */
+ modifier whenPaused() {
+ require(_paused, "Pausable: not paused");
+ _;
+ }
+
+ /**
+ * @dev Called by a pauser to pause, triggers stopped state.
+ */
+ function pause() public onlyPauser whenNotPaused {
+ _paused = true;
+ emit Paused(_msgSender());
+ }
+
+ /**
+ * @dev Called by a pauser to unpause, returns to normal state.
+ */
+ function unpause() public onlyPauser whenPaused {
+ _paused = false;
+ emit Unpaused(_msgSender());
+ }
+}
diff --git a/bridge/contracts/zeppelin/upgradable/ownership/README.md b/bridge/contracts/zeppelin/upgradable/ownership/README.md
new file mode 100644
index 000000000..5e112d068
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/ownership/README.md
@@ -0,0 +1,3 @@
+Contract modules for simple authorization and access control mechanisms.
+
+For more complex needs see [Access](access).
diff --git a/bridge/contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol b/bridge/contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol
new file mode 100644
index 000000000..e862b44d4
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "../Initializable.sol";
+
+import "../../GSN/Context.sol";
+
+/**
+ * @dev Contract module which provides a basic access control mechanism, where
+ * there is an account (an owner) that can be granted exclusive access to
+ * specific functions.
+ *
+ * This module is used through inheritance. It will make available the modifier
+ * `onlyOwner`, which can be aplied to your functions to restrict their use to
+ * the owner.
+ */
+contract UpgradableOwnable is Initializable, Context {
+ address private _owner;
+
+ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
+
+ /**
+ * @dev Initializes the contract setting the deployer as the initial owner.
+ */
+ function initialize(address sender) public initializer {
+ _owner = sender;
+ emit OwnershipTransferred(address(0), _owner);
+ }
+
+ /**
+ * @dev Returns the address of the current owner.
+ */
+ function owner() public view returns (address) {
+ return _owner;
+ }
+
+ /**
+ * @dev Throws if called by any account other than the owner.
+ */
+ modifier onlyOwner() {
+ require(isOwner(), "Ownable: caller is not the owner");
+ _;
+ }
+
+ /**
+ * @dev Returns true if the caller is the current owner.
+ */
+ function isOwner() public view returns (bool) {
+ return _msgSender() == _owner;
+ }
+
+ /**
+ * @dev Leaves the contract without owner. It will not be possible to call
+ * `onlyOwner` functions anymore. Can only be called by the current owner.
+ *
+ * > Note: Renouncing ownership will leave the contract without an owner,
+ * thereby removing any functionality that is only available to the owner.
+ */
+ function renounceOwnership() public onlyOwner {
+ emit OwnershipTransferred(_owner, address(0));
+ _owner = address(0);
+ }
+
+ /**
+ * @dev Transfers ownership of the contract to a new account (`newOwner`).
+ * Can only be called by the current owner.
+ */
+ function transferOwnership(address newOwner) public onlyOwner {
+ _transferOwnership(newOwner);
+ }
+
+ /**
+ * @dev Transfers ownership of the contract to a new account (`newOwner`).
+ */
+ function _transferOwnership(address newOwner) internal {
+ require(newOwner != address(0), "Ownable: new owner is zero address");
+ emit OwnershipTransferred(_owner, newOwner);
+ _owner = newOwner;
+ }
+
+}
diff --git a/bridge/contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol b/bridge/contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol
new file mode 100644
index 000000000..7acdf7e0e
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "../Initializable.sol";
+
+import "../../GSN/Context.sol";
+
+/**
+ * @dev A Secondary contract can only be used by its primary account (the one that created it).
+ */
+contract UpgradableSecondary is Initializable, Context {
+ address private _primary;
+
+ /**
+ * @dev Emitted when the primary contract changes.
+ */
+ event PrimaryTransferred(
+ address recipient
+ );
+
+ /**
+ * @dev Sets the primary account to the one that is creating the Secondary contract.
+ */
+ function __Secondary_init(address sender) public initializer {
+ _primary = sender;
+ emit PrimaryTransferred(_primary);
+ }
+
+ /**
+ * @dev Reverts if called from any account other than the primary.
+ */
+ modifier onlyPrimary() {
+ require(_msgSender() == _primary, "Secondary: caller is not the primary account");
+ _;
+ }
+
+ /**
+ * @return the address of the primary.
+ */
+ function primary() public view returns (address) {
+ return _primary;
+ }
+
+ /**
+ * @dev Transfers contract to a new primary.
+ * @param recipient The address of new primary.
+ */
+ function transferPrimary(address recipient) public onlyPrimary {
+ require(recipient != address(0), "Secondary: new primary is the zero address");
+ _primary = recipient;
+ emit PrimaryTransferred(recipient);
+ }
+
+}
\ No newline at end of file
diff --git a/bridge/contracts/zeppelin/upgradable/proxy/Proxy.sol b/bridge/contracts/zeppelin/upgradable/proxy/Proxy.sol
new file mode 100644
index 000000000..28a775d84
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/proxy/Proxy.sol
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
+ * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
+ * be specified by overriding the virtual {_implementation} function.
+ *
+ * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
+ * different contract through the {_delegate} function.
+ *
+ * The success and return data of the delegated call will be returned back to the caller of the proxy.
+ */
+abstract contract Proxy {
+ /**
+ * @dev Delegates the current call to `implementation`.
+ *
+ * This function does not return to its internall call site, it will return directly to the external caller.
+ */
+ function _delegate(address implementation) internal virtual {
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ // Copy msg.data. We take full control of memory in this inline assembly
+ // block because it will not return to Solidity code. We overwrite the
+ // Solidity scratch pad at memory position 0.
+ calldatacopy(0, 0, calldatasize())
+
+ // Call the implementation.
+ // out and outsize are 0 because we don't know the size yet.
+ let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
+
+ // Copy the returned data.
+ returndatacopy(0, 0, returndatasize())
+
+ switch result
+ // delegatecall returns 0 on error.
+ case 0 { revert(0, returndatasize()) }
+ default { return(0, returndatasize()) }
+ }
+ }
+
+ /**
+ * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function
+ * and {_fallback} should delegate.
+ */
+ function _implementation() internal view virtual returns (address);
+
+ /**
+ * @dev Delegates the current call to the address returned by `_implementation()`.
+ *
+ * This function does not return to its internall call site, it will return directly to the external caller.
+ */
+ function _fallback() internal virtual {
+ _beforeFallback();
+ _delegate(_implementation());
+ }
+
+ /**
+ * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
+ * function in the contract matches the call data.
+ */
+ fallback () external payable virtual {
+ _fallback();
+ }
+
+ /**
+ * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
+ * is empty.
+ */
+ receive () external payable virtual {
+ _fallback();
+ }
+
+ /**
+ * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
+ * call, or as part of the Solidity `fallback` or `receive` functions.
+ *
+ * If overriden should call `super._beforeFallback()`.
+ */
+ function _beforeFallback() internal virtual {
+ }
+}
diff --git a/bridge/contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol b/bridge/contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol
new file mode 100644
index 000000000..237bb9f93
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "../../ownership/Ownable.sol";
+import "./TransparentUpgradeableProxy.sol";
+
+/**
+ * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an
+ * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.
+ */
+contract ProxyAdmin is Ownable {
+
+ /**
+ * @dev Returns the current implementation of `proxy`.
+ *
+ * Requirements:
+ *
+ * - This contract must be the admin of `proxy`.
+ */
+ function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {
+ // We need to manually run the static call since the getter cannot be flagged as view
+ // bytes4(keccak256("implementation()")) == 0x5c60da1b
+ (bool success, bytes memory returndata) = address(proxy).staticcall(hex"5c60da1b");
+ require(success);
+ return abi.decode(returndata, (address));
+ }
+
+ /**
+ * @dev Returns the current admin of `proxy`.
+ *
+ * Requirements:
+ *
+ * - This contract must be the admin of `proxy`.
+ */
+ function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {
+ // We need to manually run the static call since the getter cannot be flagged as view
+ // bytes4(keccak256("admin()")) == 0xf851a440
+ (bool success, bytes memory returndata) = address(proxy).staticcall(hex"f851a440");
+ require(success);
+ return abi.decode(returndata, (address));
+ }
+
+ /**
+ * @dev Changes the admin of `proxy` to `newAdmin`.
+ *
+ * Requirements:
+ *
+ * - This contract must be the current admin of `proxy`.
+ */
+ function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {
+ proxy.changeAdmin(newAdmin);
+ }
+
+ /**
+ * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.
+ *
+ * Requirements:
+ *
+ * - This contract must be the admin of `proxy`.
+ */
+ function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {
+ proxy.upgradeTo(implementation);
+ }
+
+ /**
+ * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See
+ * {TransparentUpgradeableProxy-upgradeToAndCall}.
+ *
+ * Requirements:
+ *
+ * - This contract must be the admin of `proxy`.
+ */
+ function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {
+ proxy.upgradeToAndCall{value: msg.value}(implementation, data);
+ }
+}
diff --git a/bridge/contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol b/bridge/contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol
new file mode 100644
index 000000000..d507e65ca
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "./UpgradeableProxy.sol";
+
+/**
+ * @dev This contract implements a proxy that is upgradeable by an admin.
+ *
+ * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector
+ * clashing], which can potentially be used in an attack, this contract uses the
+ * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two
+ * things that go hand in hand:
+ *
+ * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if
+ * that call matches one of the admin functions exposed by the proxy itself.
+ * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the
+ * implementation. If the admin tries to call a function on the implementation it will fail with an error that says
+ * "admin cannot fallback to proxy target".
+ *
+ * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing
+ * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due
+ * to sudden errors when trying to call a function from the proxy implementation.
+ *
+ * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,
+ * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.
+ */
+contract TransparentUpgradeableProxy is UpgradeableProxy {
+ /**
+ * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and
+ * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.
+ */
+ constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {
+ assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));
+ _setAdmin(admin_);
+ }
+
+ /**
+ * @dev Emitted when the admin account has changed.
+ */
+ event AdminChanged(address previousAdmin, address newAdmin);
+
+ /**
+ * @dev Storage slot with the admin of the contract.
+ * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
+ * validated in the constructor.
+ */
+ bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
+
+ /**
+ * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.
+ */
+ modifier ifAdmin() {
+ if (msg.sender == _admin()) {
+ _;
+ } else {
+ _fallback();
+ }
+ }
+
+ /**
+ * @dev Returns the current admin.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.
+ *
+ * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
+ * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
+ * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
+ */
+ function admin() external ifAdmin returns (address admin_) {
+ admin_ = _admin();
+ }
+
+ /**
+ * @dev Returns the current implementation.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.
+ *
+ * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
+ * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
+ * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
+ */
+ function implementation() external ifAdmin returns (address implementation_) {
+ implementation_ = _implementation();
+ }
+
+ /**
+ * @dev Changes the admin of the proxy.
+ *
+ * Emits an {AdminChanged} event.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.
+ */
+ function changeAdmin(address newAdmin) external virtual ifAdmin {
+ require(newAdmin != address(0), "TransparentUpgradeableProxy: new admin is the zero address");
+ emit AdminChanged(_admin(), newAdmin);
+ _setAdmin(newAdmin);
+ }
+
+ /**
+ * @dev Upgrade the implementation of the proxy.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.
+ */
+ function upgradeTo(address newImplementation) external virtual ifAdmin {
+ _upgradeTo(newImplementation);
+ }
+
+ /**
+ * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified
+ * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the
+ * proxied contract.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.
+ */
+ function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {
+ _upgradeTo(newImplementation);
+ Address.functionDelegateCall(newImplementation, data);
+ }
+
+ /**
+ * @dev Returns the current admin.
+ */
+ function _admin() internal view virtual returns (address adm) {
+ bytes32 slot = _ADMIN_SLOT;
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ adm := sload(slot)
+ }
+ }
+
+ /**
+ * @dev Stores a new address in the EIP1967 admin slot.
+ */
+ function _setAdmin(address newAdmin) private {
+ bytes32 slot = _ADMIN_SLOT;
+
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ sstore(slot, newAdmin)
+ }
+ }
+
+ /**
+ * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.
+ */
+ function _beforeFallback() internal virtual override {
+ require(msg.sender != _admin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target");
+ super._beforeFallback();
+ }
+}
diff --git a/bridge/contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol b/bridge/contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol
new file mode 100644
index 000000000..ab595cdd9
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "./Proxy.sol";
+import "../../utils/Address.sol";
+
+/**
+ * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
+ * implementation address that can be changed. This address is stored in storage in the location specified by
+ * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
+ * implementation behind the proxy.
+ *
+ * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see
+ * {TransparentUpgradeableProxy}.
+ */
+contract UpgradeableProxy is Proxy {
+ /**
+ * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
+ *
+ * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
+ * function call, and allows initializating the storage of the proxy like a Solidity constructor.
+ */
+ constructor(address _logic, bytes memory _data) payable {
+ assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
+ _setImplementation(_logic);
+ if(_data.length > 0) {
+ Address.functionDelegateCall(_logic, _data);
+ }
+ }
+
+ /**
+ * @dev Emitted when the implementation is upgraded.
+ */
+ event Upgraded(address indexed implementation);
+
+ /**
+ * @dev Storage slot with the address of the current implementation.
+ * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
+ * validated in the constructor.
+ */
+ bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
+
+ /**
+ * @dev Returns the current implementation address.
+ */
+ function _implementation() internal view virtual override returns (address impl) {
+ bytes32 slot = _IMPLEMENTATION_SLOT;
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ impl := sload(slot)
+ }
+ }
+
+ /**
+ * @dev Upgrades the proxy to a new implementation.
+ *
+ * Emits an {Upgraded} event.
+ */
+ function _upgradeTo(address newImplementation) internal virtual {
+ _setImplementation(newImplementation);
+ emit Upgraded(newImplementation);
+ }
+
+ /**
+ * @dev Stores a new address in the EIP1967 implementation slot.
+ */
+ function _setImplementation(address newImplementation) private {
+ require(Address.isContract(newImplementation), "UpgradeableProxy: new implementation is not a contract");
+
+ bytes32 slot = _IMPLEMENTATION_SLOT;
+
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ sstore(slot, newImplementation)
+ }
+ }
+}
diff --git a/bridge/contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol b/bridge/contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol
new file mode 100644
index 000000000..7ab0eaae2
--- /dev/null
+++ b/bridge/contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+import "../Initializable.sol";
+
+/**
+ * @title Helps contracts guard against reentrancy attacks.
+ * @author Remco Bloemen , Eenae
+ * @dev If you mark a function `nonReentrant`, you should also
+ * mark it `external`.
+ */
+contract ReentrancyGuard is Initializable {
+ /// @dev counter to allow mutex lock with only one SSTORE operation
+ uint256 private _guardCounter;
+
+ function initialize() public initializer {
+ // The counter starts at one to prevent changing it from zero to a non-zero
+ // value, which is a more expensive operation.
+ _guardCounter = 1;
+ }
+
+ /**
+ * @dev Prevents a contract from calling itself, directly or indirectly.
+ * Calling a `nonReentrant` function from another `nonReentrant`
+ * function is not supported. It is possible to prevent this from happening
+ * by making the `nonReentrant` function external, and make it call a
+ * `private` function that does the actual work.
+ */
+ modifier nonReentrant() {
+ _guardCounter += 1;
+ uint256 localCounter = _guardCounter;
+ _;
+ require(localCounter == _guardCounter, "ReentrancyGuard: no reentrant allowed");
+ }
+}
\ No newline at end of file
diff --git a/bridge/contracts/zeppelin/utils/Address.sol b/bridge/contracts/zeppelin/utils/Address.sol
new file mode 100644
index 000000000..2755a2966
--- /dev/null
+++ b/bridge/contracts/zeppelin/utils/Address.sol
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Collection of functions related to the address type
+ */
+library Address {
+ /**
+ * @dev Returns true if `account` is a contract.
+ *
+ * [IMPORTANT]
+ * ====
+ * It is unsafe to assume that an address for which this function returns
+ * false is an externally-owned account (EOA) and not a contract.
+ *
+ * Among others, `isContract` will return false for the following
+ * types of addresses:
+ *
+ * - an externally-owned account
+ * - a contract in construction
+ * - an address where a contract will be created
+ * - an address where a contract lived, but was destroyed
+ * ====
+ */
+ function isContract(address account) internal view returns (bool) {
+ // This method relies on extcodesize, which returns 0 for contracts in
+ // construction, since the code is only stored at the end of the
+ // constructor execution.
+
+ uint256 size;
+ // solhint-disable-next-line no-inline-assembly
+ assembly { size := extcodesize(account) }
+ return size > 0;
+ }
+
+ /**
+ * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
+ * `recipient`, forwarding all available gas and reverting on errors.
+ *
+ * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
+ * of certain opcodes, possibly making contracts go over the 2300 gas limit
+ * imposed by `transfer`, making them unable to receive funds via
+ * `transfer`. {sendValue} removes this limitation.
+ *
+ * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
+ *
+ * IMPORTANT: because control is transferred to `recipient`, care must be
+ * taken to not create reentrancy vulnerabilities. Consider using
+ * {ReentrancyGuard} or the
+ * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
+ */
+ function sendValue(address payable recipient, uint256 amount) internal {
+ require(address(this).balance >= amount, "Address: insufficient balance");
+
+ // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
+ (bool success, ) = recipient.call{ value: amount }("");
+ require(success, "Address: unable to send value, recipient may have reverted");
+ }
+
+ /**
+ * @dev Performs a Solidity function call using a low level `call`. A
+ * plain`call` is an unsafe replacement for a function call: use this
+ * function instead.
+ *
+ * If `target` reverts with a revert reason, it is bubbled up by this
+ * function (like regular Solidity function calls).
+ *
+ * Returns the raw returned data. To convert to the expected return value,
+ * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
+ *
+ * Requirements:
+ *
+ * - `target` must be a contract.
+ * - calling `target` with `data` must not revert.
+ *
+ * _Available since v3.1._
+ */
+ function functionCall(address target, bytes memory data) internal returns (bytes memory) {
+ return functionCall(target, data, "Address: low-level call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
+ * `errorMessage` as a fallback revert reason when `target` reverts.
+ *
+ * _Available since v3.1._
+ */
+ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
+ return functionCallWithValue(target, data, 0, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but also transferring `value` wei to `target`.
+ *
+ * Requirements:
+ *
+ * - the calling contract must have an ETH balance of at least `value`.
+ * - the called Solidity function must be `payable`.
+ *
+ * _Available since v3.1._
+ */
+ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
+ return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
+ * with `errorMessage` as a fallback revert reason when `target` reverts.
+ *
+ * _Available since v3.1._
+ */
+ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
+ require(address(this).balance >= value, "Address: insufficient balance for call");
+ require(isContract(target), "Address: call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.call{ value: value }(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but performing a static call.
+ *
+ * _Available since v3.3._
+ */
+ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
+ return functionStaticCall(target, data, "Address: low-level static call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
+ * but performing a static call.
+ *
+ * _Available since v3.3._
+ */
+ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
+ require(isContract(target), "Address: static call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.staticcall(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but performing a delegate call.
+ *
+ * _Available since v3.4._
+ */
+ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
+ return functionDelegateCall(target, data, "Address: low-level delegate call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
+ * but performing a delegate call.
+ *
+ * _Available since v3.4._
+ */
+ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
+ require(isContract(target), "Address: delegate call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.delegatecall(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
+ if (success) {
+ return returndata;
+ } else {
+ // Look for revert reason and bubble it up if present
+ if (returndata.length > 0) {
+ // The easiest way to bubble the revert reason is using memory via assembly
+
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ let returndata_size := mload(returndata)
+ revert(add(32, returndata), returndata_size)
+ }
+ } else {
+ revert(errorMessage);
+ }
+ }
+ }
+}
diff --git a/bridge/contracts/zeppelin/utils/EnumerableMap.sol b/bridge/contracts/zeppelin/utils/EnumerableMap.sol
new file mode 100644
index 000000000..77fd12562
--- /dev/null
+++ b/bridge/contracts/zeppelin/utils/EnumerableMap.sol
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+/**
+ * @dev Library for managing an enumerable variant of Solidity's
+ * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
+ * type.
+ *
+ * Maps have the following properties:
+ *
+ * - Entries are added, removed, and checked for existence in constant time
+ * (O(1)).
+ * - Entries are enumerated in O(n). No guarantees are made on the ordering.
+ *
+ * ```
+ * contract Example {
+ * // Add the library methods
+ * using EnumerableMap for EnumerableMap.UintToAddressMap;
+ *
+ * // Declare a set state variable
+ * EnumerableMap.UintToAddressMap private myMap;
+ * }
+ * ```
+ *
+ * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are
+ * supported.
+ */
+library EnumerableMap {
+ // To implement this library for multiple types with as little code
+ // repetition as possible, we write it in terms of a generic Map type with
+ // bytes32 keys and values.
+ // The Map implementation uses private functions, and user-facing
+ // implementations (such as Uint256ToAddressMap) are just wrappers around
+ // the underlying Map.
+ // This means that we can only create new EnumerableMaps for types that fit
+ // in bytes32.
+
+ struct MapEntry {
+ bytes32 _key;
+ bytes32 _value;
+ }
+
+ struct Map {
+ // Storage of map keys and values
+ MapEntry[] _entries;
+
+ // Position of the entry defined by a key in the `entries` array, plus 1
+ // because index 0 means a key is not in the map.
+ mapping (bytes32 => uint256) _indexes;
+ }
+
+ /**
+ * @dev Adds a key-value pair to a map, or updates the value for an existing
+ * key. O(1).
+ *
+ * Returns true if the key was added to the map, that is if it was not
+ * already present.
+ */
+ function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {
+ // We read and store the key's index to prevent multiple reads from the same storage slot
+ uint256 keyIndex = map._indexes[key];
+
+ if (keyIndex == 0) { // Equivalent to !contains(map, key)
+ map._entries.push(MapEntry({ _key: key, _value: value }));
+ // The entry is stored at length-1, but we add 1 to all indexes
+ // and use 0 as a sentinel value
+ map._indexes[key] = map._entries.length;
+ return true;
+ } else {
+ map._entries[keyIndex - 1]._value = value;
+ return false;
+ }
+ }
+
+ /**
+ * @dev Removes a key-value pair from a map. O(1).
+ *
+ * Returns true if the key was removed from the map, that is if it was present.
+ */
+ function _remove(Map storage map, bytes32 key) private returns (bool) {
+ // We read and store the key's index to prevent multiple reads from the same storage slot
+ uint256 keyIndex = map._indexes[key];
+
+ if (keyIndex != 0) { // Equivalent to contains(map, key)
+ // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one
+ // in the array, and then remove the last entry (sometimes called as 'swap and pop').
+ // This modifies the order of the array, as noted in {at}.
+
+ uint256 toDeleteIndex = keyIndex - 1;
+ uint256 lastIndex = map._entries.length - 1;
+
+ // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs
+ // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
+
+ MapEntry storage lastEntry = map._entries[lastIndex];
+
+ // Move the last entry to the index where the entry to delete is
+ map._entries[toDeleteIndex] = lastEntry;
+ // Update the index for the moved entry
+ map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based
+
+ // Delete the slot where the moved entry was stored
+ map._entries.pop();
+
+ // Delete the index for the deleted slot
+ delete map._indexes[key];
+
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @dev Returns true if the key is in the map. O(1).
+ */
+ function _contains(Map storage map, bytes32 key) private view returns (bool) {
+ return map._indexes[key] != 0;
+ }
+
+ /**
+ * @dev Returns the number of key-value pairs in the map. O(1).
+ */
+ function _length(Map storage map) private view returns (uint256) {
+ return map._entries.length;
+ }
+
+ /**
+ * @dev Returns the key-value pair stored at position `index` in the map. O(1).
+ *
+ * Note that there are no guarantees on the ordering of entries inside the
+ * array, and it may change when more entries are added or removed.
+ *
+ * Requirements:
+ *
+ * - `index` must be strictly less than {length}.
+ */
+ function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {
+ require(map._entries.length > index, "EnumerableMap: index out of bounds");
+
+ MapEntry storage entry = map._entries[index];
+ return (entry._key, entry._value);
+ }
+
+ /**
+ * @dev Tries to returns the value associated with `key`. O(1).
+ * Does not revert if `key` is not in the map.
+ */
+ function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {
+ uint256 keyIndex = map._indexes[key];
+ if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)
+ return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based
+ }
+
+ /**
+ * @dev Returns the value associated with `key`. O(1).
+ *
+ * Requirements:
+ *
+ * - `key` must be in the map.
+ */
+ function _get(Map storage map, bytes32 key) private view returns (bytes32) {
+ uint256 keyIndex = map._indexes[key];
+ require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key)
+ return map._entries[keyIndex - 1]._value; // All indexes are 1-based
+ }
+
+ /**
+ * @dev Same as {_get}, with a custom error message when `key` is not in the map.
+ *
+ * CAUTION: This function is deprecated because it requires allocating memory for the error
+ * message unnecessarily. For custom revert reasons use {_tryGet}.
+ */
+ function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {
+ uint256 keyIndex = map._indexes[key];
+ require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)
+ return map._entries[keyIndex - 1]._value; // All indexes are 1-based
+ }
+
+ // UintToAddressMap
+
+ struct UintToAddressMap {
+ Map _inner;
+ }
+
+ /**
+ * @dev Adds a key-value pair to a map, or updates the value for an existing
+ * key. O(1).
+ *
+ * Returns true if the key was added to the map, that is if it was not
+ * already present.
+ */
+ function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {
+ return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
+ }
+
+ /**
+ * @dev Removes a value from a set. O(1).
+ *
+ * Returns true if the key was removed from the map, that is if it was present.
+ */
+ function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
+ return _remove(map._inner, bytes32(key));
+ }
+
+ /**
+ * @dev Returns true if the key is in the map. O(1).
+ */
+ function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
+ return _contains(map._inner, bytes32(key));
+ }
+
+ /**
+ * @dev Returns the number of elements in the map. O(1).
+ */
+ function length(UintToAddressMap storage map) internal view returns (uint256) {
+ return _length(map._inner);
+ }
+
+ /**
+ * @dev Returns the element stored at position `index` in the set. O(1).
+ * Note that there are no guarantees on the ordering of values inside the
+ * array, and it may change when more values are added or removed.
+ *
+ * Requirements:
+ *
+ * - `index` must be strictly less than {length}.
+ */
+ function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
+ (bytes32 key, bytes32 value) = _at(map._inner, index);
+ return (uint256(key), address(uint160(uint256(value))));
+ }
+
+ /**
+ * @dev Tries to returns the value associated with `key`. O(1).
+ * Does not revert if `key` is not in the map.
+ *
+ * _Available since v3.4._
+ */
+ function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
+ (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
+ return (success, address(uint160(uint256(value))));
+ }
+
+ /**
+ * @dev Returns the value associated with `key`. O(1).
+ *
+ * Requirements:
+ *
+ * - `key` must be in the map.
+ */
+ function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
+ return address(uint160(uint256(_get(map._inner, bytes32(key)))));
+ }
+
+ /**
+ * @dev Same as {get}, with a custom error message when `key` is not in the map.
+ *
+ * CAUTION: This function is deprecated because it requires allocating memory for the error
+ * message unnecessarily. For custom revert reasons use {tryGet}.
+ */
+ function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {
+ return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));
+ }
+}
diff --git a/bridge/contracts/zeppelin/utils/EnumerableSet.sol b/bridge/contracts/zeppelin/utils/EnumerableSet.sol
new file mode 100644
index 000000000..637f1901d
--- /dev/null
+++ b/bridge/contracts/zeppelin/utils/EnumerableSet.sol
@@ -0,0 +1,297 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+/**
+ * @dev Library for managing
+ * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
+ * types.
+ *
+ * Sets have the following properties:
+ *
+ * - Elements are added, removed, and checked for existence in constant time
+ * (O(1)).
+ * - Elements are enumerated in O(n). No guarantees are made on the ordering.
+ *
+ * ```
+ * contract Example {
+ * // Add the library methods
+ * using EnumerableSet for EnumerableSet.AddressSet;
+ *
+ * // Declare a set state variable
+ * EnumerableSet.AddressSet private mySet;
+ * }
+ * ```
+ *
+ * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
+ * and `uint256` (`UintSet`) are supported.
+ */
+library EnumerableSet {
+ // To implement this library for multiple types with as little code
+ // repetition as possible, we write it in terms of a generic Set type with
+ // bytes32 values.
+ // The Set implementation uses private functions, and user-facing
+ // implementations (such as AddressSet) are just wrappers around the
+ // underlying Set.
+ // This means that we can only create new EnumerableSets for types that fit
+ // in bytes32.
+
+ struct Set {
+ // Storage of set values
+ bytes32[] _values;
+
+ // Position of the value in the `values` array, plus 1 because index 0
+ // means a value is not in the set.
+ mapping (bytes32 => uint256) _indexes;
+ }
+
+ /**
+ * @dev Add a value to a set. O(1).
+ *
+ * Returns true if the value was added to the set, that is if it was not
+ * already present.
+ */
+ function _add(Set storage set, bytes32 value) private returns (bool) {
+ if (!_contains(set, value)) {
+ set._values.push(value);
+ // The value is stored at length-1, but we add 1 to all indexes
+ // and use 0 as a sentinel value
+ set._indexes[value] = set._values.length;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @dev Removes a value from a set. O(1).
+ *
+ * Returns true if the value was removed from the set, that is if it was
+ * present.
+ */
+ function _remove(Set storage set, bytes32 value) private returns (bool) {
+ // We read and store the value's index to prevent multiple reads from the same storage slot
+ uint256 valueIndex = set._indexes[value];
+
+ if (valueIndex != 0) { // Equivalent to contains(set, value)
+ // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
+ // the array, and then remove the last element (sometimes called as 'swap and pop').
+ // This modifies the order of the array, as noted in {at}.
+
+ uint256 toDeleteIndex = valueIndex - 1;
+ uint256 lastIndex = set._values.length - 1;
+
+ // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
+ // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
+
+ bytes32 lastvalue = set._values[lastIndex];
+
+ // Move the last value to the index where the value to delete is
+ set._values[toDeleteIndex] = lastvalue;
+ // Update the index for the moved value
+ set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based
+
+ // Delete the slot where the moved value was stored
+ set._values.pop();
+
+ // Delete the index for the deleted slot
+ delete set._indexes[value];
+
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @dev Returns true if the value is in the set. O(1).
+ */
+ function _contains(Set storage set, bytes32 value) private view returns (bool) {
+ return set._indexes[value] != 0;
+ }
+
+ /**
+ * @dev Returns the number of values on the set. O(1).
+ */
+ function _length(Set storage set) private view returns (uint256) {
+ return set._values.length;
+ }
+
+ /**
+ * @dev Returns the value stored at position `index` in the set. O(1).
+ *
+ * Note that there are no guarantees on the ordering of values inside the
+ * array, and it may change when more values are added or removed.
+ *
+ * Requirements:
+ *
+ * - `index` must be strictly less than {length}.
+ */
+ function _at(Set storage set, uint256 index) private view returns (bytes32) {
+ require(set._values.length > index, "EnumerableSet: index out of bounds");
+ return set._values[index];
+ }
+
+ // Bytes32Set
+
+ struct Bytes32Set {
+ Set _inner;
+ }
+
+ /**
+ * @dev Add a value to a set. O(1).
+ *
+ * Returns true if the value was added to the set, that is if it was not
+ * already present.
+ */
+ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
+ return _add(set._inner, value);
+ }
+
+ /**
+ * @dev Removes a value from a set. O(1).
+ *
+ * Returns true if the value was removed from the set, that is if it was
+ * present.
+ */
+ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
+ return _remove(set._inner, value);
+ }
+
+ /**
+ * @dev Returns true if the value is in the set. O(1).
+ */
+ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
+ return _contains(set._inner, value);
+ }
+
+ /**
+ * @dev Returns the number of values in the set. O(1).
+ */
+ function length(Bytes32Set storage set) internal view returns (uint256) {
+ return _length(set._inner);
+ }
+
+ /**
+ * @dev Returns the value stored at position `index` in the set. O(1).
+ *
+ * Note that there are no guarantees on the ordering of values inside the
+ * array, and it may change when more values are added or removed.
+ *
+ * Requirements:
+ *
+ * - `index` must be strictly less than {length}.
+ */
+ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
+ return _at(set._inner, index);
+ }
+
+ // AddressSet
+
+ struct AddressSet {
+ Set _inner;
+ }
+
+ /**
+ * @dev Add a value to a set. O(1).
+ *
+ * Returns true if the value was added to the set, that is if it was not
+ * already present.
+ */
+ function add(AddressSet storage set, address value) internal returns (bool) {
+ return _add(set._inner, bytes32(uint256(uint160(value))));
+ }
+
+ /**
+ * @dev Removes a value from a set. O(1).
+ *
+ * Returns true if the value was removed from the set, that is if it was
+ * present.
+ */
+ function remove(AddressSet storage set, address value) internal returns (bool) {
+ return _remove(set._inner, bytes32(uint256(uint160(value))));
+ }
+
+ /**
+ * @dev Returns true if the value is in the set. O(1).
+ */
+ function contains(AddressSet storage set, address value) internal view returns (bool) {
+ return _contains(set._inner, bytes32(uint256(uint160(value))));
+ }
+
+ /**
+ * @dev Returns the number of values in the set. O(1).
+ */
+ function length(AddressSet storage set) internal view returns (uint256) {
+ return _length(set._inner);
+ }
+
+ /**
+ * @dev Returns the value stored at position `index` in the set. O(1).
+ *
+ * Note that there are no guarantees on the ordering of values inside the
+ * array, and it may change when more values are added or removed.
+ *
+ * Requirements:
+ *
+ * - `index` must be strictly less than {length}.
+ */
+ function at(AddressSet storage set, uint256 index) internal view returns (address) {
+ return address(uint160(uint256(_at(set._inner, index))));
+ }
+
+
+ // UintSet
+
+ struct UintSet {
+ Set _inner;
+ }
+
+ /**
+ * @dev Add a value to a set. O(1).
+ *
+ * Returns true if the value was added to the set, that is if it was not
+ * already present.
+ */
+ function add(UintSet storage set, uint256 value) internal returns (bool) {
+ return _add(set._inner, bytes32(value));
+ }
+
+ /**
+ * @dev Removes a value from a set. O(1).
+ *
+ * Returns true if the value was removed from the set, that is if it was
+ * present.
+ */
+ function remove(UintSet storage set, uint256 value) internal returns (bool) {
+ return _remove(set._inner, bytes32(value));
+ }
+
+ /**
+ * @dev Returns true if the value is in the set. O(1).
+ */
+ function contains(UintSet storage set, uint256 value) internal view returns (bool) {
+ return _contains(set._inner, bytes32(value));
+ }
+
+ /**
+ * @dev Returns the number of values on the set. O(1).
+ */
+ function length(UintSet storage set) internal view returns (uint256) {
+ return _length(set._inner);
+ }
+
+ /**
+ * @dev Returns the value stored at position `index` in the set. O(1).
+ *
+ * Note that there are no guarantees on the ordering of values inside the
+ * array, and it may change when more values are added or removed.
+ *
+ * Requirements:
+ *
+ * - `index` must be strictly less than {length}.
+ */
+ function at(UintSet storage set, uint256 index) internal view returns (uint256) {
+ return uint256(_at(set._inner, index));
+ }
+}
diff --git a/bridge/contracts/zeppelin/utils/Strings.sol b/bridge/contracts/zeppelin/utils/Strings.sol
new file mode 100644
index 000000000..aa3e7f9af
--- /dev/null
+++ b/bridge/contracts/zeppelin/utils/Strings.sol
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+/**
+ * @dev String operations.
+ */
+library Strings {
+ /**
+ * @dev Converts a `uint256` to its ASCII `string` decimal representation.
+ */
+ function toString(uint256 value) internal pure returns (string memory) {
+ // Inspired by OraclizeAPI's implementation - MIT licence
+ // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
+
+ if (value == 0) {
+ return "0";
+ }
+ uint256 temp = value;
+ uint256 digits;
+ while (temp != 0) {
+ digits++;
+ temp /= 10;
+ }
+ bytes memory buffer = new bytes(digits);
+ while (value != 0) {
+ digits -= 1;
+ buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
+ value /= 10;
+ }
+ return string(buffer);
+ }
+}
diff --git a/bridge/deploy/01_deploy_multiSigWallet.js b/bridge/deploy/01_deploy_multiSigWallet.js
new file mode 100644
index 000000000..c3b7d114a
--- /dev/null
+++ b/bridge/deploy/01_deploy_multiSigWallet.js
@@ -0,0 +1,26 @@
+const {deploy1820} = require('@thinkanddev/deploy-eip-1820-web3-rsk');
+
+module.exports = async function({getNamedAccounts, deployments, network}) { // HardhatRuntimeEnvironment
+ const {deployer, multiSig} = await getNamedAccounts();
+ const {deploy, log} = deployments;
+
+ if (multiSig) {
+ return;
+ }
+
+ const deployResult = await deploy('MultiSigWallet', {
+ from: deployer,
+ args: [[deployer], 1],
+ log: true
+ });
+
+ if (deployResult.newlyDeployed) {
+ log(`Contract MultiSigWallet deployed at ${deployResult.address} using ${deployResult.receipt.gasUsed.toString()} gas`);
+ }
+
+ if (!network.live) {
+ await deploy1820(web3);
+ }
+};
+module.exports.id = 'deploy_multiSigWallet'; // id required to prevent re-execution
+module.exports.tags = ['MultiSigWallet', 'DeployFromScratch', 'IntegrationTest'];
diff --git a/bridge/deploy/02_deploy_proxyAdmin.js b/bridge/deploy/02_deploy_proxyAdmin.js
new file mode 100644
index 000000000..390f45037
--- /dev/null
+++ b/bridge/deploy/02_deploy_proxyAdmin.js
@@ -0,0 +1,36 @@
+const address = require('../hardhat/helper/address');
+
+module.exports = async function(hre) { // HardhatRuntimeEnvironment
+ const {getNamedAccounts, deployments} = hre;
+ const {deployer, proxyAdmin} = await getNamedAccounts();
+ const {deploy, log, execute} = deployments;
+
+ if (proxyAdmin) {
+ return;
+ }
+
+ const deployResult = await deploy('ProxyAdmin', {
+ from: deployer,
+ log: true
+ });
+
+ if (!deployResult.newlyDeployed) {
+ return;
+ }
+
+ const multiSigAddress = await address.getMultiSigAddress(hre);
+ log(`Contract ProxyAdmin deployed at ${deployResult.address} using ${deployResult.receipt.gasUsed.toString()} gas`);
+ await execute('ProxyAdmin', {from: deployer}, 'transferOwnership', multiSigAddress);
+ log(`Transfered Ownership to MultiSig`);
+
+ if(network.live && !chains.isRSK(network)) {
+ log(`Startig Verification of ${deployResult.address}`);
+ await hre.run("verify:verify", {
+ address: deployResult.address,
+ constructorArguments: [],
+ });
+ }
+};
+module.exports.id = 'deploy_proxyAdmin'; // id required to prevent reexecution
+module.exports.tags = ['ProxyAdmin', 'DeployFromScratch', 'IntegrationTest'];
+module.exports.dependencies = ['MultiSigWallet'];
diff --git a/bridge/deploy/03_deploy_sideTokenFactory.js b/bridge/deploy/03_deploy_sideTokenFactory.js
new file mode 100644
index 000000000..3edab897d
--- /dev/null
+++ b/bridge/deploy/03_deploy_sideTokenFactory.js
@@ -0,0 +1,33 @@
+const chains = require("../hardhat/helper/chains");
+
+module.exports = async function (hre) { // HardhatRuntimeEnvironment
+ const {getNamedAccounts, deployments, network} = hre;
+ const {deployer, bridgeProxy} = await getNamedAccounts();
+ const {deploy, log} = deployments;
+
+ // if we have the bridge proxy address
+ // doesn't need to deploy a new SideTokenFactory
+ // because most probably the sideTokenFactory already exists
+ if (bridgeProxy) {
+ return;
+ }
+
+ const deployResult = await deploy('SideTokenFactory', {
+ from: deployer,
+ log: true,
+ });
+
+ if (deployResult.newlyDeployed) {
+ log(`Contract SideTokenFactory deployed at ${deployResult.address} using ${deployResult.receipt.gasUsed.toString()} gas`);
+
+ if(network.live && !chains.isRSK(network)) {
+ log(`Startig Verification of ${deployResult.address}`);
+ await hre.run("verify:verify", {
+ address: deployResult.address,
+ constructorArguments: [],
+ });
+ }
+ }
+};
+module.exports.id = 'deploy_sideTokenFactory'; // id required to prevent reexecution
+module.exports.tags = ['SideTokenFactory', 'DeployFromScratch', 'IntegrationTest'];
diff --git a/bridge/deploy/04_deploy_bridge.js b/bridge/deploy/04_deploy_bridge.js
new file mode 100644
index 000000000..8a6aafd59
--- /dev/null
+++ b/bridge/deploy/04_deploy_bridge.js
@@ -0,0 +1,38 @@
+const address = require('../hardhat/helper/address');
+const chains = require("../hardhat/helper/chains");
+
+module.exports = async function(hre) { // HardhatRuntimeEnvironment
+ const {deployments, network} = hre;
+ const {deployer} = await getNamedAccounts();
+ const {deploy, log} = deployments;
+ const BRIDGE_LAST_VERSION = 'v4'
+
+ const bridgeProxyAddress = await address.getBridgeProxyAddress(hre);
+ if (bridgeProxyAddress) {
+ const Bridge = await deployments.getArtifact('Bridge');
+ const bridge = new web3.eth.Contract(Bridge.abi, bridgeProxyAddress);
+ const currentBridgeVersion = bridge.methods.version().call();
+ if (currentBridgeVersion === BRIDGE_LAST_VERSION) {
+ return;
+ }
+ }
+
+ const deployResult = await deploy('Bridge', {
+ from: deployer,
+ log: true,
+ });
+
+ if (deployResult.newlyDeployed) {
+ log(`Contract Bridge deployed at ${deployResult.address} using ${deployResult.receipt.gasUsed.toString()} gas`);
+
+ if(network.live && !chains.isRSK(network)) {
+ log(`Startig Verification of ${deployResult.address}`);
+ await hre.run("verify:verify", {
+ address: deployResult.address,
+ constructorArguments: [],
+ });
+ }
+ }
+};
+module.exports.id = 'deploy_bridge'; // id required to prevent reexecution
+module.exports.tags = ['Bridge', 'Upgrade', 'DeployFromScratch', 'IntegrationTest'];
diff --git a/bridge/deploy/05_deploy_bridgeProxy.js b/bridge/deploy/05_deploy_bridgeProxy.js
new file mode 100644
index 000000000..f4d6934bb
--- /dev/null
+++ b/bridge/deploy/05_deploy_bridgeProxy.js
@@ -0,0 +1,53 @@
+const chains = require('../hardhat/helper/chains');
+const address = require('../hardhat/helper/address');
+
+module.exports = async function (hre) { // HardhatRuntimeEnvironment
+ const {getNamedAccounts, deployments, network} = hre;
+ const {deployer, bridgeProxy} = await getNamedAccounts();
+ const {deploy, log} = deployments;
+
+ if (bridgeProxy) {
+ return;
+ }
+
+ const Bridge = await deployments.get('Bridge');
+ const multiSigAddress = await address.getMultiSigAddress(hre);
+ const proxyAdminAddress = await address.getProxyAdminAddress(hre);
+ const sideTokenFactoryAddress = await address.getSideTokenFactoryAddress(hre);
+
+ const bridge = new web3.eth.Contract(Bridge.abi, Bridge.address);
+ const methodCall = bridge.methods.initialize(
+ multiSigAddress,
+ deployer,
+ deployer,
+ sideTokenFactoryAddress
+ );
+ await methodCall.call({ from: deployer })
+
+ const constructorArguments = [
+ Bridge.address,
+ proxyAdminAddress,
+ methodCall.encodeABI()
+ ];
+
+ const deployProxyResult = await deploy('BridgeProxy', {
+ from: deployer,
+ args: constructorArguments,
+ log: true,
+ });
+ if (deployProxyResult.newlyDeployed) {
+ log(`Contract BridgeProxy deployed at ${deployProxyResult.address} using ${deployProxyResult.receipt.gasUsed.toString()} gas`);
+
+ if(network.live && !chains.isRSK(network)) {
+ log(`Startig Verification of ${deployResult.address}`);
+ await hre.run("verify:verify", {
+ address: deployResult.address,
+ constructorArguments: constructorArguments,
+ });
+ }
+ }
+
+};
+module.exports.id = 'deploy_bridge_proxy'; // id required to prevent reexecution
+module.exports.tags = ['BridgeProxy', 'DeployFromScratch', 'IntegrationTest'];
+module.exports.dependencies = ['Bridge', 'MultiSigWallet', 'ProxyAdmin', 'SideTokenFactory'];
diff --git a/bridge/deploy/06_deploy_federation.js b/bridge/deploy/06_deploy_federation.js
new file mode 100644
index 000000000..95871d247
--- /dev/null
+++ b/bridge/deploy/06_deploy_federation.js
@@ -0,0 +1,38 @@
+const address = require('../hardhat/helper/address');
+const chains = require('../hardhat/helper/chains');
+
+module.exports = async function(hre) { // HardhatRuntimeEnvironment
+ const {deployments, network} = hre;
+ const {deployer} = await getNamedAccounts();
+ const {deploy, log} = deployments;
+ const FEDERATION_LAST_VERSION = 'v3'
+
+ const federationProxyAddress = await address.getFederationProxyAddress(hre);
+ if (federationProxyAddress) {
+ const Federation = await deployments.getArtifact('Federation');
+ const federation = new web3.eth.Contract(Federation.abi, federationProxyAddress);
+ const currentFederationVersion = federation.methods.version().call();
+ if (currentFederationVersion === FEDERATION_LAST_VERSION) {
+ return;
+ }
+ }
+
+ const deployResult = await deploy('Federation', {
+ from: deployer,
+ log: true
+ });
+
+ if (deployResult.newlyDeployed) {
+ log(`Contract Federation deployed at ${deployResult.address} using ${deployResult.receipt.gasUsed.toString()} gas`);
+
+ if(network.live && !chains.isRSK(network)) {
+ log(`Startig Verification of ${deployResult.address}`);
+ await hre.run("verify:verify", {
+ address: deployResult.address,
+ constructorArguments: [],
+ });
+ }
+ }
+};
+module.exports.id = 'deploy_federation'; // id required to prevent reexecution
+module.exports.tags = ['Federation', 'Upgrade', 'DeployFromScratch', 'IntegrationTest'];
diff --git a/bridge/deploy/07_deploy_federationProxy.js b/bridge/deploy/07_deploy_federationProxy.js
new file mode 100644
index 000000000..3c1630084
--- /dev/null
+++ b/bridge/deploy/07_deploy_federationProxy.js
@@ -0,0 +1,85 @@
+const address = require('../hardhat/helper/address');
+const chains = require('../hardhat/helper/chains');
+
+
+module.exports = async function(hre) { // HardhatRuntimeEnvironment
+ const {getNamedAccounts, deployments, network} = hre;
+ const {deployer, federationProxy} = await getNamedAccounts();
+ const {deploy, log} = deployments;
+
+ if (federationProxy) {
+ return;
+ }
+
+ const Federation = await deployments.get('Federation');
+ const proxyAdminAddress = await address.getProxyAdminAddress(hre);
+ const multiSigAddress = await address.getMultiSigAddress(hre);
+ const bridgeProxyAddress = await address.getBridgeProxyAddress(hre);
+ const federationConf = getFederationConf(deployer, network);
+
+ const federationLogic = new web3.eth.Contract(Federation.abi, Federation.address);
+ const methodCall = federationLogic.methods.initialize(
+ federationConf.members,
+ federationConf.required,
+ bridgeProxyAddress,
+ multiSigAddress,
+ );
+ methodCall.call({from: deployer});
+
+ const constructorArguments = [
+ Federation.address,
+ proxyAdminAddress,
+ methodCall.encodeABI()
+ ];
+
+ console.log('constructorArguments', constructorArguments)
+
+ const deployProxyResult = await deploy('FederationProxy', {
+ from: deployer,
+ contract: 'TransparentUpgradeableProxy',
+ args: constructorArguments,
+ log: true
+ });
+ if (deployProxyResult.newlyDeployed) {
+ log(`Contract FederationProxy deployed at ${deployProxyResult.address} using ${deployProxyResult.receipt.gasUsed.toString()} gas`);
+
+ if(network.live && !chains.isRSK(network)) {
+ log(`Startig Verification of ${deployProxyResult.address}`);
+ await hre.run("verify:verify", {
+ address: deployProxyResult.address,
+ constructorArguments: constructorArguments,
+ });
+ }
+ }
+};
+module.exports.id = 'deploy_federation_proxy'; // id required to prevent reexecution
+module.exports.tags = ['FederationProxy', 'DeployFromScratch', 'IntegrationTest'];
+module.exports.dependencies = ['MultiSigWallet', 'ProxyAdmin', 'Federation', 'BridgeProxy'];
+
+function getFederationConf(deployer, network) {
+ const networkName = network.name.toLowerCase();
+ if (networkName.includes('testnet') || networkName.includes('kovan') || networkName.includes('rinkeby')) {
+ return {
+ members: ['0x8f397ff074ff190fc650e5cab4da039a8163e12a'],
+ required: 1,
+ };
+ }
+
+ if (networkName.includes('mainnet')) {
+ return {
+ members: [
+ '0x5eb6ceca6bdd82f4a38aac0b957e6a4b5b1cceba',
+ '0x8a9ec366c1b359fed1a7372cf8607ec52963b550',
+ '0xa4398c6ff62e9b93b32b28dd29bd27c6b106245f',
+ '0x1089a708b03821b19db9bdf179fbd7ed7ce591d7',
+ '0x04237d65eb6cdc9f93db42fef53f7d5aaca2f1d6'
+ ],
+ required: 2,
+ };
+ }
+
+ return {
+ members: [deployer],
+ required: 1,
+ };
+}
\ No newline at end of file
diff --git a/bridge/deploy/08_deploy_allowToken.js b/bridge/deploy/08_deploy_allowToken.js
new file mode 100644
index 000000000..58d751245
--- /dev/null
+++ b/bridge/deploy/08_deploy_allowToken.js
@@ -0,0 +1,38 @@
+const address = require('../hardhat/helper/address');
+const chains = require('../hardhat/helper/chains');
+
+module.exports = async function(hre) { // HardhatRuntimeEnvironment
+ const {getNamedAccounts, deployments, network} = hre;
+ const {deployer} = await getNamedAccounts();
+ const {deploy, log} = deployments;
+ const ALLOW_TOKEN_LAST_VERSION = 'v2'
+
+ const allowTokensProxyAddress = await address.getAllowTokensProxyAddress(hre);
+ if (allowTokensProxyAddress) {
+ const AllowTokens = await deployments.getArtifact('AllowTokens');
+ const allowTokens = new web3.eth.Contract(AllowTokens.abi, allowTokensProxyAddress);
+ const currentAllowTokensVersion = allowTokens.methods.version().call();
+ if (currentAllowTokensVersion === ALLOW_TOKEN_LAST_VERSION) {
+ return;
+ }
+ }
+
+ const deployResult = await deploy('AllowTokens', {
+ from: deployer,
+ log: true
+ });
+
+ if (deployResult.newlyDeployed) {
+ log(`Contract AllowTokens deployed at ${deployResult.address} using ${deployResult.receipt.gasUsed.toString()} gas`);
+
+ if(network.live && !chains.isRSK(network)) {
+ log(`Startig Verification of ${deployResult.address}`);
+ await hre.run("verify:verify", {
+ address: deployResult.address,
+ constructorArguments: [],
+ });
+ }
+ }
+};
+module.exports.id = 'deploy_allow_tokens'; // id required to prevent reexecution
+module.exports.tags = ['AllowTokens', 'DeployFromScratch', 'IntegrationTest'];
diff --git a/bridge/deploy/09_deploy_allowTokensProxy.js b/bridge/deploy/09_deploy_allowTokensProxy.js
new file mode 100644
index 000000000..2c86e3341
--- /dev/null
+++ b/bridge/deploy/09_deploy_allowTokensProxy.js
@@ -0,0 +1,199 @@
+// We are actually gonna use the latest Bridge but truffle only knows the address of the proxy
+const toWei = web3.utils.toWei;
+const deployHelper = require('../deployed/deployHelper');
+const chains = require('../hardhat/helper/chains');
+const address = require('../hardhat/helper/address');
+
+module.exports = async function(hre) { // HardhatRuntimeEnvironment
+ const {getNamedAccounts, deployments, network} = hre;
+ const {deployer, allowTokensProxy} = await getNamedAccounts();
+ const {deploy, log} = deployments;
+
+ if (allowTokensProxy) {
+ return;
+ }
+
+ const AllowTokens = await deployments.get('AllowTokens');
+ const proxyAdminAddress = await address.getProxyAdminAddress(hre);
+ const bridgeProxyAddress = await address.getBridgeProxyAddress(hre);
+
+ const deployedJson = deployHelper.getDeployed(network.name);
+ const typesInfo = chains.isMainnet(network) ? tokensTypesMainnet() : tokensTypesTestnet();
+
+ const allowTokensLogic = new web3.eth.Contract(AllowTokens.abi, AllowTokens.address);
+ const methodCall = allowTokensLogic.methods.initialize(
+ deployer,
+ bridgeProxyAddress,
+ deployedJson.smallAmountConfirmations ?? '0',
+ deployedJson.mediumAmountConfirmations ?? '0',
+ deployedJson.largeAmountConfirmations ?? '0',
+ typesInfo
+ );
+ methodCall.call({from: deployer});
+
+ const constructorArguments = [
+ AllowTokens.address,
+ proxyAdminAddress,
+ methodCall.encodeABI()
+ ];
+
+ console.log('constructorArguments', constructorArguments)
+
+ const deployResultProxy = await deploy('AllowTokensProxy', {
+ from: deployer,
+ contract: 'TransparentUpgradeableProxy',
+ args: constructorArguments,
+ log: true
+ });
+
+ if (deployResultProxy.newlyDeployed) {
+ log(`Contract AllowTokensProxy deployed at ${deployResultProxy.address} using ${deployResultProxy.receipt.gasUsed.toString()} gas`);
+
+ if(network.live && !chains.isRSK(network)) {
+ log(`Startig Verification of ${deployResultProxy.address}`);
+ await hre.run("verify:verify", {
+ address: deployResultProxy.address,
+ constructorArguments: constructorArguments,
+ });
+ }
+ }
+};
+module.exports.id = 'deploy_allow_tokens_proxy'; // id required to prevent reexecution
+module.exports.tags = ['AllowTokensProxy', 'DeployFromScratch', 'IntegrationTest'];
+module.exports.dependencies = ['ProxyAdmin', 'BridgeProxy', 'AllowTokens'];
+
+function tokensTypesMainnet() {
+ return [
+ {
+ description: 'BTC', limits: {
+ min: toWei('0.0001'),
+ max: toWei('25'),
+ daily: toWei('100'),
+ mediumAmount: toWei('0.1'),
+ largeAmount: toWei('1')
+ }
+ },
+ {
+ description: 'ETH', limits: {
+ min: toWei('0.005'),
+ max: toWei('750'),
+ daily: toWei('3000'),
+ mediumAmount: toWei('3'),
+ largeAmount: toWei('30')
+ }
+ },
+ {
+ description: '<1000usd', limits: {
+ min: toWei('0.01'),
+ max: toWei('2500'),
+ daily: toWei('5000'),
+ mediumAmount: toWei('10'),
+ largeAmount: toWei('100')
+ }
+ },
+ {
+ description: '<100usd', limits: {
+ min: toWei('0.1'),
+ max: toWei('25000'),
+ daily: toWei('50000'),
+ mediumAmount: toWei('100'),
+ largeAmount: toWei('1000')
+ }
+ },
+ {
+ description: '=1usd', limits: {
+ min: toWei('10'),
+ max: toWei('2500000'),
+ daily: toWei('5000000'),
+ mediumAmount: toWei('10000'),
+ largeAmount: toWei('100000')
+ }
+ },
+ {
+ description: '<1usd', limits: {
+ min: toWei('1000'),
+ max: toWei('250000000'),
+ daily: toWei('500000000'),
+ mediumAmount: toWei('1000000'),
+ largeAmount: toWei('10000000')
+ }
+ },
+ {
+ description: '<1cent', limits: {
+ min: toWei('100000'),
+ max: toWei('25000000000'),
+ daily: toWei('50000000000'),
+ mediumAmount: toWei('100000000'),
+ largeAmount: toWei('1000000000')
+ }
+ }
+ ];
+}
+
+function tokensTypesTestnet() {
+ return [
+ {
+ description: 'BTC', limits: {
+ min: toWei('0.0001'),
+ max: toWei('25'),
+ daily: toWei('100'),
+ mediumAmount: toWei('0.01'),
+ largeAmount: toWei('0.1')
+ }
+ },
+ {
+ description: 'ETH', limits: {
+ min: toWei('0.0005'),
+ max: toWei('750'),
+ daily: toWei('3000'),
+ mediumAmount: toWei('0.03'),
+ largeAmount: toWei('0.3')
+ }
+ },
+ {
+ description: '<1000usd', limits: {
+ min: toWei('0.001'),
+ max: toWei('2500'),
+ daily: toWei('5000'),
+ mediumAmount: toWei('0.01'),
+ largeAmount: toWei('0.1')
+ }
+ },
+ {
+ description: '<100usd', limits: {
+ min: toWei('0.1'),
+ max: toWei('25000'),
+ daily: toWei('50000'),
+ mediumAmount: toWei('1'),
+ largeAmount: toWei('10')
+ }
+ },
+ {
+ description: '=1usd', limits: {
+ min: toWei('1'),
+ max: toWei('2500000'),
+ daily: toWei('5000000'),
+ mediumAmount: toWei('10'),
+ largeAmount: toWei('100')
+ }
+ },
+ {
+ description: '<1usd', limits: {
+ min: toWei('10'),
+ max: toWei('250000000'),
+ daily: toWei('500000000'),
+ mediumAmount: toWei('100'),
+ largeAmount: toWei('1000')
+ }
+ },
+ {
+ description: '<1cent', limits: {
+ min: toWei('10'),
+ max: toWei('25000000000'),
+ daily: toWei('50000000000'),
+ mediumAmount: toWei('100'),
+ largeAmount: toWei('1000')
+ }
+ }
+ ];
+}
diff --git a/bridge/deploy/10_transfer_setTokens_allowTokens.js b/bridge/deploy/10_transfer_setTokens_allowTokens.js
new file mode 100644
index 000000000..963c8ca69
--- /dev/null
+++ b/bridge/deploy/10_transfer_setTokens_allowTokens.js
@@ -0,0 +1,49 @@
+const { tokensByChainId } = require("../hardhat/helper/tokens");
+const address = require('../hardhat/helper/address');
+
+function formatToken(token) {
+ return {token: token.address, typeId: token.typeId};
+}
+
+module.exports = async function(hre) { // HardhatRuntimeEnvironment
+ const {getNamedAccounts, deployments, network} = hre;
+ const {deployer, allowTokensProxy} = await getNamedAccounts();
+ const {log} = deployments;
+
+ if (allowTokensProxy) {
+ return;
+ }
+
+ const AllowTokens = await deployments.getArtifact('AllowTokens');
+ const AllowTokensProxy = await deployments.get('AllowTokensProxy');
+ const allowTokens = new web3.eth.Contract(AllowTokens.abi, AllowTokensProxy.address);
+ const multiSigAddress = await address.getMultiSigAddress(hre);
+
+ const owner = await allowTokens.methods.owner().call({from: deployer});
+ if (owner === multiSigAddress) {
+ return
+ }
+
+ const chainID = network.config.network_id;
+ const tokensToSet = [];
+ const tokens = tokensByChainId(chainID);
+
+ for (const token in tokens) {
+ tokensToSet.push(formatToken(tokens[token]));
+ }
+
+ if(tokensToSet.length > 0 ) {
+ await allowTokens.methods.setMultipleTokens(tokensToSet).send({from: deployer});
+ log(`AllowTokens Setted Tokens`);
+ } else {
+ if(network.live) {
+ log(`Set AllowTokens empty tokens to allow`);
+ }
+ }
+ // Set multisig as the owner
+ await allowTokens.methods.transferOwnership(multiSigAddress).send({from: deployer});
+ log(`AllowTokens Transfered Ownership to MultiSigWallet`);
+};
+module.exports.id = 'transfer_set_tokens_allow_tokens'; // id required to prevent reexecution
+module.exports.tags = ['TransferSetTokens', 'DeployFromScratch', 'IntegrationTest'];
+module.exports.dependencies = ['MultiSigWallet', 'AllowTokens', 'AllowTokensProxy'];
\ No newline at end of file
diff --git a/bridge/deploy/11_transfer_sideTokenFactoryToBridge.js b/bridge/deploy/11_transfer_sideTokenFactoryToBridge.js
new file mode 100644
index 000000000..aea7b909e
--- /dev/null
+++ b/bridge/deploy/11_transfer_sideTokenFactoryToBridge.js
@@ -0,0 +1,33 @@
+const sideTokenFactoryName = 'SideTokenFactory';
+const bridgeProxyName = 'BridgeProxy';
+const GAS_LIMIT = 4000000;
+
+/**
+ * Transfers primary ownership of SideTokenFactory to BridgeProxy - if it fails, check if the primary transfer
+ * already occurred (if you're re-running the deploy script and haven't added the side token factory address to
+ * the hardhat.config.js, this can happen).
+ * @param getNamedAccounts
+ * @param deployments
+ * @returns {Promise}
+ */
+module.exports = async function({getNamedAccounts, deployments}) { // HardhatRuntimeEnvironment
+ const {deployer, sideTokenFactory} = await getNamedAccounts();
+ const {log, execute} = deployments;
+ if (sideTokenFactory) {
+ return;
+ }
+ const BridgeProxy = await deployments.get(bridgeProxyName);
+ const SideTokenFactory = await deployments.get(sideTokenFactoryName);
+
+ const sideTokenFactoryContract = new web3.eth.Contract(SideTokenFactory.abi, SideTokenFactory.address);
+ const primary = await sideTokenFactoryContract.methods.primary().call({from: deployer});
+ if (primary === BridgeProxy.address) {
+ return
+ }
+
+ await execute(sideTokenFactoryName, {from: deployer, gasLimit: GAS_LIMIT}, 'transferPrimary', BridgeProxy.address);
+ log(`SideTokenFactory Transferred Primary to BridgeProxy`);
+};
+module.exports.id = 'transfer_side_token_factory_to_bridge';
+module.exports.tags = ['SideTokenFactoryToBridge', 'DeployFromScratch', 'IntegrationTest'];
+module.exports.dependencies = [bridgeProxyName, sideTokenFactoryName];
diff --git a/bridge/deploy/12_transfer_federationToBridge.js b/bridge/deploy/12_transfer_federationToBridge.js
new file mode 100644
index 000000000..8ff2e6d66
--- /dev/null
+++ b/bridge/deploy/12_transfer_federationToBridge.js
@@ -0,0 +1,29 @@
+const address = require('../hardhat/helper/address');
+
+module.exports = async function (hre) { // HardhatRuntimeEnvironment
+ const {getNamedAccounts, deployments} = hre;
+ const {deployer, federationProxy} = await getNamedAccounts();
+ const {log} = deployments;
+
+ if (federationProxy) {
+ return;
+ }
+
+ const Bridge = await deployments.getArtifact('Bridge');
+ const MultiSigWallet = await deployments.getArtifact('MultiSigWallet');
+
+ const bridgeProxyAddress = await address.getBridgeProxyAddress(hre);
+ const federationProxyAddress = await address.getFederationProxyAddress(hre);
+ const multiSigAddress = await address.getMultiSigAddress(hre);
+
+ const multiSigContract = new web3.eth.Contract(MultiSigWallet.abi, multiSigAddress);
+ const bridge = new web3.eth.Contract(Bridge.abi, bridgeProxyAddress);
+
+ const methodCall = bridge.methods.changeFederation(federationProxyAddress);
+ await methodCall.call({ from: multiSigAddress });
+ await multiSigContract.methods.submitTransaction(bridgeProxyAddress, 0, methodCall.encodeABI()).send({ from: deployer });
+ log(`MultiSig submitTransaction Change Federation in the Bridge`);
+};
+module.exports.id = 'transfer_federation_to_bridge'; // id required to prevent reexecution
+module.exports.tags = ['TransferFederationToBridge', 'DeployFromScratch', 'IntegrationTest'];
+module.exports.dependencies = ['Bridge', 'BridgeProxy', 'FederationProxy', 'MultiSigWallet'];
diff --git a/bridge/deploy/13_transfer_allowTokensToBridge.js b/bridge/deploy/13_transfer_allowTokensToBridge.js
new file mode 100644
index 000000000..9e72c4935
--- /dev/null
+++ b/bridge/deploy/13_transfer_allowTokensToBridge.js
@@ -0,0 +1,29 @@
+const address = require('../hardhat/helper/address');
+
+module.exports = async function (hre) { // HardhatRuntimeEnvironment
+ const {getNamedAccounts, deployments} = hre;
+ const {deployer, allowTokensProxy} = await getNamedAccounts()
+ const {log} = deployments
+
+ if (allowTokensProxy) {
+ return;
+ }
+
+ const Bridge = await deployments.getArtifact('Bridge');
+ const MultiSigWallet = await deployments.getArtifact('MultiSigWallet');
+
+ const multiSigAddress = await address.getMultiSigAddress(hre);
+ const allowTokensAddress = await address.getAllowTokensProxyAddress(hre);
+ const bridgeProxyAddress = await address.getBridgeProxyAddress(hre);
+
+ const bridge = new web3.eth.Contract(Bridge.abi, bridgeProxyAddress);
+ const multiSigContract = new web3.eth.Contract(MultiSigWallet.abi, multiSigAddress);
+
+ const methodCall = bridge.methods.changeAllowTokens(allowTokensAddress);
+ await methodCall.call({ from: multiSigAddress });
+ await multiSigContract.methods.submitTransaction(bridgeProxyAddress, 0, methodCall.encodeABI()).send({ from: deployer });
+ log(`MultiSig submitTransaction changeAllowtokens to AllowTokens in the Bridge`);
+};
+module.exports.id = 'transfer_allow_tokens'; // id required to prevent reexecution
+module.exports.tags = ['TransferAllowTokensToBridge', 'DeployFromScratch', 'IntegrationTest'];
+module.exports.dependencies = ['Bridge', 'BridgeProxy', 'AllowTokensProxy', 'MultiSigWallet'];
diff --git a/bridge/deploy/14_conditional_deploy_mainToken.js b/bridge/deploy/14_conditional_deploy_mainToken.js
new file mode 100644
index 000000000..4acabea7b
--- /dev/null
+++ b/bridge/deploy/14_conditional_deploy_mainToken.js
@@ -0,0 +1,25 @@
+module.exports = async function ({getNamedAccounts, deployments, network}) { // HardhatRuntimeEnvironment
+ const {deployer} = await getNamedAccounts()
+ const {deploy, log} = deployments
+
+ if (network.live) {
+ return;
+ }
+
+ const deployResult = await deploy('MainToken', {
+ from: deployer,
+ args: [
+ 'MAIN',
+ 'MAIN',
+ 18,
+ web3.utils.toWei('1000')
+ ],
+ log: true,
+ });
+
+ if (deployResult.newlyDeployed) {
+ log(`Contract MainToken deployed at ${deployResult.address} using ${deployResult.receipt.gasUsed.toString()} gas`);
+ }
+};
+module.exports.id = 'deploy_main_token'; // id required to prevent reexecution
+module.exports.tags = ['MainToken', 'IntegrationTest'];
diff --git a/bridge/deploy/15_conditional_deploy_WRBTC.js b/bridge/deploy/15_conditional_deploy_WRBTC.js
new file mode 100644
index 000000000..c1276486f
--- /dev/null
+++ b/bridge/deploy/15_conditional_deploy_WRBTC.js
@@ -0,0 +1,19 @@
+module.exports = async function ({getNamedAccounts, deployments, network}) { // HardhatRuntimeEnvironment
+ const {deployer} = await getNamedAccounts();
+ const {deploy, log} = deployments;
+
+ if (network.live) {
+ return;
+ }
+
+ const deployResult = await deploy('WRBTC', {
+ from: deployer,
+ log: true,
+ });
+
+ if (deployResult.newlyDeployed) {
+ log(`Contract WRBTC deployed at ${deployResult.address}`);
+ }
+};
+module.exports.id = 'deploy_WRBTC'; // id required to prevent reexecution
+module.exports.tags = ['WRBTC', 'IntegrationTest'];
diff --git a/bridge/deploy/17_set_wrapped_currency.js b/bridge/deploy/17_set_wrapped_currency.js
new file mode 100644
index 000000000..47d78d482
--- /dev/null
+++ b/bridge/deploy/17_set_wrapped_currency.js
@@ -0,0 +1,52 @@
+const address = require('../hardhat/helper/address');
+
+module.exports = async function (hre) { // HardhatRuntimeEnvironment
+ const {getNamedAccounts, deployments, network} = hre;
+ const {deployer, wrappedCurrency, bridgeProxy} = await getNamedAccounts();
+ const {log} = deployments;
+
+ if (bridgeProxy) {
+ return;
+ }
+
+ const Bridge = await deployments.getArtifact('Bridge');
+ const BridgeProxy = await deployments.get('BridgeProxy');
+ const MultiSigWallet = await deployments.getArtifact('MultiSigWallet');
+
+ const multiSigAddress = await address.getMultiSigAddress(hre);
+ const bridgeProxyAddress = await address.getBridgeProxyAddress(hre);
+ const bridge = new web3.eth.Contract(Bridge.abi, bridgeProxyAddress);
+ const multiSigContract = new web3.eth.Contract(MultiSigWallet.abi, multiSigAddress);
+
+ if (!network.live) {
+ const WRBTC = await deployments.get('WRBTC');
+ log(`Get deployed WRBTC at ${WRBTC.address}`);
+ const methodCallSetWrappedCurrency = bridge.methods.setWrappedCurrency(WRBTC.address);
+ await methodCallSetWrappedCurrency.call({ from: multiSigAddress })
+ await multiSigContract.methods.submitTransaction(BridgeProxy.address, 0, methodCallSetWrappedCurrency.encodeABI()).send({ from: deployer });
+ log(`MultiSig submitTransaction set Wrapped Currency in the Bridge`);
+
+ const AllowTokens = await deployments.get('AllowTokens');
+ const AllowTokensProxy = await deployments.get('AllowTokensProxy');
+ const allowTokens = new web3.eth.Contract(AllowTokens.abi, AllowTokensProxy.address);
+ const methodCallSetToken = allowTokens.methods.setToken(WRBTC.address, '0');
+ await methodCallSetToken.call({ from: multiSigAddress });
+ await multiSigContract.methods.submitTransaction(AllowTokensProxy.address, 0, methodCallSetToken.encodeABI()).send({ from: deployer });
+ log(`MultiSig submitTransaction set token WRBTC in AllowTokens`);
+ } else {
+ const methodCallSetWrappedCurrency = bridge.methods.setWrappedCurrency(wrappedCurrency);
+ await methodCallSetWrappedCurrency.call({ from: multiSigAddress });
+ await multiSigContract.methods.submitTransaction(BridgeProxy.address, 0, methodCallSetWrappedCurrency.encodeABI()).send({ from: deployer });
+ log(`MultiSig submitTransaction set Wrapped Currency in the Bridge`);
+ }
+ const methodCallInitDomainSeparator = bridge.methods.initDomainSeparator();
+ await methodCallInitDomainSeparator.call({ from: multiSigAddress });
+ await multiSigContract.methods.submitTransaction(BridgeProxy.address, 0, methodCallInitDomainSeparator.encodeABI()).send({ from: deployer });
+ log(`MultiSig submitTransaction init Domain Separator in the Bridge`);
+
+};
+module.exports.id = 'set_bridge_wrapped_currency'; // id required to prevent reexecution
+module.exports.tags = ['BridgeSetWrappedCurrency', 'DeployFromScratch', 'IntegrationTest'];
+module.exports.dependencies = [
+ 'AllowTokensProxy', 'AllowTokens', 'Bridge', 'BridgeProxy', 'MultiSigWallet'
+];
diff --git a/bridge/deploy/30_create_config_file.js b/bridge/deploy/30_create_config_file.js
new file mode 100644
index 000000000..6e9a67bd9
--- /dev/null
+++ b/bridge/deploy/30_create_config_file.js
@@ -0,0 +1,70 @@
+const fs = require('fs');
+const { web3 } = require('hardhat');
+const hardhatConfig = require('../hardhat.config');
+const toWei = web3.utils.toWei;
+const address = require('../hardhat/helper/address');
+
+module.exports = async function (hre) { // HardhatRuntimeEnvironment
+ const {getNamedAccounts, deployments, network} = hre;
+ const {deployer} = await getNamedAccounts();
+ const {log} = deployments;
+
+ if (network.name === 'soliditycoverage' || network.name === 'hardhat') {
+ return;
+ }
+
+ const BridgeProxy = await deployments.get('BridgeProxy');
+ const multiSigAddress = await address.getMultiSigAddress(hre);
+ const federationProxyAddress = await address.getFederationProxyAddress(hre);
+ const MultiSigWallet = await deployments.getArtifact('MultiSigWallet');
+ const AllowTokensProxy = await deployments.get('AllowTokensProxy');
+
+ const config = {
+ name: network.name,
+ bridge: BridgeProxy.address.toLowerCase(),
+ federation: federationProxyAddress.toLowerCase(),
+ multiSig: multiSigAddress.toLowerCase(),
+ allowTokens: AllowTokensProxy.address.toLowerCase()
+ };
+
+ config.chainId = await web3.eth.net.getId();
+ if (!network.live) {
+ const AllowTokens = await deployments.get('AllowTokens');
+ const allowTokens = new web3.eth.Contract(AllowTokens.abi, AllowTokensProxy.address);
+ const multiSigContract = new web3.eth.Contract(MultiSigWallet.abi, multiSigAddress);
+
+ const MainToken = await deployments.get('MainToken');
+ config.testToken = MainToken.address.toLowerCase();
+ let data = allowTokens.methods.addTokenType(
+ 'MAIN',
+ {
+ max:toWei('10000'),
+ min:toWei('1'),
+ daily:toWei('100000'),
+ mediumAmount:toWei('2'),
+ largeAmount:toWei('3')
+ }
+ ).encodeABI();
+ await multiSigContract.methods.submitTransaction(AllowTokensProxy.address, 0, data).send({ from: deployer });
+ log(`MultiSig submitTransaction addTokenType in the AllowTokens`);
+
+ const typeId = 0;
+ data = allowTokens.methods.setToken(MainToken.address, typeId).encodeABI();
+ await multiSigContract.methods.submitTransaction(AllowTokensProxy.address, 0, data).send({ from: deployer });
+ log(`MultiSig submitTransaction setToken MainToken in the AllowTokens`);
+ // Uncomment below lines to use multiple federators
+ // await multiSigContract.confirmTransaction(0).send({ from: accounts[1] });
+ // await multiSigContract.confirmTransaction(0).send({ from: accounts[2] });
+ }
+ const host = hardhatConfig.networks[network.name]?.url
+ if (host) {
+ config.host = host;
+ } else {
+ config.host = '';
+ }
+ config.fromBlock = await web3.eth.getBlockNumber();
+ fs.writeFileSync(`../federator/config/${network.name}.json`, JSON.stringify(config, null, 4));
+};
+module.exports.id = 'create_config_file'; // id required to prevent reexecution
+module.exports.tags = ['CreateConfigFile', 'DeployFromScratch', 'IntegrationTest'];
+module.exports.dependencies = ['BridgeProxy', 'FederationProxy', 'MultiSigWallet', 'AllowTokensProxy'];
diff --git a/bridge/deploy/upgrades/01_upgrade_bridge.js b/bridge/deploy/upgrades/01_upgrade_bridge.js
new file mode 100644
index 000000000..ec9799a2d
--- /dev/null
+++ b/bridge/deploy/upgrades/01_upgrade_bridge.js
@@ -0,0 +1,26 @@
+const address = require('../../hardhat/helper/address');
+
+module.exports = async function (hre) { // HardhatRuntimeEnvironment
+ const {getNamedAccounts, deployments} = hre;
+ const {deployer, bridgeProxy, proxyAdmin, multiSig} = await getNamedAccounts();
+ const {log} = deployments;
+
+ const bridgeDeployed = await deployments.get('Bridge');
+ const proxyAdminArtifact = await deployments.getArtifact('ProxyAdmin');
+ const multiSigWalletArtifact = await deployments.getArtifact('MultiSigWallet');
+
+ const proxyAdminContract = new web3.eth.Contract(proxyAdminArtifact.abi, proxyAdmin);
+ const methodCallUpdagradeBridgeDeployment = proxyAdminContract.methods.upgrade(bridgeProxy, bridgeDeployed.address);
+ await methodCallUpdagradeBridgeDeployment.call({ from: multiSig });
+
+ const multiSigContract = new web3.eth.Contract(multiSigWalletArtifact.abi, multiSig);
+ await multiSigContract.methods.submitTransaction(
+ proxyAdmin,
+ 0,
+ methodCallUpdagradeBridgeDeployment.encodeABI(),
+ ).send({ from: deployer });
+ log(`MultiSig submitTransaction upgrade BridgeProxy contract in ProxyAdmin`);
+};
+module.exports.id = 'upgrade_bridge'; // id required to prevent reexecution
+module.exports.tags = ['UpgradeBridge', 'Upgrade'];
+module.exports.dependencies = ['Bridge'];
diff --git a/bridge/deploy/upgrades/02_upgrade_federation.js b/bridge/deploy/upgrades/02_upgrade_federation.js
new file mode 100644
index 000000000..6f1e7f148
--- /dev/null
+++ b/bridge/deploy/upgrades/02_upgrade_federation.js
@@ -0,0 +1,26 @@
+const address = require('../../hardhat/helper/address');
+
+module.exports = async function (hre) { // HardhatRuntimeEnvironment
+ const {getNamedAccounts, deployments} = hre;
+ const {deployer, federationProxy, proxyAdmin, multiSig} = await getNamedAccounts();
+ const {log} = deployments;
+
+ const federationDeployed = await deployments.get('Federation');
+ const proxyAdminArtifact = await deployments.getArtifact('ProxyAdmin');
+ const multiSigWalletDeployment = await deployments.getArtifact('MultiSigWallet');
+
+ const proxyAdminContract = new web3.eth.Contract(proxyAdminArtifact.abi, proxyAdmin);
+ const methodCallUpdagradeBridgeDeployment = proxyAdminContract.methods.upgrade(federationProxy, federationDeployed.address);
+ await methodCallUpdagradeBridgeDeployment.call({ from: multiSig });
+
+ const multiSigContract = new web3.eth.Contract(multiSigWalletDeployment.abi, multiSig);
+ await multiSigContract.methods.submitTransaction(
+ proxyAdmin,
+ 0,
+ methodCallUpdagradeBridgeDeployment.encodeABI(),
+ ).send({ from: deployer });
+ log(`MultiSig submitTransaction upgrade FederationProxy contract in ProxyAdmin`);
+};
+module.exports.id = 'upgrade_federation'; // id required to prevent reexecution
+module.exports.tags = ['UpgradeFederation', 'Upgrade'];
+module.exports.dependencies = ['Federation'];
diff --git a/bridge/deployasymm.cmd b/bridge/deployasymm.cmd
deleted file mode 100644
index 214bba58e..000000000
--- a/bridge/deployasymm.cmd
+++ /dev/null
@@ -1,2 +0,0 @@
-call truffle exec maindeploy.js --network development
-call truffle exec sidedeploy.js --network development
diff --git a/bridge/deployed/deployHelper.js b/bridge/deployed/deployHelper.js
new file mode 100644
index 000000000..90d40a9ab
--- /dev/null
+++ b/bridge/deployed/deployHelper.js
@@ -0,0 +1,34 @@
+const fs = require('fs')
+
+function isMainnet(network) {
+ return network.toLowerCase().includes('mainnet')
+}
+
+function isLocalNetwork(network) {
+ return !network.toLowerCase().includes('mainnet')
+ && !network.toLowerCase().includes('kovan')
+ && !network.toLowerCase().includes('testnet');
+}
+
+function getDeployed(network) {
+ try {
+ const deployedString = fs.readFileSync(`${__dirname}/${network}.json`, 'utf8');
+ return JSON.parse(deployedString);
+ } catch(err) {
+ if(!err.message.includes('ENOENT')) {
+ throw err;
+ }
+ return { network };
+ }
+}
+
+function saveDeployed(deployJson) {
+ fs.writeFileSync(`${__dirname}/${deployJson.network}.json`, JSON.stringify(deployJson, null, 4));
+}
+
+module.exports = {
+ isLocalNetwork: isLocalNetwork,
+ getDeployed: getDeployed,
+ saveDeployed: saveDeployed,
+ isMainnet: isMainnet,
+};
diff --git a/bridge/deployed/ethmainnet.json b/bridge/deployed/ethmainnet.json
new file mode 100644
index 000000000..b2f6812ab
--- /dev/null
+++ b/bridge/deployed/ethmainnet.json
@@ -0,0 +1,17 @@
+{
+ "network": "ethmainnet",
+ "MultiSig": "0x040007b1804ad78a97f541bebed377dcb60e4138",
+ "ProxyAdmin": "0xe4d351911a6d599f91a3db1843e2ecb0f851e7e6",
+ "Utils": "0x5f989f2f323a1732a565c9a3f694f2Fa8f0b6120",
+ "Federation": "0x5631a6ac95b6bde690807085aaa70e3b2d9d76c5",
+ "SideTokenFactory": "0xf73c60863bf2930bde2c69df4cb8fe700ae713fb",
+ "AllowTokens": "0x118522603dc0b8490fec2b8db92e6f1c66cd697c",
+ "BridgeProxy": "0x12ed69359919fc775bc2674860e8fe2d2b6a7b5d",
+ "Bridge": "0x9f29f9bda2052884d39f0f032b68aaa14fc363d8",
+ "smallAmountConfirmations": "120",
+ "mediumAmountConfirmations": "240",
+ "largeAmountConfirmations": "5760",
+ "WrappedCurrency": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
+ "AllowTokensProxy": "0xa3fc98e0a7a979677bc14d541be770b2cb0a15f3",
+ "FederationProxy": "0x5e29c223d99648c88610519f96e85e627b3abe17"
+}
\ No newline at end of file
diff --git a/bridge/deployed/kovan.json b/bridge/deployed/kovan.json
new file mode 100644
index 000000000..860250e8b
--- /dev/null
+++ b/bridge/deployed/kovan.json
@@ -0,0 +1,17 @@
+{
+ "network": "kovan",
+ "MultiSig": "0x040007b1804ad78a97f541bebed377dcb60e4138",
+ "ProxyAdmin": "0xe4d351911a6d599f91a3db1843e2ecb0f851e7e6",
+ "Utils": "0xE18b8fb2942493EA96BfC46a044e4F966f2dFaB6",
+ "Federation": "0xb861a1b6690c0252e6fdb707a06b4aca46bc9900",
+ "SideTokenFactory": "0x984192ad76a8fff2edf39c260324d32d8a80512b",
+ "AllowTokens": "0x37f1087591D4685Eb440aCB2Fb2f71a56144A7Db",
+ "Bridge": "0xcb442b34c29b6f2f35f4044dfe7a3eb18531f332",
+ "BridgeProxy": "0x12ed69359919fc775bc2674860e8fe2d2b6a7b5d",
+ "smallAmountConfirmations": "10",
+ "mediumAmountConfirmations": "20",
+ "largeAmountConfirmations": "40",
+ "WrappedCurrency": "0xd0A1E359811322d97991E03f863a0C30C2cF029C",
+ "AllowTokensProxy": "0x92bf86334583909b60f9b798a9dd7debd899fec4",
+ "FederationProxy": "0xa347438bc288f56cb6083a79133e70dd2d1f6c2d"
+}
\ No newline at end of file
diff --git a/bridge/deployed/rskmainnet.json b/bridge/deployed/rskmainnet.json
new file mode 100644
index 000000000..7bd3a1575
--- /dev/null
+++ b/bridge/deployed/rskmainnet.json
@@ -0,0 +1,17 @@
+{
+ "network": "rskmainnet",
+ "MultiSig": "0x040007b1804ad78a97f541bebed377dcb60e4138",
+ "ProxyAdmin": "0x12ed69359919fc775bc2674860e8fe2d2b6a7b5d",
+ "Utils": "0x95ed2b8d3115bae6c0ce539781b7d44119e019bc",
+ "Federation": "0x950a384d950ea319f7d634cabac41ffee49320f0",
+ "SideTokenFactory": "0x44fcd0854d745efdef4cfe9868efe4d4eb51ecd6",
+ "AllowTokens": "0x882846c2792a999cee1d080e89bec9e17f885bdd",
+ "Bridge": "0x4e159f565555fc4eb27d864ff0bd308f1cefa0ac",
+ "BridgeProxy": "0x9d11937e2179dc5270aa86a3f8143232d6da0e69",
+ "smallAmountConfirmations": "60",
+ "mediumAmountConfirmations": "120",
+ "largeAmountConfirmations": "2880",
+ "WrappedCurrency": "0x967f8799af07df1534d48a95a5c9febe92c53ae0",
+ "AllowTokensProxy": "0xcb789036894a83a008a2aa5b3c2dde41d0605a9a",
+ "FederationProxy": "0x7ecfda6072942577d36f939ad528b366b020004b"
+}
\ No newline at end of file
diff --git a/bridge/deployed/rsktestnet.json b/bridge/deployed/rsktestnet.json
new file mode 100644
index 000000000..0af75a86c
--- /dev/null
+++ b/bridge/deployed/rsktestnet.json
@@ -0,0 +1,17 @@
+{
+ "network": "rsktestnet",
+ "MultiSig": "0x88f6b2bc66f4c31a3669b9b1359524abf79cfc4a",
+ "ProxyAdmin": "0x8c35e166d2dea7a8a28aaea11ad7933cdae4b0ab",
+ "Utils": "0xa8C48C20a5D66F706f43D5F749aB63e814A0C8F3",
+ "Federation": "0x28d2f02381915275b2a42798739b0522fcb39339",
+ "SideTokenFactory": "0x08c191a7b5edaa59853705f7eae95e3e4238d73e",
+ "AllowTokens": "0xa39b89d1e36af95183cc09ab83e8fe374bd82f49",
+ "Bridge": "0x860cf53e001e74e1970f38c845b8cbe29b1c622a",
+ "BridgeProxy": "0x684a8a976635fb7ad74a0134ace990a6a0fcce84",
+ "smallAmountConfirmations": "2",
+ "mediumAmountConfirmations": "4",
+ "largeAmountConfirmations": "10",
+ "WrappedCurrency": "0x09b6ca5e4496238a1f176aea6bb607db96c2286e",
+ "AllowTokensProxy": "0xc65bf0ae75dc1a5fc9e6f4215125692a548c773a",
+ "FederationProxy": "0x5d663981d930e8ec108280b9d80885658148ab0f"
+}
\ No newline at end of file
diff --git a/bridge/deployments/bsctestnet/.chainId b/bridge/deployments/bsctestnet/.chainId
new file mode 100644
index 000000000..c4fbb1cfa
--- /dev/null
+++ b/bridge/deployments/bsctestnet/.chainId
@@ -0,0 +1 @@
+97
\ No newline at end of file
diff --git a/bridge/deployments/bsctestnet/AllowTokens.json b/bridge/deployments/bsctestnet/AllowTokens.json
new file mode 100644
index 000000000..b2aff5573
--- /dev/null
+++ b/bridge/deployments/bsctestnet/AllowTokens.json
@@ -0,0 +1,1278 @@
+{
+ "address": "0x3f1e3e613FE9e8f1817677152DDDeE7504B19959",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ }
+ ],
+ "name": "AllowedTokenRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "ConfirmationsChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ }
+ ],
+ "name": "SetToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_typeDescription",
+ "type": "string"
+ }
+ ],
+ "name": "TokenTypeAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "indexed": false,
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "TypeLimitsChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_lastDay",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_spentToday",
+ "type": "uint256"
+ }
+ ],
+ "name": "UpdateTokensTransfered",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_TYPES",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Secondary_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "description",
+ "type": "string"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "addTokenType",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "len",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "allowedTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "calcMaxWithdraw",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "maxWithdraw",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "smallAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ }
+ ],
+ "name": "getInfoAndLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokenInfo",
+ "name": "info",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limit",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypeDescriptions",
+ "outputs": [
+ {
+ "internalType": "string[]",
+ "name": "descriptions",
+ "type": "string[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypeDescriptionsLength",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypesLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits[]",
+ "name": "limits",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_primary",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "string",
+ "name": "description",
+ "type": "string"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TypeInfo[]",
+ "name": "typesInfo",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "isTokenAllowed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "largeAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "mediumAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "removeAllowedToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "setConfirmations",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokensAndType[]",
+ "name": "tokensAndTypes",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "setMultipleTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ }
+ ],
+ "name": "setToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "components": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokenInfo",
+ "name": "info",
+ "type": "tuple"
+ }
+ ],
+ "name": "setTokenInfoByTokenAddress",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "setTypeLimits",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "smallAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ }
+ ],
+ "name": "tokenInfo",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokenInfo",
+ "name": "",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "typeDescriptions",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "typeLimits",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "updateTokenTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xe94cba527ce280dc27a03f8cb6b1616f8e78b75c84d1e0e5b1a64cd8cae0d17d",
+ "receipt": {
+ "to": null,
+ "from": "0x9C95B0EF2D3E1D9ca479524Ba738C87BE28C1585",
+ "contractAddress": "0x3f1e3e613FE9e8f1817677152DDDeE7504B19959",
+ "transactionIndex": 7,
+ "gasUsed": "2092786",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x65c5ee6a97322fc9061d94faede8fba52f8941009f305eb43f4970650b06a431",
+ "transactionHash": "0xe94cba527ce280dc27a03f8cb6b1616f8e78b75c84d1e0e5b1a64cd8cae0d17d",
+ "logs": [],
+ "blockNumber": 16645768,
+ "cumulativeGasUsed": "2996799",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "numDeployments": 1,
+ "solcInputHash": "f27c8e19ddc2cd2a95162a1eabc0e272",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"}],\"name\":\"AllowedTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"}],\"name\":\"ConfirmationsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"}],\"name\":\"SetToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_typeDescription\",\"type\":\"string\"}],\"name\":\"TokenTypeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"TypeLimitsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_lastDay\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_spentToday\",\"type\":\"uint256\"}],\"name\":\"UpdateTokensTransfered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_TYPES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__Secondary_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"addTokenType\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"len\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowedTokens\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"spentToday\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastDay\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"calcMaxWithdraw\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"maxWithdraw\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"smallAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"getInfoAndLimits\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"spentToday\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastDay\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.TokenInfo\",\"name\":\"info\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limit\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypeDescriptions\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"descriptions\",\"type\":\"string[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypeDescriptionsLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypesLimits\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits[]\",\"name\":\"limits\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_primary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"internalType\":\"struct IAllowTokens.TypeInfo[]\",\"name\":\"typesInfo\",\"type\":\"tuple[]\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isTokenAllowed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"largeAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mediumAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"removeAllowedToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"}],\"name\":\"setConfirmations\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.TokensAndType[]\",\"name\":\"tokensAndTypes\",\"type\":\"tuple[]\"}],\"name\":\"setMultipleTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"}],\"name\":\"setToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"spentToday\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastDay\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.TokenInfo\",\"name\":\"info\",\"type\":\"tuple\"}],\"name\":\"setTokenInfoByTokenAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"setTypeLimits\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"smallAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"tokenInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"spentToday\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastDay\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.TokenInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"typeDescriptions\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"typeLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"updateTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"__Secondary_init(address)\":{\"details\":\"Sets the primary account to the one that is creating the Secondary contract.\"},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/AllowTokens/AllowTokens.sol\":\"AllowTokens\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/AllowTokens/AllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../zeppelin/math/SafeMath.sol\\\";\\n// Upgradables\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\\\";\\n\\nimport \\\"../interface/IAllowTokens.sol\\\";\\n\\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\\n\\tusing SafeMath for uint256;\\n\\n\\taddress constant private NULL_ADDRESS = address(0);\\n\\tuint256 constant public MAX_TYPES = 250;\\n\\tmapping (address => TokenInfo) public allowedTokens;\\n\\tmapping (uint256 => Limits) public typeLimits;\\n\\tuint256 public smallAmountConfirmations;\\n\\tuint256 public mediumAmountConfirmations;\\n\\tuint256 public largeAmountConfirmations;\\n\\tstring[] public typeDescriptions;\\n\\n\\tevent SetToken(address indexed _tokenAddress, uint256 _typeId);\\n\\tevent AllowedTokenRemoved(address indexed _tokenAddress);\\n\\tevent TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\\n\\tevent TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\\n\\tevent UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\\n\\tevent ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\\n\\n\\tmodifier notNull(address _address) {\\n\\t\\trequire(_address != NULL_ADDRESS, \\\"AllowTokens: Null Address\\\");\\n\\t\\t_;\\n\\t}\\n\\n\\tfunction initialize(\\n\\t\\taddress _manager,\\n\\t\\taddress _primary,\\n\\t\\tuint256 _smallAmountConfirmations,\\n\\t\\tuint256 _mediumAmountConfirmations,\\n\\t\\tuint256 _largeAmountConfirmations,\\n\\t\\tTypeInfo[] memory typesInfo) public initializer {\\n\\t\\tUpgradableOwnable.initialize(_manager);\\n\\t\\tUpgradableSecondary.__Secondary_init(_primary);\\n\\t\\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\n\\t\\tfor(uint i = 0; i < typesInfo.length; i = i + 1) {\\n\\t\\t\\t_addTokenType(typesInfo[i].description, typesInfo[i].limits);\\n\\t\\t}\\n\\t}\\n\\n\\tfunction version() override external pure returns (string memory) {\\n\\t\\treturn \\\"v1\\\";\\n\\t}\\n\\n\\tfunction tokenInfo(address tokenAddress) public view returns(TokenInfo memory) {\\n\\t\\treturn allowedTokens[tokenAddress];\\n\\t}\\n\\n\\tfunction setTokenInfoByTokenAddress(address tokenAddress, TokenInfo memory info) public {\\n\\t\\trequire(isOwner() || _msgSender() == primary(), \\\"AllowTokens: unauthorized sender\\\");\\n\\t\\tallowedTokens[tokenAddress] = info;\\n\\t}\\n\\n\\tfunction getInfoAndLimits(\\n\\t\\taddress tokenAddress\\n\\t) public view override returns (\\n\\t\\tTokenInfo memory info,\\n\\t\\tLimits memory limit\\n\\t) {\\n\\t\\tinfo = tokenInfo(tokenAddress);\\n\\t\\tlimit = typeLimits[info.typeId];\\n\\t\\treturn (info, limit);\\n\\t}\\n\\n\\tfunction calcMaxWithdraw(address token) public view override returns (uint256 maxWithdraw) {\\n\\t\\t(TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\\n\\t\\treturn _calcMaxWithdraw(info, limits);\\n\\t}\\n\\n\\tfunction _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\\n\\t\\t// solium-disable-next-line security/no-block-members\\n\\t\\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\\n\\t\\t\\tinfo.spentToday = 0;\\n\\t\\t}\\n\\t\\tif (limits.daily <= info.spentToday) {\\n\\t\\t\\treturn 0;\\n\\t\\t}\\n\\t\\tmaxWithdraw = limits.daily - info.spentToday;\\n\\t\\tif (maxWithdraw > limits.max) {\\n\\t\\t\\tmaxWithdraw = limits.max;\\n\\t\\t}\\n\\t\\treturn maxWithdraw;\\n\\t}\\n\\n\\tfunction updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\\n\\t\\t(TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\\n\\t\\trequire(isTokenAllowed(token), \\\"AllowTokens: Not whitelisted\\\");\\n\\t\\trequire(amount >= limit.min, \\\"AllowTokens: Lower than limit\\\");\\n\\n\\t\\t// solium-disable-next-line security/no-block-members\\n\\t\\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\\n\\t\\t\\t// solium-disable-next-line security/no-block-members\\n\\t\\t\\tinfo.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\\n\\t\\t\\tinfo.spentToday = 0;\\n\\t\\t}\\n\\t\\tuint maxWithdraw = _calcMaxWithdraw(info, limit);\\n\\t\\trequire(amount <= maxWithdraw, \\\"AllowTokens: Exceeded limit\\\");\\n\\t\\tinfo.spentToday = info.spentToday.add(amount);\\n\\t\\tsetTokenInfoByTokenAddress(token, info);\\n\\n\\t\\temit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\\n\\t}\\n\\n\\tfunction _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\\n\\t\\trequire(bytes(description).length > 0, \\\"AllowTokens: Empty description\\\");\\n\\t\\tlen = typeDescriptions.length;\\n\\t\\trequire(len + 1 <= MAX_TYPES, \\\"AllowTokens: Reached MAX_TYPES\\\");\\n\\t\\ttypeDescriptions.push(description);\\n\\t\\t_setTypeLimits(len, limits);\\n\\t\\temit TokenTypeAdded(len, description);\\n\\t\\treturn len;\\n\\t}\\n\\n\\tfunction addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\\n\\t\\treturn _addTokenType(description, limits);\\n\\t}\\n\\n\\tfunction _setTypeLimits(uint256 typeId, Limits memory limits) private {\\n\\t\\trequire(typeId < typeDescriptions.length, \\\"AllowTokens: bigger than typeDescriptions\\\");\\n\\t\\trequire(limits.max >= limits.min, \\\"AllowTokens: maxTokens smaller than minTokens\\\");\\n\\t\\trequire(limits.daily >= limits.max, \\\"AllowTokens: dailyLimit smaller than maxTokens\\\");\\n\\t\\trequire(limits.mediumAmount > limits.min, \\\"AllowTokens: limits.mediumAmount smaller than min\\\");\\n\\t\\trequire(limits.largeAmount > limits.mediumAmount, \\\"AllowTokens: limits.largeAmount smaller than mediumAmount\\\");\\n\\t\\ttypeLimits[typeId] = limits;\\n\\t\\temit TypeLimitsChanged(typeId, limits);\\n\\t}\\n\\n\\tfunction setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\\n\\t\\t_setTypeLimits(typeId, limits);\\n\\t}\\n\\n\\tfunction getTypesLimits() external view override returns(Limits[] memory limits) {\\n\\t\\tlimits = new Limits[](typeDescriptions.length);\\n\\t\\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\\n\\t\\t\\tlimits[i] = typeLimits[i];\\n\\t\\t}\\n\\t\\treturn limits;\\n\\t}\\n\\n\\tfunction getTypeDescriptionsLength() external view override returns(uint256) {\\n\\t\\treturn typeDescriptions.length;\\n\\t}\\n\\n\\tfunction getTypeDescriptions() external view override returns(string[] memory descriptions) {\\n\\t\\tdescriptions = new string[](typeDescriptions.length);\\n\\t\\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\\n\\t\\t\\tdescriptions[i] = typeDescriptions[i];\\n\\t\\t}\\n\\t\\treturn descriptions;\\n\\t}\\n\\n\\tfunction isTokenAllowed(address token) public view notNull(token) override returns (bool) {\\n\\t\\treturn tokenInfo(token).allowed;\\n\\t}\\n\\n\\tfunction setToken(address token, uint256 typeId) override public notNull(token) {\\n\\t\\trequire(isOwner() || _msgSender() == primary(), \\\"AllowTokens: unauthorized sender\\\");\\n\\t\\trequire(typeId < typeDescriptions.length, \\\"AllowTokens: typeId does not exist\\\");\\n\\t\\tTokenInfo memory info = tokenInfo(token);\\n\\t\\tinfo.allowed = true;\\n\\t\\tinfo.typeId = typeId;\\n\\t\\tsetTokenInfoByTokenAddress(token, info);\\n\\t\\temit SetToken(token, typeId);\\n\\t}\\n\\n\\tfunction setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\\n\\t\\trequire(tokensAndTypes.length > 0, \\\"AllowTokens: empty tokens\\\");\\n\\t\\tfor(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\\n\\t\\t\\tsetToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\\n\\t\\t}\\n\\t}\\n\\n\\tfunction removeAllowedToken(address token) external notNull(token) onlyOwner {\\n\\t\\tTokenInfo memory info = tokenInfo(token);\\n\\t\\trequire(info.allowed, \\\"AllowTokens: Not Allowed\\\");\\n\\t\\tinfo.allowed = false;\\n\\t\\tsetTokenInfoByTokenAddress(token, info);\\n\\t\\temit AllowedTokenRemoved(token);\\n\\t}\\n\\n\\tfunction setConfirmations(\\n\\t\\tuint256 _smallAmountConfirmations,\\n\\t\\tuint256 _mediumAmountConfirmations,\\n\\t\\tuint256 _largeAmountConfirmations) external onlyOwner {\\n\\t\\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\n\\t}\\n\\n\\tfunction _setConfirmations(\\n\\t\\tuint256 _smallAmountConfirmations,\\n\\t\\tuint256 _mediumAmountConfirmations,\\n\\t\\tuint256 _largeAmountConfirmations) private {\\n\\t\\trequire(_smallAmountConfirmations <= _mediumAmountConfirmations, \\\"AllowTokens: small bigger than medium confirmations\\\");\\n\\t\\trequire(_mediumAmountConfirmations <= _largeAmountConfirmations, \\\"AllowTokens: medium bigger than large confirmations\\\");\\n\\t\\tsmallAmountConfirmations = _smallAmountConfirmations;\\n\\t\\tmediumAmountConfirmations = _mediumAmountConfirmations;\\n\\t\\tlargeAmountConfirmations = _largeAmountConfirmations;\\n\\t\\temit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\n\\t}\\n\\n\\tfunction getConfirmations() external view override\\n\\t\\treturns (\\n\\t\\tuint256 smallAmount,\\n\\t\\tuint256 mediumAmount,\\n\\t\\tuint256 largeAmount\\n\\t) {\\n\\t\\treturn (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\\n\\t}\\n\\n}\\n\",\"keccak256\":\"0x5d8f60e6c272465d54e138fde82b884891823c76e145420651f151610d4b5a23\",\"license\":\"MIT\"},\"contracts/interface/IAllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\ninterface IAllowTokens {\\n\\n\\tstruct Limits {\\n\\t\\tuint256 min;\\n\\t\\tuint256 max;\\n\\t\\tuint256 daily;\\n\\t\\tuint256 mediumAmount;\\n\\t\\tuint256 largeAmount;\\n\\t}\\n\\n\\tstruct TokenInfo {\\n\\t\\tbool allowed;\\n\\t\\tuint256 typeId;\\n\\t\\tuint256 spentToday;\\n\\t\\tuint256 lastDay;\\n\\t}\\n\\n\\tstruct TypeInfo {\\n\\t\\tstring description;\\n\\t\\tLimits limits;\\n\\t}\\n\\n\\tstruct TokensAndType {\\n\\t\\taddress token;\\n\\t\\tuint256 typeId;\\n\\t}\\n\\n\\tfunction version() external pure returns (string memory);\\n\\n\\tfunction getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\\n\\n\\tfunction calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\\n\\n\\tfunction getTypesLimits() external view returns(Limits[] memory limits);\\n\\n\\tfunction getTypeDescriptionsLength() external view returns(uint256);\\n\\n\\tfunction getTypeDescriptions() external view returns(string[] memory descriptions);\\n\\n\\tfunction setToken(address token, uint256 typeId) external;\\n\\n\\tfunction getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\\n\\n\\tfunction isTokenAllowed(address token) external view returns (bool);\\n\\n\\tfunction updateTokenTransfer(address token, uint256 amount) external;\\n}\",\"keccak256\":\"0x7a68f098e5efaad2d9d84314b2df76897fa9dbbe65c64d629b02b1dc4d9d36b5\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return payable(msg.sender);\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x6f3f274a2270bfe073339370edfa2485e2d515a2656039937f6b972fae96d297\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x8038a6eca31e013b0c7f248c7a4eb5846ab0d52bb3f7636fafcf00b075643afe\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\",\"keccak256\":\"0x14063a689bff5eecf0f36cb519feb575f60349ecf0d425ead5b931b77dd599d4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract UpgradableOwnable is Initializable, Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function initialize(address sender) public initializer {\\n _owner = sender;\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * > Note: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n\\n}\\n\",\"keccak256\":\"0xdf439a167ae82e7e3dd241ea0c831a1bb0329432ceb4fa889778d1f2d196ce00\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\n */\\ncontract UpgradableSecondary is Initializable, Context {\\n address private _primary;\\n\\n /**\\n * @dev Emitted when the primary contract changes.\\n */\\n event PrimaryTransferred(\\n address recipient\\n );\\n\\n /**\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\n */\\n function __Secondary_init(address sender) public initializer {\\n _primary = sender;\\n emit PrimaryTransferred(_primary);\\n }\\n\\n /**\\n * @dev Reverts if called from any account other than the primary.\\n */\\n modifier onlyPrimary() {\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\n _;\\n }\\n\\n /**\\n * @return the address of the primary.\\n */\\n function primary() public view returns (address) {\\n return _primary;\\n }\\n\\n /**\\n * @dev Transfers contract to a new primary.\\n * @param recipient The address of new primary.\\n */\\n function transferPrimary(address recipient) public onlyPrimary {\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\n _primary = recipient;\\n emit PrimaryTransferred(recipient);\\n }\\n\\n}\",\"keccak256\":\"0x3dc61c8d0ab62fff2c3d1c56a5e2dbb20be7d0a11947463d86572afec5a1fe27\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b506124e5806100206000396000f3fe608060405234801561001057600080fd5b50600436106101fb5760003560e01c80638f32d59b1161011a578063c4d66de8116100ad578063e4f89ae41161007c578063e4f89ae414610493578063e744092e146104a6578063f2fde38b14610501578063f5dab71114610514578063f9eaee0d1461053457600080fd5b8063c4d66de814610454578063c6dbdf6114610467578063d4164b5d14610478578063d7516faa1461048b57600080fd5b8063adfeb5eb116100e9578063adfeb5eb146103f7578063b348a29f1461040a578063bb698dad1461041d578063c361ce831461043057600080fd5b80638f32d59b1461039b57806390469a9d146103ba5780639d27d226146103cd578063a81a8b1f146103ee57600080fd5b806354fd4d50116101925780637d496be9116101615780637d496be9146103515780638c34bc551461035a5780638da5cb5b1461036d5780638de52dd71461039257600080fd5b806354fd4d5014610305578063601ad4c914610323578063715018a61461033657806378bf2b531461033e57600080fd5b8063250540cf116101ce578063250540cf146102b55780633777804f146102c857806353a8b574146102dd578063545d4f8b146102f257600080fd5b806307fc9eb9146102005780630a9763d71461026a5780631c21a08f146102805780632348238c146102a0575b600080fd5b61023d61020e366004611bc9565b603660205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b604080519586526020860194909452928401919091526060830152608082015260a0015b60405180910390f35b61027260fa81565b604051908152602001610261565b61029361028e366004611bc9565b610547565b6040516102619190611c2f565b6102b36102ae366004611c5e565b6105f3565b005b6102726102c3366004611c5e565b6106ec565b6102d0610710565b6040516102619190611c79565b6102e5610824565b6040516102619190611cf2565b6102b3610300366004611dc2565b61095a565b604080518082019091526002815261763160f01b6020820152610293565b6102b3610331366004611e59565b610a15565b6102b3610a4f565b6102b361034c366004611e85565b610ac3565b61027260395481565b6102b3610368366004611e85565b610c20565b6033546001600160a01b03165b6040516001600160a01b039091168152602001610261565b61027260385481565b6033546001600160a01b031633145b6040519015158152602001610261565b6102b36103c8366004611c5e565b610dfe565b6103e06103db366004611c5e565b610ef2565b604051610261929190611eaf565b61027260375481565b6102b3610405366004611c5e565b610fb7565b6102b3610418366004611f7a565b611075565b61027261042b366004611fa7565b6110a9565b60375460385460395460408051938452602084019290925290820152606001610261565b6102b3610462366004611c5e565b61112e565b6034546001600160a01b031661037a565b6102b3610486366004612035565b6111e3565b603a54610272565b6102b36104a136600461220e565b6112d6565b6104df6104b4366004611c5e565b603560205260009081526040902080546001820154600283015460039093015460ff90921692909184565b6040805194151585526020850193909352918301526060820152608001610261565b6102b361050f366004611c5e565b6113b6565b610527610522366004611c5e565b6113ec565b6040516102619190612282565b6103aa610542366004611c5e565b61146c565b603a818154811061055757600080fd5b906000526020600020016000915090508054610572906122af565b80601f016020809104026020016040519081016040528092919081815260200182805461059e906122af565b80156105eb5780601f106105c0576101008083540402835291602001916105eb565b820191906000526020600020905b8154815290600101906020018083116105ce57829003601f168201915b505050505081565b6034546001600160a01b0316336001600160a01b03161461062f5760405162461bcd60e51b8152600401610626906122e4565b60405180910390fd5b6001600160a01b0381166106985760405162461bcd60e51b815260206004820152602a60248201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604482015269726f206164647265737360b01b6064820152608401610626565b603480546001600160a01b0319166001600160a01b0383169081179091556040519081527f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d99060200160405180910390a150565b60008060006106fa84610ef2565b9150915061070882826114a8565b949350505050565b603a546060906001600160401b0381111561072d5761072d611d54565b60405190808252806020026020018201604052801561079057816020015b61077d6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b81526020019060019003908161074b5790505b50905060005b603a5481101561082057603660008281526020019081526020016000206040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152505082828151811061080257610802612330565b602002602001018190525080806108189061235c565b915050610796565b5090565b603a546060906001600160401b0381111561084157610841611d54565b60405190808252806020026020018201604052801561087457816020015b606081526020019060019003908161085f5790505b50905060005b603a5481101561082057603a818154811061089757610897612330565b9060005260206000200180546108ac906122af565b80601f01602080910402602001604051908101604052809291908181526020018280546108d8906122af565b80156109255780601f106108fa57610100808354040283529160200191610925565b820191906000526020600020905b81548152906001019060200180831161090857829003601f168201915b505050505082828151811061093c5761093c612330565b602002602001018190525080806109529061235c565b91505061087a565b6033546001600160a01b031633148061097d57506034546001600160a01b031633145b6109c95760405162461bcd60e51b815260206004820181905260248201527f416c6c6f77546f6b656e733a20756e617574686f72697a65642073656e6465726044820152606401610626565b6001600160a01b03919091166000908152603560209081526040918290208351815460ff1916901515178155908301516001820155908201516002820155606090910151600390910155565b6033546001600160a01b03163314610a3f5760405162461bcd60e51b815260040161062690612377565b610a4a838383611512565b505050565b6033546001600160a01b03163314610a795760405162461bcd60e51b815260040161062690612377565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b816001600160a01b038116610aea5760405162461bcd60e51b8152600401610626906123ac565b6033546001600160a01b0316331480610b0d57506034546001600160a01b031633145b610b595760405162461bcd60e51b815260206004820181905260248201527f416c6c6f77546f6b656e733a20756e617574686f72697a65642073656e6465726044820152606401610626565b603a548210610bb55760405162461bcd60e51b815260206004820152602260248201527f416c6c6f77546f6b656e733a2074797065496420646f6573206e6f74206578696044820152611cdd60f21b6064820152608401610626565b6000610bc0846113ec565b60018152602081018490529050610bd7848261095a565b836001600160a01b03167f720764556647dd167f4229d6a4255ac86018e302a50fc29dd67a70edb7b314d084604051610c1291815260200190565b60405180910390a250505050565b6034546001600160a01b0316336001600160a01b031614610c535760405162461bcd60e51b8152600401610626906122e4565b600080610c5f84610ef2565b91509150610c6c8461146c565b610cb85760405162461bcd60e51b815260206004820152601c60248201527f416c6c6f77546f6b656e733a204e6f742077686974656c6973746564000000006044820152606401610626565b8051831015610d095760405162461bcd60e51b815260206004820152601d60248201527f416c6c6f77546f6b656e733a204c6f776572207468616e206c696d69740000006044820152606401610626565b6060820151610d1b90620151806123e3565b421115610d3057426060830152600060408301525b6000610d3c83836114a8565b905080841115610d8e5760405162461bcd60e51b815260206004820152601b60248201527f416c6c6f77546f6b656e733a204578636565646564206c696d697400000000006044820152606401610626565b6040830151610d9d908561163f565b6040840152610dac858461095a565b6060830151604080850151815192835260208301526001600160a01b038716917f84480cc6a063ffd72c3eddf21e3ffd30db3e2b8e386ec3abf09c98ee9e0e8d34910160405180910390a25050505050565b806001600160a01b038116610e255760405162461bcd60e51b8152600401610626906123ac565b6033546001600160a01b03163314610e4f5760405162461bcd60e51b815260040161062690612377565b6000610e5a836113ec565b8051909150610eab5760405162461bcd60e51b815260206004820152601860248201527f416c6c6f77546f6b656e733a204e6f7420416c6c6f77656400000000000000006044820152606401610626565b60008152610eb9838261095a565b6040516001600160a01b038416907fbf996b4fd74f0c7159bb017b1db415b0d9a6f13129f46d0b93309d170b78df3190600090a2505050565b610f1f60405180608001604052806000151581526020016000815260200160008152602001600081525090565b610f516040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b610f5a836113ec565b915060366000836020015181526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250509050915091565b600054610100900460ff1680610fd0575060005460ff16155b610fec5760405162461bcd60e51b8152600401610626906123fb565b600054610100900460ff1615801561100e576000805461ffff19166101011790555b603480546001600160a01b0319166001600160a01b0384169081179091556040519081527f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d99060200160405180910390a18015611071576000805461ff00191690555b5050565b6033546001600160a01b0316331461109f5760405162461bcd60e51b815260040161062690612377565b611071828261169e565b6033546000906001600160a01b031633146110d65760405162461bcd60e51b815260040161062690612377565b61112484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061111f9250505036859003850185612443565b61193f565b90505b9392505050565b600054610100900460ff1680611147575060005460ff16155b6111635760405162461bcd60e51b8152600401610626906123fb565b600054610100900460ff16158015611185576000805461ffff19166101011790555b603380546001600160a01b0319166001600160a01b0384169081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015611071576000805461ff00191690555050565b600054610100900460ff16806111fc575060005460ff16155b6112185760405162461bcd60e51b8152600401610626906123fb565b600054610100900460ff1615801561123a576000805461ffff19166101011790555b6112438761112e565b61124c86610fb7565b611257858585611512565b60005b82518110156112ba576112a783828151811061127857611278612330565b60200260200101516000015184838151811061129657611296612330565b60200260200101516020015161193f565b506112b38160016123e3565b905061125a565b5080156112cd576000805461ff00191690555b50505050505050565b6033546001600160a01b031633146113005760405162461bcd60e51b815260040161062690612377565b8061134d5760405162461bcd60e51b815260206004820152601960248201527f416c6c6f77546f6b656e733a20656d70747920746f6b656e73000000000000006044820152606401610626565b60005b81811015610a4a576113a483838381811061136d5761136d612330565b6113839260206040909202019081019150611c5e565b84848481811061139557611395612330565b90506040020160200135610ac3565b6113af8160016123e3565b9050611350565b6033546001600160a01b031633146113e05760405162461bcd60e51b815260040161062690612377565b6113e981611a7c565b50565b61141960405180608001604052806000151581526020016000815260200160008152602001600081525090565b506001600160a01b03166000908152603560209081526040918290208251608081018452815460ff1615158152600182015492810192909252600281015492820192909252600390910154606082015290565b6000816001600160a01b0381166114955760405162461bcd60e51b8152600401610626906123ac565b61149e836113ec565b5191505b50919050565b60008260600151620151806114bd91906123e3565b4211156114cc57600060408401525b82604001518260400151116114e35750600061150c565b826040015182604001516114f7919061245f565b9050816020015181111561150c575060208101515b92915050565b8183111561157e5760405162461bcd60e51b815260206004820152603360248201527f416c6c6f77546f6b656e733a20736d616c6c20626967676572207468616e206d604482015272656469756d20636f6e6669726d6174696f6e7360681b6064820152608401610626565b808211156115ea5760405162461bcd60e51b815260206004820152603360248201527f416c6c6f77546f6b656e733a206d656469756d20626967676572207468616e206044820152726c6172676520636f6e6669726d6174696f6e7360681b6064820152608401610626565b60378390556038829055603981905560408051848152602081018490529081018290527ffcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac42199060600160405180910390a1505050565b60008061164c83856123e3565b9050838110156111275760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610626565b603a5482106117015760405162461bcd60e51b815260206004820152602960248201527f416c6c6f77546f6b656e733a20626967676572207468616e20747970654465736044820152686372697074696f6e7360b81b6064820152608401610626565b80516020820151101561176c5760405162461bcd60e51b815260206004820152602d60248201527f416c6c6f77546f6b656e733a206d6178546f6b656e7320736d616c6c6572207460448201526c68616e206d696e546f6b656e7360981b6064820152608401610626565b8060200151816040015110156117db5760405162461bcd60e51b815260206004820152602e60248201527f416c6c6f77546f6b656e733a206461696c794c696d697420736d616c6c65722060448201526d7468616e206d6178546f6b656e7360901b6064820152608401610626565b80516060820151116118495760405162461bcd60e51b815260206004820152603160248201527f416c6c6f77546f6b656e733a206c696d6974732e6d656469756d416d6f756e746044820152701039b6b0b63632b9103a3430b71036b4b760791b6064820152608401610626565b80606001518160800151116118c65760405162461bcd60e51b815260206004820152603960248201527f416c6c6f77546f6b656e733a206c696d6974732e6c61726765416d6f756e742060448201527f736d616c6c6572207468616e206d656469756d416d6f756e74000000000000006064820152608401610626565b600082815260366020908152604091829020835181559083015160018201558183015160028201556060830151600382015560808301516004909101555182907f1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb90611933908490612476565b60405180910390a25050565b6000808351116119915760405162461bcd60e51b815260206004820152601e60248201527f416c6c6f77546f6b656e733a20456d707479206465736372697074696f6e00006044820152606401610626565b50603a5460fa6119a28260016123e3565b11156119f05760405162461bcd60e51b815260206004820152601e60248201527f416c6c6f77546f6b656e733a2052656163686564204d41585f545950455300006044820152606401610626565b603a80546001810182556000919091528351611a33917fa2999d817b6757290b50e8ecf3fa939673403dd35c97de392fdb343b4015ce9e01906020860190611b39565b50611a3e818361169e565b807fb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a084604051611a6e9190611c2f565b60405180910390a292915050565b6001600160a01b038116611add5760405162461bcd60e51b815260206004820152602260248201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604482015261737360f01b6064820152608401610626565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b828054611b45906122af565b90600052602060002090601f016020900481019282611b675760008555611bad565b82601f10611b8057805160ff1916838001178555611bad565b82800160010185558215611bad579182015b82811115611bad578251825591602001919060010190611b92565b506108209291505b808211156108205760008155600101611bb5565b600060208284031215611bdb57600080fd5b5035919050565b6000815180845260005b81811015611c0857602081850181015186830182015201611bec565b81811115611c1a576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006111276020830184611be2565b80356001600160a01b0381168114611c5957600080fd5b919050565b600060208284031215611c7057600080fd5b61112782611c42565b6020808252825182820181905260009190848201906040850190845b81811015611ce657611cd383855180518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b9284019260a09290920191600101611c95565b50909695505050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015611d4757603f19888603018452611d35858351611be2565b94509285019290850190600101611d19565b5092979650505050505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715611d8c57611d8c611d54565b60405290565b604051601f8201601f191681016001600160401b0381118282101715611dba57611dba611d54565b604052919050565b60008082840360a0811215611dd657600080fd5b611ddf84611c42565b92506080601f1982011215611df357600080fd5b50604051608081018181106001600160401b0382111715611e1657611e16611d54565b60405260208401358015158114611e2c57600080fd5b80825250604084013560208201526060840135604082015260808401356060820152809150509250929050565b600080600060608486031215611e6e57600080fd5b505081359360208301359350604090920135919050565b60008060408385031215611e9857600080fd5b611ea183611c42565b946020939093013593505050565b82511515815260208084015181830152604080850151818401526060808601518185015284516080808601919091529285015160a08501529084015160c084015283015160e08301528201516101008201526101208101611127565b600060a08284031215611f1d57600080fd5b60405160a081018181106001600160401b0382111715611f3f57611f3f611d54565b806040525080915082358152602083013560208201526040830135604082015260608301356060820152608083013560808201525092915050565b60008060c08385031215611f8d57600080fd5b82359150611f9e8460208501611f0b565b90509250929050565b600080600083850360c0811215611fbd57600080fd5b84356001600160401b0380821115611fd457600080fd5b818701915087601f830112611fe857600080fd5b813581811115611ff757600080fd5b88602082850101111561200957600080fd5b60209290920195509093505060a0601f198201121561202757600080fd5b506020840190509250925092565b60008060008060008060c0878903121561204e57600080fd5b61205787611c42565b955061206560208801611c42565b94506040870135935060608701359250608087013591506001600160401b0360a0880135111561209457600080fd5b60a0870135870188601f8201126120aa57600080fd5b6001600160401b03813511156120c2576120c2611d54565b6120d26020823560051b01611d92565b81358082526020808301929160051b8401018b10156120f057600080fd5b602083015b6020843560051b8501018110156121fd576001600160401b038135111561211b57600080fd5b8035840160c0818e03601f1901121561213357600080fd5b61213b611d6a565b6001600160401b036020830135111561215357600080fd5b8d603f60208401358401011261216857600080fd5b602080830135830101356001600160401b0381111561218957612189611d54565b61219c601f8201601f1916602001611d92565b8181528f60408360208701358701010111156121b757600080fd5b8160406020860135860101602083013760006020838301015280835250506121e28e60408401611f0b565b602082015280855250506020830192506020810190506120f5565b508093505050509295509295509295565b6000806020838503121561222157600080fd5b82356001600160401b038082111561223857600080fd5b818501915085601f83011261224c57600080fd5b81358181111561225b57600080fd5b8660208260061b850101111561227057600080fd5b60209290920196919550909350505050565b8151151581526020808301519082015260408083015190820152606080830151908201526080810161150c565b600181811c908216806122c357607f821691505b602082108114156114a257634e487b7160e01b600052602260045260246000fd5b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060001982141561237057612370612346565b5060010190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526019908201527f416c6c6f77546f6b656e733a204e756c6c204164647265737300000000000000604082015260600190565b600082198211156123f6576123f6612346565b500190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b600060a0828403121561245557600080fd5b6111278383611f0b565b60008282101561247157612471612346565b500390565b60a0810161150c82848051825260208101516020830152604081015160408301526060810151606083015260808101516080830152505056fea2646970667358221220588bcd64f385196d7b218829dcee968e741eb45fcd6a03515f3e68378b16d70564736f6c63430008090033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101fb5760003560e01c80638f32d59b1161011a578063c4d66de8116100ad578063e4f89ae41161007c578063e4f89ae414610493578063e744092e146104a6578063f2fde38b14610501578063f5dab71114610514578063f9eaee0d1461053457600080fd5b8063c4d66de814610454578063c6dbdf6114610467578063d4164b5d14610478578063d7516faa1461048b57600080fd5b8063adfeb5eb116100e9578063adfeb5eb146103f7578063b348a29f1461040a578063bb698dad1461041d578063c361ce831461043057600080fd5b80638f32d59b1461039b57806390469a9d146103ba5780639d27d226146103cd578063a81a8b1f146103ee57600080fd5b806354fd4d50116101925780637d496be9116101615780637d496be9146103515780638c34bc551461035a5780638da5cb5b1461036d5780638de52dd71461039257600080fd5b806354fd4d5014610305578063601ad4c914610323578063715018a61461033657806378bf2b531461033e57600080fd5b8063250540cf116101ce578063250540cf146102b55780633777804f146102c857806353a8b574146102dd578063545d4f8b146102f257600080fd5b806307fc9eb9146102005780630a9763d71461026a5780631c21a08f146102805780632348238c146102a0575b600080fd5b61023d61020e366004611bc9565b603660205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b604080519586526020860194909452928401919091526060830152608082015260a0015b60405180910390f35b61027260fa81565b604051908152602001610261565b61029361028e366004611bc9565b610547565b6040516102619190611c2f565b6102b36102ae366004611c5e565b6105f3565b005b6102726102c3366004611c5e565b6106ec565b6102d0610710565b6040516102619190611c79565b6102e5610824565b6040516102619190611cf2565b6102b3610300366004611dc2565b61095a565b604080518082019091526002815261763160f01b6020820152610293565b6102b3610331366004611e59565b610a15565b6102b3610a4f565b6102b361034c366004611e85565b610ac3565b61027260395481565b6102b3610368366004611e85565b610c20565b6033546001600160a01b03165b6040516001600160a01b039091168152602001610261565b61027260385481565b6033546001600160a01b031633145b6040519015158152602001610261565b6102b36103c8366004611c5e565b610dfe565b6103e06103db366004611c5e565b610ef2565b604051610261929190611eaf565b61027260375481565b6102b3610405366004611c5e565b610fb7565b6102b3610418366004611f7a565b611075565b61027261042b366004611fa7565b6110a9565b60375460385460395460408051938452602084019290925290820152606001610261565b6102b3610462366004611c5e565b61112e565b6034546001600160a01b031661037a565b6102b3610486366004612035565b6111e3565b603a54610272565b6102b36104a136600461220e565b6112d6565b6104df6104b4366004611c5e565b603560205260009081526040902080546001820154600283015460039093015460ff90921692909184565b6040805194151585526020850193909352918301526060820152608001610261565b6102b361050f366004611c5e565b6113b6565b610527610522366004611c5e565b6113ec565b6040516102619190612282565b6103aa610542366004611c5e565b61146c565b603a818154811061055757600080fd5b906000526020600020016000915090508054610572906122af565b80601f016020809104026020016040519081016040528092919081815260200182805461059e906122af565b80156105eb5780601f106105c0576101008083540402835291602001916105eb565b820191906000526020600020905b8154815290600101906020018083116105ce57829003601f168201915b505050505081565b6034546001600160a01b0316336001600160a01b03161461062f5760405162461bcd60e51b8152600401610626906122e4565b60405180910390fd5b6001600160a01b0381166106985760405162461bcd60e51b815260206004820152602a60248201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604482015269726f206164647265737360b01b6064820152608401610626565b603480546001600160a01b0319166001600160a01b0383169081179091556040519081527f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d99060200160405180910390a150565b60008060006106fa84610ef2565b9150915061070882826114a8565b949350505050565b603a546060906001600160401b0381111561072d5761072d611d54565b60405190808252806020026020018201604052801561079057816020015b61077d6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b81526020019060019003908161074b5790505b50905060005b603a5481101561082057603660008281526020019081526020016000206040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152505082828151811061080257610802612330565b602002602001018190525080806108189061235c565b915050610796565b5090565b603a546060906001600160401b0381111561084157610841611d54565b60405190808252806020026020018201604052801561087457816020015b606081526020019060019003908161085f5790505b50905060005b603a5481101561082057603a818154811061089757610897612330565b9060005260206000200180546108ac906122af565b80601f01602080910402602001604051908101604052809291908181526020018280546108d8906122af565b80156109255780601f106108fa57610100808354040283529160200191610925565b820191906000526020600020905b81548152906001019060200180831161090857829003601f168201915b505050505082828151811061093c5761093c612330565b602002602001018190525080806109529061235c565b91505061087a565b6033546001600160a01b031633148061097d57506034546001600160a01b031633145b6109c95760405162461bcd60e51b815260206004820181905260248201527f416c6c6f77546f6b656e733a20756e617574686f72697a65642073656e6465726044820152606401610626565b6001600160a01b03919091166000908152603560209081526040918290208351815460ff1916901515178155908301516001820155908201516002820155606090910151600390910155565b6033546001600160a01b03163314610a3f5760405162461bcd60e51b815260040161062690612377565b610a4a838383611512565b505050565b6033546001600160a01b03163314610a795760405162461bcd60e51b815260040161062690612377565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b816001600160a01b038116610aea5760405162461bcd60e51b8152600401610626906123ac565b6033546001600160a01b0316331480610b0d57506034546001600160a01b031633145b610b595760405162461bcd60e51b815260206004820181905260248201527f416c6c6f77546f6b656e733a20756e617574686f72697a65642073656e6465726044820152606401610626565b603a548210610bb55760405162461bcd60e51b815260206004820152602260248201527f416c6c6f77546f6b656e733a2074797065496420646f6573206e6f74206578696044820152611cdd60f21b6064820152608401610626565b6000610bc0846113ec565b60018152602081018490529050610bd7848261095a565b836001600160a01b03167f720764556647dd167f4229d6a4255ac86018e302a50fc29dd67a70edb7b314d084604051610c1291815260200190565b60405180910390a250505050565b6034546001600160a01b0316336001600160a01b031614610c535760405162461bcd60e51b8152600401610626906122e4565b600080610c5f84610ef2565b91509150610c6c8461146c565b610cb85760405162461bcd60e51b815260206004820152601c60248201527f416c6c6f77546f6b656e733a204e6f742077686974656c6973746564000000006044820152606401610626565b8051831015610d095760405162461bcd60e51b815260206004820152601d60248201527f416c6c6f77546f6b656e733a204c6f776572207468616e206c696d69740000006044820152606401610626565b6060820151610d1b90620151806123e3565b421115610d3057426060830152600060408301525b6000610d3c83836114a8565b905080841115610d8e5760405162461bcd60e51b815260206004820152601b60248201527f416c6c6f77546f6b656e733a204578636565646564206c696d697400000000006044820152606401610626565b6040830151610d9d908561163f565b6040840152610dac858461095a565b6060830151604080850151815192835260208301526001600160a01b038716917f84480cc6a063ffd72c3eddf21e3ffd30db3e2b8e386ec3abf09c98ee9e0e8d34910160405180910390a25050505050565b806001600160a01b038116610e255760405162461bcd60e51b8152600401610626906123ac565b6033546001600160a01b03163314610e4f5760405162461bcd60e51b815260040161062690612377565b6000610e5a836113ec565b8051909150610eab5760405162461bcd60e51b815260206004820152601860248201527f416c6c6f77546f6b656e733a204e6f7420416c6c6f77656400000000000000006044820152606401610626565b60008152610eb9838261095a565b6040516001600160a01b038416907fbf996b4fd74f0c7159bb017b1db415b0d9a6f13129f46d0b93309d170b78df3190600090a2505050565b610f1f60405180608001604052806000151581526020016000815260200160008152602001600081525090565b610f516040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b610f5a836113ec565b915060366000836020015181526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250509050915091565b600054610100900460ff1680610fd0575060005460ff16155b610fec5760405162461bcd60e51b8152600401610626906123fb565b600054610100900460ff1615801561100e576000805461ffff19166101011790555b603480546001600160a01b0319166001600160a01b0384169081179091556040519081527f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d99060200160405180910390a18015611071576000805461ff00191690555b5050565b6033546001600160a01b0316331461109f5760405162461bcd60e51b815260040161062690612377565b611071828261169e565b6033546000906001600160a01b031633146110d65760405162461bcd60e51b815260040161062690612377565b61112484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061111f9250505036859003850185612443565b61193f565b90505b9392505050565b600054610100900460ff1680611147575060005460ff16155b6111635760405162461bcd60e51b8152600401610626906123fb565b600054610100900460ff16158015611185576000805461ffff19166101011790555b603380546001600160a01b0319166001600160a01b0384169081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015611071576000805461ff00191690555050565b600054610100900460ff16806111fc575060005460ff16155b6112185760405162461bcd60e51b8152600401610626906123fb565b600054610100900460ff1615801561123a576000805461ffff19166101011790555b6112438761112e565b61124c86610fb7565b611257858585611512565b60005b82518110156112ba576112a783828151811061127857611278612330565b60200260200101516000015184838151811061129657611296612330565b60200260200101516020015161193f565b506112b38160016123e3565b905061125a565b5080156112cd576000805461ff00191690555b50505050505050565b6033546001600160a01b031633146113005760405162461bcd60e51b815260040161062690612377565b8061134d5760405162461bcd60e51b815260206004820152601960248201527f416c6c6f77546f6b656e733a20656d70747920746f6b656e73000000000000006044820152606401610626565b60005b81811015610a4a576113a483838381811061136d5761136d612330565b6113839260206040909202019081019150611c5e565b84848481811061139557611395612330565b90506040020160200135610ac3565b6113af8160016123e3565b9050611350565b6033546001600160a01b031633146113e05760405162461bcd60e51b815260040161062690612377565b6113e981611a7c565b50565b61141960405180608001604052806000151581526020016000815260200160008152602001600081525090565b506001600160a01b03166000908152603560209081526040918290208251608081018452815460ff1615158152600182015492810192909252600281015492820192909252600390910154606082015290565b6000816001600160a01b0381166114955760405162461bcd60e51b8152600401610626906123ac565b61149e836113ec565b5191505b50919050565b60008260600151620151806114bd91906123e3565b4211156114cc57600060408401525b82604001518260400151116114e35750600061150c565b826040015182604001516114f7919061245f565b9050816020015181111561150c575060208101515b92915050565b8183111561157e5760405162461bcd60e51b815260206004820152603360248201527f416c6c6f77546f6b656e733a20736d616c6c20626967676572207468616e206d604482015272656469756d20636f6e6669726d6174696f6e7360681b6064820152608401610626565b808211156115ea5760405162461bcd60e51b815260206004820152603360248201527f416c6c6f77546f6b656e733a206d656469756d20626967676572207468616e206044820152726c6172676520636f6e6669726d6174696f6e7360681b6064820152608401610626565b60378390556038829055603981905560408051848152602081018490529081018290527ffcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac42199060600160405180910390a1505050565b60008061164c83856123e3565b9050838110156111275760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610626565b603a5482106117015760405162461bcd60e51b815260206004820152602960248201527f416c6c6f77546f6b656e733a20626967676572207468616e20747970654465736044820152686372697074696f6e7360b81b6064820152608401610626565b80516020820151101561176c5760405162461bcd60e51b815260206004820152602d60248201527f416c6c6f77546f6b656e733a206d6178546f6b656e7320736d616c6c6572207460448201526c68616e206d696e546f6b656e7360981b6064820152608401610626565b8060200151816040015110156117db5760405162461bcd60e51b815260206004820152602e60248201527f416c6c6f77546f6b656e733a206461696c794c696d697420736d616c6c65722060448201526d7468616e206d6178546f6b656e7360901b6064820152608401610626565b80516060820151116118495760405162461bcd60e51b815260206004820152603160248201527f416c6c6f77546f6b656e733a206c696d6974732e6d656469756d416d6f756e746044820152701039b6b0b63632b9103a3430b71036b4b760791b6064820152608401610626565b80606001518160800151116118c65760405162461bcd60e51b815260206004820152603960248201527f416c6c6f77546f6b656e733a206c696d6974732e6c61726765416d6f756e742060448201527f736d616c6c6572207468616e206d656469756d416d6f756e74000000000000006064820152608401610626565b600082815260366020908152604091829020835181559083015160018201558183015160028201556060830151600382015560808301516004909101555182907f1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb90611933908490612476565b60405180910390a25050565b6000808351116119915760405162461bcd60e51b815260206004820152601e60248201527f416c6c6f77546f6b656e733a20456d707479206465736372697074696f6e00006044820152606401610626565b50603a5460fa6119a28260016123e3565b11156119f05760405162461bcd60e51b815260206004820152601e60248201527f416c6c6f77546f6b656e733a2052656163686564204d41585f545950455300006044820152606401610626565b603a80546001810182556000919091528351611a33917fa2999d817b6757290b50e8ecf3fa939673403dd35c97de392fdb343b4015ce9e01906020860190611b39565b50611a3e818361169e565b807fb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a084604051611a6e9190611c2f565b60405180910390a292915050565b6001600160a01b038116611add5760405162461bcd60e51b815260206004820152602260248201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604482015261737360f01b6064820152608401610626565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b828054611b45906122af565b90600052602060002090601f016020900481019282611b675760008555611bad565b82601f10611b8057805160ff1916838001178555611bad565b82800160010185558215611bad579182015b82811115611bad578251825591602001919060010190611b92565b506108209291505b808211156108205760008155600101611bb5565b600060208284031215611bdb57600080fd5b5035919050565b6000815180845260005b81811015611c0857602081850181015186830182015201611bec565b81811115611c1a576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006111276020830184611be2565b80356001600160a01b0381168114611c5957600080fd5b919050565b600060208284031215611c7057600080fd5b61112782611c42565b6020808252825182820181905260009190848201906040850190845b81811015611ce657611cd383855180518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b9284019260a09290920191600101611c95565b50909695505050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015611d4757603f19888603018452611d35858351611be2565b94509285019290850190600101611d19565b5092979650505050505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715611d8c57611d8c611d54565b60405290565b604051601f8201601f191681016001600160401b0381118282101715611dba57611dba611d54565b604052919050565b60008082840360a0811215611dd657600080fd5b611ddf84611c42565b92506080601f1982011215611df357600080fd5b50604051608081018181106001600160401b0382111715611e1657611e16611d54565b60405260208401358015158114611e2c57600080fd5b80825250604084013560208201526060840135604082015260808401356060820152809150509250929050565b600080600060608486031215611e6e57600080fd5b505081359360208301359350604090920135919050565b60008060408385031215611e9857600080fd5b611ea183611c42565b946020939093013593505050565b82511515815260208084015181830152604080850151818401526060808601518185015284516080808601919091529285015160a08501529084015160c084015283015160e08301528201516101008201526101208101611127565b600060a08284031215611f1d57600080fd5b60405160a081018181106001600160401b0382111715611f3f57611f3f611d54565b806040525080915082358152602083013560208201526040830135604082015260608301356060820152608083013560808201525092915050565b60008060c08385031215611f8d57600080fd5b82359150611f9e8460208501611f0b565b90509250929050565b600080600083850360c0811215611fbd57600080fd5b84356001600160401b0380821115611fd457600080fd5b818701915087601f830112611fe857600080fd5b813581811115611ff757600080fd5b88602082850101111561200957600080fd5b60209290920195509093505060a0601f198201121561202757600080fd5b506020840190509250925092565b60008060008060008060c0878903121561204e57600080fd5b61205787611c42565b955061206560208801611c42565b94506040870135935060608701359250608087013591506001600160401b0360a0880135111561209457600080fd5b60a0870135870188601f8201126120aa57600080fd5b6001600160401b03813511156120c2576120c2611d54565b6120d26020823560051b01611d92565b81358082526020808301929160051b8401018b10156120f057600080fd5b602083015b6020843560051b8501018110156121fd576001600160401b038135111561211b57600080fd5b8035840160c0818e03601f1901121561213357600080fd5b61213b611d6a565b6001600160401b036020830135111561215357600080fd5b8d603f60208401358401011261216857600080fd5b602080830135830101356001600160401b0381111561218957612189611d54565b61219c601f8201601f1916602001611d92565b8181528f60408360208701358701010111156121b757600080fd5b8160406020860135860101602083013760006020838301015280835250506121e28e60408401611f0b565b602082015280855250506020830192506020810190506120f5565b508093505050509295509295509295565b6000806020838503121561222157600080fd5b82356001600160401b038082111561223857600080fd5b818501915085601f83011261224c57600080fd5b81358181111561225b57600080fd5b8660208260061b850101111561227057600080fd5b60209290920196919550909350505050565b8151151581526020808301519082015260408083015190820152606080830151908201526080810161150c565b600181811c908216806122c357607f821691505b602082108114156114a257634e487b7160e01b600052602260045260246000fd5b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060001982141561237057612370612346565b5060010190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526019908201527f416c6c6f77546f6b656e733a204e756c6c204164647265737300000000000000604082015260600190565b600082198211156123f6576123f6612346565b500190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b600060a0828403121561245557600080fd5b6111278383611f0b565b60008282101561247157612471612346565b500390565b60a0810161150c82848051825260208101516020830152604081015160408301526060810151606083015260808101516080830152505056fea2646970667358221220588bcd64f385196d7b218829dcee968e741eb45fcd6a03515f3e68378b16d70564736f6c63430008090033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "__Secondary_init(address)": {
+ "details": "Sets the primary account to the one that is creating the Secondary contract."
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 16199,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16202,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16242,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16488,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 16621,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_address"
+ },
+ {
+ "astId": 32,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "allowedTokens",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_mapping(t_address,t_struct(TokenInfo)7104_storage)"
+ },
+ {
+ "astId": 37,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeLimits",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_mapping(t_uint256,t_struct(Limits)7095_storage)"
+ },
+ {
+ "astId": 39,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "smallAmountConfirmations",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 41,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "mediumAmountConfirmations",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 43,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "largeAmountConfirmations",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 46,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeDescriptions",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_array(t_string_storage)dyn_storage"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "base": "t_string_storage",
+ "encoding": "dynamic_array",
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_struct(TokenInfo)7104_storage)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => struct IAllowTokens.TokenInfo)",
+ "numberOfBytes": "32",
+ "value": "t_struct(TokenInfo)7104_storage"
+ },
+ "t_mapping(t_uint256,t_struct(Limits)7095_storage)": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => struct IAllowTokens.Limits)",
+ "numberOfBytes": "32",
+ "value": "t_struct(Limits)7095_storage"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(Limits)7095_storage": {
+ "encoding": "inplace",
+ "label": "struct IAllowTokens.Limits",
+ "members": [
+ {
+ "astId": 7086,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "min",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7088,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "max",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7090,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "daily",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7092,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "mediumAmount",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7094,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "largeAmount",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "160"
+ },
+ "t_struct(TokenInfo)7104_storage": {
+ "encoding": "inplace",
+ "label": "struct IAllowTokens.TokenInfo",
+ "members": [
+ {
+ "astId": 7097,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "allowed",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 7099,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeId",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7101,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "spentToday",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7103,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "lastDay",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/bsctestnet/AllowTokensProxy.json b/bridge/deployments/bsctestnet/AllowTokensProxy.json
new file mode 100644
index 000000000..0ec58cb6d
--- /dev/null
+++ b/bridge/deployments/bsctestnet/AllowTokensProxy.json
@@ -0,0 +1,427 @@
+{
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "receipt": {
+ "to": null,
+ "from": "0x9C95B0EF2D3E1D9ca479524Ba738C87BE28C1585",
+ "contractAddress": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "transactionIndex": 0,
+ "gasUsed": "1612927",
+ "logsBloom": "0x04000000200000000000000000010000000000000000200002800000000000000000000000000000000000000000000000042000420400000000000000040000000010000000400000000000000000000001000100040000000000000000000008000000020000000000800000000800000000000000000000000000000000400000000400000000000000000004001000000800000000000000000000000000000000000000000000000100000004000000000000800000002000080000400000000000000004000000000000000000000008008000000000000000000060200000000080000000000000000000000000000000008000000001000000100000",
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58",
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000009c95b0ef2d3e1d9ca479524ba738c87be28c1585"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ],
+ "data": "0x000000000000000000000000d9d2f9ee990ddb1147e595ae4f69ec468a0b58d0",
+ "logIndex": 1,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0xfcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 2,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "data": "0x00000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000015af1d78b58c400000000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a0000",
+ "logIndex": 3,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034254430000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 4,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000001"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000028a857425466f800000000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000429d069189e0000",
+ "logIndex": 5,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000001"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034554480000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 6,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000002"
+ ],
+ "data": "0x00000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000878678326eac90000000000000000000000000000000000000000000000000010f0cf064dd59200000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a0000",
+ "logIndex": 7,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000002"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000083c31303030757364000000000000000000000000000000000000000000000000",
+ "logIndex": 8,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000003"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000054b40b1f852bda00000000000000000000000000000000000000000000000000a968163f0a57b4000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000008ac7230489e80000",
+ "logIndex": 9,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000003"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000073c31303075736400000000000000000000000000000000000000000000000000",
+ "logIndex": 10,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000004"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000002116545850052128000000000000000000000000000000000000000000000000422ca8b0a00a4250000000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000056bc75e2d63100000",
+ "logIndex": 11,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000004"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000053d31757364000000000000000000000000000000000000000000000000000000",
+ "logIndex": 12,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000005"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000cecb8f27f4200f3a0000000000000000000000000000000000000000000000019d971e4fe8401e740000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea00000",
+ "logIndex": 13,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000005"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000053c31757364000000000000000000000000000000000000000000000000000000",
+ "logIndex": 14,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000006"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000050c783eb9b5c85f2a80000000000000000000000000000000000000000000000a18f07d736b90be5500000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea00000",
+ "logIndex": 15,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 16645814,
+ "transactionHash": "0x7bad9deebb39158d16c92b3a47081ac0d748984de70a1df1526f2392235a4aeb",
+ "address": "0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000006"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000063c3163656e740000000000000000000000000000000000000000000000000000",
+ "logIndex": 16,
+ "blockHash": "0x94a27457aaa802dd88e5bd10427df75b49241d5fe0de0b8ce9bd351094c9fa58"
+ }
+ ],
+ "blockNumber": 16645814,
+ "cumulativeGasUsed": "1612927",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0x3f1e3e613FE9e8f1817677152DDDeE7504B19959",
+ "0x6C62BF5440De2Cb157205B15C424BCEb5C3368F5",
+ "0xd4164b5d0000000000000000000000009c95b0ef2d3e1d9ca479524ba738c87be28c1585000000000000000000000000d9d2f9ee990ddb1147e595ae4f69ec468a0b58d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000015af1d78b58c400000000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000000003425443000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000028a857425466f800000000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000429d069189e00000000000000000000000000000000000000000000000000000000000000000003455448000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000878678326eac90000000000000000000000000000000000000000000000000010f0cf064dd59200000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000083c3130303075736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000054b40b1f852bda00000000000000000000000000000000000000000000000000a968163f0a57b4000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000073c3130307573640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000002116545850052128000000000000000000000000000000000000000000000000422ca8b0a00a4250000000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000053d3175736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000cecb8f27f4200f3a0000000000000000000000000000000000000000000000019d971e4fe8401e740000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000053c3175736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000050c783eb9b5c85f2a80000000000000000000000000000000000000000000000a18f07d736b90be5500000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000063c3163656e740000000000000000000000000000000000000000000000000000"
+ ],
+ "numDeployments": 1,
+ "solcInputHash": "f27c8e19ddc2cd2a95162a1eabc0e272",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"stateVariables\":{\"_ADMIN_SLOT\":{\"details\":\"Storage slot with the admin of the contract. This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0xdc0ebdc6f4ae0b5f9dd0a6c041a2238e4a7a2afbc6cef539437b0004ada42370\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x3327b21f85d71d3b9bad1a89267f08b19966e03446a18d810bd80fe42789ac5f\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb54322ec8ec142c149ad1f561aa2f0da6d6ea2d9f45639164088db9e16d5a69d\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x04801fc2398ee3370f3903f95389ea3a8da65a8df01f24b352e499e44d492e9b\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000d9138038062000d91833981016040819052620000269162000369565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd62000449565b60008051602062000d4a833981519152146200007557620000756200046f565b620000808262000112565b805115620000a1576200009f8282620001b360201b620003ba1760201c565b505b50620000d1905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610462000449565b60008051602062000d2a83398151915214620000f157620000f16200046f565b620001098260008051602062000d2a83398151915255565b505050620004d8565b6200012881620001e260201b620003e61760201c565b620001a05760405162461bcd60e51b815260206004820152603660248201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160448201527f74696f6e206973206e6f74206120636f6e74726163740000000000000000000060648201526084015b60405180910390fd5b60008051602062000d4a83398151915255565b6060620001db838360405180606001604052806027815260200162000d6a60279139620001e8565b9392505050565b3b151590565b6060833b620002495760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000197565b600080856001600160a01b03168560405162000266919062000485565b600060405180830381855af49150503d8060008114620002a3576040519150601f19603f3d011682016040523d82523d6000602084013e620002a8565b606091505b509092509050620002bb828286620002c5565b9695505050505050565b60608315620002d6575081620001db565b825115620002e75782518084602001fd5b8160405162461bcd60e51b8152600401620001979190620004a3565b80516001600160a01b03811681146200031b57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200035357818101518382015260200162000339565b8381111562000363576000848401525b50505050565b6000806000606084860312156200037f57600080fd5b6200038a8462000303565b92506200039a6020850162000303565b60408501519092506001600160401b0380821115620003b857600080fd5b818601915086601f830112620003cd57600080fd5b815181811115620003e257620003e262000320565b604051601f8201601f19908116603f011681019083821181831017156200040d576200040d62000320565b816040528281528960208487010111156200042757600080fd5b6200043a83602083016020880162000336565b80955050505050509250925092565b6000828210156200046a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b600082516200049981846020870162000336565b9190910192915050565b6020815260008251806020840152620004c481604085016020870162000336565b601f01601f19169190910160400192915050565b61084280620004e86000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ac565b610138565b61005b6100933660046106c7565b610175565b3480156100a457600080fd5b506100ad6101fa565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ac565b61025c565b3480156100f557600080fd5b506100ad610375565b6101066103ec565b6101366101317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b61048e565b565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b0316141561016d5761016a816104b2565b50565b61016a6100fe565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b031614156101ed576101a7836104b2565b6101e78383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ba92505050565b50505050565b6101f56100fe565b505050565b60006102126000805160206107c68339815191525490565b6001600160a01b0316336001600160a01b0316141561025157507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6102596100fe565b90565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b0316141561016d576001600160a01b0381166103065760405162461bcd60e51b815260206004820152603a60248201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760448201527f2061646d696e20697320746865207a65726f206164647265737300000000000060648201526084015b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61033d6000805160206107c68339815191525490565b604080516001600160a01b03928316815291841660208301520160405180910390a161016a816000805160206107c683398151915255565b600061038d6000805160206107c68339815191525490565b6001600160a01b0316336001600160a01b0316141561025157506000805160206107c68339815191525490565b60606103df83836040518060600160405280602781526020016107e6602791396104f2565b9392505050565b3b151590565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b031614156101365760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4016102fd565b3660008037600080366000845af43d6000803e8080156104ad573d6000f35b3d6000fd5b6104bb816105c6565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060833b6105515760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016102fd565b600080856001600160a01b03168560405161056c9190610776565b600060405180830381855af49150503d80600081146105a7576040519150601f19603f3d011682016040523d82523d6000602084013e6105ac565b606091505b50915091506105bc828286610657565b9695505050505050565b803b6106335760405162461bcd60e51b815260206004820152603660248201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616044820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b60648201526084016102fd565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156106665750816103df565b8251156106765782518084602001fd5b8160405162461bcd60e51b81526004016102fd9190610792565b80356001600160a01b03811681146106a757600080fd5b919050565b6000602082840312156106be57600080fd5b6103df82610690565b6000806000604084860312156106dc57600080fd5b6106e584610690565b9250602084013567ffffffffffffffff8082111561070257600080fd5b818601915086601f83011261071657600080fd5b81358181111561072557600080fd5b87602082850101111561073757600080fd5b6020830194508093505050509250925092565b60005b8381101561076557818101518382015260200161074d565b838111156101e75750506000910152565b6000825161078881846020870161074a565b9190910192915050565b60208152600082518060208401526107b181604085016020870161074a565b601f01601f1916919091016040019291505056feb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122001f23e5e5d70499e22926447138d9a73085390bf4c2f13e017a1d16843ca77ac64736f6c63430008090033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ac565b610138565b61005b6100933660046106c7565b610175565b3480156100a457600080fd5b506100ad6101fa565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ac565b61025c565b3480156100f557600080fd5b506100ad610375565b6101066103ec565b6101366101317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b61048e565b565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b0316141561016d5761016a816104b2565b50565b61016a6100fe565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b031614156101ed576101a7836104b2565b6101e78383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ba92505050565b50505050565b6101f56100fe565b505050565b60006102126000805160206107c68339815191525490565b6001600160a01b0316336001600160a01b0316141561025157507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6102596100fe565b90565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b0316141561016d576001600160a01b0381166103065760405162461bcd60e51b815260206004820152603a60248201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760448201527f2061646d696e20697320746865207a65726f206164647265737300000000000060648201526084015b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61033d6000805160206107c68339815191525490565b604080516001600160a01b03928316815291841660208301520160405180910390a161016a816000805160206107c683398151915255565b600061038d6000805160206107c68339815191525490565b6001600160a01b0316336001600160a01b0316141561025157506000805160206107c68339815191525490565b60606103df83836040518060600160405280602781526020016107e6602791396104f2565b9392505050565b3b151590565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b031614156101365760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4016102fd565b3660008037600080366000845af43d6000803e8080156104ad573d6000f35b3d6000fd5b6104bb816105c6565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060833b6105515760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016102fd565b600080856001600160a01b03168560405161056c9190610776565b600060405180830381855af49150503d80600081146105a7576040519150601f19603f3d011682016040523d82523d6000602084013e6105ac565b606091505b50915091506105bc828286610657565b9695505050505050565b803b6106335760405162461bcd60e51b815260206004820152603660248201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616044820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b60648201526084016102fd565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156106665750816103df565b8251156106765782518084602001fd5b8160405162461bcd60e51b81526004016102fd9190610792565b80356001600160a01b03811681146106a757600080fd5b919050565b6000602082840312156106be57600080fd5b6103df82610690565b6000806000604084860312156106dc57600080fd5b6106e584610690565b9250602084013567ffffffffffffffff8082111561070257600080fd5b818601915086601f83011261071657600080fd5b81358181111561072557600080fd5b87602082850101111561073757600080fd5b6020830194508093505050509250925092565b60005b8381101561076557818101518382015260200161074d565b838111156101e75750506000910152565b6000825161078881846020870161074a565b9190910192915050565b60208152600082518060208401526107b181604085016020870161074a565b601f01601f1916919091016040019291505056feb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122001f23e5e5d70499e22926447138d9a73085390bf4c2f13e017a1d16843ca77ac64736f6c63430008090033",
+ "devdoc": {
+ "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.",
+ "events": {
+ "AdminChanged(address,address)": {
+ "details": "Emitted when the admin account has changed."
+ }
+ },
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "constructor": {
+ "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "stateVariables": {
+ "_ADMIN_SLOT": {
+ "details": "Storage slot with the admin of the contract. This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/bsctestnet/Bridge.json b/bridge/deployments/bsctestnet/Bridge.json
new file mode 100644
index 000000000..301bb8fad
--- /dev/null
+++ b/bridge/deployments/bsctestnet/Bridge.json
@@ -0,0 +1,2129 @@
+{
+ "address": "0x1974A084f07118C0Ab31b811ab9806343b49ed88",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "AcceptedCrossTransfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "AllowTokensChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_reciever",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Claimed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "_userData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Cross",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "FederationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "FeePercentageChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_newSideTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_newSymbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_granularity",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_chainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "NewSideToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Paused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "SideTokenFactoryChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Unpaused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "Upgrading",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "WrappedCurrencyChanged",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "CLAIM_TYPEHASH",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Pausable_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__PauserRol_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "acceptTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "addPauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "allowTokens",
+ "outputs": [
+ {
+ "internalType": "contract IAllowTokens",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "changeAllowTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "changeFederation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "changeSideTokenFactory",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claim",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claimFallback",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_deadline",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_v",
+ "type": "uint8"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_r",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_s",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimGasless",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_originalTokenDecimals",
+ "type": "uint8"
+ },
+ {
+ "internalType": "string",
+ "name": "_tokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_tokenName",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deprecatedKnownTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deprecatedMappedTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deprecatedOriginalTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "deprecatedSymbolPrefix",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "domainSeparator",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "feePercentageDivider",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFederation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFeePercentage",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ }
+ ],
+ "name": "getOriginalTokenBySideToken",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.OriginalToken",
+ "name": "originalToken",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getTransactionDataHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasBeenClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasCrossed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initDomainSeparator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_federation",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_allowTokens",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_sideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionDataHashMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionDataHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionDataHashMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isPauser",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isUpgrading",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "originalToken",
+ "type": "address"
+ }
+ ],
+ "name": "knownToken",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "knownTokenByChain",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "nonces",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "originalTokenAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "originalTokenBySideToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "pause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "paused",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "tokenToUse",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "receiveTokensTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renouncePauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "senderAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "setFeePercentage",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ },
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.OriginalToken",
+ "name": "originalToken",
+ "type": "tuple"
+ }
+ ],
+ "name": "setOriginalTokenBySideTokenByChain",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "originalToken",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ }
+ ],
+ "name": "setSideTokenByOriginalAddressByChain",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "setUpgrading",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "setWrappedCurrency",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "originalToken",
+ "type": "address"
+ }
+ ],
+ "name": "sideTokenByOriginalToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "sideTokenByOriginalTokenByChain",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "sideTokenFactory",
+ "outputs": [
+ {
+ "internalType": "contract ISideTokenFactory",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "userData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "tokensReceived",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionsDataHashes",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unpause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "wrappedCurrency",
+ "outputs": [
+ {
+ "internalType": "contract IWrapped",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xa1c83505d06f837fe57ad0bdd2af588a55bf41fe6ad2320c6489082c975e0dc9",
+ "receipt": {
+ "to": null,
+ "from": "0x9C95B0EF2D3E1D9ca479524Ba738C87BE28C1585",
+ "contractAddress": "0x1974A084f07118C0Ab31b811ab9806343b49ed88",
+ "transactionIndex": 7,
+ "gasUsed": "4245348",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xc83b27c0810115190a17cbee774ad40a073207cb26919ee521b8ac481e5a301d",
+ "transactionHash": "0xa1c83505d06f837fe57ad0bdd2af588a55bf41fe6ad2320c6489082c975e0dc9",
+ "logs": [],
+ "blockNumber": 16645071,
+ "cumulativeGasUsed": "5873449",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "numDeployments": 1,
+ "solcInputHash": "f27c8e19ddc2cd2a95162a1eabc0e272",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"}],\"name\":\"AcceptedCrossTransfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newAllowTokens\",\"type\":\"address\"}],\"name\":\"AllowTokensChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_reciever\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_relayer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"}],\"name\":\"Claimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_userData\",\"type\":\"bytes\"}],\"name\":\"Cross\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newFederation\",\"type\":\"address\"}],\"name\":\"FederationChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"FeePercentageChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newSideTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_newSymbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_granularity\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_chainId\",\"type\":\"uint256\"}],\"name\":\"NewSideToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newSideTokenFactory\",\"type\":\"address\"}],\"name\":\"SideTokenFactoryChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"Upgrading\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_wrappedCurrency\",\"type\":\"address\"}],\"name\":\"WrappedCurrencyChanged\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"CLAIM_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__Pausable_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__PauserRol_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"}],\"name\":\"acceptTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"addPauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allowTokens\",\"outputs\":[{\"internalType\":\"contract IAllowTokens\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAllowTokens\",\"type\":\"address\"}],\"name\":\"changeAllowTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFederation\",\"type\":\"address\"}],\"name\":\"changeFederation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newSideTokenFactory\",\"type\":\"address\"}],\"name\":\"changeSideTokenFactory\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claim\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claimFallback\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"},{\"internalType\":\"address payable\",\"name\":\"_relayer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_s\",\"type\":\"bytes32\"}],\"name\":\"claimGasless\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"claimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"_originalTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"_tokenSymbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_tokenName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"}],\"name\":\"createSideToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deprecatedKnownTokens\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deprecatedMappedTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deprecatedOriginalTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deprecatedSymbolPrefix\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"domainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePercentageDivider\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFederation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeePercentage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"}],\"name\":\"getOriginalTokenBySideToken\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.OriginalToken\",\"name\":\"originalToken\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"}],\"name\":\"getTransactionDataHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasBeenClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasCrossed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initDomainSeparator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_federation\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_allowTokens\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_sideTokenFactory\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"transactionDataHashMultichain\",\"type\":\"bytes32\"}],\"name\":\"isClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionDataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionDataHashMultichain\",\"type\":\"bytes32\"}],\"name\":\"isClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isPauser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUpgrading\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalToken\",\"type\":\"address\"}],\"name\":\"knownToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"knownTokenByChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"originalTokenAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"originalTokenBySideToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenToUse\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"receiveTokensTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renouncePauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"senderAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"setFeePercentage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.OriginalToken\",\"name\":\"originalToken\",\"type\":\"tuple\"}],\"name\":\"setOriginalTokenBySideTokenByChain\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"}],\"name\":\"setSideTokenByOriginalAddressByChain\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"setUpgrading\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_wrappedCurrency\",\"type\":\"address\"}],\"name\":\"setWrappedCurrency\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalToken\",\"type\":\"address\"}],\"name\":\"sideTokenByOriginalToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"sideTokenByOriginalTokenByChain\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sideTokenFactory\",\"outputs\":[{\"internalType\":\"contract ISideTokenFactory\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"userData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transactionsDataHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wrappedCurrency\",\"outputs\":[{\"internalType\":\"contract IWrapped\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"__Pausable_init(address)\":{\"details\":\"Initializes the contract in unpaused state. Assigns the Pauser role to the deployer.\"},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pause()\":{\"details\":\"Called by a pauser to pause, triggers stopped state.\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"params\":{\"userData\":\"it can be 2 options in the first one you can send the receiver and the chain id of the destination const userData = web3.eth.abi.encodeParameters( [\\\"address\\\", \\\"uint256\\\"], [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID] ); or you also can send only the destination chain id, and the receiver would be the same as the from parameter const userData = web3.eth.abi.encodeParameters([\\\"uint256\\\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"unpause()\":{\"details\":\"Called by a pauser to unpause, returns to normal state.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"acceptTransfer(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)\":{\"notice\":\"Accepts the transaction from the other chain that was voted and sent by the Federation contract\"},\"claim((address,uint256,bytes32,bytes32,uint32,uint256))\":{\"notice\":\"Claims the crossed transaction using the hash, this sends the funds to the address indicated in\"},\"depositTo(uint256,address)\":{\"notice\":\"Use network currency and cross it.\"},\"receiveTokensTo(uint256,address,address,uint256)\":{\"notice\":\"ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction See https://eips.ethereum.org/EIPS/eip-777#motivation for details\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Bridge/Bridge.sol\":\"Bridge\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Bridge/Bridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n// import \\\"hardhat/console.sol\\\";\\n// Import base Initializable contract\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\n// Import interface and library from OpenZeppelin contracts\\nimport \\\"../zeppelin/upgradable/utils/ReentrancyGuard.sol\\\";\\nimport \\\"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\n\\nimport \\\"../zeppelin/introspection/IERC1820Registry.sol\\\";\\nimport \\\"../zeppelin/token/ERC777/IERC777Recipient.sol\\\";\\nimport \\\"../zeppelin/token/ERC20/IERC20.sol\\\";\\nimport \\\"../zeppelin/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"../zeppelin/utils/Address.sol\\\";\\nimport \\\"../zeppelin/math/SafeMath.sol\\\";\\nimport \\\"../zeppelin/token/ERC777/IERC777.sol\\\";\\n\\nimport \\\"../lib/LibEIP712.sol\\\";\\nimport \\\"../lib/LibUtils.sol\\\";\\n\\nimport \\\"../interface/IBridge.sol\\\";\\nimport \\\"../interface/ISideToken.sol\\\";\\nimport \\\"../interface/ISideTokenFactory.sol\\\";\\nimport \\\"../interface/IAllowTokens.sol\\\";\\nimport \\\"../interface/IWrapped.sol\\\";\\n\\n// solhint-disable-next-line max-states-count\\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\\n\\tusing SafeMath for uint256;\\n\\tusing SafeERC20 for IERC20;\\n\\tusing Address for address;\\n\\n\\taddress constant internal NULL_ADDRESS = address(0);\\n\\tbytes32 constant internal NULL_HASH = bytes32(0);\\n\\tIERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\n\\n\\taddress internal federation;\\n\\tuint256 internal feePercentage;\\n\\tstring public deprecatedSymbolPrefix;\\n\\t// domainSeparator replaces uint256 internal _depprecatedLastDay;\\n\\tbytes32 public domainSeparator;\\n\\tuint256 internal _deprecatedSpentToday;\\n\\n\\tmapping (address => address) public deprecatedMappedTokens; // OriginalToken => SideToken\\n\\tmapping (address => address) public deprecatedOriginalTokens; // SideToken => OriginalToken\\n\\tmapping (address => bool) public deprecatedKnownTokens; // OriginalToken => true\\n\\n\\t// claimed can use the same of bytes32\\n\\tmapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\\n\\n\\tIAllowTokens public allowTokens;\\n\\tISideTokenFactory public sideTokenFactory;\\n\\t//Bridge_v1 variables\\n\\tbool public isUpgrading;\\n\\t// Percentage with up to 2 decimals\\n\\tuint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\\n\\t//Bridge_v2 variables\\n\\tbytes32 constant internal _erc777Interface = keccak256(\\\"ERC777Token\\\"); // solhint-disable-line const-name-snakecase\\n\\tIWrapped public wrappedCurrency;\\n\\tmapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\\n\\tmapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\\n\\tmapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\\n\\n\\t// keccak256(\\\"Claim(address to,uint256 amount,bytes32 transactionHash,uint256 originChainId,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\\\");\\n\\tbytes32 public constant CLAIM_TYPEHASH = 0xaf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c;\\n\\tmapping(address => uint) public nonces;\\n\\n\\t//Bridge_v3 variables multichain\\n\\tmapping (uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain; // chainId => OriginalToken Address => SideToken Address\\n\\tmapping (address => OriginalToken) public originalTokenBySideToken; // SideTokenAddress => struct {}\\n\\tmapping (uint256 => mapping(address => bool)) public knownTokenByChain; // chainId => OriginalToken Address => Know\\n\\n\\tevent AllowTokensChanged(address _newAllowTokens);\\n\\tevent FederationChanged(address _newFederation);\\n\\tevent SideTokenFactoryChanged(address _newSideTokenFactory);\\n\\tevent Upgrading(bool _isUpgrading);\\n\\tevent WrappedCurrencyChanged(address _wrappedCurrency);\\n\\n\\tfunction initialize(\\n\\t\\taddress _manager,\\n\\t\\taddress _federation,\\n\\t\\taddress _allowTokens,\\n\\t\\taddress _sideTokenFactory\\n\\t) public initializer {\\n\\t\\tUpgradableOwnable.initialize(_manager);\\n\\t\\tUpgradablePausable.__Pausable_init(_manager);\\n\\t\\tallowTokens = IAllowTokens(_allowTokens);\\n\\t\\tsideTokenFactory = ISideTokenFactory(_sideTokenFactory);\\n\\t\\tfederation = _federation;\\n\\t\\t//keccak256(\\\"ERC777TokensRecipient\\\")\\n\\t\\tERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\\n\\t\\tinitDomainSeparator();\\n\\t}\\n\\n\\treceive () external payable {\\n\\t\\t// The fallback function is needed to use WRBTC\\n\\t\\trequire(_msgSender() == address(wrappedCurrency), \\\"Bridge: not wrappedCurrency\\\");\\n\\t}\\n\\n\\tfunction version() override external pure returns (string memory) {\\n\\t\\treturn \\\"v4\\\";\\n\\t}\\n\\n\\tfunction initDomainSeparator() public {\\n\\t\\tdomainSeparator = LibEIP712.hashEIP712Domain(\\n\\t\\t\\t\\\"RSK Token Bridge\\\",\\n\\t\\t\\t\\\"1\\\",\\n\\t\\t\\tblock.chainid,\\n\\t\\t\\taddress(this)\\n\\t\\t);\\n\\t}\\n\\n\\tmodifier whenNotUpgrading() {\\n\\t\\trequire(!isUpgrading, \\\"Bridge: Upgrading\\\");\\n\\t\\t_;\\n\\t}\\n\\n\\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\\n\\t\\trequire(chainId == block.chainid, \\\"Bridge: Not block.chainid\\\");\\n\\t}\\n\\n\\tfunction sideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\\n\\t\\taddress sideTokenAddr = sideTokenByOriginalTokenByChain[chainId][originalToken];\\n\\n\\t\\tif (sideTokenAddr != NULL_ADDRESS) {\\n\\t\\t\\treturn sideTokenAddr;\\n\\t\\t}\\n\\n\\t\\t// specification for retrocompatibility\\n\\t\\treturn deprecatedMappedTokens[originalToken];\\n\\t}\\n\\n\\tfunction setSideTokenByOriginalAddressByChain(uint256 chainId, address originalToken, address sideToken) public onlyOwner {\\n\\t\\tsideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\\n\\t}\\n\\n\\tfunction getOriginalTokenBySideToken(address sideToken) public view returns(OriginalToken memory originalToken) {\\n\\t\\toriginalToken = originalTokenBySideToken[sideToken];\\n\\t\\tif (originalToken.tokenAddress != NULL_ADDRESS) {\\n\\t\\t\\treturn originalToken;\\n\\t\\t}\\n\\n\\t\\t// specification for retrocompatibility\\n\\t\\toriginalToken.originChainId = 1; // ethereum main chain id\\n\\t\\toriginalToken.tokenAddress = deprecatedOriginalTokens[sideToken];\\n\\t\\treturn originalToken;\\n\\t}\\n\\n\\tfunction setOriginalTokenBySideTokenByChain(address sideToken, OriginalToken memory originalToken) public onlyOwner {\\n\\t\\toriginalTokenBySideToken[sideToken] = originalToken;\\n\\t}\\n\\n\\tfunction knownToken(uint256 chainId, address originalToken) public view returns(bool) {\\n\\t\\tbool knowToken = knownTokenByChain[chainId][originalToken];\\n\\t\\tif (knowToken) {\\n\\t\\t\\treturn knowToken;\\n\\t\\t}\\n\\n\\t\\t// specification for retrocompatibility\\n\\t\\treturn deprecatedKnownTokens[originalToken];\\n\\t}\\n\\n\\tfunction _setKnownTokenByChain(uint256 chainId, address originalToken, bool knownTokenValue) internal {\\n\\t\\tknownTokenByChain[chainId][originalToken] = knownTokenValue;\\n\\t}\\n\\n\\tfunction acceptTransfer(\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _from,\\n\\t\\taddress payable _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t) external whenNotPaused nonReentrant override {\\n\\t\\trequire(_msgSender() == federation, \\\"Bridge: Not Federation\\\");\\n\\t\\tcheckChainId(_originChainId);\\n\\t\\tshouldBeCurrentChainId(_destinationChainId);\\n\\t\\trequire(knownToken(_originChainId, _originalTokenAddress) ||\\n\\t\\t\\tsideTokenByOriginalToken(_originChainId, _originalTokenAddress) != NULL_ADDRESS,\\n\\t\\t\\t\\\"Bridge: Unknown token\\\"\\n\\t\\t);\\n\\t\\trequire(_to != NULL_ADDRESS, \\\"Bridge: Null To\\\");\\n\\t\\trequire(_amount > 0, \\\"Bridge: Amount 0\\\");\\n\\t\\trequire(_blockHash != NULL_HASH, \\\"Bridge: Null BlockHash\\\");\\n\\t\\trequire(_transactionHash != NULL_HASH, \\\"Bridge: Null TxHash\\\");\\n\\t\\trequire(transactionsDataHashes[_transactionHash] == bytes32(0), \\\"Bridge: Already accepted\\\");\\n\\n\\t\\tbytes32 _transactionDataHash = getTransactionDataHash(\\n\\t\\t\\t_to,\\n\\t\\t\\t_amount,\\n\\t\\t\\t_blockHash,\\n\\t\\t\\t_transactionHash,\\n\\t\\t\\t_logIndex\\n\\t\\t);\\n\\n\\t\\tbytes32 _transactionDataHashMultichain = getTransactionDataHash(\\n\\t\\t\\t_to,\\n\\t\\t\\t_amount,\\n\\t\\t\\t_blockHash,\\n\\t\\t\\t_transactionHash,\\n\\t\\t\\t_logIndex,\\n\\t\\t\\t_originChainId,\\n\\t\\t\\t_destinationChainId\\n\\t\\t);\\n\\t\\t// Do not remove, claimed also has the previously processed using the older bridge version\\n\\t\\t// https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\\n\\t\\trequire(!isClaimed(_transactionDataHash, _transactionDataHashMultichain), \\\"Bridge: Already claimed\\\");\\n\\n\\t\\ttransactionsDataHashes[_transactionHash] = _transactionDataHashMultichain;\\n\\t\\toriginalTokenAddresses[_transactionHash] = _originalTokenAddress;\\n\\t\\tsenderAddresses[_transactionHash] = _from;\\n\\n\\t\\temit AcceptedCrossTransfer(\\n\\t\\t\\t_transactionHash,\\n\\t\\t\\t_originalTokenAddress,\\n\\t\\t\\t_to,\\n\\t\\t\\t_from,\\n\\t\\t\\t_amount,\\n\\t\\t\\t_blockHash,\\n\\t\\t\\t_logIndex,\\n\\t\\t\\t_originChainId,\\n\\t\\t\\t_destinationChainId\\n\\t\\t);\\n\\t}\\n\\n\\tfunction checkChainId(uint256 chainId) internal pure {\\n\\t\\trequire(chainId > 0, \\\"Bridge: ChainId is 0\\\");\\n\\t}\\n\\n\\tfunction createSideToken(\\n\\t\\tuint256 _typeId,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\tuint8 _originalTokenDecimals,\\n\\t\\tstring calldata _tokenSymbol,\\n\\t\\tstring calldata _tokenName,\\n\\t\\tuint256 _originChainId\\n\\t) external onlyOwner override {\\n\\t\\trequire(_originalTokenAddress != NULL_ADDRESS, \\\"Bridge: Null token\\\");\\n\\t\\tcheckChainId(_originChainId);\\n\\t\\taddress sideToken = sideTokenByOriginalToken(_originChainId, _originalTokenAddress);\\n\\t\\trequire(sideToken == NULL_ADDRESS, \\\"Bridge: Already exists\\\");\\n\\n\\t\\tuint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\\n\\n\\t\\t// Create side token\\n\\t\\tsideToken = sideTokenFactory.createSideToken(_tokenName, _tokenSymbol, granularity);\\n\\n\\t\\tsetSideTokenByOriginalAddressByChain(_originChainId, _originalTokenAddress, sideToken);\\n\\n\\t\\tOriginalToken memory originalToken;\\n\\t\\toriginalToken.originChainId = _originChainId;\\n\\t\\toriginalToken.tokenAddress = _originalTokenAddress;\\n\\t\\tsetOriginalTokenBySideTokenByChain(sideToken, originalToken);\\n\\t\\tallowTokens.setToken(sideToken, _typeId);\\n\\n\\t\\temit NewSideToken(sideToken, _originalTokenAddress, _tokenSymbol, granularity, _originChainId);\\n\\t}\\n\\n\\tfunction claim(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\\n\\t\\treceivedAmount = _claim(\\n\\t\\t\\t_claimData,\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\tpayable(address(0)),\\n\\t\\t\\t0\\n\\t\\t);\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\tfunction claimFallback(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\\n\\t\\trequire(_msgSender() == senderAddresses[_claimData.transactionHash],\\\"Bridge: invalid sender\\\");\\n\\t\\treceivedAmount = _claim(\\n\\t\\t\\t_claimData,\\n\\t\\t\\t_msgSender(),\\n\\t\\t\\tpayable(address(0)),\\n\\t\\t\\t0\\n\\t\\t);\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\tfunction getDigest(\\n\\t\\tClaimData memory _claimData,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _deadline\\n\\t) internal returns (bytes32) {\\n\\t\\treturn LibEIP712.hashEIP712Message(\\n\\t\\t\\tdomainSeparator,\\n\\t\\t\\tkeccak256(\\n\\t\\t\\t\\tabi.encode(\\n\\t\\t\\t\\t\\tCLAIM_TYPEHASH,\\n\\t\\t\\t\\t\\t_claimData.to,\\n\\t\\t\\t\\t\\t_claimData.amount,\\n\\t\\t\\t\\t\\t_claimData.transactionHash,\\n\\t\\t\\t\\t\\t_claimData.originChainId,\\n\\t\\t\\t\\t\\t_relayer,\\n\\t\\t\\t\\t\\t_fee,\\n\\t\\t\\t\\t\\tnonces[_claimData.to]++,\\n\\t\\t\\t\\t\\t_deadline\\n\\t\\t\\t\\t)\\n\\t\\t\\t)\\n\\t\\t);\\n\\t}\\n\\n\\t// Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\\n\\tfunction claimGasless(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _deadline,\\n\\t\\tuint8 _v,\\n\\t\\tbytes32 _r,\\n\\t\\tbytes32 _s\\n\\t) external override returns (uint256 receivedAmount) {\\n\\t\\trequire(_deadline >= block.timestamp, \\\"Bridge: EXPIRED\\\"); // solhint-disable-line not-rely-on-time\\n\\n\\t\\tbytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\\n\\t\\taddress recoveredAddress = ecrecover(digest, _v, _r, _s);\\n\\t\\trequire(_claimData.to != address(0) && recoveredAddress == _claimData.to, \\\"Bridge: INVALID_SIGNATURE\\\");\\n\\n\\t\\treturn _claim(\\n\\t\\t\\t_claimData,\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\t_relayer,\\n\\t\\t\\t_fee\\n\\t\\t);\\n\\t}\\n\\n\\tfunction isClaimed(bytes32 transactionDataHash, bytes32 transactionDataHashMultichain) public view returns(bool) {\\n\\t\\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\\n\\t}\\n\\n\\tfunction isClaimed(ClaimData calldata _claimData, bytes32 transactionDataHashMultichain) public view returns(bool) {\\n\\t\\tbytes32 transactionDataHash = getTransactionDataHash(\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\t_claimData.amount,\\n\\t\\t\\t_claimData.blockHash,\\n\\t\\t\\t_claimData.transactionHash,\\n\\t\\t\\t_claimData.logIndex\\n\\t\\t);\\n\\n\\t\\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\\n\\t}\\n\\n\\tfunction _claim(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress payable _reciever,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal nonReentrant returns (uint256 receivedAmount) {\\n\\t\\taddress originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\\n\\t\\trequire(originalTokenAddress != NULL_ADDRESS, \\\"Bridge: Tx not crossed\\\");\\n\\n\\t\\tbytes32 transactionDataHash = getTransactionDataHash(\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\t_claimData.amount,\\n\\t\\t\\t_claimData.blockHash,\\n\\t\\t\\t_claimData.transactionHash,\\n\\t\\t\\t_claimData.logIndex,\\n\\t\\t\\t_claimData.originChainId,\\n\\t\\t\\tblock.chainid\\n\\t\\t);\\n\\n\\t\\trequire(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \\\"Bridge: Wrong transactionDataHash\\\");\\n\\t\\trequire(!isClaimed(_claimData, transactionDataHash), \\\"Bridge: Already claimed\\\");\\n\\t\\tclaimed[transactionDataHash] = true;\\n\\n\\t\\treceivedAmount = _claimCross(\\n\\t\\t\\t_claimData.originChainId,\\n\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t_reciever,\\n\\t\\t\\t_claimData.amount,\\n\\t\\t\\t_relayer,\\n\\t\\t\\t_fee\\n\\t\\t);\\n\\n\\t\\temitClaimed(_claimData, originalTokenAddress, _reciever, _relayer, _fee);\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\tfunction emitClaimed(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _reciever,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal {\\n\\t\\temit Claimed(\\n\\t\\t\\t_claimData.transactionHash,\\n\\t\\t\\t_originalTokenAddress,\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\tsenderAddresses[_claimData.transactionHash],\\n\\t\\t\\t_claimData.amount,\\n\\t\\t\\t_claimData.blockHash,\\n\\t\\t\\t_claimData.logIndex,\\n\\t\\t\\t_reciever,\\n\\t\\t\\t_relayer,\\n\\t\\t\\t_fee,\\n\\t\\t\\t_claimData.originChainId,\\n\\t\\t\\tblock.chainid\\n\\t\\t);\\n\\t}\\n\\n\\tfunction _claimCross(\\n\\t\\tuint256 _originalChainId,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _reciever,\\n\\t\\tuint256 _amount,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal returns (uint256) {\\n\\t\\tcheckChainId(_originalChainId);\\n\\t\\tif (knownToken(_originalChainId, _originalTokenAddress)) {\\n\\t\\t\\treturn _claimCrossBackToToken(\\n\\t\\t\\t\\t_originalTokenAddress,\\n\\t\\t\\t\\t_reciever,\\n\\t\\t\\t\\t_amount,\\n\\t\\t\\t\\t_relayer,\\n\\t\\t\\t\\t_fee\\n\\t\\t\\t);\\n\\t\\t}\\n\\n\\t\\treturn _claimCrossToSideToken(\\n\\t\\t\\tsideTokenByOriginalToken(_originalChainId, _originalTokenAddress),\\n\\t\\t\\t_reciever,\\n\\t\\t\\t_amount,\\n\\t\\t\\t_relayer,\\n\\t\\t\\t_fee\\n\\t\\t);\\n\\t}\\n\\n\\tfunction _claimCrossToSideToken(\\n\\t\\taddress _sideToken,\\n\\t\\taddress payable _receiver,\\n\\t\\tuint256 _amount,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal returns (uint256 receivedAmount) {\\n\\t\\trequire(_sideToken != NULL_ADDRESS, \\\"Bridge: side token is null\\\");\\n\\t\\tuint256 granularity = IERC777(_sideToken).granularity();\\n\\t\\tuint256 formattedAmount = _amount.mul(granularity);\\n\\t\\trequire(_fee <= formattedAmount, \\\"Bridge: fee too high\\\");\\n\\t\\treceivedAmount = formattedAmount.sub(_fee);\\n\\t\\tISideToken(_sideToken).mint(_receiver, receivedAmount, \\\"\\\", \\\"\\\");\\n\\t\\tif (_fee > 0) {\\n\\t\\t\\tISideToken(_sideToken).mint(_relayer, _fee, \\\"\\\", \\\"relayer fee\\\");\\n\\t\\t}\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\tfunction _claimCrossBackToToken(\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _receiver,\\n\\t\\tuint256 _amount,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal returns (uint256 receivedAmount) {\\n\\t\\tuint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\\n\\t\\t//As side tokens are ERC777 they will always have 18 decimals\\n\\t\\tuint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\\n\\t\\trequire(_fee <= formattedAmount, \\\"Bridge: fee too high\\\");\\n\\t\\treceivedAmount = formattedAmount.sub(_fee);\\n\\t\\tif (address(wrappedCurrency) == _originalTokenAddress) {\\n\\t\\t\\twrappedCurrency.withdraw(formattedAmount);\\n\\t\\t\\t_receiver.transfer(receivedAmount);\\n\\t\\t\\tif(_fee > 0) {\\n\\t\\t\\t\\t_relayer.transfer(_fee);\\n\\t\\t\\t}\\n\\t\\t} else {\\n\\t\\t\\tIERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\\n\\t\\t\\tif(_fee > 0) {\\n\\t\\t\\t\\tIERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\t/**\\n\\t\\t* ERC-20 tokens approve and transferFrom pattern\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\n\\t\\t*/\\n\\tfunction receiveTokensTo(uint256 destinationChainId, address tokenToUse, address to, uint256 amount) external override {\\n\\t\\taddress sender = _msgSender();\\n\\t\\t//Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\\n\\t\\tIERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\\n\\t\\tcrossTokens(tokenToUse, sender, to, amount, \\\"\\\", destinationChainId);\\n\\t}\\n\\n\\t/**\\n\\t\\t* Use network currency and cross it.\\n\\t\\t*/\\n\\tfunction depositTo(uint256 chainId, address to) external payable override {\\n\\t\\taddress sender = _msgSender();\\n\\t\\trequire(address(wrappedCurrency) != NULL_ADDRESS, \\\"Bridge: wrappedCurrency empty\\\");\\n\\t\\twrappedCurrency.deposit{ value: msg.value }();\\n\\t\\tcrossTokens(address(wrappedCurrency), sender, to, msg.value, \\\"\\\", chainId);\\n\\t}\\n\\n\\t/**\\n\\t\\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\n\\t\\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\\n\\t\\t* const userData = web3.eth.abi.encodeParameters(\\n * [\\\"address\\\", \\\"uint256\\\"],\\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\\n * );\\n\\t\\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\\n\\t\\t* const userData = web3.eth.abi.encodeParameters([\\\"uint256\\\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\\n\\t\\t*/\\n\\tfunction tokensReceived(\\n\\t\\taddress operator,\\n\\t\\taddress from,\\n\\t\\taddress to,\\n\\t\\tuint amount,\\n\\t\\tbytes calldata userData, // [address,uint256] user addrest receiver, destinationChainId || [uint256] same as from, destinationChainId\\n\\t\\tbytes calldata\\n\\t) external override(IBridge, IERC777Recipient) {\\n\\t\\t//Hook from ERC777address\\n\\t\\tif(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\\n\\t\\trequire(to == address(this), \\\"Bridge: Not to this address\\\");\\n\\t\\taddress tokenToUse = _msgSender();\\n\\t\\trequire(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \\\"Bridge: Not ERC777 token\\\");\\n\\t\\trequire(userData.length >= 32, \\\"Bridge: user data with at least the destinationChainId\\\");\\n\\t\\trequire(userData.length == 64 || !from.isContract(), \\\"Bridge: Specify receiver address in data\\\");\\n\\t\\taddress receiver = userData.length == 32 ? from : LibUtils.toAddress(userData, 12);\\n\\t\\tuint256 destinationChainId = LibUtils.toUint256(userData, userData.length - 32);\\n\\t\\tcrossTokens(tokenToUse, from, receiver, amount, userData, destinationChainId);\\n\\t}\\n\\n\\tfunction crossTokens(\\n\\t\\taddress tokenToUse,\\n\\t\\taddress from,\\n\\t\\taddress to,\\n\\t\\tuint256 amount,\\n\\t\\tbytes memory userData,\\n\\t\\tuint256 destinationChainId\\n\\t) internal whenNotUpgrading whenNotPaused nonReentrant {\\n\\t\\trequire(block.chainid != destinationChainId, \\\"Bridge: destination chain id equal current chain id\\\");\\n\\t\\tcheckChainId(destinationChainId);\\n\\t\\t_setKnownTokenByChain(destinationChainId, tokenToUse, true);\\n\\t\\tuint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\\n\\t\\tuint256 amountMinusFees = amount.sub(fee);\\n\\t\\tuint8 decimals = LibUtils.getDecimals(tokenToUse);\\n\\t\\tuint formattedAmount = amount;\\n\\t\\tif (decimals != 18) {\\n\\t\\t\\tformattedAmount = amount.mul(uint256(10)**(18-decimals));\\n\\t\\t}\\n\\t\\t// We consider the amount before fees converted to 18 decimals to check the limits\\n\\t\\t// updateTokenTransfer revert if token not allowed\\n\\t\\tallowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\\n\\n\\t\\tOriginalToken memory sideToken = getOriginalTokenBySideToken(tokenToUse);\\n\\t\\tif (sideToken.tokenAddress != NULL_ADDRESS) {\\n\\t\\t\\t// Side Token Crossing back\\n\\t\\t\\t{ // Created scope to avoid stack too deep\\n\\t\\t\\t\\tuint256 granularity = LibUtils.getGranularity(tokenToUse);\\n\\t\\t\\t\\tuint256 modulo = amountMinusFees.mod(granularity);\\n\\t\\t\\t\\tfee = fee.add(modulo);\\n\\t\\t\\t\\tamountMinusFees = amountMinusFees.sub(modulo);\\n\\t\\t\\t\\tIERC777(tokenToUse).burn(amountMinusFees, userData);\\n\\t\\t\\t}\\n\\t\\t\\temit Cross(\\n\\t\\t\\t\\tsideToken.tokenAddress,\\n\\t\\t\\t\\tto,\\n\\t\\t\\t\\tdestinationChainId,\\n\\t\\t\\t\\tfrom,\\n\\t\\t\\t\\tblock.chainid,\\n\\t\\t\\t\\tamountMinusFees,\\n\\t\\t\\t\\tuserData\\n\\t\\t\\t);\\n\\t\\t} else {\\n\\t\\t\\temit Cross(\\n\\t\\t\\t\\ttokenToUse,\\n\\t\\t\\t\\tto,\\n\\t\\t\\t\\tdestinationChainId,\\n\\t\\t\\t\\tfrom,\\n\\t\\t\\t\\tblock.chainid,\\n\\t\\t\\t\\tamountMinusFees,\\n\\t\\t\\t\\tuserData\\n\\t\\t\\t);\\n\\t\\t}\\n\\n\\t\\tif (fee > 0) {\\n\\t\\t\\t//Send the payment to the MultiSig of the Federation\\n\\t\\t\\tIERC20(tokenToUse).safeTransfer(owner(), fee);\\n\\t\\t}\\n\\t}\\n\\n\\t// function for retrocompatibility\\n\\tfunction getTransactionDataHash(\\n\\t\\taddress _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex\\n\\t) internal pure returns(bytes32) {\\n\\t\\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\\n\\t}\\n\\n\\tfunction getTransactionDataHash(\\n\\t\\taddress _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t) public pure override returns(bytes32) {\\n\\t\\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex, _originChainId, _destinationChainId));\\n\\t}\\n\\n\\tfunction setFeePercentage(uint amount) external onlyOwner {\\n\\t\\trequire(amount < (feePercentageDivider/10), \\\"Bridge: bigger than 10%\\\");\\n\\t\\tfeePercentage = amount;\\n\\t\\temit FeePercentageChanged(feePercentage);\\n\\t}\\n\\n\\tfunction getFeePercentage() external view override returns(uint) {\\n\\t\\treturn feePercentage;\\n\\t}\\n\\n\\tfunction changeFederation(address newFederation) external onlyOwner {\\n\\t\\trequire(newFederation != NULL_ADDRESS, \\\"Bridge: Federation is empty\\\");\\n\\t\\tfederation = newFederation;\\n\\t\\temit FederationChanged(federation);\\n\\t}\\n\\n\\tfunction changeAllowTokens(address newAllowTokens) external onlyOwner {\\n\\t\\trequire(newAllowTokens != NULL_ADDRESS, \\\"Bridge: AllowTokens is empty\\\");\\n\\t\\tallowTokens = IAllowTokens(newAllowTokens);\\n\\t\\temit AllowTokensChanged(newAllowTokens);\\n\\t}\\n\\n\\tfunction getFederation() external view returns(address) {\\n\\t\\treturn federation;\\n\\t}\\n\\n\\tfunction changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\\n\\t\\trequire(newSideTokenFactory != NULL_ADDRESS, \\\"Bridge: SideTokenFactory is empty\\\");\\n\\t\\tsideTokenFactory = ISideTokenFactory(newSideTokenFactory);\\n\\t\\temit SideTokenFactoryChanged(newSideTokenFactory);\\n\\t}\\n\\n\\tfunction setUpgrading(bool _isUpgrading) external onlyOwner {\\n\\t\\tisUpgrading = _isUpgrading;\\n\\t\\temit Upgrading(isUpgrading);\\n\\t}\\n\\n\\tfunction setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\\n\\t\\trequire(_wrappedCurrency != NULL_ADDRESS, \\\"Bridge: wrapp is empty\\\");\\n\\t\\twrappedCurrency = IWrapped(_wrappedCurrency);\\n\\t\\temit WrappedCurrencyChanged(_wrappedCurrency);\\n\\t}\\n\\n\\tfunction hasCrossed(bytes32 transactionHash) public view returns (bool) {\\n\\t\\treturn transactionsDataHashes[transactionHash] != bytes32(0);\\n\\t}\\n\\n\\tfunction hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\\n\\t\\treturn claimed[transactionsDataHashes[transactionHash]];\\n\\t}\\n\\n}\\n\",\"keccak256\":\"0xf11ace92389f7edb41aaec4e9431e139260ddd5167c6ecbc8aa9941f52d856d8\",\"license\":\"MIT\"},\"contracts/interface/IAllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\ninterface IAllowTokens {\\n\\n\\tstruct Limits {\\n\\t\\tuint256 min;\\n\\t\\tuint256 max;\\n\\t\\tuint256 daily;\\n\\t\\tuint256 mediumAmount;\\n\\t\\tuint256 largeAmount;\\n\\t}\\n\\n\\tstruct TokenInfo {\\n\\t\\tbool allowed;\\n\\t\\tuint256 typeId;\\n\\t\\tuint256 spentToday;\\n\\t\\tuint256 lastDay;\\n\\t}\\n\\n\\tstruct TypeInfo {\\n\\t\\tstring description;\\n\\t\\tLimits limits;\\n\\t}\\n\\n\\tstruct TokensAndType {\\n\\t\\taddress token;\\n\\t\\tuint256 typeId;\\n\\t}\\n\\n\\tfunction version() external pure returns (string memory);\\n\\n\\tfunction getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\\n\\n\\tfunction calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\\n\\n\\tfunction getTypesLimits() external view returns(Limits[] memory limits);\\n\\n\\tfunction getTypeDescriptionsLength() external view returns(uint256);\\n\\n\\tfunction getTypeDescriptions() external view returns(string[] memory descriptions);\\n\\n\\tfunction setToken(address token, uint256 typeId) external;\\n\\n\\tfunction getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\\n\\n\\tfunction isTokenAllowed(address token) external view returns (bool);\\n\\n\\tfunction updateTokenTransfer(address token, uint256 amount) external;\\n}\",\"keccak256\":\"0x7a68f098e5efaad2d9d84314b2df76897fa9dbbe65c64d629b02b1dc4d9d36b5\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\ninterface IBridge {\\n\\n\\tstruct ClaimData {\\n\\t\\taddress payable to;\\n\\t\\tuint256 amount;\\n\\t\\tbytes32 blockHash;\\n\\t\\tbytes32 transactionHash;\\n\\t\\tuint32 logIndex;\\n\\t\\tuint256 originChainId;\\n\\t}\\n\\n\\tstruct OriginalToken {\\n\\t\\taddress tokenAddress;\\n\\t\\tuint256 originChainId;\\n\\t}\\n\\n\\tfunction version() external pure returns (string memory);\\n\\n\\tfunction getFeePercentage() external view returns(uint);\\n\\n\\t/**\\n\\t\\t* ERC-20 tokens approve and transferFrom pattern\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\n\\t\\t*/\\n\\tfunction receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;\\n\\n\\t/**\\n\\t\\t* Use network currency and cross it.\\n\\t\\t*/\\n\\tfunction depositTo(uint256 chainId, address to) external payable;\\n\\n\\t/**\\n\\t\\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\n\\t\\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\\n\\t\\t* const userData = web3.eth.abi.encodeParameters(\\n * [\\\"address\\\", \\\"uint256\\\"],\\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\\n * );\\n\\t\\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\\n\\t\\t* const userData = web3.eth.abi.encodeParameters([\\\"uint256\\\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\\n\\t\\t*/\\n\\tfunction tokensReceived (\\n\\t\\taddress operator,\\n\\t\\taddress from,\\n\\t\\taddress to,\\n\\t\\tuint amount,\\n\\t\\tbytes calldata userData,\\n\\t\\tbytes calldata operatorData\\n\\t) external;\\n\\n\\t/**\\n\\t\\t* Accepts the transaction from the other chain that was voted and sent by the Federation contract\\n\\t\\t*/\\n\\tfunction acceptTransfer(\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _from,\\n\\t\\taddress payable _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t) external;\\n\\n\\t/**\\n\\t\\t* Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\n\\t\\t*/\\n\\tfunction claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n\\tfunction claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n\\tfunction claimGasless(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _deadline,\\n\\t\\tuint8 _v,\\n\\t\\tbytes32 _r,\\n\\t\\tbytes32 _s\\n\\t) external returns (uint256 receivedAmount);\\n\\n\\tfunction createSideToken(\\n\\t\\tuint256 _typeId,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\tuint8 _originalTokenDecimals,\\n\\t\\tstring calldata _originalTokenSymbol,\\n\\t\\tstring calldata _originalTokenName,\\n\\t\\tuint256 _chainId\\n\\t) external;\\n\\n\\tfunction getTransactionDataHash(\\n\\t\\taddress _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256 _destinationChainId\\n\\t) external returns(bytes32);\\n\\n\\tevent Cross(\\n\\t\\taddress indexed _tokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\tuint256 indexed _destinationChainId,\\n\\t\\taddress _from,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes _userData\\n\\t);\\n\\n\\tevent NewSideToken(\\n\\t\\taddress indexed _newSideTokenAddress,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\tstring _newSymbol,\\n\\t\\tuint256 _granularity,\\n\\t\\tuint256 _chainId\\n\\t);\\n\\tevent AcceptedCrossTransfer(\\n\\t\\tbytes32 indexed _transactionHash,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\taddress _from,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tuint256 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t);\\n\\tevent FeePercentageChanged(uint256 _amount);\\n\\tevent Claimed(\\n\\t\\tbytes32 indexed _transactionHash,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\taddress _sender,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tuint256 _logIndex,\\n\\t\\taddress _reciever,\\n\\t\\taddress _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _destinationChainId,\\n\\t\\tuint256 _originChainId\\n\\t);\\n}\",\"keccak256\":\"0x6731a952e7419e95412fd97c9f34ef403a2c16d2cf5cb1bbab4374fa6d41ff0f\",\"license\":\"MIT\"},\"contracts/interface/ISideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\ninterface ISideToken {\\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\\n}\",\"keccak256\":\"0x43d96442dcb622e7efbad6ff3fcfe109d9f881c18415b571511f326b39d7a70e\",\"license\":\"MIT\"},\"contracts/interface/ISideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\ninterface ISideTokenFactory {\\n\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\\n\\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\\n}\",\"keccak256\":\"0x5c3c0db3ad07c2cb9933ea8a37e01b83d4ec77c7bc0ac684de87f6b1e09d25dc\",\"license\":\"MIT\"},\"contracts/interface/IWrapped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\ninterface IWrapped {\\n function balanceOf(address) external returns(uint);\\n\\n function deposit() external payable;\\n\\n function withdraw(uint wad) external;\\n\\n function totalSupply() external view returns (uint);\\n\\n function approve(address guy, uint wad) external returns (bool);\\n\\n function transfer(address dst, uint wad) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint wad)\\n external\\n returns (bool);\\n}\",\"keccak256\":\"0xea9894370181d2b7a43d973e033d1ceb8d8d229fed2b775d267ca23b58836e7f\",\"license\":\"MIT\"},\"contracts/lib/LibEIP712.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\\nlibrary LibEIP712 {\\n\\n // Hash of the EIP712 Domain Separator Schema\\n // keccak256(abi.encodePacked(\\n // \\\"EIP712Domain(\\\",\\n // \\\"string name,\\\",\\n // \\\"string version,\\\",\\n // \\\"uint256 chainId,\\\",\\n // \\\"address verifyingContract\\\",\\n // \\\")\\\"\\n // ))\\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\\n\\n /// @dev Calculates a EIP712 domain separator.\\n /// @param name The EIP712 domain name.\\n /// @param version The EIP712 domain version.\\n /// @param verifyingContract The EIP712 verifying contract.\\n /// @return result EIP712 domain separator.\\n function hashEIP712Domain(\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract\\n )\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\\n\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\\n // keccak256(bytes(name)),\\n // keccak256(bytes(version)),\\n // chainId,\\n // uint256(verifyingContract)\\n // ))\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Calculate hashes of dynamic data\\n let nameHash := keccak256(add(name, 32), mload(name))\\n let versionHash := keccak256(add(version, 32), mload(version))\\n\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n // Store params in memory\\n mstore(memPtr, schemaHash)\\n mstore(add(memPtr, 32), nameHash)\\n mstore(add(memPtr, 64), versionHash)\\n mstore(add(memPtr, 96), chainId)\\n mstore(add(memPtr, 128), verifyingContract)\\n\\n // Compute hash\\n result := keccak256(memPtr, 160)\\n }\\n return result;\\n }\\n\\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\\n /// with getDomainHash().\\n /// @param hashStruct The EIP712 hash struct.\\n /// @return result EIP712 hash applied to the given EIP712 Domain.\\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // EIP191_HEADER,\\n // EIP712_DOMAIN_HASH,\\n // hashStruct\\n // ));\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\\n\\n // Compute hash\\n result := keccak256(memPtr, 66)\\n }\\n return result;\\n }\\n}\",\"keccak256\":\"0x0314f8cfcab5979a2d713b4863bf5783b1181151ac144091d23f802d3f8ac7c5\",\"license\":\"MIT\"},\"contracts/lib/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nlibrary LibUtils {\\n\\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\\n require(decimals <= 18, \\\"LibUtils: Decimals not <= 18\\\");\\n return uint256(10)**(18-decimals);\\n }\\n\\n function getDecimals(address tokenToUse) internal view returns (uint8) {\\n //support decimals as uint256 or uint8\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"decimals()\\\"));\\n require(success, \\\"LibUtils: No decimals\\\");\\n // uint: enc(X) is the big-endian encoding of X,\\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\\n return uint8(abi.decode(data, (uint256)));\\n }\\n\\n function getGranularity(address tokenToUse) internal view returns (uint256) {\\n //support granularity if ERC777\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"granularity()\\\"));\\n require(success, \\\"LibUtils: No granularity\\\");\\n\\n return abi.decode(data, (uint256));\\n }\\n\\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n addr := mload(add(bys,20))\\n }\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"LibUtils: toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"LibUtils: toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n\\t\\trequire(_bytes.length >= _start + 32, \\\"LibUtils: toUint256_outOfBounds\\\");\\n\\t\\tuint256 tempUint;\\n\\n // solium-disable-next-line security/no-inline-assembly\\n\\t\\tassembly {\\n\\t\\t\\ttempUint := mload(add(add(_bytes, 0x20), _start))\\n\\t\\t}\\n\\n\\t\\treturn tempUint;\\n\\t}\\n}\\n\",\"keccak256\":\"0xf9495f9e5371f47c7ae2a3ce423598414ee24e60983602d76563a782b2562104\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return payable(msg.sender);\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x6f3f274a2270bfe073339370edfa2485e2d515a2656039937f6b972fae96d297\",\"license\":\"MIT\"},\"contracts/zeppelin/access/Roles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Roles\\n * @dev Library for managing addresses assigned to a Role.\\n */\\nlibrary Roles {\\n struct Role {\\n mapping (address => bool) bearer;\\n }\\n\\n /**\\n * @dev Give an account access to this role.\\n */\\n function add(Role storage role, address account) internal {\\n require(!has(role, account), \\\"Roles: account already has role\\\");\\n role.bearer[account] = true;\\n }\\n\\n /**\\n * @dev Remove an account's access to this role.\\n */\\n function remove(Role storage role, address account) internal {\\n require(has(role, account), \\\"Roles: account doesn't have role\\\");\\n role.bearer[account] = false;\\n }\\n\\n /**\\n * @dev Check if an account has this role.\\n * @return bool\\n */\\n function has(Role storage role, address account) internal view returns (bool) {\\n require(account != address(0), \\\"Roles: account is the zero address\\\");\\n return role.bearer[account];\\n }\\n}\\n\",\"keccak256\":\"0x932fc31748c82142ad9f51abd8c9bbaa562c7e6183b967b78a61884ee18e3474\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC1820Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\n * implementers for interfaces in this registry, as well as query support.\\n *\\n * Implementers may be shared by multiple accounts, and can also implement more\\n * than a single interface for each account. Contracts can implement interfaces\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\n * contract.\\n *\\n * {IERC165} interfaces can also be queried via the registry.\\n *\\n * For an in-depth explanation and source code analysis, see the EIP text.\\n */\\ninterface IERC1820Registry {\\n /**\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\n * account is able to set interface implementers for it.\\n *\\n * By default, each account is its own manager. Passing a value of `0x0` in\\n * `newManager` will reset the manager to this initial state.\\n *\\n * Emits a {ManagerChanged} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `account`.\\n */\\n function setManager(address account, address newManager) external;\\n\\n /**\\n * @dev Returns the manager for `account`.\\n *\\n * See {setManager}.\\n */\\n function getManager(address account) external view returns (address);\\n\\n /**\\n * @dev Sets the `implementer` contract as `account`'s implementer for\\n * `interfaceHash`.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n * The zero address can also be used in `implementer` to remove an old one.\\n *\\n * See {interfaceHash} to learn how these are created.\\n *\\n * Emits an {InterfaceImplementerSet} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `_account`.\\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\n * end in 28 zeroes).\\n * - `_implementer` must implement {IERC1820Implementer} and return true when\\n * queried for support, unless `implementer` is the caller. See\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\n */\\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\\n\\n /**\\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\\n * implementer is registered, returns the zero address.\\n *\\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\n * zeroes), `_account` will be queried for support of it.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n */\\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\\n\\n /**\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\n * corresponding\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\n */\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\n\\n /**\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\n * @param account Address of the contract for which to update the cache.\\n * @param interfaceId ERC165 interface for which to update the cache.\\n */\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\n * If the result is not cached a direct lookup on the contract address is performed.\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\n * {updateERC165Cache} with the contract address.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\n\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\n\\n event ManagerChanged(address indexed account, address indexed newManager);\\n}\\n\",\"keccak256\":\"0x8877787cbe99ab8e2dcb85e9b22066b7e62bcea328091c1ff9ae462e54afa66e\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x8038a6eca31e013b0c7f248c7a4eb5846ab0d52bb3f7636fafcf00b075643afe\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {ERC20Detailed}.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xdb194e173849ac56dbc15eaf0c01848361748ff8e4679985c3d11013ee4fa4b6\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeERC20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeERC20: low-level call failed\\\");\\n\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb7197e89889e574b9774604c7583b7226b06f6ebf8327c462fb15d5f8465ab8b\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777Token standard as defined in the EIP.\\n *\\n * This contract uses the\\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\\n * token holders and recipients react to token movements by using setting implementers\\n * for the associated interfaces in said registry. See `IERC1820Registry` and\\n * `ERC1820Implementer`.\\n */\\ninterface IERC777 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the smallest part of the token that is not divisible. This\\n * means all token operations (creation, movement and destruction) must have\\n * amounts that are a multiple of this number.\\n *\\n * For most token contracts, this value will equal 1.\\n */\\n function granularity() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by an account (`owner`).\\n */\\n function balanceOf(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * If send or receive hooks are registered for the caller and `recipient`,\\n * the corresponding functions will be called with `data` and empty\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function send(address recipient, uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Destroys `amount` tokens from the caller's account, reducing the\\n * total supply.\\n *\\n * If a send hook is registered for the caller, the corresponding function\\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n */\\n function burn(uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Returns true if an account is an operator of `tokenHolder`.\\n * Operators can send and burn tokens on behalf of their owners. All\\n * accounts are their own operator.\\n *\\n * See `operatorSend` and `operatorBurn`.\\n */\\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor`.\\n *\\n * Emits an `AuthorizedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function authorizeOperator(address operator) external;\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor` and `defaultOperators`.\\n *\\n * Emits a `RevokedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function revokeOperator(address operator) external;\\n\\n /**\\n * @dev Returns the list of default operators. These accounts are operators\\n * for all token holders, even if `authorizeOperator` was never called on\\n * them.\\n *\\n * This list is immutable, but individual holders may revoke these via\\n * `revokeOperator`, in which case `isOperatorFor` will return false.\\n */\\n function defaultOperators() external view returns (address[] memory);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\\n * be an operator of `sender`.\\n *\\n * If send or receive hooks are registered for `sender` and `recipient`,\\n * the corresponding functions will be called with `data` and\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - `sender` cannot be the zero address.\\n * - `sender` must have at least `amount` tokens.\\n * - the caller must be an operator for `sender`.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function operatorSend(\\n address sender,\\n address recipient,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n /**\\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\\n * The caller must be an operator of `account`.\\n *\\n * If a send hook is registered for `account`, the corresponding function\\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n * - the caller must be an operator for `account`.\\n */\\n function operatorBurn(\\n address account,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n event Sent(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256 amount,\\n bytes data,\\n bytes operatorData\\n );\\n\\n function decimals() external returns (uint8);\\n\\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\\n\\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\\n\\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\\n\\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\\n}\\n\",\"keccak256\":\"0xd8fb2f5bda9acc32af1bc5ed8a64c67a42ac7f32dd1195387535e8e148d40421\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\n *\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an `IERC777` token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0xc1e6f2d257d4973a27a86e590e01a3289317bd4b44ea040a622b4823c7793875\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\",\"keccak256\":\"0x14063a689bff5eecf0f36cb519feb575f60349ecf0d425ead5b931b77dd599d4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../../Initializable.sol\\\";\\n\\nimport \\\"../../../GSN/Context.sol\\\";\\nimport \\\"../../../access/Roles.sol\\\";\\n\\ncontract UpgradablePauserRole is Initializable, Context {\\n using Roles for Roles.Role;\\n\\n event PauserAdded(address indexed account);\\n event PauserRemoved(address indexed account);\\n\\n Roles.Role private _pausers;\\n\\n function __PauserRol_init(address sender) public initializer {\\n if (!isPauser(sender)) {\\n _addPauser(sender);\\n }\\n }\\n\\n modifier onlyPauser() {\\n require(isPauser(_msgSender()), \\\"PauserRole: caller doesn't have the role\\\");\\n _;\\n }\\n\\n function isPauser(address account) public view returns (bool) {\\n return _pausers.has(account);\\n }\\n\\n function addPauser(address account) public onlyPauser {\\n _addPauser(account);\\n }\\n\\n function renouncePauser() public {\\n _removePauser(_msgSender());\\n }\\n\\n function _addPauser(address account) internal {\\n _pausers.add(account);\\n emit PauserAdded(account);\\n }\\n\\n function _removePauser(address account) internal {\\n _pausers.remove(account);\\n emit PauserRemoved(account);\\n }\\n}\\n\",\"keccak256\":\"0xb484fd9ca5d28b46ec2c0d765cd592786a5a2c796987b5a7000e0b3d8b2a0ac9\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"../access/roles/UpgradablePauserRole.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\\n /**\\n * @dev Emitted when the pause is triggered by a pauser (`account`).\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by a pauser (`account`).\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\\n * to the deployer.\\n */\\n function __Pausable_init(address sender) public initializer {\\n UpgradablePauserRole.__PauserRol_init(sender);\\n\\n _paused = false;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n */\\n modifier whenNotPaused() {\\n require(!_paused, \\\"Pausable: paused\\\");\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n */\\n modifier whenPaused() {\\n require(_paused, \\\"Pausable: not paused\\\");\\n _;\\n }\\n\\n /**\\n * @dev Called by a pauser to pause, triggers stopped state.\\n */\\n function pause() public onlyPauser whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Called by a pauser to unpause, returns to normal state.\\n */\\n function unpause() public onlyPauser whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n}\\n\",\"keccak256\":\"0xdc64aa92b0dd6c6d4dc898bee62b70ebf64449b8c27fac6dff027e2fb367e6c0\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract UpgradableOwnable is Initializable, Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function initialize(address sender) public initializer {\\n _owner = sender;\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * > Note: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n\\n}\\n\",\"keccak256\":\"0xdf439a167ae82e7e3dd241ea0c831a1bb0329432ceb4fa889778d1f2d196ce00\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\n/**\\n * @title Helps contracts guard against reentrancy attacks.\\n * @author Remco Bloemen , Eenae \\n * @dev If you mark a function `nonReentrant`, you should also\\n * mark it `external`.\\n */\\ncontract ReentrancyGuard is Initializable {\\n /// @dev counter to allow mutex lock with only one SSTORE operation\\n uint256 private _guardCounter;\\n\\n function initialize() public initializer {\\n // The counter starts at one to prevent changing it from zero to a non-zero\\n // value, which is a more expensive operation.\\n _guardCounter = 1;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n _guardCounter += 1;\\n uint256 localCounter = _guardCounter;\\n _;\\n require(localCounter == _guardCounter, \\\"ReentrancyGuard: no reentrant allowed\\\");\\n }\\n}\",\"keccak256\":\"0x56f7b326ffaf9484cbcad316cb3344153584065d5b33da5698e3eedce30565fa\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x04801fc2398ee3370f3903f95389ea3a8da65a8df01f24b352e499e44d492e9b\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50614bda806100206000396000f3fe6080604052600436106103b05760003560e01c806382dc1ec4116101e7578063c4d66de81161010d578063e4e5bbcb116100a0578063f2fde38b1161006f578063f2fde38b14610cb5578063f698da2514610cd5578063f8c8765e14610ceb578063fa0caa1614610d0b57600080fd5b8063e4e5bbcb14610c41578063e6fc774414610c61578063ea21709114610c77578063eb16136f14610c9557600080fd5b8063d12e825d116100dc578063d12e825d14610bbd578063d3401a2214610bd2578063da67703714610bf2578063e07801d014610c2157600080fd5b8063c4d66de814610b17578063ca07140c14610b37578063cbc7328014610b6d578063cc3c0f0614610b8d57600080fd5b8063a53d6e6e11610185578063b0e1268e11610154578063b0e1268e14610a72578063b794726214610a92578063b86f60d214610ab3578063b984a40414610ad357600080fd5b8063a53d6e6e146109f2578063a89f298a14610a12578063ae06c1b714610a32578063b048c4fb14610a5257600080fd5b80638ca01082116101c15780638ca01082146109745780638da5cb5b146109895780638f32d59b146109ac578063916dc59d146109d257600080fd5b806382dc1ec41461091f5780638456cb591461093f57806388710e2e1461095457600080fd5b806342cdb2c6116102d75780636ef8d66d1161026a5780637a98187b116102395780637a98187b1461084e5780637ecebe00146108ad5780638129fc1c146108da57806382a0b8cb146108ef57600080fd5b80636ef8d66d146107db57806370aff70f146107f0578063715018a6146108035780637a0ab28f1461081857600080fd5b806354fd4d50116102a657806354fd4d501461073b5780635c975abb1461076f578063615bfd6e146107875780636b0509b1146107a757600080fd5b806342cdb2c6146106bb57806346fbf68e146106db57806347f8bbd4146106fb5780634c7395091461071b57600080fd5b806322f89ba41161034f5780633a1cbbcb1161031e5780633a1cbbcb146105e15780633c3f63f41461062f5780633cf3058b146106705780633f4ba83a146106a657600080fd5b806322f89ba4146105195780632f3cca4e146105645780633500c1dc1461058457806337e76109146105a457600080fd5b80630ed928af1161038b5780630ed928af146104a45780630ef1335c146104c457806311efbf61146104e4578063122aa5d4146104f957600080fd5b806223de2914610424578063026976191461044457806307c8f7b01461048457600080fd5b3661041f576041546001600160a01b0316336001600160a01b03161461041d5760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a206e6f74207772617070656443757272656e6379000000000060448201526064015b60405180910390fd5b005b600080fd5b34801561043057600080fd5b5061041d61043f36600461409b565b610d2b565b34801561045057600080fd5b5061047161045f36600461414c565b60426020526000908152604090205481565b6040519081526020015b60405180910390f35b34801561049057600080fd5b5061041d61049f366004614173565b611086565b3480156104b057600080fd5b506104716104bf3660046141a8565b611115565b3480156104d057600080fd5b506104716104df3660046141a8565b611136565b3480156104f057600080fd5b50603754610471565b34801561050557600080fd5b5061041d6105143660046141dd565b6111ad565b34801561052557600080fd5b50610554610534366004614268565b604860209081526000928352604080842090915290825290205460ff1681565b604051901515815260200161047b565b34801561057057600080fd5b5061041d61057f366004614298565b6115eb565b34801561059057600080fd5b5061041d61059f366004614298565b61166b565b3480156105b057600080fd5b506105546105bf36600461414c565b6000908152604260209081526040808320548352603e90915290205460ff1690565b3480156105ed57600080fd5b506106176105fc366004614298565b603b602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161047b565b34801561063b57600080fd5b5061061761064a366004614268565b60466020908152600092835260408084209091529082529020546001600160a01b031681565b34801561067c57600080fd5b5061061761068b36600461414c565b6044602052600090815260409020546001600160a01b031681565b3480156106b257600080fd5b5061041d61173d565b3480156106c757600080fd5b5061041d6106d6366004614298565b6117f5565b3480156106e757600080fd5b506105546106f6366004614298565b6118d6565b34801561070757600080fd5b5061041d6107163660046142b5565b6118e3565b34801561072757600080fd5b5061041d610736366004614340565b611954565b34801561074757600080fd5b506040805180820190915260028152611d8d60f21b60208201525b60405161047b91906143da565b34801561077b57600080fd5b5060345460ff16610554565b34801561079357600080fd5b506105546107a23660046143ed565b6119c4565b3480156107b357600080fd5b506104717faf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c81565b3480156107e757600080fd5b5061041d611a31565b61041d6107fe366004614268565b611a3c565b34801561080f57600080fd5b5061041d611b36565b34801561082457600080fd5b50610617610833366004614298565b603c602052600090815260409020546001600160a01b031681565b34801561085a57600080fd5b5061088e610869366004614298565b604760205260009081526040902080546001909101546001600160a01b039091169082565b604080516001600160a01b03909316835260208301919091520161047b565b3480156108b957600080fd5b506104716108c8366004614298565b60456020526000908152604090205481565b3480156108e657600080fd5b5061041d611bbb565b3480156108fb57600080fd5b5061055461090a366004614298565b603d6020526000908152604090205460ff1681565b34801561092b57600080fd5b5061041d61093a366004614298565b611c2c565b34801561094b57600080fd5b5061041d611c5a565b34801561096057600080fd5b5061047161096f366004614429565b611cd7565b34801561098057600080fd5b50610762611e52565b34801561099557600080fd5b5060345461010090046001600160a01b0316610617565b3480156109b857600080fd5b5061055460345461010090046001600160a01b0316331490565b3480156109de57600080fd5b5061041d6109ed366004614298565b611ee0565b3480156109fe57600080fd5b50603f54610617906001600160a01b031681565b348015610a1e57600080fd5b50610471610a2d36600461449b565b611fb9565b348015610a3e57600080fd5b5061041d610a4d36600461414c565b61202b565b348015610a5e57600080fd5b50610554610a6d366004614500565b6120f0565b348015610a7e57600080fd5b50604154610617906001600160a01b031681565b348015610a9e57600080fd5b5060405461055490600160a01b900460ff1681565b348015610abf57600080fd5b50604054610617906001600160a01b031681565b348015610adf57600080fd5b50610af3610aee366004614298565b612122565b6040805182516001600160a01b03168152602092830151928101929092520161047b565b348015610b2357600080fd5b5061041d610b32366004614298565b6121a1565b348015610b4357600080fd5b50610617610b5236600461414c565b6043602052600090815260409020546001600160a01b031681565b348015610b7957600080fd5b5061041d610b88366004614522565b612263565b348015610b9957600080fd5b50610554610ba836600461414c565b603e6020526000908152604090205460ff1681565b348015610bc957600080fd5b5061041d6124d8565b348015610bde57600080fd5b50610617610bed366004614268565b61257f565b348015610bfe57600080fd5b50610554610c0d36600461414c565b600090815260426020526040902054151590565b348015610c2d57600080fd5b50610554610c3c366004614268565b6125d2565b348015610c4d57600080fd5b5061041d610c5c3660046145c6565b612627565b348015610c6d57600080fd5b5061047161271081565b348015610c8357600080fd5b506036546001600160a01b0316610617565b348015610ca157600080fd5b5061041d610cb0366004614298565b612661565b348015610cc157600080fd5b5061041d610cd0366004614298565b6126e3565b348015610ce157600080fd5b5061047160395481565b348015610cf757600080fd5b5061041d610d0636600461460e565b612721565b348015610d1757600080fd5b5061041d610d26366004614298565b612876565b6001600160a01b038816301415610d415761107c565b6001600160a01b0386163014610d995760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a204e6f7420746f2074686973206164647265737300000000006044820152606401610414565b60003360405163555ddc6560e11b81526001600160a01b03821660048201527fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce21770546024820152909150600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca9060440160206040518083038186803b158015610e1b57600080fd5b505afa158015610e2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e53919061466a565b6001600160a01b03161415610eaa5760405162461bcd60e51b815260206004820152601860248201527f4272696467653a204e6f742045524337373720746f6b656e00000000000000006044820152606401610414565b6020841015610f1a5760405162461bcd60e51b815260206004820152603660248201527f4272696467653a207573657220646174612077697468206174206c65617374206044820152751d1a194819195cdd1a5b985d1a5bdb90da185a5b925960521b6064820152608401610414565b6040841480610f3157506001600160a01b0388163b155b610f8e5760405162461bcd60e51b815260206004820152602860248201527f4272696467653a2053706563696679207265636569766572206164647265737360448201526720696e206461746160c01b6064820152608401610414565b600060208514610fdf57610fda86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600c925061294f915050565b610fe1565b885b9050600061103187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061102c9250602091508a905061469d565b6129bc565b9050611078838b848b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250899250612a22915050565b5050505b5050505050505050565b61109f60345461010090046001600160a01b0316331490565b6110bb5760405162461bcd60e51b8152600401610414906146b4565b6040805460ff60a01b1916600160a01b831515810291909117808355915160ff9190920416151581527f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad9906020015b60405180910390a150565b6000611130826111286020820182614298565b600080612de2565b92915050565b60608101356000908152604460205260408120546001600160a01b0316336001600160a01b0316146111a35760405162461bcd60e51b8152602060048201526016602482015275213934b233b29d1034b73b30b634b21039b2b73232b960511b6044820152606401610414565b6111308233611128565b60345460ff16156111d05760405162461bcd60e51b8152600401610414906146e9565b6001603560008282546111e39190614713565b90915550506035546036546001600160a01b0316336001600160a01b0316146112475760405162461bcd60e51b8152602060048201526016602482015275213934b233b29d102737ba102332b232b930ba34b7b760511b6044820152606401610414565b61125083612fcd565b61125982613014565b611263838b6125d2565b8061128157506000611275848c61257f565b6001600160a01b031614155b6112c55760405162461bcd60e51b8152602060048201526015602482015274213934b233b29d102ab735b737bbb7103a37b5b2b760591b6044820152606401610414565b6001600160a01b03881661130d5760405162461bcd60e51b815260206004820152600f60248201526e4272696467653a204e756c6c20546f60881b6044820152606401610414565b600087116113505760405162461bcd60e51b815260206004820152601060248201526f04272696467653a20416d6f756e7420360841b6044820152606401610414565b856113965760405162461bcd60e51b8152602060048201526016602482015275084e4d2c8ceca74409cead8d84084d8dec6d690c2e6d60531b6044820152606401610414565b846113d95760405162461bcd60e51b8152602060048201526013602482015272084e4d2c8ceca74409cead8d840a8f090c2e6d606b1b6044820152606401610414565b600085815260426020526040902054156114355760405162461bcd60e51b815260206004820152601860248201527f4272696467653a20416c726561647920616363657074656400000000000000006044820152606401610414565b60006114448989898989613063565b905060006114578a8a8a8a8a8a8a611fb9565b905061146382826120f0565b156114aa5760405162461bcd60e51b8152602060048201526017602482015276109c9a5919d94e88105b1c9958591e4818db185a5b5959604a1b6044820152606401610414565b8060426000898152602001908152602001600020819055508b6043600089815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508a6044600089815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550896001600160a01b03168c6001600160a01b0316887fddae5e892ad96ac0e35e9018a1a3e32ecd7f3dfe55ea34d9ab1e8faecd6ccb5a8e8d8d8c8c8c6040516115b4969594939291906001600160a01b039690961686526020860194909452604085019290925263ffffffff166060840152608083015260a082015260c00190565b60405180910390a4505060355481146115df5760405162461bcd60e51b81526004016104149061472b565b50505050505050505050565b600054610100900460ff1680611604575060005460ff16155b6116205760405162461bcd60e51b815260040161041490614770565b600054610100900460ff16158015611642576000805461ffff19166101011790555b61164b82612661565b6034805460ff191690558015611667576000805461ff00191690555b5050565b61168460345461010090046001600160a01b0316331490565b6116a05760405162461bcd60e51b8152600401610414906146b4565b6001600160a01b0381166116ef5760405162461bcd60e51b81526020600482015260166024820152754272696467653a20777261707020697320656d70747960501b6044820152606401610414565b604180546001600160a01b0319166001600160a01b0383169081179091556040519081527f0966c958966f6fac9ff807af074f8117eb2e9ce2b76390db7a158e9bdeb2485c9060200161110a565b611746336118d6565b6117625760405162461bcd60e51b8152600401610414906147b8565b60345460ff166117ab5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610414565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b61180e60345461010090046001600160a01b0316331490565b61182a5760405162461bcd60e51b8152600401610414906146b4565b6001600160a01b03811661188a5760405162461bcd60e51b815260206004820152602160248201527f4272696467653a2053696465546f6b656e466163746f727920697320656d70746044820152607960f81b6064820152608401610414565b604080546001600160a01b0319166001600160a01b038316908117825590519081527f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e31836925216259060200161110a565b60006111306033836130ce565b6118fc60345461010090046001600160a01b0316331490565b6119185760405162461bcd60e51b8152600401610414906146b4565b6001600160a01b039182166000908152604760209081526040909120825181546001600160a01b03191694169390931783550151600190910155565b61196d60345461010090046001600160a01b0316331490565b6119895760405162461bcd60e51b8152600401610414906146b4565b60009283526046602090815260408085206001600160a01b0394851686529091529092208054919092166001600160a01b0319909116179055565b6000806119fb6119d76020860186614298565b6020860135604087013560608801356119f660a08a0160808b01614800565b613063565b6000818152603e602052604090205490915060ff1680611a2957506000838152603e602052604090205460ff165b949350505050565b611a3a33613151565b565b60415433906001600160a01b0316611a965760405162461bcd60e51b815260206004820152601d60248201527f4272696467653a207772617070656443757272656e637920656d7074790000006044820152606401610414565b604160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611ae657600080fd5b505af1158015611afa573d6000803e3d6000fd5b5050505050611b31604160009054906101000a90046001600160a01b03168284346040518060200160405280600081525088612a22565b505050565b611b4f60345461010090046001600160a01b0316331490565b611b6b5760405162461bcd60e51b8152600401610414906146b4565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b600054610100900460ff1680611bd4575060005460ff16155b611bf05760405162461bcd60e51b815260040161041490614770565b600054610100900460ff16158015611c12576000805461ffff19166101011790555b60016035558015611c29576000805461ff00191690555b50565b611c35336118d6565b611c515760405162461bcd60e51b8152600401610414906147b8565b611c2981613193565b611c63336118d6565b611c7f5760405162461bcd60e51b8152600401610414906147b8565b60345460ff1615611ca25760405162461bcd60e51b8152600401610414906146e9565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586117d83390565b600042851015611d1b5760405162461bcd60e51b815260206004820152600f60248201526e109c9a5919d94e8811561412549151608a1b6044820152606401610414565b6000611d37611d2f368b90038b018b61481b565b8989896131d5565b6040805160008082526020820180845284905260ff89169282019290925260608101879052608081018690529192509060019060a0016020604051602081039080840390855afa158015611d8f573d6000803e3d6000fd5b5050604051601f190151915060009050611dac60208c018c614298565b6001600160a01b031614158015611de05750611dcb60208b018b614298565b6001600160a01b0316816001600160a01b0316145b611e2c5760405162461bcd60e51b815260206004820152601960248201527f4272696467653a20494e56414c49445f5349474e4154555245000000000000006044820152606401610414565b611e448a611e3d6020820182614298565b8b8b612de2565b9a9950505050505050505050565b60388054611e5f906148b3565b80601f0160208091040260200160405190810160405280929190818152602001828054611e8b906148b3565b8015611ed85780601f10611ead57610100808354040283529160200191611ed8565b820191906000526020600020905b815481529060010190602001808311611ebb57829003601f168201915b505050505081565b611ef960345461010090046001600160a01b0316331490565b611f155760405162461bcd60e51b8152600401610414906146b4565b6001600160a01b038116611f6b5760405162461bcd60e51b815260206004820152601c60248201527f4272696467653a20416c6c6f77546f6b656e7320697320656d707479000000006044820152606401610414565b603f80546001600160a01b0319166001600160a01b0383169081179091556040519081527f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e39060200161110a565b6040805160208082019790975280820195909552606097881b6bffffffffffffffffffffffff191697850197909752607484019590955260e09190911b6001600160e01b0319166094830152609882015260b8808201939093528351808203909301835260d801909252805191012090565b61204460345461010090046001600160a01b0316331490565b6120605760405162461bcd60e51b8152600401610414906146b4565b61206d600a6127106148fe565b81106120bb5760405162461bcd60e51b815260206004820152601760248201527f4272696467653a20626967676572207468616e203130250000000000000000006044820152606401610414565b60378190556040518181527f97e97c577f03bda90e2c9739011ec065ed5fbfb36ae217d20bb0d9be95e160cd9060200161110a565b6000828152603e602052604081205460ff168061211b57506000828152603e602052604090205460ff165b9392505050565b604080518082018252600080825260209182018190526001600160a01b038481168252604783529083902083518085019094528054909116808452600190910154918301919091521561217457919050565b60016020808301919091526001600160a01b039283166000908152603c9091526040902054909116815290565b600054610100900460ff16806121ba575060005460ff16155b6121d65760405162461bcd60e51b815260040161041490614770565b600054610100900460ff161580156121f8576000805461ffff19166101011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015611667576000805461ff00191690555050565b61227c60345461010090046001600160a01b0316331490565b6122985760405162461bcd60e51b8152600401610414906146b4565b6001600160a01b0387166122e35760405162461bcd60e51b8152602060048201526012602482015271213934b233b29d10273ab636103a37b5b2b760711b6044820152606401610414565b6122ec81612fcd565b60006122f8828961257f565b90506001600160a01b0381161561234a5760405162461bcd60e51b81526020600482015260166024820152754272696467653a20416c72656164792065786973747360501b6044820152606401610414565b6000612355886132d9565b6040805490516326d9e96360e01b81529192506001600160a01b0316906326d9e9639061238e90889088908c908c90889060040161493b565b602060405180830381600087803b1580156123a857600080fd5b505af11580156123bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e0919061466a565b91506123ed838a84611954565b60408051808201909152602081018490526001600160a01b038a16815261241483826118e3565b603f546040516378bf2b5360e01b81526001600160a01b038581166004830152602482018e9052909116906378bf2b5390604401600060405180830381600087803b15801561246257600080fd5b505af1158015612476573d6000803e3d6000fd5b50505050896001600160a01b0316836001600160a01b03167f88dcf8b72e53287db29df3fee9a0f2cb07d1f986cee153aa7d7554405d5db0178a8a86896040516124c39493929190614975565b60405180910390a35050505050505050505050565b604080518082018252601081526f52534b20546f6b656e2042726964676560801b60208083019182528351808501855260018152603160f81b908201529151902082517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8152918201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc69181019190915246606082015230608082015260a09020603955565b60008281526046602090815260408083206001600160a01b03808616855292528220541680156125b0579050611130565b50506001600160a01b039081166000908152603b602052604090205416919050565b60008281526048602090815260408083206001600160a01b038516845290915281205460ff168015612605579050611130565b50506001600160a01b03166000908152603d602052604090205460ff16919050565b3361263d6001600160a01b038516823085613345565b61265a84828585604051806020016040528060008152508a612a22565b5050505050565b600054610100900460ff168061267a575060005460ff16155b6126965760405162461bcd60e51b815260040161041490614770565b600054610100900460ff161580156126b8576000805461ffff19166101011790555b6126c1826118d6565b6126ce576126ce82613193565b8015611667576000805461ff00191690555050565b6126fc60345461010090046001600160a01b0316331490565b6127185760405162461bcd60e51b8152600401610414906146b4565b611c29816133b6565b600054610100900460ff168061273a575060005460ff16155b6127565760405162461bcd60e51b815260040161041490614770565b600054610100900460ff16158015612778576000805461ffff19166101011790555b612781856121a1565b61278a856115eb565b603f80546001600160a01b038581166001600160a01b031992831617909255604080548584169083161781556036805493881693909216929092179055516329965a1d60e01b815230600482018190527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b60248301526044820152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90606401600060405180830381600087803b15801561283e57600080fd5b505af1158015612852573d6000803e3d6000fd5b5050505061285e6124d8565b801561265a576000805461ff00191690555050505050565b61288f60345461010090046001600160a01b0316331490565b6128ab5760405162461bcd60e51b8152600401610414906146b4565b6001600160a01b0381166129015760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a2046656465726174696f6e20697320656d70747900000000006044820152606401610414565b603680546001600160a01b0319166001600160a01b0383169081179091556040519081527f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb9060200161110a565b600061295c826014614713565b835110156129ac5760405162461bcd60e51b815260206004820152601f60248201527f4c69625574696c733a20746f416464726573735f6f75744f66426f756e6473006044820152606401610414565b500160200151600160601b900490565b60006129c9826020614713565b83511015612a195760405162461bcd60e51b815260206004820152601f60248201527f4c69625574696c733a20746f55696e743235365f6f75744f66426f756e6473006044820152606401610414565b50016020015190565b604054600160a01b900460ff1615612a705760405162461bcd60e51b81526020600482015260116024820152704272696467653a20557067726164696e6760781b6044820152606401610414565b60345460ff1615612a935760405162461bcd60e51b8152600401610414906146e9565b600160356000828254612aa69190614713565b909155505060355446821415612b1a5760405162461bcd60e51b815260206004820152603360248201527f4272696467653a2064657374696e6174696f6e20636861696e20696420657175604482015272185b0818dd5c9c995b9d0818da185a5b881a59606a1b6064820152608401610414565b612b2382612fcd565b60008281526048602090815260408083206001600160a01b038b1684529091529020805460ff191660011790556000612b73612710612b6d6037548861347e90919063ffffffff16565b906134fd565b90506000612b81868361353f565b90506000612b8e8a613581565b905086601260ff831614612bbf57612bbc612baa83601261499c565b612bb590600a614aa3565b899061347e565b90505b603f54604051638c34bc5560e01b81526001600160a01b038d811660048301526024820184905290911690638c34bc5590604401600060405180830381600087803b158015612c0d57600080fd5b505af1158015612c21573d6000803e3d6000fd5b505050506000612c308c612122565b80519091506001600160a01b031615612d34576000612c4e8d613665565b90506000612c5c868361373d565b9050612c68878261377f565b9650612c74868261353f565b60405163fe9d930360e01b81529096506001600160a01b038f169063fe9d930390612ca59089908e90600401614ab2565b600060405180830381600087803b158015612cbf57600080fd5b505af1158015612cd3573d6000803e3d6000fd5b505050505050868a6001600160a01b031682600001516001600160a01b03167fb2320a1ad388e1e16b142f7d2e822f31d8a2bbdd7d4f29260e7c203c5f45e8498e46898e604051612d279493929190614acb565b60405180910390a4612d87565b868a6001600160a01b03168d6001600160a01b03167fb2320a1ad388e1e16b142f7d2e822f31d8a2bbdd7d4f29260e7c203c5f45e8498e46898e604051612d7e9493929190614acb565b60405180910390a45b8415612db357603454612db39061010090046001600160a01b03166001600160a01b038e1690876137de565b50505050506035548114612dd95760405162461bcd60e51b81526004016104149061472b565b50505050505050565b6000600160356000828254612df79190614713565b909155505060355460608601356000908152604360205260409020546001600160a01b031680612e625760405162461bcd60e51b8152602060048201526016602482015275109c9a5919d94e88151e081b9bdd0818dc9bdcdcd95960521b6044820152606401610414565b6000612e9e612e7460208a018a614298565b60208a013560408b013560608c0135612e9360a08e0160808f01614800565b8d60a0013546611fb9565b60608901356000908152604260205260409020549091508114612f0d5760405162461bcd60e51b815260206004820152602160248201527f4272696467653a2057726f6e67207472616e73616374696f6e446174614861736044820152600d60fb1b6064820152608401610414565b612f1788826119c4565b15612f5e5760405162461bcd60e51b8152602060048201526017602482015276109c9a5919d94e88105b1c9958591e4818db185a5b5959604a1b6044820152606401610414565b6000818152603e60209081526040909120805460ff19166001179055612f929060a08a01359084908a908c01358a8a61380e565b9350612fa1888389898961385f565b50506035548114612fc45760405162461bcd60e51b81526004016104149061472b565b50949350505050565b60008111611c295760405162461bcd60e51b815260206004820152601460248201527304272696467653a20436861696e496420697320360641b6044820152606401610414565b468114611c295760405162461bcd60e51b815260206004820152601960248201527f4272696467653a204e6f7420626c6f636b2e636861696e6964000000000000006044820152606401610414565b6040805160208101859052908101839052606086811b6bffffffffffffffffffffffff1916908201526074810185905260e082901b6001600160e01b031916609482015260009060980160405160208183030381529060405280519060200120905095945050505050565b60006001600160a01b0382166131315760405162461bcd60e51b815260206004820152602260248201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604482015261737360f01b6064820152608401610414565b506001600160a01b03166000908152602091909152604090205460ff1690565b61315c60338261393a565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b61319e6033826139b2565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6039548451602080870151606088015160a08901516001600160a01b0385166000908152604590945260408420805494966132d09690957faf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c959194919391928c918c918b61324283614af8565b909155506040805160208101999099526001600160a01b03978816908901526060880195909552608087019390935260a086019190915290921660c084015260e08301919091526101008201526101208101859052610140016040516020818303038152906040528051906020012060405161190160f01b8152600281019290925260228201526042902090565b95945050505050565b600060128260ff16111561332f5760405162461bcd60e51b815260206004820152601c60248201527f4c69625574696c733a20446563696d616c73206e6f74203c3d203138000000006044820152606401610414565b61333a82601261499c565b61113090600a614aa3565b6040516001600160a01b03808516602483015283166044820152606481018290526133b09085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613a2e565b50505050565b6001600160a01b0381166134175760405162461bcd60e51b815260206004820152602260248201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604482015261737360f01b6064820152608401610414565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b60008261348d57506000611130565b60006134998385614b13565b9050826134a685836148fe565b1461211b5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610414565b600061211b83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613bae565b600061211b83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613bdc565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b038616916135c79190614b32565b600060405180830381855afa9150503d8060008114613602576040519150601f19603f3d011682016040523d82523d6000602084013e613607565b606091505b5091509150816136515760405162461bcd60e51b81526020600482015260156024820152744c69625574696c733a204e6f20646563696d616c7360581b6044820152606401610414565b80806020019051810190611a299190614b4e565b60408051600481526024810182526020810180516001600160e01b031663556f0dc760e01b1790529051600091829182916001600160a01b038616916136ab9190614b32565b600060405180830381855afa9150503d80600081146136e6576040519150601f19603f3d011682016040523d82523d6000602084013e6136eb565b606091505b5091509150816136515760405162461bcd60e51b815260206004820152601860248201527f4c69625574696c733a204e6f206772616e756c617269747900000000000000006044820152606401610414565b600061211b83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250613c0d565b60008061378c8385614713565b90508381101561211b5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610414565b6040516001600160a01b038316602482015260448101829052611b3190849063a9059cbb60e01b90606401613379565b600061381987612fcd565b61382387876125d2565b1561383c576138358686868686613c39565b9050613855565b613852613849888861257f565b86868686613de9565b90505b9695505050505050565b61386c6020860186614298565b6060860135600081815260446020908152604091829020546001600160a01b039485169489811694937fa7a84dcc6757cdf9b9122d3bbc42d58358c28dc4b09cc24349599a63c56c62fd9392909116918b0135908b01356138d360a08d0160808e01614800565b604080516001600160a01b039586168152602081019490945283019190915263ffffffff166060820152818916608082015290871660a08281019190915260c082018790528a013560e0820152466101008201526101200160405180910390a45050505050565b61394482826130ce565b6139905760405162461bcd60e51b815260206004820181905260248201527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c656044820152606401610414565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b6139bc82826130ce565b15613a095760405162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c65006044820152606401610414565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6001600160a01b0382163b613a855760405162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e7472616374006044820152606401610414565b600080836001600160a01b031683604051613aa09190614b32565b6000604051808303816000865af19150503d8060008114613add576040519150601f19603f3d011682016040523d82523d6000602084013e613ae2565b606091505b509150915081613b345760405162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65646044820152606401610414565b8051156133b05780806020019051810190613b4f9190614b67565b6133b05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610414565b60008183613bcf5760405162461bcd60e51b815260040161041491906143da565b5060006132d084866148fe565b60008184841115613c005760405162461bcd60e51b815260040161041491906143da565b5060006132d0848661469d565b60008183613c2e5760405162461bcd60e51b815260040161041491906143da565b50611a298385614b84565b600080613c4587613581565b60ff1690506000613c6c613c5a83601261469d565b613c6590600a614b98565b87906134fd565b905080841115613cb55760405162461bcd60e51b8152602060048201526014602482015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b6044820152606401610414565b613cbf818561353f565b6041549093506001600160a01b0389811691161415613db057604154604051632e1a7d4d60e01b8152600481018390526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b158015613d1e57600080fd5b505af1158015613d32573d6000803e3d6000fd5b50506040516001600160a01b038a16925085156108fc02915085906000818181858888f19350505050158015613d6c573d6000803e3d6000fd5b508315613dab576040516001600160a01b0386169085156108fc029086906000818181858888f19350505050158015613da9573d6000803e3d6000fd5b505b613dde565b613dc46001600160a01b03891688856137de565b8315613dde57613dde6001600160a01b03891686866137de565b505095945050505050565b60006001600160a01b038616613e415760405162461bcd60e51b815260206004820152601a60248201527f4272696467653a207369646520746f6b656e206973206e756c6c0000000000006044820152606401610414565b6000866001600160a01b031663556f0dc76040518163ffffffff1660e01b815260040160206040518083038186803b158015613e7c57600080fd5b505afa158015613e90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613eb49190614b4e565b90506000613ec2868361347e565b905080841115613f0b5760405162461bcd60e51b8152602060048201526014602482015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b6044820152606401610414565b613f15818561353f565b604051630dcdc7dd60e41b81526001600160a01b038981166004830152602482018390526080604483015260006084830181905260a0606484015260a48301529194509089169063dcdc7dd09060c401600060405180830381600087803b158015613f7f57600080fd5b505af1158015613f93573d6000803e3d6000fd5b505050506000841115613dde57604051630dcdc7dd60e41b81526001600160a01b03868116600483015260248201869052608060448301526000608483015260a06064830152600b60a48301526a72656c617965722066656560a81b60c483015289169063dcdc7dd09060e401600060405180830381600087803b15801561401a57600080fd5b505af115801561402e573d6000803e3d6000fd5b50505050505095945050505050565b6001600160a01b0381168114611c2957600080fd5b60008083601f84011261406457600080fd5b50813567ffffffffffffffff81111561407c57600080fd5b60208301915083602082850101111561409457600080fd5b9250929050565b60008060008060008060008060c0898b0312156140b757600080fd5b88356140c28161403d565b975060208901356140d28161403d565b965060408901356140e28161403d565b955060608901359450608089013567ffffffffffffffff8082111561410657600080fd5b6141128c838d01614052565b909650945060a08b013591508082111561412b57600080fd5b506141388b828c01614052565b999c989b5096995094979396929594505050565b60006020828403121561415e57600080fd5b5035919050565b8015158114611c2957600080fd5b60006020828403121561418557600080fd5b813561211b81614165565b600060c082840312156141a257600080fd5b50919050565b600060c082840312156141ba57600080fd5b61211b8383614190565b803563ffffffff811681146141d857600080fd5b919050565b60008060008060008060008060006101208a8c0312156141fc57600080fd5b89356142078161403d565b985060208a01356142178161403d565b975060408a01356142278161403d565b965060608a0135955060808a0135945060a08a0135935061424a60c08b016141c4565b925060e08a013591506101008a013590509295985092959850929598565b6000806040838503121561427b57600080fd5b82359150602083013561428d8161403d565b809150509250929050565b6000602082840312156142aa57600080fd5b813561211b8161403d565b60008082840360608112156142c957600080fd5b83356142d48161403d565b92506040601f19820112156142e857600080fd5b506040516040810181811067ffffffffffffffff8211171561431a57634e487b7160e01b600052604160045260246000fd5b604052602084013561432b8161403d565b81526040939093013560208401525092909150565b60008060006060848603121561435557600080fd5b8335925060208401356143678161403d565b915060408401356143778161403d565b809150509250925092565b60005b8381101561439d578181015183820152602001614385565b838111156133b05750506000910152565b600081518084526143c6816020860160208601614382565b601f01601f19169290920160200192915050565b60208152600061211b60208301846143ae565b60008060e0838503121561440057600080fd5b61440a8484614190565b9460c0939093013593505050565b803560ff811681146141d857600080fd5b6000806000806000806000610180888a03121561444557600080fd5b61444f8989614190565b965060c088013561445f8161403d565b955060e08801359450610100880135935061447d6101208901614418565b92506101408801359150610160880135905092959891949750929550565b600080600080600080600060e0888a0312156144b657600080fd5b87356144c18161403d565b96506020880135955060408801359450606088013593506144e4608089016141c4565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561451357600080fd5b50508035926020909101359150565b60008060008060008060008060c0898b03121561453e57600080fd5b8835975060208901356145508161403d565b965061455e60408a01614418565b9550606089013567ffffffffffffffff8082111561457b57600080fd5b6145878c838d01614052565b909750955060808b01359150808211156145a057600080fd5b506145ad8b828c01614052565b999c989b50969995989497949560a00135949350505050565b600080600080608085870312156145dc57600080fd5b8435935060208501356145ee8161403d565b925060408501356145fe8161403d565b9396929550929360600135925050565b6000806000806080858703121561462457600080fd5b843561462f8161403d565b9350602085013561463f8161403d565b9250604085013561464f8161403d565b9150606085013561465f8161403d565b939692955090935050565b60006020828403121561467c57600080fd5b815161211b8161403d565b634e487b7160e01b600052601160045260246000fd5b6000828210156146af576146af614687565b500390565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6000821982111561472657614726614687565b500190565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b60006020828403121561481257600080fd5b61211b826141c4565b600060c0828403121561482d57600080fd5b60405160c0810181811067ffffffffffffffff8211171561485e57634e487b7160e01b600052604160045260246000fd5b604052823561486c8161403d565b8082525060208301356020820152604083013560408201526060830135606082015261489a608084016141c4565b608082015260a083013560a08201528091505092915050565b600181811c908216806148c757607f821691505b602082108114156141a257634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b60008261490d5761490d6148e8565b500490565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60608152600061494f606083018789614912565b8281036020840152614962818688614912565b9150508260408301529695505050505050565b606081526000614989606083018688614912565b6020830194909452506040015292915050565b600060ff821660ff8416808210156149b6576149b6614687565b90039392505050565b600181815b808511156149fa5781600019048211156149e0576149e0614687565b808516156149ed57918102915b93841c93908002906149c4565b509250929050565b600082614a1157506001611130565b81614a1e57506000611130565b8160018114614a345760028114614a3e57614a5a565b6001915050611130565b60ff841115614a4f57614a4f614687565b50506001821b611130565b5060208310610133831016604e8410600b8410161715614a7d575081810a611130565b614a8783836149bf565b8060001904821115614a9b57614a9b614687565b029392505050565b600061211b60ff841683614a02565b828152604060208201526000611a2960408301846143ae565b60018060a01b038516815283602082015282604082015260806060820152600061385560808301846143ae565b6000600019821415614b0c57614b0c614687565b5060010190565b6000816000190483118215151615614b2d57614b2d614687565b500290565b60008251614b44818460208701614382565b9190910192915050565b600060208284031215614b6057600080fd5b5051919050565b600060208284031215614b7957600080fd5b815161211b81614165565b600082614b9357614b936148e8565b500690565b600061211b8383614a0256fea2646970667358221220575509595c84b7b6f30a376b571b86c9c397962f491392aca2b37537d49d7f0a64736f6c63430008090033",
+ "deployedBytecode": "0x6080604052600436106103b05760003560e01c806382dc1ec4116101e7578063c4d66de81161010d578063e4e5bbcb116100a0578063f2fde38b1161006f578063f2fde38b14610cb5578063f698da2514610cd5578063f8c8765e14610ceb578063fa0caa1614610d0b57600080fd5b8063e4e5bbcb14610c41578063e6fc774414610c61578063ea21709114610c77578063eb16136f14610c9557600080fd5b8063d12e825d116100dc578063d12e825d14610bbd578063d3401a2214610bd2578063da67703714610bf2578063e07801d014610c2157600080fd5b8063c4d66de814610b17578063ca07140c14610b37578063cbc7328014610b6d578063cc3c0f0614610b8d57600080fd5b8063a53d6e6e11610185578063b0e1268e11610154578063b0e1268e14610a72578063b794726214610a92578063b86f60d214610ab3578063b984a40414610ad357600080fd5b8063a53d6e6e146109f2578063a89f298a14610a12578063ae06c1b714610a32578063b048c4fb14610a5257600080fd5b80638ca01082116101c15780638ca01082146109745780638da5cb5b146109895780638f32d59b146109ac578063916dc59d146109d257600080fd5b806382dc1ec41461091f5780638456cb591461093f57806388710e2e1461095457600080fd5b806342cdb2c6116102d75780636ef8d66d1161026a5780637a98187b116102395780637a98187b1461084e5780637ecebe00146108ad5780638129fc1c146108da57806382a0b8cb146108ef57600080fd5b80636ef8d66d146107db57806370aff70f146107f0578063715018a6146108035780637a0ab28f1461081857600080fd5b806354fd4d50116102a657806354fd4d501461073b5780635c975abb1461076f578063615bfd6e146107875780636b0509b1146107a757600080fd5b806342cdb2c6146106bb57806346fbf68e146106db57806347f8bbd4146106fb5780634c7395091461071b57600080fd5b806322f89ba41161034f5780633a1cbbcb1161031e5780633a1cbbcb146105e15780633c3f63f41461062f5780633cf3058b146106705780633f4ba83a146106a657600080fd5b806322f89ba4146105195780632f3cca4e146105645780633500c1dc1461058457806337e76109146105a457600080fd5b80630ed928af1161038b5780630ed928af146104a45780630ef1335c146104c457806311efbf61146104e4578063122aa5d4146104f957600080fd5b806223de2914610424578063026976191461044457806307c8f7b01461048457600080fd5b3661041f576041546001600160a01b0316336001600160a01b03161461041d5760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a206e6f74207772617070656443757272656e6379000000000060448201526064015b60405180910390fd5b005b600080fd5b34801561043057600080fd5b5061041d61043f36600461409b565b610d2b565b34801561045057600080fd5b5061047161045f36600461414c565b60426020526000908152604090205481565b6040519081526020015b60405180910390f35b34801561049057600080fd5b5061041d61049f366004614173565b611086565b3480156104b057600080fd5b506104716104bf3660046141a8565b611115565b3480156104d057600080fd5b506104716104df3660046141a8565b611136565b3480156104f057600080fd5b50603754610471565b34801561050557600080fd5b5061041d6105143660046141dd565b6111ad565b34801561052557600080fd5b50610554610534366004614268565b604860209081526000928352604080842090915290825290205460ff1681565b604051901515815260200161047b565b34801561057057600080fd5b5061041d61057f366004614298565b6115eb565b34801561059057600080fd5b5061041d61059f366004614298565b61166b565b3480156105b057600080fd5b506105546105bf36600461414c565b6000908152604260209081526040808320548352603e90915290205460ff1690565b3480156105ed57600080fd5b506106176105fc366004614298565b603b602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161047b565b34801561063b57600080fd5b5061061761064a366004614268565b60466020908152600092835260408084209091529082529020546001600160a01b031681565b34801561067c57600080fd5b5061061761068b36600461414c565b6044602052600090815260409020546001600160a01b031681565b3480156106b257600080fd5b5061041d61173d565b3480156106c757600080fd5b5061041d6106d6366004614298565b6117f5565b3480156106e757600080fd5b506105546106f6366004614298565b6118d6565b34801561070757600080fd5b5061041d6107163660046142b5565b6118e3565b34801561072757600080fd5b5061041d610736366004614340565b611954565b34801561074757600080fd5b506040805180820190915260028152611d8d60f21b60208201525b60405161047b91906143da565b34801561077b57600080fd5b5060345460ff16610554565b34801561079357600080fd5b506105546107a23660046143ed565b6119c4565b3480156107b357600080fd5b506104717faf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c81565b3480156107e757600080fd5b5061041d611a31565b61041d6107fe366004614268565b611a3c565b34801561080f57600080fd5b5061041d611b36565b34801561082457600080fd5b50610617610833366004614298565b603c602052600090815260409020546001600160a01b031681565b34801561085a57600080fd5b5061088e610869366004614298565b604760205260009081526040902080546001909101546001600160a01b039091169082565b604080516001600160a01b03909316835260208301919091520161047b565b3480156108b957600080fd5b506104716108c8366004614298565b60456020526000908152604090205481565b3480156108e657600080fd5b5061041d611bbb565b3480156108fb57600080fd5b5061055461090a366004614298565b603d6020526000908152604090205460ff1681565b34801561092b57600080fd5b5061041d61093a366004614298565b611c2c565b34801561094b57600080fd5b5061041d611c5a565b34801561096057600080fd5b5061047161096f366004614429565b611cd7565b34801561098057600080fd5b50610762611e52565b34801561099557600080fd5b5060345461010090046001600160a01b0316610617565b3480156109b857600080fd5b5061055460345461010090046001600160a01b0316331490565b3480156109de57600080fd5b5061041d6109ed366004614298565b611ee0565b3480156109fe57600080fd5b50603f54610617906001600160a01b031681565b348015610a1e57600080fd5b50610471610a2d36600461449b565b611fb9565b348015610a3e57600080fd5b5061041d610a4d36600461414c565b61202b565b348015610a5e57600080fd5b50610554610a6d366004614500565b6120f0565b348015610a7e57600080fd5b50604154610617906001600160a01b031681565b348015610a9e57600080fd5b5060405461055490600160a01b900460ff1681565b348015610abf57600080fd5b50604054610617906001600160a01b031681565b348015610adf57600080fd5b50610af3610aee366004614298565b612122565b6040805182516001600160a01b03168152602092830151928101929092520161047b565b348015610b2357600080fd5b5061041d610b32366004614298565b6121a1565b348015610b4357600080fd5b50610617610b5236600461414c565b6043602052600090815260409020546001600160a01b031681565b348015610b7957600080fd5b5061041d610b88366004614522565b612263565b348015610b9957600080fd5b50610554610ba836600461414c565b603e6020526000908152604090205460ff1681565b348015610bc957600080fd5b5061041d6124d8565b348015610bde57600080fd5b50610617610bed366004614268565b61257f565b348015610bfe57600080fd5b50610554610c0d36600461414c565b600090815260426020526040902054151590565b348015610c2d57600080fd5b50610554610c3c366004614268565b6125d2565b348015610c4d57600080fd5b5061041d610c5c3660046145c6565b612627565b348015610c6d57600080fd5b5061047161271081565b348015610c8357600080fd5b506036546001600160a01b0316610617565b348015610ca157600080fd5b5061041d610cb0366004614298565b612661565b348015610cc157600080fd5b5061041d610cd0366004614298565b6126e3565b348015610ce157600080fd5b5061047160395481565b348015610cf757600080fd5b5061041d610d0636600461460e565b612721565b348015610d1757600080fd5b5061041d610d26366004614298565b612876565b6001600160a01b038816301415610d415761107c565b6001600160a01b0386163014610d995760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a204e6f7420746f2074686973206164647265737300000000006044820152606401610414565b60003360405163555ddc6560e11b81526001600160a01b03821660048201527fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce21770546024820152909150600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca9060440160206040518083038186803b158015610e1b57600080fd5b505afa158015610e2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e53919061466a565b6001600160a01b03161415610eaa5760405162461bcd60e51b815260206004820152601860248201527f4272696467653a204e6f742045524337373720746f6b656e00000000000000006044820152606401610414565b6020841015610f1a5760405162461bcd60e51b815260206004820152603660248201527f4272696467653a207573657220646174612077697468206174206c65617374206044820152751d1a194819195cdd1a5b985d1a5bdb90da185a5b925960521b6064820152608401610414565b6040841480610f3157506001600160a01b0388163b155b610f8e5760405162461bcd60e51b815260206004820152602860248201527f4272696467653a2053706563696679207265636569766572206164647265737360448201526720696e206461746160c01b6064820152608401610414565b600060208514610fdf57610fda86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600c925061294f915050565b610fe1565b885b9050600061103187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061102c9250602091508a905061469d565b6129bc565b9050611078838b848b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250899250612a22915050565b5050505b5050505050505050565b61109f60345461010090046001600160a01b0316331490565b6110bb5760405162461bcd60e51b8152600401610414906146b4565b6040805460ff60a01b1916600160a01b831515810291909117808355915160ff9190920416151581527f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad9906020015b60405180910390a150565b6000611130826111286020820182614298565b600080612de2565b92915050565b60608101356000908152604460205260408120546001600160a01b0316336001600160a01b0316146111a35760405162461bcd60e51b8152602060048201526016602482015275213934b233b29d1034b73b30b634b21039b2b73232b960511b6044820152606401610414565b6111308233611128565b60345460ff16156111d05760405162461bcd60e51b8152600401610414906146e9565b6001603560008282546111e39190614713565b90915550506035546036546001600160a01b0316336001600160a01b0316146112475760405162461bcd60e51b8152602060048201526016602482015275213934b233b29d102737ba102332b232b930ba34b7b760511b6044820152606401610414565b61125083612fcd565b61125982613014565b611263838b6125d2565b8061128157506000611275848c61257f565b6001600160a01b031614155b6112c55760405162461bcd60e51b8152602060048201526015602482015274213934b233b29d102ab735b737bbb7103a37b5b2b760591b6044820152606401610414565b6001600160a01b03881661130d5760405162461bcd60e51b815260206004820152600f60248201526e4272696467653a204e756c6c20546f60881b6044820152606401610414565b600087116113505760405162461bcd60e51b815260206004820152601060248201526f04272696467653a20416d6f756e7420360841b6044820152606401610414565b856113965760405162461bcd60e51b8152602060048201526016602482015275084e4d2c8ceca74409cead8d84084d8dec6d690c2e6d60531b6044820152606401610414565b846113d95760405162461bcd60e51b8152602060048201526013602482015272084e4d2c8ceca74409cead8d840a8f090c2e6d606b1b6044820152606401610414565b600085815260426020526040902054156114355760405162461bcd60e51b815260206004820152601860248201527f4272696467653a20416c726561647920616363657074656400000000000000006044820152606401610414565b60006114448989898989613063565b905060006114578a8a8a8a8a8a8a611fb9565b905061146382826120f0565b156114aa5760405162461bcd60e51b8152602060048201526017602482015276109c9a5919d94e88105b1c9958591e4818db185a5b5959604a1b6044820152606401610414565b8060426000898152602001908152602001600020819055508b6043600089815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508a6044600089815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550896001600160a01b03168c6001600160a01b0316887fddae5e892ad96ac0e35e9018a1a3e32ecd7f3dfe55ea34d9ab1e8faecd6ccb5a8e8d8d8c8c8c6040516115b4969594939291906001600160a01b039690961686526020860194909452604085019290925263ffffffff166060840152608083015260a082015260c00190565b60405180910390a4505060355481146115df5760405162461bcd60e51b81526004016104149061472b565b50505050505050505050565b600054610100900460ff1680611604575060005460ff16155b6116205760405162461bcd60e51b815260040161041490614770565b600054610100900460ff16158015611642576000805461ffff19166101011790555b61164b82612661565b6034805460ff191690558015611667576000805461ff00191690555b5050565b61168460345461010090046001600160a01b0316331490565b6116a05760405162461bcd60e51b8152600401610414906146b4565b6001600160a01b0381166116ef5760405162461bcd60e51b81526020600482015260166024820152754272696467653a20777261707020697320656d70747960501b6044820152606401610414565b604180546001600160a01b0319166001600160a01b0383169081179091556040519081527f0966c958966f6fac9ff807af074f8117eb2e9ce2b76390db7a158e9bdeb2485c9060200161110a565b611746336118d6565b6117625760405162461bcd60e51b8152600401610414906147b8565b60345460ff166117ab5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610414565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b61180e60345461010090046001600160a01b0316331490565b61182a5760405162461bcd60e51b8152600401610414906146b4565b6001600160a01b03811661188a5760405162461bcd60e51b815260206004820152602160248201527f4272696467653a2053696465546f6b656e466163746f727920697320656d70746044820152607960f81b6064820152608401610414565b604080546001600160a01b0319166001600160a01b038316908117825590519081527f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e31836925216259060200161110a565b60006111306033836130ce565b6118fc60345461010090046001600160a01b0316331490565b6119185760405162461bcd60e51b8152600401610414906146b4565b6001600160a01b039182166000908152604760209081526040909120825181546001600160a01b03191694169390931783550151600190910155565b61196d60345461010090046001600160a01b0316331490565b6119895760405162461bcd60e51b8152600401610414906146b4565b60009283526046602090815260408085206001600160a01b0394851686529091529092208054919092166001600160a01b0319909116179055565b6000806119fb6119d76020860186614298565b6020860135604087013560608801356119f660a08a0160808b01614800565b613063565b6000818152603e602052604090205490915060ff1680611a2957506000838152603e602052604090205460ff165b949350505050565b611a3a33613151565b565b60415433906001600160a01b0316611a965760405162461bcd60e51b815260206004820152601d60248201527f4272696467653a207772617070656443757272656e637920656d7074790000006044820152606401610414565b604160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611ae657600080fd5b505af1158015611afa573d6000803e3d6000fd5b5050505050611b31604160009054906101000a90046001600160a01b03168284346040518060200160405280600081525088612a22565b505050565b611b4f60345461010090046001600160a01b0316331490565b611b6b5760405162461bcd60e51b8152600401610414906146b4565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b600054610100900460ff1680611bd4575060005460ff16155b611bf05760405162461bcd60e51b815260040161041490614770565b600054610100900460ff16158015611c12576000805461ffff19166101011790555b60016035558015611c29576000805461ff00191690555b50565b611c35336118d6565b611c515760405162461bcd60e51b8152600401610414906147b8565b611c2981613193565b611c63336118d6565b611c7f5760405162461bcd60e51b8152600401610414906147b8565b60345460ff1615611ca25760405162461bcd60e51b8152600401610414906146e9565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586117d83390565b600042851015611d1b5760405162461bcd60e51b815260206004820152600f60248201526e109c9a5919d94e8811561412549151608a1b6044820152606401610414565b6000611d37611d2f368b90038b018b61481b565b8989896131d5565b6040805160008082526020820180845284905260ff89169282019290925260608101879052608081018690529192509060019060a0016020604051602081039080840390855afa158015611d8f573d6000803e3d6000fd5b5050604051601f190151915060009050611dac60208c018c614298565b6001600160a01b031614158015611de05750611dcb60208b018b614298565b6001600160a01b0316816001600160a01b0316145b611e2c5760405162461bcd60e51b815260206004820152601960248201527f4272696467653a20494e56414c49445f5349474e4154555245000000000000006044820152606401610414565b611e448a611e3d6020820182614298565b8b8b612de2565b9a9950505050505050505050565b60388054611e5f906148b3565b80601f0160208091040260200160405190810160405280929190818152602001828054611e8b906148b3565b8015611ed85780601f10611ead57610100808354040283529160200191611ed8565b820191906000526020600020905b815481529060010190602001808311611ebb57829003601f168201915b505050505081565b611ef960345461010090046001600160a01b0316331490565b611f155760405162461bcd60e51b8152600401610414906146b4565b6001600160a01b038116611f6b5760405162461bcd60e51b815260206004820152601c60248201527f4272696467653a20416c6c6f77546f6b656e7320697320656d707479000000006044820152606401610414565b603f80546001600160a01b0319166001600160a01b0383169081179091556040519081527f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e39060200161110a565b6040805160208082019790975280820195909552606097881b6bffffffffffffffffffffffff191697850197909752607484019590955260e09190911b6001600160e01b0319166094830152609882015260b8808201939093528351808203909301835260d801909252805191012090565b61204460345461010090046001600160a01b0316331490565b6120605760405162461bcd60e51b8152600401610414906146b4565b61206d600a6127106148fe565b81106120bb5760405162461bcd60e51b815260206004820152601760248201527f4272696467653a20626967676572207468616e203130250000000000000000006044820152606401610414565b60378190556040518181527f97e97c577f03bda90e2c9739011ec065ed5fbfb36ae217d20bb0d9be95e160cd9060200161110a565b6000828152603e602052604081205460ff168061211b57506000828152603e602052604090205460ff165b9392505050565b604080518082018252600080825260209182018190526001600160a01b038481168252604783529083902083518085019094528054909116808452600190910154918301919091521561217457919050565b60016020808301919091526001600160a01b039283166000908152603c9091526040902054909116815290565b600054610100900460ff16806121ba575060005460ff16155b6121d65760405162461bcd60e51b815260040161041490614770565b600054610100900460ff161580156121f8576000805461ffff19166101011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015611667576000805461ff00191690555050565b61227c60345461010090046001600160a01b0316331490565b6122985760405162461bcd60e51b8152600401610414906146b4565b6001600160a01b0387166122e35760405162461bcd60e51b8152602060048201526012602482015271213934b233b29d10273ab636103a37b5b2b760711b6044820152606401610414565b6122ec81612fcd565b60006122f8828961257f565b90506001600160a01b0381161561234a5760405162461bcd60e51b81526020600482015260166024820152754272696467653a20416c72656164792065786973747360501b6044820152606401610414565b6000612355886132d9565b6040805490516326d9e96360e01b81529192506001600160a01b0316906326d9e9639061238e90889088908c908c90889060040161493b565b602060405180830381600087803b1580156123a857600080fd5b505af11580156123bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e0919061466a565b91506123ed838a84611954565b60408051808201909152602081018490526001600160a01b038a16815261241483826118e3565b603f546040516378bf2b5360e01b81526001600160a01b038581166004830152602482018e9052909116906378bf2b5390604401600060405180830381600087803b15801561246257600080fd5b505af1158015612476573d6000803e3d6000fd5b50505050896001600160a01b0316836001600160a01b03167f88dcf8b72e53287db29df3fee9a0f2cb07d1f986cee153aa7d7554405d5db0178a8a86896040516124c39493929190614975565b60405180910390a35050505050505050505050565b604080518082018252601081526f52534b20546f6b656e2042726964676560801b60208083019182528351808501855260018152603160f81b908201529151902082517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8152918201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc69181019190915246606082015230608082015260a09020603955565b60008281526046602090815260408083206001600160a01b03808616855292528220541680156125b0579050611130565b50506001600160a01b039081166000908152603b602052604090205416919050565b60008281526048602090815260408083206001600160a01b038516845290915281205460ff168015612605579050611130565b50506001600160a01b03166000908152603d602052604090205460ff16919050565b3361263d6001600160a01b038516823085613345565b61265a84828585604051806020016040528060008152508a612a22565b5050505050565b600054610100900460ff168061267a575060005460ff16155b6126965760405162461bcd60e51b815260040161041490614770565b600054610100900460ff161580156126b8576000805461ffff19166101011790555b6126c1826118d6565b6126ce576126ce82613193565b8015611667576000805461ff00191690555050565b6126fc60345461010090046001600160a01b0316331490565b6127185760405162461bcd60e51b8152600401610414906146b4565b611c29816133b6565b600054610100900460ff168061273a575060005460ff16155b6127565760405162461bcd60e51b815260040161041490614770565b600054610100900460ff16158015612778576000805461ffff19166101011790555b612781856121a1565b61278a856115eb565b603f80546001600160a01b038581166001600160a01b031992831617909255604080548584169083161781556036805493881693909216929092179055516329965a1d60e01b815230600482018190527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b60248301526044820152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90606401600060405180830381600087803b15801561283e57600080fd5b505af1158015612852573d6000803e3d6000fd5b5050505061285e6124d8565b801561265a576000805461ff00191690555050505050565b61288f60345461010090046001600160a01b0316331490565b6128ab5760405162461bcd60e51b8152600401610414906146b4565b6001600160a01b0381166129015760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a2046656465726174696f6e20697320656d70747900000000006044820152606401610414565b603680546001600160a01b0319166001600160a01b0383169081179091556040519081527f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb9060200161110a565b600061295c826014614713565b835110156129ac5760405162461bcd60e51b815260206004820152601f60248201527f4c69625574696c733a20746f416464726573735f6f75744f66426f756e6473006044820152606401610414565b500160200151600160601b900490565b60006129c9826020614713565b83511015612a195760405162461bcd60e51b815260206004820152601f60248201527f4c69625574696c733a20746f55696e743235365f6f75744f66426f756e6473006044820152606401610414565b50016020015190565b604054600160a01b900460ff1615612a705760405162461bcd60e51b81526020600482015260116024820152704272696467653a20557067726164696e6760781b6044820152606401610414565b60345460ff1615612a935760405162461bcd60e51b8152600401610414906146e9565b600160356000828254612aa69190614713565b909155505060355446821415612b1a5760405162461bcd60e51b815260206004820152603360248201527f4272696467653a2064657374696e6174696f6e20636861696e20696420657175604482015272185b0818dd5c9c995b9d0818da185a5b881a59606a1b6064820152608401610414565b612b2382612fcd565b60008281526048602090815260408083206001600160a01b038b1684529091529020805460ff191660011790556000612b73612710612b6d6037548861347e90919063ffffffff16565b906134fd565b90506000612b81868361353f565b90506000612b8e8a613581565b905086601260ff831614612bbf57612bbc612baa83601261499c565b612bb590600a614aa3565b899061347e565b90505b603f54604051638c34bc5560e01b81526001600160a01b038d811660048301526024820184905290911690638c34bc5590604401600060405180830381600087803b158015612c0d57600080fd5b505af1158015612c21573d6000803e3d6000fd5b505050506000612c308c612122565b80519091506001600160a01b031615612d34576000612c4e8d613665565b90506000612c5c868361373d565b9050612c68878261377f565b9650612c74868261353f565b60405163fe9d930360e01b81529096506001600160a01b038f169063fe9d930390612ca59089908e90600401614ab2565b600060405180830381600087803b158015612cbf57600080fd5b505af1158015612cd3573d6000803e3d6000fd5b505050505050868a6001600160a01b031682600001516001600160a01b03167fb2320a1ad388e1e16b142f7d2e822f31d8a2bbdd7d4f29260e7c203c5f45e8498e46898e604051612d279493929190614acb565b60405180910390a4612d87565b868a6001600160a01b03168d6001600160a01b03167fb2320a1ad388e1e16b142f7d2e822f31d8a2bbdd7d4f29260e7c203c5f45e8498e46898e604051612d7e9493929190614acb565b60405180910390a45b8415612db357603454612db39061010090046001600160a01b03166001600160a01b038e1690876137de565b50505050506035548114612dd95760405162461bcd60e51b81526004016104149061472b565b50505050505050565b6000600160356000828254612df79190614713565b909155505060355460608601356000908152604360205260409020546001600160a01b031680612e625760405162461bcd60e51b8152602060048201526016602482015275109c9a5919d94e88151e081b9bdd0818dc9bdcdcd95960521b6044820152606401610414565b6000612e9e612e7460208a018a614298565b60208a013560408b013560608c0135612e9360a08e0160808f01614800565b8d60a0013546611fb9565b60608901356000908152604260205260409020549091508114612f0d5760405162461bcd60e51b815260206004820152602160248201527f4272696467653a2057726f6e67207472616e73616374696f6e446174614861736044820152600d60fb1b6064820152608401610414565b612f1788826119c4565b15612f5e5760405162461bcd60e51b8152602060048201526017602482015276109c9a5919d94e88105b1c9958591e4818db185a5b5959604a1b6044820152606401610414565b6000818152603e60209081526040909120805460ff19166001179055612f929060a08a01359084908a908c01358a8a61380e565b9350612fa1888389898961385f565b50506035548114612fc45760405162461bcd60e51b81526004016104149061472b565b50949350505050565b60008111611c295760405162461bcd60e51b815260206004820152601460248201527304272696467653a20436861696e496420697320360641b6044820152606401610414565b468114611c295760405162461bcd60e51b815260206004820152601960248201527f4272696467653a204e6f7420626c6f636b2e636861696e6964000000000000006044820152606401610414565b6040805160208101859052908101839052606086811b6bffffffffffffffffffffffff1916908201526074810185905260e082901b6001600160e01b031916609482015260009060980160405160208183030381529060405280519060200120905095945050505050565b60006001600160a01b0382166131315760405162461bcd60e51b815260206004820152602260248201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604482015261737360f01b6064820152608401610414565b506001600160a01b03166000908152602091909152604090205460ff1690565b61315c60338261393a565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b61319e6033826139b2565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6039548451602080870151606088015160a08901516001600160a01b0385166000908152604590945260408420805494966132d09690957faf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c959194919391928c918c918b61324283614af8565b909155506040805160208101999099526001600160a01b03978816908901526060880195909552608087019390935260a086019190915290921660c084015260e08301919091526101008201526101208101859052610140016040516020818303038152906040528051906020012060405161190160f01b8152600281019290925260228201526042902090565b95945050505050565b600060128260ff16111561332f5760405162461bcd60e51b815260206004820152601c60248201527f4c69625574696c733a20446563696d616c73206e6f74203c3d203138000000006044820152606401610414565b61333a82601261499c565b61113090600a614aa3565b6040516001600160a01b03808516602483015283166044820152606481018290526133b09085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613a2e565b50505050565b6001600160a01b0381166134175760405162461bcd60e51b815260206004820152602260248201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604482015261737360f01b6064820152608401610414565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b60008261348d57506000611130565b60006134998385614b13565b9050826134a685836148fe565b1461211b5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610414565b600061211b83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613bae565b600061211b83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613bdc565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b038616916135c79190614b32565b600060405180830381855afa9150503d8060008114613602576040519150601f19603f3d011682016040523d82523d6000602084013e613607565b606091505b5091509150816136515760405162461bcd60e51b81526020600482015260156024820152744c69625574696c733a204e6f20646563696d616c7360581b6044820152606401610414565b80806020019051810190611a299190614b4e565b60408051600481526024810182526020810180516001600160e01b031663556f0dc760e01b1790529051600091829182916001600160a01b038616916136ab9190614b32565b600060405180830381855afa9150503d80600081146136e6576040519150601f19603f3d011682016040523d82523d6000602084013e6136eb565b606091505b5091509150816136515760405162461bcd60e51b815260206004820152601860248201527f4c69625574696c733a204e6f206772616e756c617269747900000000000000006044820152606401610414565b600061211b83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250613c0d565b60008061378c8385614713565b90508381101561211b5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610414565b6040516001600160a01b038316602482015260448101829052611b3190849063a9059cbb60e01b90606401613379565b600061381987612fcd565b61382387876125d2565b1561383c576138358686868686613c39565b9050613855565b613852613849888861257f565b86868686613de9565b90505b9695505050505050565b61386c6020860186614298565b6060860135600081815260446020908152604091829020546001600160a01b039485169489811694937fa7a84dcc6757cdf9b9122d3bbc42d58358c28dc4b09cc24349599a63c56c62fd9392909116918b0135908b01356138d360a08d0160808e01614800565b604080516001600160a01b039586168152602081019490945283019190915263ffffffff166060820152818916608082015290871660a08281019190915260c082018790528a013560e0820152466101008201526101200160405180910390a45050505050565b61394482826130ce565b6139905760405162461bcd60e51b815260206004820181905260248201527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c656044820152606401610414565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b6139bc82826130ce565b15613a095760405162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c65006044820152606401610414565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6001600160a01b0382163b613a855760405162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e7472616374006044820152606401610414565b600080836001600160a01b031683604051613aa09190614b32565b6000604051808303816000865af19150503d8060008114613add576040519150601f19603f3d011682016040523d82523d6000602084013e613ae2565b606091505b509150915081613b345760405162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65646044820152606401610414565b8051156133b05780806020019051810190613b4f9190614b67565b6133b05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610414565b60008183613bcf5760405162461bcd60e51b815260040161041491906143da565b5060006132d084866148fe565b60008184841115613c005760405162461bcd60e51b815260040161041491906143da565b5060006132d0848661469d565b60008183613c2e5760405162461bcd60e51b815260040161041491906143da565b50611a298385614b84565b600080613c4587613581565b60ff1690506000613c6c613c5a83601261469d565b613c6590600a614b98565b87906134fd565b905080841115613cb55760405162461bcd60e51b8152602060048201526014602482015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b6044820152606401610414565b613cbf818561353f565b6041549093506001600160a01b0389811691161415613db057604154604051632e1a7d4d60e01b8152600481018390526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b158015613d1e57600080fd5b505af1158015613d32573d6000803e3d6000fd5b50506040516001600160a01b038a16925085156108fc02915085906000818181858888f19350505050158015613d6c573d6000803e3d6000fd5b508315613dab576040516001600160a01b0386169085156108fc029086906000818181858888f19350505050158015613da9573d6000803e3d6000fd5b505b613dde565b613dc46001600160a01b03891688856137de565b8315613dde57613dde6001600160a01b03891686866137de565b505095945050505050565b60006001600160a01b038616613e415760405162461bcd60e51b815260206004820152601a60248201527f4272696467653a207369646520746f6b656e206973206e756c6c0000000000006044820152606401610414565b6000866001600160a01b031663556f0dc76040518163ffffffff1660e01b815260040160206040518083038186803b158015613e7c57600080fd5b505afa158015613e90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613eb49190614b4e565b90506000613ec2868361347e565b905080841115613f0b5760405162461bcd60e51b8152602060048201526014602482015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b6044820152606401610414565b613f15818561353f565b604051630dcdc7dd60e41b81526001600160a01b038981166004830152602482018390526080604483015260006084830181905260a0606484015260a48301529194509089169063dcdc7dd09060c401600060405180830381600087803b158015613f7f57600080fd5b505af1158015613f93573d6000803e3d6000fd5b505050506000841115613dde57604051630dcdc7dd60e41b81526001600160a01b03868116600483015260248201869052608060448301526000608483015260a06064830152600b60a48301526a72656c617965722066656560a81b60c483015289169063dcdc7dd09060e401600060405180830381600087803b15801561401a57600080fd5b505af115801561402e573d6000803e3d6000fd5b50505050505095945050505050565b6001600160a01b0381168114611c2957600080fd5b60008083601f84011261406457600080fd5b50813567ffffffffffffffff81111561407c57600080fd5b60208301915083602082850101111561409457600080fd5b9250929050565b60008060008060008060008060c0898b0312156140b757600080fd5b88356140c28161403d565b975060208901356140d28161403d565b965060408901356140e28161403d565b955060608901359450608089013567ffffffffffffffff8082111561410657600080fd5b6141128c838d01614052565b909650945060a08b013591508082111561412b57600080fd5b506141388b828c01614052565b999c989b5096995094979396929594505050565b60006020828403121561415e57600080fd5b5035919050565b8015158114611c2957600080fd5b60006020828403121561418557600080fd5b813561211b81614165565b600060c082840312156141a257600080fd5b50919050565b600060c082840312156141ba57600080fd5b61211b8383614190565b803563ffffffff811681146141d857600080fd5b919050565b60008060008060008060008060006101208a8c0312156141fc57600080fd5b89356142078161403d565b985060208a01356142178161403d565b975060408a01356142278161403d565b965060608a0135955060808a0135945060a08a0135935061424a60c08b016141c4565b925060e08a013591506101008a013590509295985092959850929598565b6000806040838503121561427b57600080fd5b82359150602083013561428d8161403d565b809150509250929050565b6000602082840312156142aa57600080fd5b813561211b8161403d565b60008082840360608112156142c957600080fd5b83356142d48161403d565b92506040601f19820112156142e857600080fd5b506040516040810181811067ffffffffffffffff8211171561431a57634e487b7160e01b600052604160045260246000fd5b604052602084013561432b8161403d565b81526040939093013560208401525092909150565b60008060006060848603121561435557600080fd5b8335925060208401356143678161403d565b915060408401356143778161403d565b809150509250925092565b60005b8381101561439d578181015183820152602001614385565b838111156133b05750506000910152565b600081518084526143c6816020860160208601614382565b601f01601f19169290920160200192915050565b60208152600061211b60208301846143ae565b60008060e0838503121561440057600080fd5b61440a8484614190565b9460c0939093013593505050565b803560ff811681146141d857600080fd5b6000806000806000806000610180888a03121561444557600080fd5b61444f8989614190565b965060c088013561445f8161403d565b955060e08801359450610100880135935061447d6101208901614418565b92506101408801359150610160880135905092959891949750929550565b600080600080600080600060e0888a0312156144b657600080fd5b87356144c18161403d565b96506020880135955060408801359450606088013593506144e4608089016141c4565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561451357600080fd5b50508035926020909101359150565b60008060008060008060008060c0898b03121561453e57600080fd5b8835975060208901356145508161403d565b965061455e60408a01614418565b9550606089013567ffffffffffffffff8082111561457b57600080fd5b6145878c838d01614052565b909750955060808b01359150808211156145a057600080fd5b506145ad8b828c01614052565b999c989b50969995989497949560a00135949350505050565b600080600080608085870312156145dc57600080fd5b8435935060208501356145ee8161403d565b925060408501356145fe8161403d565b9396929550929360600135925050565b6000806000806080858703121561462457600080fd5b843561462f8161403d565b9350602085013561463f8161403d565b9250604085013561464f8161403d565b9150606085013561465f8161403d565b939692955090935050565b60006020828403121561467c57600080fd5b815161211b8161403d565b634e487b7160e01b600052601160045260246000fd5b6000828210156146af576146af614687565b500390565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6000821982111561472657614726614687565b500190565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b60006020828403121561481257600080fd5b61211b826141c4565b600060c0828403121561482d57600080fd5b60405160c0810181811067ffffffffffffffff8211171561485e57634e487b7160e01b600052604160045260246000fd5b604052823561486c8161403d565b8082525060208301356020820152604083013560408201526060830135606082015261489a608084016141c4565b608082015260a083013560a08201528091505092915050565b600181811c908216806148c757607f821691505b602082108114156141a257634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b60008261490d5761490d6148e8565b500490565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60608152600061494f606083018789614912565b8281036020840152614962818688614912565b9150508260408301529695505050505050565b606081526000614989606083018688614912565b6020830194909452506040015292915050565b600060ff821660ff8416808210156149b6576149b6614687565b90039392505050565b600181815b808511156149fa5781600019048211156149e0576149e0614687565b808516156149ed57918102915b93841c93908002906149c4565b509250929050565b600082614a1157506001611130565b81614a1e57506000611130565b8160018114614a345760028114614a3e57614a5a565b6001915050611130565b60ff841115614a4f57614a4f614687565b50506001821b611130565b5060208310610133831016604e8410600b8410161715614a7d575081810a611130565b614a8783836149bf565b8060001904821115614a9b57614a9b614687565b029392505050565b600061211b60ff841683614a02565b828152604060208201526000611a2960408301846143ae565b60018060a01b038516815283602082015282604082015260806060820152600061385560808301846143ae565b6000600019821415614b0c57614b0c614687565b5060010190565b6000816000190483118215151615614b2d57614b2d614687565b500290565b60008251614b44818460208701614382565b9190910192915050565b600060208284031215614b6057600080fd5b5051919050565b600060208284031215614b7957600080fd5b815161211b81614165565b600082614b9357614b936148e8565b500690565b600061211b8383614a0256fea2646970667358221220575509595c84b7b6f30a376b571b86c9c397962f491392aca2b37537d49d7f0a64736f6c63430008090033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "__Pausable_init(address)": {
+ "details": "Initializes the contract in unpaused state. Assigns the Pauser role to the deployer."
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "pause()": {
+ "details": "Called by a pauser to pause, triggers stopped state."
+ },
+ "paused()": {
+ "details": "Returns true if the contract is paused, and false otherwise."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "tokensReceived(address,address,address,uint256,bytes,bytes)": {
+ "params": {
+ "userData": "it can be 2 options in the first one you can send the receiver and the chain id of the destination const userData = web3.eth.abi.encodeParameters( [\"address\", \"uint256\"], [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID] ); or you also can send only the destination chain id, and the receiver would be the same as the from parameter const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);"
+ }
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "unpause()": {
+ "details": "Called by a pauser to unpause, returns to normal state."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "acceptTransfer(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)": {
+ "notice": "Accepts the transaction from the other chain that was voted and sent by the Federation contract"
+ },
+ "claim((address,uint256,bytes32,bytes32,uint32,uint256))": {
+ "notice": "Claims the crossed transaction using the hash, this sends the funds to the address indicated in"
+ },
+ "depositTo(uint256,address)": {
+ "notice": "Use network currency and cross it."
+ },
+ "receiveTokensTo(uint256,address,address,uint256)": {
+ "notice": "ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom"
+ },
+ "tokensReceived(address,address,address,uint256,bytes,bytes)": {
+ "notice": "ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction See https://eips.ethereum.org/EIPS/eip-777#motivation for details"
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 16199,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16202,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16242,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16268,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_pausers",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_struct(Role)10525_storage"
+ },
+ {
+ "astId": 16390,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_paused",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16488,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_owner",
+ "offset": 1,
+ "slot": "52",
+ "type": "t_address"
+ },
+ {
+ "astId": 17207,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_guardCounter",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1344,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "federation",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_address"
+ },
+ {
+ "astId": 1346,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "feePercentage",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1348,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "deprecatedSymbolPrefix",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 1350,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "domainSeparator",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_bytes32"
+ },
+ {
+ "astId": 1352,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_deprecatedSpentToday",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1356,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "deprecatedMappedTokens",
+ "offset": 0,
+ "slot": "59",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 1360,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "deprecatedOriginalTokens",
+ "offset": 0,
+ "slot": "60",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 1364,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "deprecatedKnownTokens",
+ "offset": 0,
+ "slot": "61",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 1368,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "claimed",
+ "offset": 0,
+ "slot": "62",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ },
+ {
+ "astId": 1371,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "allowTokens",
+ "offset": 0,
+ "slot": "63",
+ "type": "t_contract(IAllowTokens)7187"
+ },
+ {
+ "astId": 1374,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "sideTokenFactory",
+ "offset": 0,
+ "slot": "64",
+ "type": "t_contract(ISideTokenFactory)7654"
+ },
+ {
+ "astId": 1376,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "isUpgrading",
+ "offset": 20,
+ "slot": "64",
+ "type": "t_bool"
+ },
+ {
+ "astId": 1387,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "wrappedCurrency",
+ "offset": 0,
+ "slot": "65",
+ "type": "t_contract(IWrapped)7707"
+ },
+ {
+ "astId": 1391,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "transactionsDataHashes",
+ "offset": 0,
+ "slot": "66",
+ "type": "t_mapping(t_bytes32,t_bytes32)"
+ },
+ {
+ "astId": 1395,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originalTokenAddresses",
+ "offset": 0,
+ "slot": "67",
+ "type": "t_mapping(t_bytes32,t_address)"
+ },
+ {
+ "astId": 1399,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "senderAddresses",
+ "offset": 0,
+ "slot": "68",
+ "type": "t_mapping(t_bytes32,t_address)"
+ },
+ {
+ "astId": 1406,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "nonces",
+ "offset": 0,
+ "slot": "69",
+ "type": "t_mapping(t_address,t_uint256)"
+ },
+ {
+ "astId": 1412,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "sideTokenByOriginalTokenByChain",
+ "offset": 0,
+ "slot": "70",
+ "type": "t_mapping(t_uint256,t_mapping(t_address,t_address))"
+ },
+ {
+ "astId": 1417,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originalTokenBySideToken",
+ "offset": 0,
+ "slot": "71",
+ "type": "t_mapping(t_address,t_struct(OriginalToken)7208_storage)"
+ },
+ {
+ "astId": 1423,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "knownTokenByChain",
+ "offset": 0,
+ "slot": "72",
+ "type": "t_mapping(t_uint256,t_mapping(t_address,t_bool))"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IAllowTokens)7187": {
+ "encoding": "inplace",
+ "label": "contract IAllowTokens",
+ "numberOfBytes": "20"
+ },
+ "t_contract(ISideTokenFactory)7654": {
+ "encoding": "inplace",
+ "label": "contract ISideTokenFactory",
+ "numberOfBytes": "20"
+ },
+ "t_contract(IWrapped)7707": {
+ "encoding": "inplace",
+ "label": "contract IWrapped",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_address)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_address,t_struct(OriginalToken)7208_storage)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => struct IBridge.OriginalToken)",
+ "numberOfBytes": "32",
+ "value": "t_struct(OriginalToken)7208_storage"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_mapping(t_bytes32,t_address)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bytes32)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bytes32)",
+ "numberOfBytes": "32",
+ "value": "t_bytes32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_address,t_address))": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => mapping(address => address))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_address)"
+ },
+ "t_mapping(t_uint256,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(OriginalToken)7208_storage": {
+ "encoding": "inplace",
+ "label": "struct IBridge.OriginalToken",
+ "members": [
+ {
+ "astId": 7205,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "tokenAddress",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ },
+ {
+ "astId": 7207,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originChainId",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Role)10525_storage": {
+ "encoding": "inplace",
+ "label": "struct Roles.Role",
+ "members": [
+ {
+ "astId": 10524,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "bearer",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_address,t_bool)"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/bsctestnet/BridgeProxy.json b/bridge/deployments/bsctestnet/BridgeProxy.json
new file mode 100644
index 000000000..bbc6deb6c
--- /dev/null
+++ b/bridge/deployments/bsctestnet/BridgeProxy.json
@@ -0,0 +1,237 @@
+{
+ "address": "0xd9d2f9ee990ddb1147e595ae4f69ec468a0b58d0",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_admin",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x4d351f1fdabe20633ba88ad23237bf94ac4212d7acd8f54f957a248a3cc714e7",
+ "receipt": {
+ "to": null,
+ "from": "0x9c95b0ef2d3e1d9ca479524ba738c87be28c1585",
+ "contractAddress": "0xd9d2f9ee990ddb1147e595ae4f69ec468a0b58d0",
+ "transactionIndex": "0x1",
+ "gasUsed": "0xbacb3",
+ "logsBloom": "0x00000000020000000000000000000000000000000000000000800000000000001000000000000000000000000000002000001000000000000000000000000000000000000484000010000000000000000003000000000000000000000000000000000000020000000000000000000800000010004020000000000000000000400000001000000000000000000000400000000000000000000000000000000000000000000000000000000000000000020000000000000000200801000000000000000000000000000000000000000000000000000000000000000100000020000000000000000000000000000000000000100000000000000000000000000001",
+ "blockHash": "0xe1fc7066077d1146d33167069ed064d0c1f1b6bd681aead94668b12f3c292b24",
+ "transactionHash": "0x4d351f1fdabe20633ba88ad23237bf94ac4212d7acd8f54f957a248a3cc714e7",
+ "logs": [
+ {
+ "address": "0xd9d2f9ee990ddb1147e595ae4f69ec468a0b58d0",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000e3848f411587c2c8658a0d6f649e7f1e403873a6"
+ ],
+ "data": "0x",
+ "blockNumber": "0xfdfca3",
+ "transactionHash": "0x4d351f1fdabe20633ba88ad23237bf94ac4212d7acd8f54f957a248a3cc714e7",
+ "transactionIndex": "0x1",
+ "blockHash": "0xe1fc7066077d1146d33167069ed064d0c1f1b6bd681aead94668b12f3c292b24",
+ "logIndex": "0x0",
+ "removed": false
+ },
+ {
+ "address": "0xd9d2f9ee990ddb1147e595ae4f69ec468a0b58d0",
+ "topics": [
+ "0x6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f8",
+ "0x000000000000000000000000e3848f411587c2c8658a0d6f649e7f1e403873a6"
+ ],
+ "data": "0x",
+ "blockNumber": "0xfdfca3",
+ "transactionHash": "0x4d351f1fdabe20633ba88ad23237bf94ac4212d7acd8f54f957a248a3cc714e7",
+ "transactionIndex": "0x1",
+ "blockHash": "0xe1fc7066077d1146d33167069ed064d0c1f1b6bd681aead94668b12f3c292b24",
+ "logIndex": "0x1",
+ "removed": false
+ },
+ {
+ "address": "0x1820a4b7618bde71dce8cdc73aab6c95905fad24",
+ "topics": [
+ "0x93baa6efbd2244243bfee6ce4cfdd1d04fc4c0e9a786abd3a41313bd352db153",
+ "0x000000000000000000000000d9d2f9ee990ddb1147e595ae4f69ec468a0b58d0",
+ "0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b",
+ "0x000000000000000000000000d9d2f9ee990ddb1147e595ae4f69ec468a0b58d0"
+ ],
+ "data": "0x",
+ "blockNumber": "0xfdfca3",
+ "transactionHash": "0x4d351f1fdabe20633ba88ad23237bf94ac4212d7acd8f54f957a248a3cc714e7",
+ "transactionIndex": "0x1",
+ "blockHash": "0xe1fc7066077d1146d33167069ed064d0c1f1b6bd681aead94668b12f3c292b24",
+ "logIndex": "0x2",
+ "removed": false
+ }
+ ],
+ "blockNumber": "0xfdfca3",
+ "cumulativeGasUsed": "0xbfebb",
+ "status": "0x1"
+ },
+ "args": [
+ "0x1974A084f07118C0Ab31b811ab9806343b49ed88",
+ "0x6C62BF5440De2Cb157205B15C424BCEb5C3368F5",
+ "0xf8c8765e000000000000000000000000e3848f411587c2c8658a0d6f649e7f1e403873a60000000000000000000000009c95b0ef2d3e1d9ca479524ba738c87be28c15850000000000000000000000009c95b0ef2d3e1d9ca479524ba738c87be28c1585000000000000000000000000e2ebfc705d473c3ddd52cb49af0bde3132e8831e"
+ ],
+ "numDeployments": 1,
+ "solcInputHash": "f27c8e19ddc2cd2a95162a1eabc0e272",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Proxies.sol\":\"BridgeProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Proxies.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\\\";\\n\\ncontract BridgeProxy is TransparentUpgradeableProxy {\\n // solhint-disable-next-line no-empty-blocks\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\n}\\n\\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\\n // solhint-disable-next-line no-empty-blocks\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\n}\\n\\ncontract FederationProxy is TransparentUpgradeableProxy {\\n // solhint-disable-next-line no-empty-blocks\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\n}\",\"keccak256\":\"0xe54cf19d7ab240930b2786d4c67a88d200ed3c3711c7ac30195aacedc6ccf0e7\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0xdc0ebdc6f4ae0b5f9dd0a6c041a2238e4a7a2afbc6cef539437b0004ada42370\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x3327b21f85d71d3b9bad1a89267f08b19966e03446a18d810bd80fe42789ac5f\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb54322ec8ec142c149ad1f561aa2f0da6d6ea2d9f45639164088db9e16d5a69d\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x04801fc2398ee3370f3903f95389ea3a8da65a8df01f24b352e499e44d492e9b\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000d9738038062000d9783398101604081905262000026916200036f565b82828282816200005860017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd6200044f565b60008051602062000d508339815191521462000078576200007862000475565b620000838262000118565b805115620000a457620000a28282620001b960201b620003ba1760201c565b505b50620000d4905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61046200044f565b60008051602062000d3083398151915214620000f457620000f462000475565b6200010c8260008051602062000d3083398151915255565b505050505050620004de565b6200012e81620001e860201b620003e61760201c565b620001a65760405162461bcd60e51b815260206004820152603660248201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160448201527f74696f6e206973206e6f74206120636f6e74726163740000000000000000000060648201526084015b60405180910390fd5b60008051602062000d5083398151915255565b6060620001e1838360405180606001604052806027815260200162000d7060279139620001ee565b9392505050565b3b151590565b6060833b6200024f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200019d565b600080856001600160a01b0316856040516200026c91906200048b565b600060405180830381855af49150503d8060008114620002a9576040519150601f19603f3d011682016040523d82523d6000602084013e620002ae565b606091505b509092509050620002c1828286620002cb565b9695505050505050565b60608315620002dc575081620001e1565b825115620002ed5782518084602001fd5b8160405162461bcd60e51b81526004016200019d9190620004a9565b80516001600160a01b03811681146200032157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620003595781810151838201526020016200033f565b8381111562000369576000848401525b50505050565b6000806000606084860312156200038557600080fd5b620003908462000309565b9250620003a06020850162000309565b60408501519092506001600160401b0380821115620003be57600080fd5b818601915086601f830112620003d357600080fd5b815181811115620003e857620003e862000326565b604051601f8201601f19908116603f0116810190838211818310171562000413576200041362000326565b816040528281528960208487010111156200042d57600080fd5b620004408360208301602088016200033c565b80955050505050509250925092565b6000828210156200047057634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b600082516200049f8184602087016200033c565b9190910192915050565b6020815260008251806020840152620004ca8160408501602087016200033c565b601f01601f19169190910160400192915050565b61084280620004ee6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ac565b610138565b61005b6100933660046106c7565b610175565b3480156100a457600080fd5b506100ad6101fa565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ac565b61025c565b3480156100f557600080fd5b506100ad610375565b6101066103ec565b6101366101317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b61048e565b565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b0316141561016d5761016a816104b2565b50565b61016a6100fe565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b031614156101ed576101a7836104b2565b6101e78383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ba92505050565b50505050565b6101f56100fe565b505050565b60006102126000805160206107c68339815191525490565b6001600160a01b0316336001600160a01b0316141561025157507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6102596100fe565b90565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b0316141561016d576001600160a01b0381166103065760405162461bcd60e51b815260206004820152603a60248201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760448201527f2061646d696e20697320746865207a65726f206164647265737300000000000060648201526084015b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61033d6000805160206107c68339815191525490565b604080516001600160a01b03928316815291841660208301520160405180910390a161016a816000805160206107c683398151915255565b600061038d6000805160206107c68339815191525490565b6001600160a01b0316336001600160a01b0316141561025157506000805160206107c68339815191525490565b60606103df83836040518060600160405280602781526020016107e6602791396104f2565b9392505050565b3b151590565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b031614156101365760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4016102fd565b3660008037600080366000845af43d6000803e8080156104ad573d6000f35b3d6000fd5b6104bb816105c6565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060833b6105515760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016102fd565b600080856001600160a01b03168560405161056c9190610776565b600060405180830381855af49150503d80600081146105a7576040519150601f19603f3d011682016040523d82523d6000602084013e6105ac565b606091505b50915091506105bc828286610657565b9695505050505050565b803b6106335760405162461bcd60e51b815260206004820152603660248201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616044820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b60648201526084016102fd565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156106665750816103df565b8251156106765782518084602001fd5b8160405162461bcd60e51b81526004016102fd9190610792565b80356001600160a01b03811681146106a757600080fd5b919050565b6000602082840312156106be57600080fd5b6103df82610690565b6000806000604084860312156106dc57600080fd5b6106e584610690565b9250602084013567ffffffffffffffff8082111561070257600080fd5b818601915086601f83011261071657600080fd5b81358181111561072557600080fd5b87602082850101111561073757600080fd5b6020830194508093505050509250925092565b60005b8381101561076557818101518382015260200161074d565b838111156101e75750506000910152565b6000825161078881846020870161074a565b9190910192915050565b60208152600082518060208401526107b181604085016020870161074a565b601f01601f1916919091016040019291505056feb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220342b70add6cfb6a21669078e26fc7a495c3f3ec30ad50633cf8274c15429cb3164736f6c63430008090033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ac565b610138565b61005b6100933660046106c7565b610175565b3480156100a457600080fd5b506100ad6101fa565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ac565b61025c565b3480156100f557600080fd5b506100ad610375565b6101066103ec565b6101366101317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b61048e565b565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b0316141561016d5761016a816104b2565b50565b61016a6100fe565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b031614156101ed576101a7836104b2565b6101e78383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ba92505050565b50505050565b6101f56100fe565b505050565b60006102126000805160206107c68339815191525490565b6001600160a01b0316336001600160a01b0316141561025157507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6102596100fe565b90565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b0316141561016d576001600160a01b0381166103065760405162461bcd60e51b815260206004820152603a60248201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760448201527f2061646d696e20697320746865207a65726f206164647265737300000000000060648201526084015b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61033d6000805160206107c68339815191525490565b604080516001600160a01b03928316815291841660208301520160405180910390a161016a816000805160206107c683398151915255565b600061038d6000805160206107c68339815191525490565b6001600160a01b0316336001600160a01b0316141561025157506000805160206107c68339815191525490565b60606103df83836040518060600160405280602781526020016107e6602791396104f2565b9392505050565b3b151590565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b031614156101365760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4016102fd565b3660008037600080366000845af43d6000803e8080156104ad573d6000f35b3d6000fd5b6104bb816105c6565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060833b6105515760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016102fd565b600080856001600160a01b03168560405161056c9190610776565b600060405180830381855af49150503d80600081146105a7576040519150601f19603f3d011682016040523d82523d6000602084013e6105ac565b606091505b50915091506105bc828286610657565b9695505050505050565b803b6106335760405162461bcd60e51b815260206004820152603660248201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616044820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b60648201526084016102fd565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156106665750816103df565b8251156106765782518084602001fd5b8160405162461bcd60e51b81526004016102fd9190610792565b80356001600160a01b03811681146106a757600080fd5b919050565b6000602082840312156106be57600080fd5b6103df82610690565b6000806000604084860312156106dc57600080fd5b6106e584610690565b9250602084013567ffffffffffffffff8082111561070257600080fd5b818601915086601f83011261071657600080fd5b81358181111561072557600080fd5b87602082850101111561073757600080fd5b6020830194508093505050509250925092565b60005b8381101561076557818101518382015260200161074d565b838111156101e75750506000910152565b6000825161078881846020870161074a565b9190910192915050565b60208152600082518060208401526107b181604085016020870161074a565b601f01601f1916919091016040019291505056feb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220342b70add6cfb6a21669078e26fc7a495c3f3ec30ad50633cf8274c15429cb3164736f6c63430008090033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/bsctestnet/Federation.json b/bridge/deployments/bsctestnet/Federation.json
new file mode 100644
index 000000000..5436b29f8
--- /dev/null
+++ b/bridge/deployments/bsctestnet/Federation.json
@@ -0,0 +1,1192 @@
+{
+ "address": "0x5D248F520b023acB815eDeCD5000B98ef84CbF1b",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridge",
+ "type": "address"
+ }
+ ],
+ "name": "BridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Executed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "currentChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "currentBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "fedVersion",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256[]",
+ "name": "fedChainsIds",
+ "type": "uint256[]"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256[]",
+ "name": "fedChainsBlocks",
+ "type": "uint256[]"
+ },
+ {
+ "indexed": false,
+ "internalType": "string[]",
+ "name": "fedChainsInfo",
+ "type": "string[]"
+ }
+ ],
+ "name": "HeartBeat",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridgeNFT",
+ "type": "address"
+ }
+ ],
+ "name": "NFTBridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Voted",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_MEMBER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_newMember",
+ "type": "address"
+ }
+ ],
+ "name": "addMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridge",
+ "outputs": [
+ {
+ "internalType": "contract IBridge",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridgeNFT",
+ "outputs": [
+ {
+ "internalType": "contract INFTBridge",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "fedVersion",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "fedChainsIds",
+ "type": "uint256[]"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "fedChainsBlocks",
+ "type": "uint256[]"
+ },
+ {
+ "internalType": "string[]",
+ "name": "fedChainsInfo",
+ "type": "string[]"
+ }
+ ],
+ "name": "emitHeartbeat",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getMembers",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getTransactionId",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_members",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridgeNFT",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isMember",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionIdMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionIdMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "members",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "processed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_oldMember",
+ "type": "address"
+ }
+ ],
+ "name": "removeMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ }
+ ],
+ "name": "setBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridgeNFT",
+ "type": "address"
+ }
+ ],
+ "name": "setNFTBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionWasProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "enum IFederation.TokenType",
+ "name": "tokenType",
+ "type": "uint8"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "voteTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "votes",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xb9abc390af12b419f20acf8a17f6e9c60abcba2fb266aea7adb057986a299265",
+ "receipt": {
+ "to": null,
+ "from": "0x9C95B0EF2D3E1D9ca479524Ba738C87BE28C1585",
+ "contractAddress": "0x5D248F520b023acB815eDeCD5000B98ef84CbF1b",
+ "transactionIndex": 6,
+ "gasUsed": "1949440",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xd25ad29300dd2f91f6459c47aa3f6555afda0554456ada974baad644d336f9df",
+ "transactionHash": "0xb9abc390af12b419f20acf8a17f6e9c60abcba2fb266aea7adb057986a299265",
+ "logs": [],
+ "blockNumber": 16645381,
+ "cumulativeGasUsed": "2816684",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "numDeployments": 1,
+ "solcInputHash": "f27c8e19ddc2cd2a95162a1eabc0e272",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"bridge\",\"type\":\"address\"}],\"name\":\"BridgeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"}],\"name\":\"Executed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"currentChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"currentBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"fedVersion\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"fedChainsIds\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"fedChainsBlocks\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"fedChainsInfo\",\"type\":\"string[]\"}],\"name\":\"HeartBeat\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"bridgeNFT\",\"type\":\"address\"}],\"name\":\"NFTBridgeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"}],\"name\":\"Voted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MEMBER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newMember\",\"type\":\"address\"}],\"name\":\"addMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contract IBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridgeNFT\",\"outputs\":[{\"internalType\":\"contract INFTBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"fedVersion\",\"type\":\"string\"},{\"internalType\":\"uint256[]\",\"name\":\"fedChainsIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"fedChainsBlocks\",\"type\":\"uint256[]\"},{\"internalType\":\"string[]\",\"name\":\"fedChainsInfo\",\"type\":\"string[]\"}],\"name\":\"emitHeartbeat\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMembers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"}],\"name\":\"getTransactionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"hasVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_members\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bridgeNFT\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMember\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionIdMultichain\",\"type\":\"bytes32\"}],\"name\":\"isProcessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionIdMultichain\",\"type\":\"bytes32\"}],\"name\":\"isVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"members\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"processed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_oldMember\",\"type\":\"address\"}],\"name\":\"removeMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"name\":\"setBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridgeNFT\",\"type\":\"address\"}],\"name\":\"setNFTBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"transactionWasProcessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"enum IFederation.TokenType\",\"name\":\"tokenType\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"}],\"name\":\"voteTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"votes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addMember(address)\":{\"params\":{\"_newMember\":\"address of the new member\"}},\"changeRequirement(uint256)\":{\"details\":\"Emits the RequirementChange event\",\"params\":{\"_required\":\"the number of minimum members to approve an transaction, it has to be bigger than 1\"}},\"emitHeartbeat(string,uint256[],uint256[],string[])\":{\"details\":\"Emits HeartBeat event\"},\"getMembers()\":{\"returns\":{\"_0\":\"Current members\"}},\"getTransactionCount(bytes32)\":{\"params\":{\"transactionId\":\"The transaction hashed from getTransactionId function\"}},\"getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)\":{\"details\":\"It encodes and applies keccak256 to the parameters received in the same order\",\"params\":{\"amount\":\"Could be the amount or the tokenId\",\"blockHash\":\"The block hash in which the transaction with the cross event occurred\",\"destinationChainId\":\"Is chainId of the destination chain\",\"logIndex\":\"Index of the event in the logs\",\"originChainId\":\"Is chainId of the original chain\",\"originalTokenAddress\":\"The address of the token in the origin (main) chain\",\"receiver\":\"Who is going to receive the token in the opposite chain\",\"sender\":\"The address who solicited the cross token\",\"transactionHash\":\"The transaction in which the cross event occurred\"},\"returns\":{\"_0\":\"The hash generated by the parameters.\"}},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"removeMember(address)\":{\"params\":{\"_oldMember\":\"address of the member to be removed from federation\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setBridge(address)\":{\"details\":\"Emits BridgeChanged event\",\"params\":{\"_bridge\":\"the new bridge contract address that should implement the IBridge interface\"}},\"setNFTBridge(address)\":{\"details\":\"Emits NFTBridgeChanged event\",\"params\":{\"_bridgeNFT\":\"the new NFT bridge contract address that should implement the INFTBridge interface\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"version()\":{\"returns\":{\"_0\":\"version in v{Number}\"}},\"voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint8,uint256,uint256)\":{\"params\":{\"blockHash\":\"The block hash in which the transaction with the cross event occurred\",\"destinationChainId\":\"Is chainId of the destination chain\",\"logIndex\":\"Index of the event in the logs\",\"originChainId\":\"Is chainId of the original chain\",\"originalTokenAddress\":\"The address of the token in the origin (main) chain\",\"receiver\":\"Who is going to receive the token in the opposite chain\",\"sender\":\"The address who solicited the cross token\",\"tokenType\":\"Is the type of bridge to be used\",\"transactionHash\":\"The transaction in which the cross event occurred\",\"value\":\"Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\"}}},\"stateVariables\":{\"isMember\":{\"details\":\"The address should be a member to vote in transactions\"},\"required\":{\"details\":\"It should have at least the required amount of members\"},\"votes\":{\"details\":\"the members should approve the transaction by 50% + 1\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addMember(address)\":{\"notice\":\"Add a new member to the federation\"},\"bridgeNFT()\":{\"notice\":\"Federator v3 variables \"},\"changeRequirement(uint256)\":{\"notice\":\"Changes the number of required members to vote and approve an transaction\"},\"emitHeartbeat(string,uint256[],uint256[],string[])\":{\"notice\":\"It emits an HeartBeat like an health check\"},\"getMembers()\":{\"notice\":\"Return all the current members of the federation\"},\"getTransactionCount(bytes32)\":{\"notice\":\"Get the amount of approved votes for that transactionId\"},\"getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)\":{\"notice\":\"Gets the hash of transaction from the following parameters encoded and keccaked\"},\"isMember(address)\":{\"notice\":\"All the addresses that are members of the federation\"},\"processed(bytes32)\":{\"notice\":\"(bytes32) transactionId => (bool) votedCheck if that transaction was already processed\"},\"removeMember(address)\":{\"notice\":\"Remove a member of the federation\"},\"required()\":{\"notice\":\"The minimum amount of votes to approve a transaction\"},\"setBridge(address)\":{\"notice\":\"Sets a new bridge contract\"},\"setNFTBridge(address)\":{\"notice\":\"Sets a new NFT bridge contract\"},\"version()\":{\"notice\":\"Current version of the contract\"},\"voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint8,uint256,uint256)\":{\"notice\":\"Vote in a transaction, if it has enough votes it accepts the transfer\"},\"votes(bytes32,address)\":{\"notice\":\"(bytes32) transactionId = keccak256( abi.encodePacked( originalTokenAddress, sender, receiver, amount, blockHash, transactionHash, logIndex ) ) => ( (address) members => (bool) voted )Votes by members by the transaction ID\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/federation/Federation.sol\":\"Federation\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/federation/Federation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n// Upgradables\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\n\\nimport \\\"../nftbridge/INFTBridge.sol\\\";\\nimport \\\"../interface/IBridge.sol\\\";\\nimport \\\"../interface/IFederation.sol\\\";\\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\\n\\tuint constant public MAX_MEMBER_COUNT = 50;\\n\\taddress constant private NULL_ADDRESS = address(0);\\n\\n\\tIBridge public bridge;\\n\\taddress[] public members;\\n\\n\\t/**\\n\\t\\t@notice The minimum amount of votes to approve a transaction\\n\\t\\t@dev It should have at least the required amount of members\\n\\t\\t*/\\n\\tuint public required;\\n\\n\\t/**\\n\\t\\t@notice All the addresses that are members of the federation\\n\\t\\t@dev The address should be a member to vote in transactions\\n\\t\\t*/\\n\\tmapping (address => bool) public isMember;\\n\\n\\t/**\\n\\t\\t(bytes32) transactionId = keccak256(\\n\\t\\t\\tabi.encodePacked(\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tamount,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\tlogIndex\\n\\t\\t\\t)\\n\\t\\t) => (\\n\\t\\t\\t(address) members => (bool) voted\\n\\t\\t)\\n\\t\\t@notice Votes by members by the transaction ID\\n\\t\\t@dev the members should approve the transaction by 50% + 1\\n\\t\\t*/\\n\\tmapping (bytes32 => mapping (address => bool)) public votes;\\n\\n\\t/**\\n\\t\\t(bytes32) transactionId => (bool) voted\\n\\t\\t@notice Check if that transaction was already processed\\n\\t*/\\n\\tmapping(bytes32 => bool) public processed;\\n\\n\\t/** Federator v3 variables */\\n\\tINFTBridge public bridgeNFT;\\n\\n\\tmodifier onlyMember() {\\n\\t\\trequire(isMember[_msgSender()], \\\"Federation: Not Federator\\\");\\n\\t\\t_;\\n\\t}\\n\\n\\tmodifier validRequirement(uint membersCount, uint _required) {\\n\\t\\trequire(_required <= membersCount && _required != 0 && membersCount != 0, \\\"Federation: Invalid requirements\\\");\\n\\t\\t_;\\n\\t}\\n\\n\\tfunction initialize(\\n\\t\\taddress[] calldata _members,\\n\\t\\tuint _required,\\n\\t\\taddress _bridge,\\n\\t\\taddress owner,\\n\\t\\taddress _bridgeNFT\\n\\t) public validRequirement(_members.length, _required) initializer {\\n\\t\\tUpgradableOwnable.initialize(owner);\\n\\t\\trequire(_members.length <= MAX_MEMBER_COUNT, \\\"Federation: Too many members\\\");\\n\\t\\tmembers = _members;\\n\\t\\tfor (uint i = 0; i < _members.length; i++) {\\n\\t\\t\\trequire(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \\\"Federation: Invalid members\\\");\\n\\t\\t\\tisMember[_members[i]] = true;\\n\\t\\t\\temit MemberAddition(_members[i]);\\n\\t\\t}\\n\\t\\trequired = _required;\\n\\t\\temit RequirementChange(required);\\n\\t\\t_setBridge(_bridge);\\n\\t\\t_setNFTBridge(_bridgeNFT);\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Current version of the contract\\n\\t\\t@return version in v{Number}\\n\\t\\t*/\\n\\tfunction version() external pure override returns (string memory) {\\n\\t\\treturn \\\"v3\\\";\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Sets a new bridge contract\\n\\t\\t@dev Emits BridgeChanged event\\n\\t\\t@param _bridge the new bridge contract address that should implement the IBridge interface\\n\\t\\t*/\\n\\tfunction setBridge(address _bridge) external onlyOwner override {\\n\\t\\t_setBridge(_bridge);\\n\\t}\\n\\n\\tfunction _setBridge(address _bridge) internal {\\n\\t\\trequire(_bridge != NULL_ADDRESS, \\\"Federation: Empty bridge\\\");\\n\\t\\tbridge = IBridge(_bridge);\\n\\t\\temit BridgeChanged(_bridge);\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Sets a new NFT bridge contract\\n\\t\\t@dev Emits NFTBridgeChanged event\\n\\t\\t@param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\\n\\t\\t*/\\n\\tfunction setNFTBridge(address _bridgeNFT) external onlyOwner override {\\n\\t\\trequire(_bridgeNFT != NULL_ADDRESS, \\\"Federation: Empty NFT bridge\\\");\\n\\t\\t_setNFTBridge(_bridgeNFT);\\n\\t}\\n\\n\\tfunction _setNFTBridge(address _bridgeNFT) internal {\\n\\t\\tbridgeNFT = INFTBridge(_bridgeNFT);\\n\\t\\temit NFTBridgeChanged(_bridgeNFT);\\n\\t}\\n\\n\\tfunction validateTransaction(bytes32 transactionId, bytes32 transactionIdMultichain) internal view returns(bool) {\\n\\t\\tuint256 minimumVotes = getMinimalNumberOfVotes();\\n\\t\\tuint256 amountVotes = 0;\\n\\n for (uint256 i = 0; i < members.length; i++) {\\n if (votes[transactionIdMultichain][members[i]]) {\\n amountVotes += 1;\\n\\t\\t\\t} else if (votes[transactionId][members[i]]) {\\n amountVotes += 1;\\n\\t\\t\\t}\\n\\n\\t\\t\\tif (amountVotes >= minimumVotes && amountVotes >= required) {\\n\\t\\t\\t\\treturn true;\\n\\t\\t\\t}\\n }\\n\\n\\t\\treturn false;\\n\\t}\\n\\n\\tfunction getMinimalNumberOfVotes() internal view returns(uint256) {\\n\\t\\treturn members.length / 2 + 1;\\n\\t}\\n\\n\\tfunction isProcessed(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\\n\\t\\treturn processed[transactionIdMultichain] || processed[transactionId];\\n\\t}\\n\\n\\tfunction isVoted(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\\n\\t\\treturn votes[transactionIdMultichain][_msgSender()] || votes[transactionId][_msgSender()];\\n\\t}\\n\\n\\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\\n\\t\\trequire(chainId == block.chainid, \\\"Federation: Not block.chainid\\\");\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Vote in a transaction, if it has enough votes it accepts the transfer\\n\\t\\t@param originalTokenAddress The address of the token in the origin (main) chain\\n\\t\\t@param sender The address who solicited the cross token\\n\\t\\t@param receiver Who is going to receive the token in the opposite chain\\n\\t\\t@param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\\n\\t\\t@param blockHash The block hash in which the transaction with the cross event occurred\\n\\t\\t@param transactionHash The transaction in which the cross event occurred\\n\\t\\t@param logIndex Index of the event in the logs\\n\\t\\t@param tokenType Is the type of bridge to be used\\n\\t\\t@param originChainId Is chainId of the original chain\\n\\t\\t@param destinationChainId Is chainId of the destination chain\\n\\t\\t*/\\n\\tfunction voteTransaction(\\n\\t\\taddress originalTokenAddress,\\n\\t\\taddress payable sender,\\n\\t\\taddress payable receiver,\\n\\t\\tuint256 value,\\n\\t\\tbytes32 blockHash,\\n\\t\\tbytes32 transactionHash,\\n\\t\\tuint32 logIndex,\\n\\t\\tTokenType tokenType,\\n\\t\\tuint256 originChainId,\\n\\t\\tuint256\\tdestinationChainId\\n\\t) external onlyMember override {\\n\\t\\tshouldBeCurrentChainId(destinationChainId);\\n\\t\\tbytes32 transactionId = keccak256(\\n\\t\\t\\tabi.encodePacked(\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tvalue,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\tlogIndex\\n\\t\\t\\t)\\n\\t\\t);\\n\\n\\t\\tbytes32 transactionIdMultichain = getTransactionId(\\n\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\tsender,\\n\\t\\t\\treceiver,\\n\\t\\t\\tvalue,\\n\\t\\t\\tblockHash,\\n\\t\\t\\ttransactionHash,\\n\\t\\t\\tlogIndex,\\n\\t\\t\\toriginChainId,\\n\\t\\t\\tdestinationChainId\\n\\t\\t);\\n\\n\\t\\tif (isProcessed(transactionId, transactionIdMultichain))\\n\\t\\t\\treturn;\\n\\n\\t\\tif (isVoted(transactionId, transactionIdMultichain))\\n\\t\\t\\treturn;\\n\\n\\t\\tvotes[transactionIdMultichain][_msgSender()] = true;\\n\\t\\temit Voted(\\n\\t\\t\\t_msgSender(),\\n\\t\\t\\ttransactionHash,\\n\\t\\t\\ttransactionIdMultichain,\\n\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\tsender,\\n\\t\\t\\treceiver,\\n\\t\\t\\tvalue,\\n\\t\\t\\tblockHash,\\n\\t\\t\\tlogIndex,\\n\\t\\t\\toriginChainId,\\n\\t\\t\\tdestinationChainId\\n\\t\\t);\\n\\n\\t\\tif (validateTransaction(transactionId, transactionIdMultichain)) {\\n\\t\\t\\tprocessed[transactionIdMultichain] = true;\\n\\n\\t\\t\\tacceptTransfer(\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tvalue,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\tlogIndex,\\n\\t\\t\\t\\ttokenType,\\n\\t\\t\\t\\toriginChainId,\\n\\t\\t\\t\\tdestinationChainId\\n\\t\\t\\t);\\n\\n\\t\\t\\temit Executed(\\n\\t\\t\\t\\t_msgSender(),\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\ttransactionIdMultichain,\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tvalue,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\tlogIndex,\\n\\t\\t\\t\\toriginChainId,\\n\\t\\t\\t\\tdestinationChainId\\n\\t\\t\\t);\\n\\t\\t}\\n\\t}\\n\\n function acceptTransfer(\\n address originalTokenAddress,\\n address payable sender,\\n address payable receiver,\\n uint256 value,\\n bytes32 blockHash,\\n bytes32 transactionHash,\\n uint32 logIndex,\\n TokenType tokenType,\\n\\tuint256 originChainId,\\n\\tuint256\\tdestinationChainId\\n ) internal {\\n if (tokenType == TokenType.NFT) {\\n require(address(bridgeNFT) != NULL_ADDRESS, \\\"Federation: Empty NFTBridge\\\");\\n bridgeNFT.acceptTransfer(\\n originalTokenAddress,\\n sender,\\n receiver,\\n value,\\n blockHash,\\n transactionHash,\\n logIndex,\\n\\t\\toriginChainId,\\n\\t\\tdestinationChainId\\n );\\n } else {\\n\\t bridge.acceptTransfer(\\n\\t\\toriginalTokenAddress,\\n\\t\\tsender,\\n\\t\\treceiver,\\n\\t\\tvalue,\\n\\t\\tblockHash,\\n\\t\\ttransactionHash,\\n\\t\\tlogIndex,\\n\\t\\toriginChainId,\\n\\t\\tdestinationChainId\\n\\t );\\n\\t}\\n }\\n\\n /**\\n @notice Get the amount of approved votes for that transactionId\\n @param transactionId The transaction hashed from getTransactionId function\\n */\\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\\n uint count = 0;\\n for (uint i = 0; i < members.length; i++) {\\n if (votes[transactionId][members[i]])\\n count += 1;\\n }\\n return count;\\n }\\n\\n\\tfunction hasVoted(bytes32 transactionId) external view returns(bool) {\\n\\t\\treturn votes[transactionId][_msgSender()];\\n\\t}\\n\\n\\tfunction transactionWasProcessed(bytes32 transactionId) external view returns(bool) {\\n\\t\\treturn processed[transactionId];\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Gets the hash of transaction from the following parameters encoded and keccaked\\n\\t\\t@dev It encodes and applies keccak256 to the parameters received in the same order\\n\\t\\t@param originalTokenAddress The address of the token in the origin (main) chain\\n\\t\\t@param sender The address who solicited the cross token\\n\\t\\t@param receiver Who is going to receive the token in the opposite chain\\n\\t\\t@param amount Could be the amount or the tokenId\\n\\t\\t@param blockHash The block hash in which the transaction with the cross event occurred\\n\\t\\t@param transactionHash The transaction in which the cross event occurred\\n\\t\\t@param logIndex Index of the event in the logs\\n\\t\\t@param originChainId Is chainId of the original chain\\n\\t\\t@param destinationChainId Is chainId of the destination chain\\n\\t\\t@return The hash generated by the parameters.\\n\\t*/\\n\\tfunction getTransactionId(\\n\\t\\taddress originalTokenAddress,\\n\\t\\taddress sender,\\n\\t\\taddress receiver,\\n\\t\\tuint256 amount,\\n\\t\\tbytes32 blockHash,\\n\\t\\tbytes32 transactionHash,\\n\\t\\tuint32 logIndex,\\n\\t\\tuint256 originChainId,\\n\\t\\tuint256\\tdestinationChainId\\n\\t) public pure returns(bytes32) {\\n\\t\\treturn keccak256(\\n\\t\\t\\tabi.encodePacked(\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tamount,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\tlogIndex,\\n\\t\\t\\t\\toriginChainId,\\n\\t\\t\\t\\tdestinationChainId\\n\\t\\t\\t)\\n\\t\\t);\\n\\t}\\n\\n\\tfunction addMember(address _newMember) external onlyOwner override {\\n\\t\\trequire(_newMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\n\\t\\trequire(!isMember[_newMember], \\\"Federation: Member already exists\\\");\\n\\t\\trequire(members.length < MAX_MEMBER_COUNT, \\\"Federation: Max members reached\\\");\\n\\n\\t\\tisMember[_newMember] = true;\\n\\t\\tmembers.push(_newMember);\\n\\t\\temit MemberAddition(_newMember);\\n\\t}\\n\\n\\tfunction removeMember(address _oldMember) external onlyOwner override {\\n\\t\\trequire(_oldMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\n\\t\\trequire(isMember[_oldMember], \\\"Federation: Member doesn't exists\\\");\\n\\t\\trequire(members.length > 1, \\\"Federation: Can't remove all the members\\\");\\n\\t\\trequire(members.length - 1 >= required, \\\"Federation: Can't have less than required members\\\");\\n\\n\\t\\tisMember[_oldMember] = false;\\n\\t\\tfor (uint i = 0; i < members.length - 1; i++) {\\n\\t\\t\\tif (members[i] == _oldMember) {\\n\\t\\t\\t\\tmembers[i] = members[members.length - 1];\\n\\t\\t\\t\\tbreak;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\tmembers.pop(); // remove an element from the end of the array.\\n\\t\\temit MemberRemoval(_oldMember);\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Return all the current members of the federation\\n\\t\\t@return Current members\\n\\t\\t*/\\n\\tfunction getMembers() external view override returns (address[] memory) {\\n\\t\\treturn members;\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Changes the number of required members to vote and approve an transaction\\n\\t\\t@dev Emits the RequirementChange event\\n\\t\\t@param _required the number of minimum members to approve an transaction, it has to be bigger than 1\\n\\t\\t*/\\n\\tfunction changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\\n\\t\\trequire(_required >= 2, \\\"Federation: Requires at least 2\\\");\\n\\t\\trequired = _required;\\n\\t\\temit RequirementChange(_required);\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice It emits an HeartBeat like an health check\\n\\t\\t@dev Emits HeartBeat event\\n\\t\\t*/\\n\\tfunction emitHeartbeat(\\n\\t\\tstring calldata fedVersion,\\n\\t\\tuint256[] calldata fedChainsIds,\\n\\t\\tuint256[] calldata fedChainsBlocks,\\n\\t\\tstring[] calldata fedChainsInfo\\n\\t) external onlyMember override {\\n\\t\\trequire(fedChainsIds.length == fedChainsBlocks.length &&\\n\\t\\t\\tfedChainsIds.length == fedChainsInfo.length, \\\"Federation: Length missmatch\\\");\\n\\t\\temit HeartBeat(\\n\\t\\t\\t_msgSender(),\\n\\t\\t\\tblock.chainid,\\n\\t\\t\\tblock.number,\\n\\t\\t\\tfedVersion,\\n\\t\\t\\tfedChainsIds,\\n\\t\\t\\tfedChainsBlocks,\\n\\t\\t\\tfedChainsInfo\\n\\t\\t);\\n\\t}\\n}\\n\",\"keccak256\":\"0x54d6ded45858d8c9175b8e77414e22e8a63298769ce5717974444055bfc8a218\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\ninterface IBridge {\\n\\n\\tstruct ClaimData {\\n\\t\\taddress payable to;\\n\\t\\tuint256 amount;\\n\\t\\tbytes32 blockHash;\\n\\t\\tbytes32 transactionHash;\\n\\t\\tuint32 logIndex;\\n\\t\\tuint256 originChainId;\\n\\t}\\n\\n\\tstruct OriginalToken {\\n\\t\\taddress tokenAddress;\\n\\t\\tuint256 originChainId;\\n\\t}\\n\\n\\tfunction version() external pure returns (string memory);\\n\\n\\tfunction getFeePercentage() external view returns(uint);\\n\\n\\t/**\\n\\t\\t* ERC-20 tokens approve and transferFrom pattern\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\n\\t\\t*/\\n\\tfunction receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;\\n\\n\\t/**\\n\\t\\t* Use network currency and cross it.\\n\\t\\t*/\\n\\tfunction depositTo(uint256 chainId, address to) external payable;\\n\\n\\t/**\\n\\t\\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\n\\t\\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\\n\\t\\t* const userData = web3.eth.abi.encodeParameters(\\n * [\\\"address\\\", \\\"uint256\\\"],\\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\\n * );\\n\\t\\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\\n\\t\\t* const userData = web3.eth.abi.encodeParameters([\\\"uint256\\\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\\n\\t\\t*/\\n\\tfunction tokensReceived (\\n\\t\\taddress operator,\\n\\t\\taddress from,\\n\\t\\taddress to,\\n\\t\\tuint amount,\\n\\t\\tbytes calldata userData,\\n\\t\\tbytes calldata operatorData\\n\\t) external;\\n\\n\\t/**\\n\\t\\t* Accepts the transaction from the other chain that was voted and sent by the Federation contract\\n\\t\\t*/\\n\\tfunction acceptTransfer(\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _from,\\n\\t\\taddress payable _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t) external;\\n\\n\\t/**\\n\\t\\t* Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\n\\t\\t*/\\n\\tfunction claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n\\tfunction claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n\\tfunction claimGasless(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _deadline,\\n\\t\\tuint8 _v,\\n\\t\\tbytes32 _r,\\n\\t\\tbytes32 _s\\n\\t) external returns (uint256 receivedAmount);\\n\\n\\tfunction createSideToken(\\n\\t\\tuint256 _typeId,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\tuint8 _originalTokenDecimals,\\n\\t\\tstring calldata _originalTokenSymbol,\\n\\t\\tstring calldata _originalTokenName,\\n\\t\\tuint256 _chainId\\n\\t) external;\\n\\n\\tfunction getTransactionDataHash(\\n\\t\\taddress _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256 _destinationChainId\\n\\t) external returns(bytes32);\\n\\n\\tevent Cross(\\n\\t\\taddress indexed _tokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\tuint256 indexed _destinationChainId,\\n\\t\\taddress _from,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes _userData\\n\\t);\\n\\n\\tevent NewSideToken(\\n\\t\\taddress indexed _newSideTokenAddress,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\tstring _newSymbol,\\n\\t\\tuint256 _granularity,\\n\\t\\tuint256 _chainId\\n\\t);\\n\\tevent AcceptedCrossTransfer(\\n\\t\\tbytes32 indexed _transactionHash,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\taddress _from,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tuint256 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t);\\n\\tevent FeePercentageChanged(uint256 _amount);\\n\\tevent Claimed(\\n\\t\\tbytes32 indexed _transactionHash,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\taddress _sender,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tuint256 _logIndex,\\n\\t\\taddress _reciever,\\n\\t\\taddress _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _destinationChainId,\\n\\t\\tuint256 _originChainId\\n\\t);\\n}\",\"keccak256\":\"0x6731a952e7419e95412fd97c9f34ef403a2c16d2cf5cb1bbab4374fa6d41ff0f\",\"license\":\"MIT\"},\"contracts/interface/IFederation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\ninterface IFederation {\\n enum TokenType{ COIN, NFT }\\n\\n /**\\n @notice Current version of the contract\\n @return version in v{Number}\\n */\\n function version() external pure returns (string memory);\\n\\n /**\\n @notice Sets a new bridge contract\\n @param _bridge the new bridge contract address that should implement the IBridge interface\\n */\\n function setBridge(address _bridge) external;\\n\\n /**\\n @notice Sets a new NFT bridge contract\\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\\n */\\n function setNFTBridge(address _bridgeNFT) external;\\n\\n /**\\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\\n @param originalTokenAddress The address of the token in the origin (main) chain\\n @param sender The address who solicited the cross token\\n @param receiver Who is going to receive the token in the opposite chain\\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\\n @param blockHash The block hash in which the transaction with the cross event occurred\\n @param transactionHash The transaction in which the cross event occurred\\n @param logIndex Index of the event in the logs\\n @param tokenType Is the type of bridge to be used\\n\\t\\t@param originChainId Is chainId of the original chain\\n\\t\\t@param destinationChainId Is chainId of the destination chain\\n */\\n function voteTransaction(\\n address originalTokenAddress,\\n address payable sender,\\n address payable receiver,\\n uint256 value,\\n bytes32 blockHash,\\n bytes32 transactionHash,\\n uint32 logIndex,\\n TokenType tokenType,\\n\\t uint256 originChainId,\\n\\t uint256\\tdestinationChainId\\n ) external;\\n\\n /**\\n @notice Add a new member to the federation\\n @param _newMember address of the new member\\n */\\n function addMember(address _newMember) external;\\n\\n /**\\n @notice Remove a member of the federation\\n @param _oldMember address of the member to be removed from federation\\n */\\n function removeMember(address _oldMember) external;\\n\\n /**\\n @notice Return all the current members of the federation\\n @return Current members\\n */\\n function getMembers() external view returns (address[] memory);\\n\\n /**\\n @notice Changes the number of required members to vote and approve an transaction\\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\\n */\\n function changeRequirement(uint _required) external;\\n\\n /**\\n @notice It emmits an HeartBeat like an healthy check\\n */\\n function emitHeartbeat(\\n string calldata federatorVersion,\\n\\t\\tuint256[] calldata fedChainsIds,\\n\\t\\tuint256[] calldata fedChainsBlocks,\\n\\t\\tstring[] calldata fedChainsInfo\\n ) external;\\n\\n event Executed(\\n address indexed federator,\\n bytes32 indexed transactionHash,\\n bytes32 indexed transactionId,\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n uint32 logIndex,\\n\\t\\tuint256 originChainId,\\n\\t\\tuint256\\tdestinationChainId\\n );\\n event MemberAddition(address indexed member);\\n event MemberRemoval(address indexed member);\\n event RequirementChange(uint required);\\n event BridgeChanged(address bridge);\\n event NFTBridgeChanged(address bridgeNFT);\\n event Voted(\\n address indexed federator,\\n bytes32 indexed transactionHash,\\n bytes32 indexed transactionId,\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n uint32 logIndex,\\n uint256 originChainId,\\n\\t\\tuint256\\tdestinationChainId\\n );\\n event HeartBeat(\\n address indexed sender,\\n uint256 currentChainId,\\n uint256 currentBlock,\\n string fedVersion,\\n uint256[] fedChainsIds,\\n\\t\\tuint256[] fedChainsBlocks,\\n\\t\\tstring[] fedChainsInfo\\n );\\n\\n}\\n\",\"keccak256\":\"0x085d1c40b0845283f29ea8dd32c112caba92baacbc9fb1a2989b6cf48e772f3d\",\"license\":\"MIT\"},\"contracts/nftbridge/INFTBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\ninterface INFTBridge {\\n\\n struct NFTClaimData {\\n address payable to;\\n address from;\\n uint256 tokenId;\\n address tokenAddress;\\n bytes32 blockHash;\\n bytes32 transactionHash;\\n uint32 logIndex;\\n uint256 originChainId;\\n }\\n\\n\\tstruct OriginalNft {\\n\\t\\taddress nftAddress;\\n\\t\\tuint256 originChainId;\\n\\t}\\n\\n function version() external pure returns (string memory);\\n\\n function getFixedFee() external view returns (uint256);\\n\\n function receiveTokensTo(\\n address tokenAddress,\\n address to,\\n uint256 tokenId,\\n uint256 destinationChainId\\n ) external payable;\\n\\n /**\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\n */\\n function acceptTransfer(\\n address _originalTokenAddress,\\n address payable _from,\\n address payable _to,\\n uint256 _tokenId,\\n bytes32 _blockHash,\\n bytes32 _transactionHash,\\n uint32 _logIndex,\\n uint256 _originChainId,\\n\\t uint256\\t_destinationChainId\\n ) external;\\n\\n /**\\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\\n */\\n function claim(NFTClaimData calldata _claimData) external;\\n\\n function claimFallback(NFTClaimData calldata _claimData) external;\\n\\n function getTransactionDataHash(\\n address _to,\\n address _from,\\n uint256 _tokenId,\\n address _tokenAddress,\\n bytes32 _blockHash,\\n bytes32 _transactionHash,\\n uint32 _logIndex,\\n uint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n ) external returns (bytes32);\\n\\n event Cross(\\n address indexed _originalTokenAddress,\\n address indexed _to,\\n uint256 indexed _destinationChainId,\\n address _from,\\n uint256 _originChainId,\\n address _tokenCreator,\\n uint256 _totalSupply,\\n uint256 _tokenId,\\n string _tokenURI,\\n bytes _userData\\n );\\n\\n event NewSideNFTToken(\\n address indexed _newSideNFTTokenAddress,\\n address indexed _originalTokenAddress,\\n string _newSymbol,\\n uint256 originChainId\\n );\\n event AcceptedNFTCrossTransfer(\\n bytes32 indexed _transactionHash,\\n address indexed _originalTokenAddress,\\n address indexed _to,\\n address _from,\\n uint256 _tokenId,\\n bytes32 _blockHash,\\n uint256 _logIndex,\\n uint256 _originChainId,\\n\\t uint256\\t_destinationChainId\\n );\\n event FixedFeeNFTChanged(uint256 _amount);\\n event ClaimedNFTToken(\\n bytes32 indexed _transactionHash,\\n address indexed _originalTokenAddress,\\n address indexed _to,\\n address _sender,\\n uint256 _tokenId,\\n bytes32 _blockHash,\\n uint256 _logIndex,\\n address _receiver,\\n uint256 _originChainId,\\n\\t uint256\\t_destinationChainId\\n );\\n}\\n\",\"keccak256\":\"0xf45f693122c7e5edf3620b4f7a372cba37d85f1ed196362baa7c65d081a02652\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return payable(msg.sender);\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x6f3f274a2270bfe073339370edfa2485e2d515a2656039937f6b972fae96d297\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\",\"keccak256\":\"0x14063a689bff5eecf0f36cb519feb575f60349ecf0d425ead5b931b77dd599d4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract UpgradableOwnable is Initializable, Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function initialize(address sender) public initializer {\\n _owner = sender;\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * > Note: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n\\n}\\n\",\"keccak256\":\"0xdf439a167ae82e7e3dd241ea0c831a1bb0329432ceb4fa889778d1f2d196ce00\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b5061224d806100206000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639dc8f9c811610104578063ba51a6df116100a2578063dc8452cd11610071578063dc8452cd1461044d578063e78cea9214610456578063ef1093a714610469578063f2fde38b1461047c57600080fd5b8063ba51a6df146103f1578063c1f0808a14610404578063c4d66de814610427578063ca6d56dc1461043a57600080fd5b8063a230c524116100de578063a230c52414610385578063a481d59b146103a8578063a8e12e4c146103bb578063a93585f0146103ce57600080fd5b80639dc8f9c81461034a5780639eab52531461035d578063a1fb4acb1461037257600080fd5b8063715018a6116101715780638da5cb5b1161014b5780638da5cb5b146102e55780638dd14802146102f65780638f32d59b146103095780639386775a1461031c57600080fd5b8063715018a6146102b757806379d9ee72146102bf5780637b6d343a146102d257600080fd5b80631b4613cb116101ad5780631b4613cb1461022457806354fd4d50146102525780635daf08ca14610276578063681fc921146102a157600080fd5b806309c69cfa146101d45780630b1ca49a146101fc5780631273835214610211575b600080fd5b6101e76101e2366004611a98565b61048f565b60405190151581526020015b60405180910390f35b61020f61020a366004611acf565b6104d9565b005b61020f61021f366004611b0c565b610817565b6101e7610232366004611bb1565b600090815260386020908152604080832033845290915290205460ff1690565b6040805180820182526002815261763360f01b602082015290516101f39190611bca565b610289610284366004611bb1565b610a59565b6040516001600160a01b0390911681526020016101f3565b6102a9603281565b6040519081526020016101f3565b61020f610a83565b61020f6102cd366004611c6b565b610af7565b6101e76102e0366004611a98565b610c09565b6033546001600160a01b0316610289565b61020f610304366004611acf565b610c38565b6033546001600160a01b031633146101e7565b6101e761032a366004611d5a565b603860209081526000928352604080842090915290825290205460ff1681565b6102a9610358366004611d8a565b610c6e565b610365610cfb565b6040516101f39190611e15565b6102a9610380366004611bb1565b610d5d565b6101e7610393366004611acf565b60376020526000908152604090205460ff1681565b61020f6103b6366004611acf565b610de5565b61020f6103c9366004611e62565b610e6e565b6101e76103dc366004611bb1565b60009081526039602052604090205460ff1690565b61020f6103ff366004611bb1565b61119b565b6101e7610412366004611bb1565b60396020526000908152604090205460ff1681565b61020f610435366004611acf565b6112bd565b61020f610448366004611acf565b611373565b6102a960365481565b603454610289906001600160a01b031681565b603a54610289906001600160a01b031681565b61020f61048a366004611acf565b61153f565b600081815260386020908152604080832033845290915281205460ff16806104d05750600083815260386020908152604080832033845290915290205460ff165b90505b92915050565b6033546001600160a01b0316331461050c5760405162461bcd60e51b815260040161050390611ee7565b60405180910390fd5b6001600160a01b03811661055d5760405162461bcd60e51b81526020600482015260186024820152772332b232b930ba34b7b71d1022b6b83a3c9036b2b6b132b960411b6044820152606401610503565b6001600160a01b03811660009081526037602052604090205460ff166105cf5760405162461bcd60e51b815260206004820152602160248201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746044820152607360f81b6064820152608401610503565b6035546001106106325760405162461bcd60e51b815260206004820152602860248201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604482015267206d656d6265727360c01b6064820152608401610503565b60365460355461064490600190611f32565b10156106ac5760405162461bcd60e51b815260206004820152603160248201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604482015270207265717569726564206d656d6265727360781b6064820152608401610503565b6001600160a01b0381166000908152603760205260408120805460ff191690555b6035546106dc90600190611f32565b8110156107ac57816001600160a01b03166035828154811061070057610700611f49565b6000918252602090912001546001600160a01b0316141561079a576035805461072b90600190611f32565b8154811061073b5761073b611f49565b600091825260209091200154603580546001600160a01b03909216918390811061076757610767611f49565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506107ac565b806107a481611f5f565b9150506106cd565b5060358054806107be576107be611f7a565b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b3360009081526037602052604090205460ff166108725760405162461bcd60e51b81526020600482015260196024820152782332b232b930ba34b7b71d102737ba102332b232b930ba37b960391b6044820152606401610503565b61087b81611572565b6040516bffffffffffffffffffffffff1960608c811b821660208401528b811b821660348401528a901b166048820152605c8101889052607c8101879052609c81018690526001600160e01b031960e086901b1660bc82015260009060c00160405160208183030381529060405280519060200120905060006109058c8c8c8c8c8c8c8b8b610c6e565b90506109118282610c09565b1561091d575050610a4d565b610927828261048f565b15610933575050610a4d565b6000818152603860205260408120600191336001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558087336001600160a01b03167fa7be469662a3e5b2343dce0cefce9d3e114875d7334d8d724d3838cf629c5b108f8f8f8f8f8e8d8d6040516109b6989796959493929190611f90565b60405180910390a46109c882826115c1565b15610a4a576000818152603960205260409020805460ff191660011790556109f88c8c8c8c8c8c8c8c8c8c6116e1565b8087336001600160a01b03167f0fe3e5a751f4df1a701ea5d318482623b6a6b59ece98cb64169279b44219355e8f8f8f8f8f8e8d8d604051610a41989796959493929190611f90565b60405180910390a45b50505b50505050505050505050565b60358181548110610a6957600080fd5b6000918252602090912001546001600160a01b0316905081565b6033546001600160a01b03163314610aad5760405162461bcd60e51b815260040161050390611ee7565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b3360009081526037602052604090205460ff16610b525760405162461bcd60e51b81526020600482015260196024820152782332b232b930ba34b7b71d102737ba102332b232b930ba37b960391b6044820152606401610503565b8483148015610b6057508481145b610bac5760405162461bcd60e51b815260206004820152601c60248201527f46656465726174696f6e3a204c656e677468206d6973736d61746368000000006044820152606401610503565b336001600160a01b03167f909659508bf1f4c0ad9b406809f943832e107af28b0b436d9b7d56d3993c77f146438b8b8b8b8b8b8b8b604051610bf79a9998979695949392919061203c565b60405180910390a25050505050505050565b60008181526039602052604081205460ff16806104d05750505060009081526039602052604090205460ff1690565b6033546001600160a01b03163314610c625760405162461bcd60e51b815260040161050390611ee7565b610c6b81611848565b50565b604080516bffffffffffffffffffffffff1960609b8c1b81166020808401919091529a8c1b8116603483015298909a1b90971660488a0152605c890195909552607c880193909352609c8701919091526001600160e01b031960e091821b1660bc87015260c086019190915280850191909152815180850390910181526101009093019052815191012090565b60606035805480602002602001604051908101604052809291908181526020018280548015610d5357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610d35575b5050505050905090565b600080805b603554811015610dde5760008481526038602052604081206035805491929184908110610d9157610d91611f49565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610dcc57610dc9600183612129565b91505b80610dd681611f5f565b915050610d62565b5092915050565b6033546001600160a01b03163314610e0f5760405162461bcd60e51b815260040161050390611ee7565b6001600160a01b038116610e655760405162461bcd60e51b815260206004820152601c60248201527f46656465726174696f6e3a20456d707479204e465420627269646765000000006044820152606401610503565b610c6b816118f3565b8484818111801590610e7f57508015155b8015610e8a57508115155b610ed65760405162461bcd60e51b815260206004820181905260248201527f46656465726174696f6e3a20496e76616c696420726571756972656d656e74736044820152606401610503565b600054610100900460ff1680610eef575060005460ff16155b610f0b5760405162461bcd60e51b815260040161050390612141565b600054610100900460ff16158015610f2d576000805461ffff19166101011790555b610f36856112bd565b6032881115610f875760405162461bcd60e51b815260206004820152601c60248201527f46656465726174696f6e3a20546f6f206d616e79206d656d62657273000000006044820152606401610503565b610f9360358a8a611a20565b5060005b8881101561113357603760008b8b84818110610fb557610fb5611f49565b9050602002016020810190610fca9190611acf565b6001600160a01b0316815260208101919091526040016000205460ff16158015611024575060008a8a8381811061100357611003611f49565b90506020020160208101906110189190611acf565b6001600160a01b031614155b6110705760405162461bcd60e51b815260206004820152601b60248201527f46656465726174696f6e3a20496e76616c6964206d656d6265727300000000006044820152606401610503565b6001603760008c8c8581811061108857611088611f49565b905060200201602081019061109d9190611acf565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558989828181106110d7576110d7611f49565b90506020020160208101906110ec9190611acf565b6001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a28061112b81611f5f565b915050610f97565b5060368790556040518781527fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9060200160405180910390a161117586611848565b61117e846118f3565b8015611190576000805461ff00191690555b505050505050505050565b6033546001600160a01b031633146111c55760405162461bcd60e51b815260040161050390611ee7565b603554818181118015906111d857508015155b80156111e357508115155b61122f5760405162461bcd60e51b815260206004820181905260248201527f46656465726174696f6e3a20496e76616c696420726571756972656d656e74736044820152606401610503565b60028310156112805760405162461bcd60e51b815260206004820152601f60248201527f46656465726174696f6e3a205265717569726573206174206c656173742032006044820152606401610503565b60368390556040518381527fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9060200160405180910390a1505050565b600054610100900460ff16806112d6575060005460ff16155b6112f25760405162461bcd60e51b815260040161050390612141565b600054610100900460ff16158015611314576000805461ffff19166101011790555b603380546001600160a01b0319166001600160a01b0384169081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3801561136f576000805461ff00191690555b5050565b6033546001600160a01b0316331461139d5760405162461bcd60e51b815260040161050390611ee7565b6001600160a01b0381166113ee5760405162461bcd60e51b81526020600482015260186024820152772332b232b930ba34b7b71d1022b6b83a3c9036b2b6b132b960411b6044820152606401610503565b6001600160a01b03811660009081526037602052604090205460ff16156114615760405162461bcd60e51b815260206004820152602160248201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746044820152607360f81b6064820152608401610503565b6035546032116114b35760405162461bcd60e51b815260206004820152601f60248201527f46656465726174696f6e3a204d6178206d656d626572732072656163686564006044820152606401610503565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b6033546001600160a01b031633146115695760405162461bcd60e51b815260040161050390611ee7565b610c6b81611941565b468114610c6b5760405162461bcd60e51b815260206004820152601d60248201527f46656465726174696f6e3a204e6f7420626c6f636b2e636861696e69640000006044820152606401610503565b6000806115cc6119fe565b90506000805b6035548110156116d5576000858152603860205260408120603580549192918490811061160157611601611f49565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff161561164057611639600183612129565b91506116a0565b6000868152603860205260408120603580549192918490811061166557611665611f49565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156116a05761169d600183612129565b91505b8282101580156116b257506036548210155b156116c357600193505050506104d3565b806116cd81611f5f565b9150506115d2565b50600095945050505050565b60018360018111156116f5576116f5612189565b14156117ca57603a546001600160a01b03166117535760405162461bcd60e51b815260206004820152601b60248201527f46656465726174696f6e3a20456d707479204e465442726964676500000000006044820152606401610503565b603a5460405163048aa97560e21b81526001600160a01b039091169063122aa5d490611793908d908d908d908d908d908d908d908c908c9060040161219f565b600060405180830381600087803b1580156117ad57600080fd5b505af11580156117c1573d6000803e3d6000fd5b50505050610a4d565b60345460405163048aa97560e21b81526001600160a01b039091169063122aa5d49061180a908d908d908d908d908d908d908d908c908c9060040161219f565b600060405180830381600087803b15801561182457600080fd5b505af1158015611838573d6000803e3d6000fd5b5050505050505050505050505050565b6001600160a01b03811661189e5760405162461bcd60e51b815260206004820152601860248201527f46656465726174696f6e3a20456d7074792062726964676500000000000000006044820152606401610503565b603480546001600160a01b0319166001600160a01b0383169081179091556040519081527f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b92551782794497906020015b60405180910390a150565b603a80546001600160a01b0319166001600160a01b0383169081179091556040519081527f41d363b5ede55d38b1fa8f7ba6188f9c20e353bc71e4a93de8938a20b27b6bc2906020016118e8565b6001600160a01b0381166119a25760405162461bcd60e51b815260206004820152602260248201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604482015261737360f01b6064820152608401610503565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b603554600090611a10906002906121f5565b611a1b906001612129565b905090565b828054828255906000526020600020908101928215611a73579160200282015b82811115611a735781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190611a40565b50611a7f929150611a83565b5090565b5b80821115611a7f5760008155600101611a84565b60008060408385031215611aab57600080fd5b50508035926020909101359150565b6001600160a01b0381168114610c6b57600080fd5b600060208284031215611ae157600080fd5b8135611aec81611aba565b9392505050565b803563ffffffff81168114611b0757600080fd5b919050565b6000806000806000806000806000806101408b8d031215611b2c57600080fd5b8a35611b3781611aba565b995060208b0135611b4781611aba565b985060408b0135611b5781611aba565b975060608b0135965060808b0135955060a08b01359450611b7a60c08c01611af3565b935060e08b013560028110611b8e57600080fd5b809350506101008b013591506101208b013590509295989b9194979a5092959850565b600060208284031215611bc357600080fd5b5035919050565b600060208083528351808285015260005b81811015611bf757858101830151858201604001528201611bdb565b81811115611c09576000604083870101525b50601f01601f1916929092016040019392505050565b60008083601f840112611c3157600080fd5b50813567ffffffffffffffff811115611c4957600080fd5b6020830191508360208260051b8501011115611c6457600080fd5b9250929050565b6000806000806000806000806080898b031215611c8757600080fd5b883567ffffffffffffffff80821115611c9f57600080fd5b818b0191508b601f830112611cb357600080fd5b813581811115611cc257600080fd5b8c6020828501011115611cd457600080fd5b60209283019a509850908a01359080821115611cef57600080fd5b611cfb8c838d01611c1f565b909850965060408b0135915080821115611d1457600080fd5b611d208c838d01611c1f565b909650945060608b0135915080821115611d3957600080fd5b50611d468b828c01611c1f565b999c989b5096995094979396929594505050565b60008060408385031215611d6d57600080fd5b823591506020830135611d7f81611aba565b809150509250929050565b60008060008060008060008060006101208a8c031215611da957600080fd5b8935611db481611aba565b985060208a0135611dc481611aba565b975060408a0135611dd481611aba565b965060608a0135955060808a0135945060a08a01359350611df760c08b01611af3565b925060e08a013591506101008a013590509295985092959850929598565b6020808252825182820181905260009190848201906040850190845b81811015611e565783516001600160a01b031683529284019291840191600101611e31565b50909695505050505050565b60008060008060008060a08789031215611e7b57600080fd5b863567ffffffffffffffff811115611e9257600080fd5b611e9e89828a01611c1f565b909750955050602087013593506040870135611eb981611aba565b92506060870135611ec981611aba565b91506080870135611ed981611aba565b809150509295509295509295565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082821015611f4457611f44611f1c565b500390565b634e487b7160e01b600052603260045260246000fd5b6000600019821415611f7357611f73611f1c565b5060010190565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b03988916815296881660208801529490961660408601526060850192909252608084015263ffffffff1660a083015260c082019290925260e08101919091526101000190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b81835260006001600160fb1b0383111561201f57600080fd5b8260051b8083602087013760009401602001938452509192915050565b8a8152600060208b8184015260c0604084015261205d60c084018b8d611fdd565b8381036060850152612070818a8c612006565b9050838103608085015261208581888a612006565b84810360a08601528581529050818101600586901b820183018760005b8881101561211157848303601f190184528135368b9003601e190181126120c857600080fd5b8a01803567ffffffffffffffff8111156120e157600080fd5b8036038c13156120f057600080fd5b6120fd85828a8501611fdd565b9588019594505050908501906001016120a2565b5050809450505050509b9a5050505050505050505050565b6000821982111561213c5761213c611f1c565b500190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b03998a16815297891660208901529590971660408701526060860193909352608085019190915260a084015263ffffffff1660c083015260e08201929092526101008101919091526101200190565b60008261221257634e487b7160e01b600052601260045260246000fd5b50049056fea26469706673582212205e6773f4f800299832aea5d8c74b303a6befad8d693c67bb9a52e7657b7db69864736f6c63430008090033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639dc8f9c811610104578063ba51a6df116100a2578063dc8452cd11610071578063dc8452cd1461044d578063e78cea9214610456578063ef1093a714610469578063f2fde38b1461047c57600080fd5b8063ba51a6df146103f1578063c1f0808a14610404578063c4d66de814610427578063ca6d56dc1461043a57600080fd5b8063a230c524116100de578063a230c52414610385578063a481d59b146103a8578063a8e12e4c146103bb578063a93585f0146103ce57600080fd5b80639dc8f9c81461034a5780639eab52531461035d578063a1fb4acb1461037257600080fd5b8063715018a6116101715780638da5cb5b1161014b5780638da5cb5b146102e55780638dd14802146102f65780638f32d59b146103095780639386775a1461031c57600080fd5b8063715018a6146102b757806379d9ee72146102bf5780637b6d343a146102d257600080fd5b80631b4613cb116101ad5780631b4613cb1461022457806354fd4d50146102525780635daf08ca14610276578063681fc921146102a157600080fd5b806309c69cfa146101d45780630b1ca49a146101fc5780631273835214610211575b600080fd5b6101e76101e2366004611a98565b61048f565b60405190151581526020015b60405180910390f35b61020f61020a366004611acf565b6104d9565b005b61020f61021f366004611b0c565b610817565b6101e7610232366004611bb1565b600090815260386020908152604080832033845290915290205460ff1690565b6040805180820182526002815261763360f01b602082015290516101f39190611bca565b610289610284366004611bb1565b610a59565b6040516001600160a01b0390911681526020016101f3565b6102a9603281565b6040519081526020016101f3565b61020f610a83565b61020f6102cd366004611c6b565b610af7565b6101e76102e0366004611a98565b610c09565b6033546001600160a01b0316610289565b61020f610304366004611acf565b610c38565b6033546001600160a01b031633146101e7565b6101e761032a366004611d5a565b603860209081526000928352604080842090915290825290205460ff1681565b6102a9610358366004611d8a565b610c6e565b610365610cfb565b6040516101f39190611e15565b6102a9610380366004611bb1565b610d5d565b6101e7610393366004611acf565b60376020526000908152604090205460ff1681565b61020f6103b6366004611acf565b610de5565b61020f6103c9366004611e62565b610e6e565b6101e76103dc366004611bb1565b60009081526039602052604090205460ff1690565b61020f6103ff366004611bb1565b61119b565b6101e7610412366004611bb1565b60396020526000908152604090205460ff1681565b61020f610435366004611acf565b6112bd565b61020f610448366004611acf565b611373565b6102a960365481565b603454610289906001600160a01b031681565b603a54610289906001600160a01b031681565b61020f61048a366004611acf565b61153f565b600081815260386020908152604080832033845290915281205460ff16806104d05750600083815260386020908152604080832033845290915290205460ff165b90505b92915050565b6033546001600160a01b0316331461050c5760405162461bcd60e51b815260040161050390611ee7565b60405180910390fd5b6001600160a01b03811661055d5760405162461bcd60e51b81526020600482015260186024820152772332b232b930ba34b7b71d1022b6b83a3c9036b2b6b132b960411b6044820152606401610503565b6001600160a01b03811660009081526037602052604090205460ff166105cf5760405162461bcd60e51b815260206004820152602160248201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746044820152607360f81b6064820152608401610503565b6035546001106106325760405162461bcd60e51b815260206004820152602860248201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604482015267206d656d6265727360c01b6064820152608401610503565b60365460355461064490600190611f32565b10156106ac5760405162461bcd60e51b815260206004820152603160248201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604482015270207265717569726564206d656d6265727360781b6064820152608401610503565b6001600160a01b0381166000908152603760205260408120805460ff191690555b6035546106dc90600190611f32565b8110156107ac57816001600160a01b03166035828154811061070057610700611f49565b6000918252602090912001546001600160a01b0316141561079a576035805461072b90600190611f32565b8154811061073b5761073b611f49565b600091825260209091200154603580546001600160a01b03909216918390811061076757610767611f49565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506107ac565b806107a481611f5f565b9150506106cd565b5060358054806107be576107be611f7a565b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b3360009081526037602052604090205460ff166108725760405162461bcd60e51b81526020600482015260196024820152782332b232b930ba34b7b71d102737ba102332b232b930ba37b960391b6044820152606401610503565b61087b81611572565b6040516bffffffffffffffffffffffff1960608c811b821660208401528b811b821660348401528a901b166048820152605c8101889052607c8101879052609c81018690526001600160e01b031960e086901b1660bc82015260009060c00160405160208183030381529060405280519060200120905060006109058c8c8c8c8c8c8c8b8b610c6e565b90506109118282610c09565b1561091d575050610a4d565b610927828261048f565b15610933575050610a4d565b6000818152603860205260408120600191336001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558087336001600160a01b03167fa7be469662a3e5b2343dce0cefce9d3e114875d7334d8d724d3838cf629c5b108f8f8f8f8f8e8d8d6040516109b6989796959493929190611f90565b60405180910390a46109c882826115c1565b15610a4a576000818152603960205260409020805460ff191660011790556109f88c8c8c8c8c8c8c8c8c8c6116e1565b8087336001600160a01b03167f0fe3e5a751f4df1a701ea5d318482623b6a6b59ece98cb64169279b44219355e8f8f8f8f8f8e8d8d604051610a41989796959493929190611f90565b60405180910390a45b50505b50505050505050505050565b60358181548110610a6957600080fd5b6000918252602090912001546001600160a01b0316905081565b6033546001600160a01b03163314610aad5760405162461bcd60e51b815260040161050390611ee7565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b3360009081526037602052604090205460ff16610b525760405162461bcd60e51b81526020600482015260196024820152782332b232b930ba34b7b71d102737ba102332b232b930ba37b960391b6044820152606401610503565b8483148015610b6057508481145b610bac5760405162461bcd60e51b815260206004820152601c60248201527f46656465726174696f6e3a204c656e677468206d6973736d61746368000000006044820152606401610503565b336001600160a01b03167f909659508bf1f4c0ad9b406809f943832e107af28b0b436d9b7d56d3993c77f146438b8b8b8b8b8b8b8b604051610bf79a9998979695949392919061203c565b60405180910390a25050505050505050565b60008181526039602052604081205460ff16806104d05750505060009081526039602052604090205460ff1690565b6033546001600160a01b03163314610c625760405162461bcd60e51b815260040161050390611ee7565b610c6b81611848565b50565b604080516bffffffffffffffffffffffff1960609b8c1b81166020808401919091529a8c1b8116603483015298909a1b90971660488a0152605c890195909552607c880193909352609c8701919091526001600160e01b031960e091821b1660bc87015260c086019190915280850191909152815180850390910181526101009093019052815191012090565b60606035805480602002602001604051908101604052809291908181526020018280548015610d5357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610d35575b5050505050905090565b600080805b603554811015610dde5760008481526038602052604081206035805491929184908110610d9157610d91611f49565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610dcc57610dc9600183612129565b91505b80610dd681611f5f565b915050610d62565b5092915050565b6033546001600160a01b03163314610e0f5760405162461bcd60e51b815260040161050390611ee7565b6001600160a01b038116610e655760405162461bcd60e51b815260206004820152601c60248201527f46656465726174696f6e3a20456d707479204e465420627269646765000000006044820152606401610503565b610c6b816118f3565b8484818111801590610e7f57508015155b8015610e8a57508115155b610ed65760405162461bcd60e51b815260206004820181905260248201527f46656465726174696f6e3a20496e76616c696420726571756972656d656e74736044820152606401610503565b600054610100900460ff1680610eef575060005460ff16155b610f0b5760405162461bcd60e51b815260040161050390612141565b600054610100900460ff16158015610f2d576000805461ffff19166101011790555b610f36856112bd565b6032881115610f875760405162461bcd60e51b815260206004820152601c60248201527f46656465726174696f6e3a20546f6f206d616e79206d656d62657273000000006044820152606401610503565b610f9360358a8a611a20565b5060005b8881101561113357603760008b8b84818110610fb557610fb5611f49565b9050602002016020810190610fca9190611acf565b6001600160a01b0316815260208101919091526040016000205460ff16158015611024575060008a8a8381811061100357611003611f49565b90506020020160208101906110189190611acf565b6001600160a01b031614155b6110705760405162461bcd60e51b815260206004820152601b60248201527f46656465726174696f6e3a20496e76616c6964206d656d6265727300000000006044820152606401610503565b6001603760008c8c8581811061108857611088611f49565b905060200201602081019061109d9190611acf565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558989828181106110d7576110d7611f49565b90506020020160208101906110ec9190611acf565b6001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a28061112b81611f5f565b915050610f97565b5060368790556040518781527fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9060200160405180910390a161117586611848565b61117e846118f3565b8015611190576000805461ff00191690555b505050505050505050565b6033546001600160a01b031633146111c55760405162461bcd60e51b815260040161050390611ee7565b603554818181118015906111d857508015155b80156111e357508115155b61122f5760405162461bcd60e51b815260206004820181905260248201527f46656465726174696f6e3a20496e76616c696420726571756972656d656e74736044820152606401610503565b60028310156112805760405162461bcd60e51b815260206004820152601f60248201527f46656465726174696f6e3a205265717569726573206174206c656173742032006044820152606401610503565b60368390556040518381527fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9060200160405180910390a1505050565b600054610100900460ff16806112d6575060005460ff16155b6112f25760405162461bcd60e51b815260040161050390612141565b600054610100900460ff16158015611314576000805461ffff19166101011790555b603380546001600160a01b0319166001600160a01b0384169081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3801561136f576000805461ff00191690555b5050565b6033546001600160a01b0316331461139d5760405162461bcd60e51b815260040161050390611ee7565b6001600160a01b0381166113ee5760405162461bcd60e51b81526020600482015260186024820152772332b232b930ba34b7b71d1022b6b83a3c9036b2b6b132b960411b6044820152606401610503565b6001600160a01b03811660009081526037602052604090205460ff16156114615760405162461bcd60e51b815260206004820152602160248201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746044820152607360f81b6064820152608401610503565b6035546032116114b35760405162461bcd60e51b815260206004820152601f60248201527f46656465726174696f6e3a204d6178206d656d626572732072656163686564006044820152606401610503565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b6033546001600160a01b031633146115695760405162461bcd60e51b815260040161050390611ee7565b610c6b81611941565b468114610c6b5760405162461bcd60e51b815260206004820152601d60248201527f46656465726174696f6e3a204e6f7420626c6f636b2e636861696e69640000006044820152606401610503565b6000806115cc6119fe565b90506000805b6035548110156116d5576000858152603860205260408120603580549192918490811061160157611601611f49565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff161561164057611639600183612129565b91506116a0565b6000868152603860205260408120603580549192918490811061166557611665611f49565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156116a05761169d600183612129565b91505b8282101580156116b257506036548210155b156116c357600193505050506104d3565b806116cd81611f5f565b9150506115d2565b50600095945050505050565b60018360018111156116f5576116f5612189565b14156117ca57603a546001600160a01b03166117535760405162461bcd60e51b815260206004820152601b60248201527f46656465726174696f6e3a20456d707479204e465442726964676500000000006044820152606401610503565b603a5460405163048aa97560e21b81526001600160a01b039091169063122aa5d490611793908d908d908d908d908d908d908d908c908c9060040161219f565b600060405180830381600087803b1580156117ad57600080fd5b505af11580156117c1573d6000803e3d6000fd5b50505050610a4d565b60345460405163048aa97560e21b81526001600160a01b039091169063122aa5d49061180a908d908d908d908d908d908d908d908c908c9060040161219f565b600060405180830381600087803b15801561182457600080fd5b505af1158015611838573d6000803e3d6000fd5b5050505050505050505050505050565b6001600160a01b03811661189e5760405162461bcd60e51b815260206004820152601860248201527f46656465726174696f6e3a20456d7074792062726964676500000000000000006044820152606401610503565b603480546001600160a01b0319166001600160a01b0383169081179091556040519081527f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b92551782794497906020015b60405180910390a150565b603a80546001600160a01b0319166001600160a01b0383169081179091556040519081527f41d363b5ede55d38b1fa8f7ba6188f9c20e353bc71e4a93de8938a20b27b6bc2906020016118e8565b6001600160a01b0381166119a25760405162461bcd60e51b815260206004820152602260248201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604482015261737360f01b6064820152608401610503565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b603554600090611a10906002906121f5565b611a1b906001612129565b905090565b828054828255906000526020600020908101928215611a73579160200282015b82811115611a735781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190611a40565b50611a7f929150611a83565b5090565b5b80821115611a7f5760008155600101611a84565b60008060408385031215611aab57600080fd5b50508035926020909101359150565b6001600160a01b0381168114610c6b57600080fd5b600060208284031215611ae157600080fd5b8135611aec81611aba565b9392505050565b803563ffffffff81168114611b0757600080fd5b919050565b6000806000806000806000806000806101408b8d031215611b2c57600080fd5b8a35611b3781611aba565b995060208b0135611b4781611aba565b985060408b0135611b5781611aba565b975060608b0135965060808b0135955060a08b01359450611b7a60c08c01611af3565b935060e08b013560028110611b8e57600080fd5b809350506101008b013591506101208b013590509295989b9194979a5092959850565b600060208284031215611bc357600080fd5b5035919050565b600060208083528351808285015260005b81811015611bf757858101830151858201604001528201611bdb565b81811115611c09576000604083870101525b50601f01601f1916929092016040019392505050565b60008083601f840112611c3157600080fd5b50813567ffffffffffffffff811115611c4957600080fd5b6020830191508360208260051b8501011115611c6457600080fd5b9250929050565b6000806000806000806000806080898b031215611c8757600080fd5b883567ffffffffffffffff80821115611c9f57600080fd5b818b0191508b601f830112611cb357600080fd5b813581811115611cc257600080fd5b8c6020828501011115611cd457600080fd5b60209283019a509850908a01359080821115611cef57600080fd5b611cfb8c838d01611c1f565b909850965060408b0135915080821115611d1457600080fd5b611d208c838d01611c1f565b909650945060608b0135915080821115611d3957600080fd5b50611d468b828c01611c1f565b999c989b5096995094979396929594505050565b60008060408385031215611d6d57600080fd5b823591506020830135611d7f81611aba565b809150509250929050565b60008060008060008060008060006101208a8c031215611da957600080fd5b8935611db481611aba565b985060208a0135611dc481611aba565b975060408a0135611dd481611aba565b965060608a0135955060808a0135945060a08a01359350611df760c08b01611af3565b925060e08a013591506101008a013590509295985092959850929598565b6020808252825182820181905260009190848201906040850190845b81811015611e565783516001600160a01b031683529284019291840191600101611e31565b50909695505050505050565b60008060008060008060a08789031215611e7b57600080fd5b863567ffffffffffffffff811115611e9257600080fd5b611e9e89828a01611c1f565b909750955050602087013593506040870135611eb981611aba565b92506060870135611ec981611aba565b91506080870135611ed981611aba565b809150509295509295509295565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082821015611f4457611f44611f1c565b500390565b634e487b7160e01b600052603260045260246000fd5b6000600019821415611f7357611f73611f1c565b5060010190565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b03988916815296881660208801529490961660408601526060850192909252608084015263ffffffff1660a083015260c082019290925260e08101919091526101000190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b81835260006001600160fb1b0383111561201f57600080fd5b8260051b8083602087013760009401602001938452509192915050565b8a8152600060208b8184015260c0604084015261205d60c084018b8d611fdd565b8381036060850152612070818a8c612006565b9050838103608085015261208581888a612006565b84810360a08601528581529050818101600586901b820183018760005b8881101561211157848303601f190184528135368b9003601e190181126120c857600080fd5b8a01803567ffffffffffffffff8111156120e157600080fd5b8036038c13156120f057600080fd5b6120fd85828a8501611fdd565b9588019594505050908501906001016120a2565b5050809450505050509b9a5050505050505050505050565b6000821982111561213c5761213c611f1c565b500190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b03998a16815297891660208901529590971660408701526060860193909352608085019190915260a084015263ffffffff1660c083015260e08201929092526101008101919091526101200190565b60008261221257634e487b7160e01b600052601260045260246000fd5b50049056fea26469706673582212205e6773f4f800299832aea5d8c74b303a6befad8d693c67bb9a52e7657b7db69864736f6c63430008090033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "addMember(address)": {
+ "params": {
+ "_newMember": "address of the new member"
+ }
+ },
+ "changeRequirement(uint256)": {
+ "details": "Emits the RequirementChange event",
+ "params": {
+ "_required": "the number of minimum members to approve an transaction, it has to be bigger than 1"
+ }
+ },
+ "emitHeartbeat(string,uint256[],uint256[],string[])": {
+ "details": "Emits HeartBeat event"
+ },
+ "getMembers()": {
+ "returns": {
+ "_0": "Current members"
+ }
+ },
+ "getTransactionCount(bytes32)": {
+ "params": {
+ "transactionId": "The transaction hashed from getTransactionId function"
+ }
+ },
+ "getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)": {
+ "details": "It encodes and applies keccak256 to the parameters received in the same order",
+ "params": {
+ "amount": "Could be the amount or the tokenId",
+ "blockHash": "The block hash in which the transaction with the cross event occurred",
+ "destinationChainId": "Is chainId of the destination chain",
+ "logIndex": "Index of the event in the logs",
+ "originChainId": "Is chainId of the original chain",
+ "originalTokenAddress": "The address of the token in the origin (main) chain",
+ "receiver": "Who is going to receive the token in the opposite chain",
+ "sender": "The address who solicited the cross token",
+ "transactionHash": "The transaction in which the cross event occurred"
+ },
+ "returns": {
+ "_0": "The hash generated by the parameters."
+ }
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "removeMember(address)": {
+ "params": {
+ "_oldMember": "address of the member to be removed from federation"
+ }
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "setBridge(address)": {
+ "details": "Emits BridgeChanged event",
+ "params": {
+ "_bridge": "the new bridge contract address that should implement the IBridge interface"
+ }
+ },
+ "setNFTBridge(address)": {
+ "details": "Emits NFTBridgeChanged event",
+ "params": {
+ "_bridgeNFT": "the new NFT bridge contract address that should implement the INFTBridge interface"
+ }
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "version()": {
+ "returns": {
+ "_0": "version in v{Number}"
+ }
+ },
+ "voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint8,uint256,uint256)": {
+ "params": {
+ "blockHash": "The block hash in which the transaction with the cross event occurred",
+ "destinationChainId": "Is chainId of the destination chain",
+ "logIndex": "Index of the event in the logs",
+ "originChainId": "Is chainId of the original chain",
+ "originalTokenAddress": "The address of the token in the origin (main) chain",
+ "receiver": "Who is going to receive the token in the opposite chain",
+ "sender": "The address who solicited the cross token",
+ "tokenType": "Is the type of bridge to be used",
+ "transactionHash": "The transaction in which the cross event occurred",
+ "value": "Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT"
+ }
+ }
+ },
+ "stateVariables": {
+ "isMember": {
+ "details": "The address should be a member to vote in transactions"
+ },
+ "required": {
+ "details": "It should have at least the required amount of members"
+ },
+ "votes": {
+ "details": "the members should approve the transaction by 50% + 1"
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "addMember(address)": {
+ "notice": "Add a new member to the federation"
+ },
+ "bridgeNFT()": {
+ "notice": "Federator v3 variables "
+ },
+ "changeRequirement(uint256)": {
+ "notice": "Changes the number of required members to vote and approve an transaction"
+ },
+ "emitHeartbeat(string,uint256[],uint256[],string[])": {
+ "notice": "It emits an HeartBeat like an health check"
+ },
+ "getMembers()": {
+ "notice": "Return all the current members of the federation"
+ },
+ "getTransactionCount(bytes32)": {
+ "notice": "Get the amount of approved votes for that transactionId"
+ },
+ "getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)": {
+ "notice": "Gets the hash of transaction from the following parameters encoded and keccaked"
+ },
+ "isMember(address)": {
+ "notice": "All the addresses that are members of the federation"
+ },
+ "processed(bytes32)": {
+ "notice": "(bytes32) transactionId => (bool) votedCheck if that transaction was already processed"
+ },
+ "removeMember(address)": {
+ "notice": "Remove a member of the federation"
+ },
+ "required()": {
+ "notice": "The minimum amount of votes to approve a transaction"
+ },
+ "setBridge(address)": {
+ "notice": "Sets a new bridge contract"
+ },
+ "setNFTBridge(address)": {
+ "notice": "Sets a new NFT bridge contract"
+ },
+ "version()": {
+ "notice": "Current version of the contract"
+ },
+ "voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint8,uint256,uint256)": {
+ "notice": "Vote in a transaction, if it has enough votes it accepts the transfer"
+ },
+ "votes(bytes32,address)": {
+ "notice": "(bytes32) transactionId = keccak256( abi.encodePacked( originalTokenAddress, sender, receiver, amount, blockHash, transactionHash, logIndex ) ) => ( (address) members => (bool) voted )Votes by members by the transaction ID"
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 16199,
+ "contract": "contracts/federation/Federation.sol:Federation",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16202,
+ "contract": "contracts/federation/Federation.sol:Federation",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16242,
+ "contract": "contracts/federation/Federation.sol:Federation",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16488,
+ "contract": "contracts/federation/Federation.sol:Federation",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 5448,
+ "contract": "contracts/federation/Federation.sol:Federation",
+ "label": "bridge",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_contract(IBridge)7426"
+ },
+ {
+ "astId": 5451,
+ "contract": "contracts/federation/Federation.sol:Federation",
+ "label": "members",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 5454,
+ "contract": "contracts/federation/Federation.sol:Federation",
+ "label": "required",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 5459,
+ "contract": "contracts/federation/Federation.sol:Federation",
+ "label": "isMember",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 5466,
+ "contract": "contracts/federation/Federation.sol:Federation",
+ "label": "votes",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_mapping(t_bytes32,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 5471,
+ "contract": "contracts/federation/Federation.sol:Federation",
+ "label": "processed",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ },
+ {
+ "astId": 5475,
+ "contract": "contracts/federation/Federation.sol:Federation",
+ "label": "bridgeNFT",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_contract(INFTBridge)8118"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IBridge)7426": {
+ "encoding": "inplace",
+ "label": "contract IBridge",
+ "numberOfBytes": "20"
+ },
+ "t_contract(INFTBridge)8118": {
+ "encoding": "inplace",
+ "label": "contract INFTBridge",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/bsctestnet/FederationProxy.json b/bridge/deployments/bsctestnet/FederationProxy.json
new file mode 100644
index 000000000..fe217c1c7
--- /dev/null
+++ b/bridge/deployments/bsctestnet/FederationProxy.json
@@ -0,0 +1,270 @@
+{
+ "address": "0xD40F8613173E636D570c47dB3A6Ac57EA9ccac83",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xe4499b5288b385cf591bb1c6fee9e1d80d0383f31708311d343740b695dc2c60",
+ "receipt": {
+ "to": null,
+ "from": "0x9C95B0EF2D3E1D9ca479524Ba738C87BE28C1585",
+ "contractAddress": "0xD40F8613173E636D570c47dB3A6Ac57EA9ccac83",
+ "transactionIndex": 4,
+ "gasUsed": "758610",
+ "logsBloom": "0x00000000000000000001000000000000000100000000000000800000000000000000000000000000000000000000000000000000400000000080000000000000000000800400000000000000008000100003000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000008000000000000000000000000000000000000000000000000000000000000004000000000000008000008000000000000000000000000040000000000000000000200000000000000000000000000000000020000010000004000000004000000000000100000000000000000800000000000001",
+ "blockHash": "0xa49054f630891917f65720011717632e346b62daefb75fdcb49c088569f93f73",
+ "transactionHash": "0xe4499b5288b385cf591bb1c6fee9e1d80d0383f31708311d343740b695dc2c60",
+ "logs": [
+ {
+ "transactionIndex": 4,
+ "blockNumber": 16645659,
+ "transactionHash": "0xe4499b5288b385cf591bb1c6fee9e1d80d0383f31708311d343740b695dc2c60",
+ "address": "0xD40F8613173E636D570c47dB3A6Ac57EA9ccac83",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000e3848f411587c2c8658a0d6f649e7f1e403873a6"
+ ],
+ "data": "0x",
+ "logIndex": 5,
+ "blockHash": "0xa49054f630891917f65720011717632e346b62daefb75fdcb49c088569f93f73"
+ },
+ {
+ "transactionIndex": 4,
+ "blockNumber": 16645659,
+ "transactionHash": "0xe4499b5288b385cf591bb1c6fee9e1d80d0383f31708311d343740b695dc2c60",
+ "address": "0xD40F8613173E636D570c47dB3A6Ac57EA9ccac83",
+ "topics": [
+ "0x72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c7",
+ "0x0000000000000000000000008f397ff074ff190fc650e5cab4da039a8163e12a"
+ ],
+ "data": "0x",
+ "logIndex": 6,
+ "blockHash": "0xa49054f630891917f65720011717632e346b62daefb75fdcb49c088569f93f73"
+ },
+ {
+ "transactionIndex": 4,
+ "blockNumber": 16645659,
+ "transactionHash": "0xe4499b5288b385cf591bb1c6fee9e1d80d0383f31708311d343740b695dc2c60",
+ "address": "0xD40F8613173E636D570c47dB3A6Ac57EA9ccac83",
+ "topics": [
+ "0xa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "logIndex": 7,
+ "blockHash": "0xa49054f630891917f65720011717632e346b62daefb75fdcb49c088569f93f73"
+ },
+ {
+ "transactionIndex": 4,
+ "blockNumber": 16645659,
+ "transactionHash": "0xe4499b5288b385cf591bb1c6fee9e1d80d0383f31708311d343740b695dc2c60",
+ "address": "0xD40F8613173E636D570c47dB3A6Ac57EA9ccac83",
+ "topics": [
+ "0x9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b92551782794497"
+ ],
+ "data": "0x000000000000000000000000d9d2f9ee990ddb1147e595ae4f69ec468a0b58d0",
+ "logIndex": 8,
+ "blockHash": "0xa49054f630891917f65720011717632e346b62daefb75fdcb49c088569f93f73"
+ },
+ {
+ "transactionIndex": 4,
+ "blockNumber": 16645659,
+ "transactionHash": "0xe4499b5288b385cf591bb1c6fee9e1d80d0383f31708311d343740b695dc2c60",
+ "address": "0xD40F8613173E636D570c47dB3A6Ac57EA9ccac83",
+ "topics": [
+ "0x41d363b5ede55d38b1fa8f7ba6188f9c20e353bc71e4a93de8938a20b27b6bc2"
+ ],
+ "data": "0x000000000000000000000000d9d2f9ee990ddb1147e595ae4f69ec468a0b58d0",
+ "logIndex": 9,
+ "blockHash": "0xa49054f630891917f65720011717632e346b62daefb75fdcb49c088569f93f73"
+ }
+ ],
+ "blockNumber": 16645659,
+ "cumulativeGasUsed": "1437530",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0x5D248F520b023acB815eDeCD5000B98ef84CbF1b",
+ "0x6C62BF5440De2Cb157205B15C424BCEb5C3368F5",
+ "0xa8e12e4c00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000d9d2f9ee990ddb1147e595ae4f69ec468a0b58d0000000000000000000000000e3848f411587c2c8658a0d6f649e7f1e403873a6000000000000000000000000d9d2f9ee990ddb1147e595ae4f69ec468a0b58d000000000000000000000000000000000000000000000000000000000000000010000000000000000000000008f397ff074ff190fc650e5cab4da039a8163e12a"
+ ],
+ "numDeployments": 1,
+ "solcInputHash": "f27c8e19ddc2cd2a95162a1eabc0e272",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"stateVariables\":{\"_ADMIN_SLOT\":{\"details\":\"Storage slot with the admin of the contract. This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0xdc0ebdc6f4ae0b5f9dd0a6c041a2238e4a7a2afbc6cef539437b0004ada42370\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x3327b21f85d71d3b9bad1a89267f08b19966e03446a18d810bd80fe42789ac5f\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb54322ec8ec142c149ad1f561aa2f0da6d6ea2d9f45639164088db9e16d5a69d\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x04801fc2398ee3370f3903f95389ea3a8da65a8df01f24b352e499e44d492e9b\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000d9138038062000d91833981016040819052620000269162000369565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd62000449565b60008051602062000d4a833981519152146200007557620000756200046f565b620000808262000112565b805115620000a1576200009f8282620001b360201b620003ba1760201c565b505b50620000d1905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610462000449565b60008051602062000d2a83398151915214620000f157620000f16200046f565b620001098260008051602062000d2a83398151915255565b505050620004d8565b6200012881620001e260201b620003e61760201c565b620001a05760405162461bcd60e51b815260206004820152603660248201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160448201527f74696f6e206973206e6f74206120636f6e74726163740000000000000000000060648201526084015b60405180910390fd5b60008051602062000d4a83398151915255565b6060620001db838360405180606001604052806027815260200162000d6a60279139620001e8565b9392505050565b3b151590565b6060833b620002495760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000197565b600080856001600160a01b03168560405162000266919062000485565b600060405180830381855af49150503d8060008114620002a3576040519150601f19603f3d011682016040523d82523d6000602084013e620002a8565b606091505b509092509050620002bb828286620002c5565b9695505050505050565b60608315620002d6575081620001db565b825115620002e75782518084602001fd5b8160405162461bcd60e51b8152600401620001979190620004a3565b80516001600160a01b03811681146200031b57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200035357818101518382015260200162000339565b8381111562000363576000848401525b50505050565b6000806000606084860312156200037f57600080fd5b6200038a8462000303565b92506200039a6020850162000303565b60408501519092506001600160401b0380821115620003b857600080fd5b818601915086601f830112620003cd57600080fd5b815181811115620003e257620003e262000320565b604051601f8201601f19908116603f011681019083821181831017156200040d576200040d62000320565b816040528281528960208487010111156200042757600080fd5b6200043a83602083016020880162000336565b80955050505050509250925092565b6000828210156200046a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b600082516200049981846020870162000336565b9190910192915050565b6020815260008251806020840152620004c481604085016020870162000336565b601f01601f19169190910160400192915050565b61084280620004e86000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ac565b610138565b61005b6100933660046106c7565b610175565b3480156100a457600080fd5b506100ad6101fa565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ac565b61025c565b3480156100f557600080fd5b506100ad610375565b6101066103ec565b6101366101317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b61048e565b565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b0316141561016d5761016a816104b2565b50565b61016a6100fe565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b031614156101ed576101a7836104b2565b6101e78383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ba92505050565b50505050565b6101f56100fe565b505050565b60006102126000805160206107c68339815191525490565b6001600160a01b0316336001600160a01b0316141561025157507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6102596100fe565b90565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b0316141561016d576001600160a01b0381166103065760405162461bcd60e51b815260206004820152603a60248201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760448201527f2061646d696e20697320746865207a65726f206164647265737300000000000060648201526084015b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61033d6000805160206107c68339815191525490565b604080516001600160a01b03928316815291841660208301520160405180910390a161016a816000805160206107c683398151915255565b600061038d6000805160206107c68339815191525490565b6001600160a01b0316336001600160a01b0316141561025157506000805160206107c68339815191525490565b60606103df83836040518060600160405280602781526020016107e6602791396104f2565b9392505050565b3b151590565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b031614156101365760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4016102fd565b3660008037600080366000845af43d6000803e8080156104ad573d6000f35b3d6000fd5b6104bb816105c6565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060833b6105515760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016102fd565b600080856001600160a01b03168560405161056c9190610776565b600060405180830381855af49150503d80600081146105a7576040519150601f19603f3d011682016040523d82523d6000602084013e6105ac565b606091505b50915091506105bc828286610657565b9695505050505050565b803b6106335760405162461bcd60e51b815260206004820152603660248201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616044820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b60648201526084016102fd565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156106665750816103df565b8251156106765782518084602001fd5b8160405162461bcd60e51b81526004016102fd9190610792565b80356001600160a01b03811681146106a757600080fd5b919050565b6000602082840312156106be57600080fd5b6103df82610690565b6000806000604084860312156106dc57600080fd5b6106e584610690565b9250602084013567ffffffffffffffff8082111561070257600080fd5b818601915086601f83011261071657600080fd5b81358181111561072557600080fd5b87602082850101111561073757600080fd5b6020830194508093505050509250925092565b60005b8381101561076557818101518382015260200161074d565b838111156101e75750506000910152565b6000825161078881846020870161074a565b9190910192915050565b60208152600082518060208401526107b181604085016020870161074a565b601f01601f1916919091016040019291505056feb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122001f23e5e5d70499e22926447138d9a73085390bf4c2f13e017a1d16843ca77ac64736f6c63430008090033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ac565b610138565b61005b6100933660046106c7565b610175565b3480156100a457600080fd5b506100ad6101fa565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ac565b61025c565b3480156100f557600080fd5b506100ad610375565b6101066103ec565b6101366101317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b61048e565b565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b0316141561016d5761016a816104b2565b50565b61016a6100fe565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b031614156101ed576101a7836104b2565b6101e78383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ba92505050565b50505050565b6101f56100fe565b505050565b60006102126000805160206107c68339815191525490565b6001600160a01b0316336001600160a01b0316141561025157507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6102596100fe565b90565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b0316141561016d576001600160a01b0381166103065760405162461bcd60e51b815260206004820152603a60248201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760448201527f2061646d696e20697320746865207a65726f206164647265737300000000000060648201526084015b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61033d6000805160206107c68339815191525490565b604080516001600160a01b03928316815291841660208301520160405180910390a161016a816000805160206107c683398151915255565b600061038d6000805160206107c68339815191525490565b6001600160a01b0316336001600160a01b0316141561025157506000805160206107c68339815191525490565b60606103df83836040518060600160405280602781526020016107e6602791396104f2565b9392505050565b3b151590565b6000805160206107c6833981519152546001600160a01b0316336001600160a01b031614156101365760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4016102fd565b3660008037600080366000845af43d6000803e8080156104ad573d6000f35b3d6000fd5b6104bb816105c6565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060833b6105515760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016102fd565b600080856001600160a01b03168560405161056c9190610776565b600060405180830381855af49150503d80600081146105a7576040519150601f19603f3d011682016040523d82523d6000602084013e6105ac565b606091505b50915091506105bc828286610657565b9695505050505050565b803b6106335760405162461bcd60e51b815260206004820152603660248201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616044820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b60648201526084016102fd565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156106665750816103df565b8251156106765782518084602001fd5b8160405162461bcd60e51b81526004016102fd9190610792565b80356001600160a01b03811681146106a757600080fd5b919050565b6000602082840312156106be57600080fd5b6103df82610690565b6000806000604084860312156106dc57600080fd5b6106e584610690565b9250602084013567ffffffffffffffff8082111561070257600080fd5b818601915086601f83011261071657600080fd5b81358181111561072557600080fd5b87602082850101111561073757600080fd5b6020830194508093505050509250925092565b60005b8381101561076557818101518382015260200161074d565b838111156101e75750506000910152565b6000825161078881846020870161074a565b9190910192915050565b60208152600082518060208401526107b181604085016020870161074a565b601f01601f1916919091016040019291505056feb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122001f23e5e5d70499e22926447138d9a73085390bf4c2f13e017a1d16843ca77ac64736f6c63430008090033",
+ "devdoc": {
+ "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.",
+ "events": {
+ "AdminChanged(address,address)": {
+ "details": "Emitted when the admin account has changed."
+ }
+ },
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "constructor": {
+ "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "stateVariables": {
+ "_ADMIN_SLOT": {
+ "details": "Storage slot with the admin of the contract. This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/bsctestnet/ProxyAdmin.json b/bridge/deployments/bsctestnet/ProxyAdmin.json
new file mode 100644
index 000000000..48264b2a3
--- /dev/null
+++ b/bridge/deployments/bsctestnet/ProxyAdmin.json
@@ -0,0 +1,262 @@
+{
+ "address": "0x6C62BF5440De2Cb157205B15C424BCEb5C3368F5",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeProxyAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ }
+ ],
+ "name": "getProxyAdmin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ }
+ ],
+ "name": "getProxyImplementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgrade",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x2975ce8ce07860f9cc9b2c4dc16f8321ac1610e1d09c655d399af1699be61d90",
+ "receipt": {
+ "to": null,
+ "from": "0x9C95B0EF2D3E1D9ca479524Ba738C87BE28C1585",
+ "contractAddress": "0x6C62BF5440De2Cb157205B15C424BCEb5C3368F5",
+ "transactionIndex": 4,
+ "gasUsed": "498542",
+ "logsBloom": "0x00000000200000000000000000000000000000000000000000800000000000000000000000000000000000002000000000040000100000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000810000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000001000000000000",
+ "blockHash": "0x7bd750c334b282e44da5ed0090a64a4a7b763b6c0bd0042e28fc0d6891f293c7",
+ "transactionHash": "0x2975ce8ce07860f9cc9b2c4dc16f8321ac1610e1d09c655d399af1699be61d90",
+ "logs": [
+ {
+ "transactionIndex": 4,
+ "blockNumber": 16643894,
+ "transactionHash": "0x2975ce8ce07860f9cc9b2c4dc16f8321ac1610e1d09c655d399af1699be61d90",
+ "address": "0x6C62BF5440De2Cb157205B15C424BCEb5C3368F5",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000009c95b0ef2d3e1d9ca479524ba738c87be28c1585"
+ ],
+ "data": "0x",
+ "logIndex": 6,
+ "blockHash": "0x7bd750c334b282e44da5ed0090a64a4a7b763b6c0bd0042e28fc0d6891f293c7"
+ }
+ ],
+ "blockNumber": 16643894,
+ "cumulativeGasUsed": "1302201",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "numDeployments": 1,
+ "solcInputHash": "f27c8e19ddc2cd2a95162a1eabc0e272",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\",\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"details\":\"Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`.\"},\"getProxyAdmin(address)\":{\"details\":\"Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"getProxyImplementation(address)\":{\"details\":\"Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"details\":\"Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`.\"},\"upgradeAndCall(address,address,bytes)\":{\"details\":\"Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol\":\"ProxyAdmin\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return payable(msg.sender);\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x6f3f274a2270bfe073339370edfa2485e2d515a2656039937f6b972fae96d297\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../GSN/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () {\\n _owner = _msgSender();\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0xc28d491022a7b7df51c1fb08998589daa944635b758dcd14b5cfb95739446cce\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0xdc0ebdc6f4ae0b5f9dd0a6c041a2238e4a7a2afbc6cef539437b0004ada42370\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../../ownership/Ownable.sol\\\";\\nimport \\\"./TransparentUpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\\n */\\ncontract ProxyAdmin is Ownable {\\n\\n /**\\n * @dev Returns the current implementation of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"implementation()\\\")) == 0x5c60da1b\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"5c60da1b\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Returns the current admin of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"admin()\\\")) == 0xf851a440\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"f851a440\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Changes the admin of `proxy` to `newAdmin`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the current admin of `proxy`.\\n */\\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\\n proxy.changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\\n proxy.upgradeTo(implementation);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\\n }\\n}\\n\",\"keccak256\":\"0xa9722406bcf07157885f323c5d0db1ec2c6869548086e94e9f16180f58ed2ee6\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x3327b21f85d71d3b9bad1a89267f08b19966e03446a18d810bd80fe42789ac5f\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb54322ec8ec142c149ad1f561aa2f0da6d6ea2d9f45639164088db9e16d5a69d\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x04801fc2398ee3370f3903f95389ea3a8da65a8df01f24b352e499e44d492e9b\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50600080546001600160a01b0319163390811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36107a38061005f6000396000f3fe6080604052600436106100865760003560e01c80638f32d59b116100595780638f32d59b1461011d5780639623609d1461014857806399a88ec41461015b578063f2fde38b1461017b578063f3b7dead1461019b57600080fd5b8063204e1c7a1461008b578063715018a6146100c85780637eff275e146100df5780638da5cb5b146100ff575b600080fd5b34801561009757600080fd5b506100ab6100a636600461056d565b6101bb565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100d457600080fd5b506100dd61024c565b005b3480156100eb57600080fd5b506100dd6100fa366004610591565b6102c9565b34801561010b57600080fd5b506000546001600160a01b03166100ab565b34801561012957600080fd5b506000546001600160a01b0316331460405190151581526020016100bf565b6100dd6101563660046105e0565b610353565b34801561016757600080fd5b506100dd610176366004610591565b6103e4565b34801561018757600080fd5b506100dd61019636600461056d565b61043c565b3480156101a757600080fd5b506100ab6101b636600461056d565b610472565b6000806000836001600160a01b03166040516101e190635c60da1b60e01b815260040190565b600060405180830381855afa9150503d806000811461021c576040519150601f19603f3d011682016040523d82523d6000602084013e610221565b606091505b50915091508161023057600080fd5b8080602001905181019061024491906106b6565b949350505050565b6000546001600160a01b0316331461027f5760405162461bcd60e51b8152600401610276906106d3565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031633146102f35760405162461bcd60e51b8152600401610276906106d3565b6040516308f2839760e41b81526001600160a01b038281166004830152831690638f283970906024015b600060405180830381600087803b15801561033757600080fd5b505af115801561034b573d6000803e3d6000fd5b505050505050565b6000546001600160a01b0316331461037d5760405162461bcd60e51b8152600401610276906106d3565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906103ad9086908690600401610708565b6000604051808303818588803b1580156103c657600080fd5b505af11580156103da573d6000803e3d6000fd5b5050505050505050565b6000546001600160a01b0316331461040e5760405162461bcd60e51b8152600401610276906106d3565b604051631b2ce7f360e11b81526001600160a01b038281166004830152831690633659cfe69060240161031d565b6000546001600160a01b031633146104665760405162461bcd60e51b8152600401610276906106d3565b61046f81610498565b50565b6000806000836001600160a01b03166040516101e1906303e1469160e61b815260040190565b6001600160a01b0381166104fd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610276565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116811461046f57600080fd5b60006020828403121561057f57600080fd5b813561058a81610558565b9392505050565b600080604083850312156105a457600080fd5b82356105af81610558565b915060208301356105bf81610558565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b6000806000606084860312156105f557600080fd5b833561060081610558565b9250602084013561061081610558565b9150604084013567ffffffffffffffff8082111561062d57600080fd5b818601915086601f83011261064157600080fd5b813581811115610653576106536105ca565b604051601f8201601f19908116603f0116810190838211818310171561067b5761067b6105ca565b8160405282815289602084870101111561069457600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156106c857600080fd5b815161058a81610558565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60018060a01b038316815260006020604081840152835180604085015260005b8181101561074457858101830151858201606001528201610728565b81811115610756576000606083870101525b50601f01601f19169290920160600194935050505056fea264697066735822122045e18dca6316824bc6fe9886dc5a9881d3200b5e741a07e9f5d029c728cdcbd664736f6c63430008090033",
+ "deployedBytecode": "0x6080604052600436106100865760003560e01c80638f32d59b116100595780638f32d59b1461011d5780639623609d1461014857806399a88ec41461015b578063f2fde38b1461017b578063f3b7dead1461019b57600080fd5b8063204e1c7a1461008b578063715018a6146100c85780637eff275e146100df5780638da5cb5b146100ff575b600080fd5b34801561009757600080fd5b506100ab6100a636600461056d565b6101bb565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100d457600080fd5b506100dd61024c565b005b3480156100eb57600080fd5b506100dd6100fa366004610591565b6102c9565b34801561010b57600080fd5b506000546001600160a01b03166100ab565b34801561012957600080fd5b506000546001600160a01b0316331460405190151581526020016100bf565b6100dd6101563660046105e0565b610353565b34801561016757600080fd5b506100dd610176366004610591565b6103e4565b34801561018757600080fd5b506100dd61019636600461056d565b61043c565b3480156101a757600080fd5b506100ab6101b636600461056d565b610472565b6000806000836001600160a01b03166040516101e190635c60da1b60e01b815260040190565b600060405180830381855afa9150503d806000811461021c576040519150601f19603f3d011682016040523d82523d6000602084013e610221565b606091505b50915091508161023057600080fd5b8080602001905181019061024491906106b6565b949350505050565b6000546001600160a01b0316331461027f5760405162461bcd60e51b8152600401610276906106d3565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031633146102f35760405162461bcd60e51b8152600401610276906106d3565b6040516308f2839760e41b81526001600160a01b038281166004830152831690638f283970906024015b600060405180830381600087803b15801561033757600080fd5b505af115801561034b573d6000803e3d6000fd5b505050505050565b6000546001600160a01b0316331461037d5760405162461bcd60e51b8152600401610276906106d3565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906103ad9086908690600401610708565b6000604051808303818588803b1580156103c657600080fd5b505af11580156103da573d6000803e3d6000fd5b5050505050505050565b6000546001600160a01b0316331461040e5760405162461bcd60e51b8152600401610276906106d3565b604051631b2ce7f360e11b81526001600160a01b038281166004830152831690633659cfe69060240161031d565b6000546001600160a01b031633146104665760405162461bcd60e51b8152600401610276906106d3565b61046f81610498565b50565b6000806000836001600160a01b03166040516101e1906303e1469160e61b815260040190565b6001600160a01b0381166104fd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610276565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116811461046f57600080fd5b60006020828403121561057f57600080fd5b813561058a81610558565b9392505050565b600080604083850312156105a457600080fd5b82356105af81610558565b915060208301356105bf81610558565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b6000806000606084860312156105f557600080fd5b833561060081610558565b9250602084013561061081610558565b9150604084013567ffffffffffffffff8082111561062d57600080fd5b818601915086601f83011261064157600080fd5b813581811115610653576106536105ca565b604051601f8201601f19908116603f0116810190838211818310171561067b5761067b6105ca565b8160405282815289602084870101111561069457600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156106c857600080fd5b815161058a81610558565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60018060a01b038316815260006020604081840152835180604085015260005b8181101561074457858101830151858201606001528201610728565b81811115610756576000606083870101525b50601f01601f19169290920160600194935050505056fea264697066735822122045e18dca6316824bc6fe9886dc5a9881d3200b5e741a07e9f5d029c728cdcbd664736f6c63430008090033",
+ "devdoc": {
+ "details": "This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.",
+ "kind": "dev",
+ "methods": {
+ "changeProxyAdmin(address,address)": {
+ "details": "Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`."
+ },
+ "getProxyAdmin(address)": {
+ "details": "Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "getProxyImplementation(address)": {
+ "details": "Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "upgrade(address,address)": {
+ "details": "Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "upgradeAndCall(address,address,bytes)": {
+ "details": "Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 11290,
+ "contract": "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol:ProxyAdmin",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/bsctestnet/SideTokenFactory.json b/bridge/deployments/bsctestnet/SideTokenFactory.json
new file mode 100644
index 000000000..753e3cdf0
--- /dev/null
+++ b/bridge/deployments/bsctestnet/SideTokenFactory.json
@@ -0,0 +1,174 @@
+{
+ "address": "0x967F8799aF07dF1534d48A95a5C9FEBE92c53AE0",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "SideTokenCreated",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x629ccdeefa5141b65254457d71dfb1a4a4d93153d654db57169f74473302aa27",
+ "receipt": {
+ "to": null,
+ "from": "0x9C95B0EF2D3E1D9ca479524Ba738C87BE28C1585",
+ "contractAddress": "0x967F8799aF07dF1534d48A95a5C9FEBE92c53AE0",
+ "transactionIndex": 18,
+ "gasUsed": "2526094",
+ "logsBloom": "0x00000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000001000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000",
+ "blockHash": "0x7f6ca1a27d160aec5158c91891a79f0f0fa937c10a4fefe48429b1c74aeea14e",
+ "transactionHash": "0x629ccdeefa5141b65254457d71dfb1a4a4d93153d654db57169f74473302aa27",
+ "logs": [
+ {
+ "transactionIndex": 18,
+ "blockNumber": 16643943,
+ "transactionHash": "0x629ccdeefa5141b65254457d71dfb1a4a4d93153d654db57169f74473302aa27",
+ "address": "0x967F8799aF07dF1534d48A95a5C9FEBE92c53AE0",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ],
+ "data": "0x0000000000000000000000009c95b0ef2d3e1d9ca479524ba738c87be28c1585",
+ "logIndex": 40,
+ "blockHash": "0x7f6ca1a27d160aec5158c91891a79f0f0fa937c10a4fefe48429b1c74aeea14e"
+ }
+ ],
+ "blockNumber": 16643943,
+ "cumulativeGasUsed": "6898922",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "numDeployments": 1,
+ "solcInputHash": "f27c8e19ddc2cd2a95162a1eabc0e272",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"granularity\",\"type\":\"uint256\"}],\"name\":\"SideTokenCreated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"granularity\",\"type\":\"uint256\"}],\"name\":\"createSideToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/SideTokenFactory/SideTokenFactory.sol\":\"SideTokenFactory\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/SideToken/SideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../zeppelin/token/ERC777/ERC777.sol\\\";\\nimport \\\"../interface/IERC677Receiver.sol\\\";\\nimport \\\"../interface/ISideToken.sol\\\";\\nimport \\\"../lib/LibEIP712.sol\\\";\\n\\ncontract SideToken is ISideToken, ERC777 {\\n using SafeMath for uint256;\\n\\n address public minter;\\n uint256 private _granularity;\\n\\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\\n bytes32 public domainSeparator;\\n // keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\\n mapping(address => uint) public nonces;\\n\\n // ERC677 Transfer Event\\n event Transfer(address,address,uint256,bytes);\\n\\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\\n require(_minterAddr != address(0), \\\"SideToken: Empty Minter\\\");\\n require(_newGranularity >= 1, \\\"SideToken: Granularity < 1\\\");\\n minter = _minterAddr;\\n _granularity = _newGranularity;\\n\\n domainSeparator = LibEIP712.hashEIP712Domain(\\n name(),\\n \\\"1\\\",\\n block.chainid,\\n address(this)\\n );\\n }\\n\\n modifier onlyMinter() {\\n require(_msgSender() == minter, \\\"SideToken: Caller is not the minter\\\");\\n _;\\n }\\n\\n function mint(\\n address account,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n )\\n external onlyMinter override\\n {\\n _mint(_msgSender(), account, amount, userData, operatorData);\\n }\\n\\n /**\\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\\n * @param recipient The address to transfer to.\\n * @param amount The amount to be transferred.\\n * @param data The extra data to be passed to the receiving contract.\\n */\\n function transferAndCall(address recipient, uint amount, bytes calldata data)\\n external returns (bool success)\\n {\\n address from = _msgSender();\\n\\n _send(from, from, recipient, amount, data, \\\"\\\", false);\\n emit Transfer(from, recipient, amount, data);\\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\\n return true;\\n }\\n\\n function granularity() public view override returns (uint256) {\\n return _granularity;\\n }\\n\\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\\n require(deadline >= block.timestamp, \\\"SideToken: EXPIRED\\\"); // solhint-disable-line not-rely-on-time\\n bytes32 digest = LibEIP712.hashEIP712Message(\\n domainSeparator,\\n keccak256(\\n abi.encode(\\n PERMIT_TYPEHASH,\\n owner,\\n spender,\\n value,\\n nonces[owner]++,\\n deadline\\n )\\n )\\n );\\n address recoveredAddress = ecrecover(digest, v, r, s);\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"SideToken: INVALID_SIGNATURE\\\");\\n _approve(owner, spender, value);\\n }\\n\\n}\",\"keccak256\":\"0x7b96a4cf24ea53026929e98f2f91a3a220f20e7e9c9fe1bb5ac2a159bdec9c9e\",\"license\":\"MIT\"},\"contracts/SideTokenFactory/SideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../zeppelin/ownership/Secondary.sol\\\";\\nimport \\\"../interface/ISideTokenFactory.sol\\\";\\nimport \\\"../SideToken/SideToken.sol\\\";\\n\\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\\n\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\\n external onlyPrimary override returns(address) {\\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\\n emit SideTokenCreated(sideToken, symbol, granularity);\\n return sideToken;\\n }\\n}\",\"keccak256\":\"0x93e8d0df38e0455155d2658bce959075aa0c7ca0c45b4fd0516f3eeeacb2a9e7\",\"license\":\"MIT\"},\"contracts/interface/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\\n}\",\"keccak256\":\"0x1f3de30ddf0428f1ff17a0424cc2396e78883a31bc286e31bcbb5f873ab04d2a\",\"license\":\"MIT\"},\"contracts/interface/ISideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\ninterface ISideToken {\\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\\n}\",\"keccak256\":\"0x43d96442dcb622e7efbad6ff3fcfe109d9f881c18415b571511f326b39d7a70e\",\"license\":\"MIT\"},\"contracts/interface/ISideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\ninterface ISideTokenFactory {\\n\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\\n\\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\\n}\",\"keccak256\":\"0x5c3c0db3ad07c2cb9933ea8a37e01b83d4ec77c7bc0ac684de87f6b1e09d25dc\",\"license\":\"MIT\"},\"contracts/lib/LibEIP712.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\\nlibrary LibEIP712 {\\n\\n // Hash of the EIP712 Domain Separator Schema\\n // keccak256(abi.encodePacked(\\n // \\\"EIP712Domain(\\\",\\n // \\\"string name,\\\",\\n // \\\"string version,\\\",\\n // \\\"uint256 chainId,\\\",\\n // \\\"address verifyingContract\\\",\\n // \\\")\\\"\\n // ))\\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\\n\\n /// @dev Calculates a EIP712 domain separator.\\n /// @param name The EIP712 domain name.\\n /// @param version The EIP712 domain version.\\n /// @param verifyingContract The EIP712 verifying contract.\\n /// @return result EIP712 domain separator.\\n function hashEIP712Domain(\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract\\n )\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\\n\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\\n // keccak256(bytes(name)),\\n // keccak256(bytes(version)),\\n // chainId,\\n // uint256(verifyingContract)\\n // ))\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Calculate hashes of dynamic data\\n let nameHash := keccak256(add(name, 32), mload(name))\\n let versionHash := keccak256(add(version, 32), mload(version))\\n\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n // Store params in memory\\n mstore(memPtr, schemaHash)\\n mstore(add(memPtr, 32), nameHash)\\n mstore(add(memPtr, 64), versionHash)\\n mstore(add(memPtr, 96), chainId)\\n mstore(add(memPtr, 128), verifyingContract)\\n\\n // Compute hash\\n result := keccak256(memPtr, 160)\\n }\\n return result;\\n }\\n\\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\\n /// with getDomainHash().\\n /// @param hashStruct The EIP712 hash struct.\\n /// @return result EIP712 hash applied to the given EIP712 Domain.\\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // EIP191_HEADER,\\n // EIP712_DOMAIN_HASH,\\n // hashStruct\\n // ));\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\\n\\n // Compute hash\\n result := keccak256(memPtr, 66)\\n }\\n return result;\\n }\\n}\",\"keccak256\":\"0x0314f8cfcab5979a2d713b4863bf5783b1181151ac144091d23f802d3f8ac7c5\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return payable(msg.sender);\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x6f3f274a2270bfe073339370edfa2485e2d515a2656039937f6b972fae96d297\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC1820Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\n * implementers for interfaces in this registry, as well as query support.\\n *\\n * Implementers may be shared by multiple accounts, and can also implement more\\n * than a single interface for each account. Contracts can implement interfaces\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\n * contract.\\n *\\n * {IERC165} interfaces can also be queried via the registry.\\n *\\n * For an in-depth explanation and source code analysis, see the EIP text.\\n */\\ninterface IERC1820Registry {\\n /**\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\n * account is able to set interface implementers for it.\\n *\\n * By default, each account is its own manager. Passing a value of `0x0` in\\n * `newManager` will reset the manager to this initial state.\\n *\\n * Emits a {ManagerChanged} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `account`.\\n */\\n function setManager(address account, address newManager) external;\\n\\n /**\\n * @dev Returns the manager for `account`.\\n *\\n * See {setManager}.\\n */\\n function getManager(address account) external view returns (address);\\n\\n /**\\n * @dev Sets the `implementer` contract as `account`'s implementer for\\n * `interfaceHash`.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n * The zero address can also be used in `implementer` to remove an old one.\\n *\\n * See {interfaceHash} to learn how these are created.\\n *\\n * Emits an {InterfaceImplementerSet} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `_account`.\\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\n * end in 28 zeroes).\\n * - `_implementer` must implement {IERC1820Implementer} and return true when\\n * queried for support, unless `implementer` is the caller. See\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\n */\\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\\n\\n /**\\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\\n * implementer is registered, returns the zero address.\\n *\\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\n * zeroes), `_account` will be queried for support of it.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n */\\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\\n\\n /**\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\n * corresponding\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\n */\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\n\\n /**\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\n * @param account Address of the contract for which to update the cache.\\n * @param interfaceId ERC165 interface for which to update the cache.\\n */\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\n * If the result is not cached a direct lookup on the contract address is performed.\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\n * {updateERC165Cache} with the contract address.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\n\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\n\\n event ManagerChanged(address indexed account, address indexed newManager);\\n}\\n\",\"keccak256\":\"0x8877787cbe99ab8e2dcb85e9b22066b7e62bcea328091c1ff9ae462e54afa66e\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x8038a6eca31e013b0c7f248c7a4eb5846ab0d52bb3f7636fafcf00b075643afe\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Secondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../GSN/Context.sol\\\";\\n/**\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\n */\\nabstract contract Secondary is Context {\\n address private _primary;\\n\\n /**\\n * @dev Emitted when the primary contract changes.\\n */\\n event PrimaryTransferred(\\n address recipient\\n );\\n\\n /**\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\n */\\n constructor () {\\n _primary = _msgSender();\\n emit PrimaryTransferred(_primary);\\n }\\n\\n /**\\n * @dev Reverts if called from any account other than the primary.\\n */\\n modifier onlyPrimary() {\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\n _;\\n }\\n\\n /**\\n * @return the address of the primary.\\n */\\n function primary() public view returns (address) {\\n return _primary;\\n }\\n\\n /**\\n * @dev Transfers contract to a new primary.\\n * @param recipient The address of new primary.\\n */\\n function transferPrimary(address recipient) public onlyPrimary {\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\n _primary = recipient;\\n emit PrimaryTransferred(_primary);\\n }\\n}\\n\",\"keccak256\":\"0xdab039c15e9fd9764351f7bddcd94710bb3cc358c9e78e6fa30f9b6f4373754d\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {ERC20Detailed}.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xdb194e173849ac56dbc15eaf0c01848361748ff8e4679985c3d11013ee4fa4b6\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/ERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"./IERC777.sol\\\";\\nimport \\\"./IERC777Recipient.sol\\\";\\nimport \\\"./IERC777Sender.sol\\\";\\nimport \\\"../../token/ERC20/IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../introspection/IERC1820Registry.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC777} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n *\\n * Support for ERC20 is included in this contract, as specified by the EIP: both\\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\\n * movements.\\n *\\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\\n * are no special restrictions in the amount of tokens that created, moved, or\\n * destroyed. This makes integration with ERC20 applications seamless.\\n */\\ncontract ERC777 is Context, IERC777, IERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\n\\n mapping(address => uint256) private _balances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\\n // See https://github.com/ethereum/solidity/issues/4024.\\n\\n // keccak256(\\\"ERC777TokensSender\\\")\\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\\n\\n // keccak256(\\\"ERC777TokensRecipient\\\")\\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\\n\\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\\n address[] private _defaultOperatorsArray;\\n\\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\\n mapping(address => bool) private _defaultOperators;\\n\\n // For each account, a mapping of its operators and revoked default operators.\\n mapping(address => mapping(address => bool)) private _operators;\\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\\n\\n // ERC20-allowances\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n /**\\n * @dev `defaultOperators` may be an empty array.\\n */\\n constructor(\\n string memory aName,\\n string memory aSymbol,\\n address[] memory theDefaultOperators\\n ) {\\n _name = aName;\\n _symbol = aSymbol;\\n\\n _defaultOperatorsArray = theDefaultOperators;\\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\\n _defaultOperators[_defaultOperatorsArray[i]] = true;\\n }\\n\\n // register interfaces\\n _erc1820.setInterfaceImplementer(address(this), keccak256(\\\"ERC777Token\\\"), address(this));\\n _erc1820.setInterfaceImplementer(address(this), keccak256(\\\"ERC20Token\\\"), address(this));\\n }\\n\\n /**\\n * @dev See {IERC777-name}.\\n */\\n function name() public view override(IERC777) returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC777-symbol}.\\n */\\n function symbol() public view override(IERC777) returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {ERC20Detailed-decimals}.\\n *\\n * Always returns 18, as per the\\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\\n */\\n function decimals() public pure override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC777-granularity}.\\n *\\n * This implementation always returns `1`.\\n */\\n function granularity() public view virtual override(IERC777) returns (uint256) {\\n return 1;\\n }\\n\\n /**\\n * @dev See {IERC777-totalSupply}.\\n */\\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\\n */\\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\\n return _balances[tokenHolder];\\n }\\n\\n /**\\n * @dev See {IERC777-send}.\\n *\\n * Also emits a {Transfer} event for ERC20 compatibility.\\n */\\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\\n _send(_msgSender(), _msgSender(), recipient, amount, data, \\\"\\\", true);\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\\n * interface if it is a contract.\\n *\\n * Also emits a {Sent} event.\\n */\\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\\n require(recipient != address(0), \\\"ERC777: transfer to zero address\\\");\\n\\n address from = _msgSender();\\n\\n _callTokensToSend(from, from, recipient, amount, \\\"\\\", \\\"\\\");\\n\\n _move(from, from, recipient, amount, \\\"\\\", \\\"\\\");\\n\\n _callTokensReceived(from, from, recipient, amount, \\\"\\\", \\\"\\\", false);\\n\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC777-burn}.\\n *\\n * Also emits a {Transfer} event for ERC20 compatibility.\\n */\\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\\n _burn(_msgSender(), _msgSender(), amount, data, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC777-isOperatorFor}.\\n */\\n function isOperatorFor(\\n address operator,\\n address tokenHolder\\n ) public view override(IERC777) returns (bool) {\\n return operator == tokenHolder ||\\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\\n _operators[tokenHolder][operator];\\n }\\n\\n /**\\n * @dev See {IERC777-authorizeOperator}.\\n */\\n function authorizeOperator(address operator) external override(IERC777) {\\n require(_msgSender() != operator, \\\"ERC777: authorizing self as operator\\\");\\n\\n if (_defaultOperators[operator]) {\\n delete _revokedDefaultOperators[_msgSender()][operator];\\n } else {\\n _operators[_msgSender()][operator] = true;\\n }\\n\\n emit AuthorizedOperator(operator, _msgSender());\\n }\\n\\n /**\\n * @dev See {IERC777-revokeOperator}.\\n */\\n function revokeOperator(address operator) external override(IERC777) {\\n require(operator != _msgSender(), \\\"ERC777: revoking self as operator\\\");\\n\\n if (_defaultOperators[operator]) {\\n _revokedDefaultOperators[_msgSender()][operator] = true;\\n } else {\\n delete _operators[_msgSender()][operator];\\n }\\n\\n emit RevokedOperator(operator, _msgSender());\\n }\\n\\n /**\\n * @dev See {IERC777-defaultOperators}.\\n */\\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\\n return _defaultOperatorsArray;\\n }\\n\\n /**\\n * @dev See {IERC777-operatorSend}.\\n *\\n * Emits {Sent} and {Transfer} events.\\n */\\n function operatorSend(\\n address sender,\\n address recipient,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n )\\n external override(IERC777)\\n {\\n require(isOperatorFor(_msgSender(), sender), \\\"ERC777: caller is not an operator\\\");\\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\\n }\\n\\n /**\\n * @dev See {IERC777-operatorBurn}.\\n *\\n * Emits {Burned} and {Transfer} events.\\n */\\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\\n external override(IERC777) {\\n require(isOperatorFor(_msgSender(), account), \\\"ERC777: caller is not an operator\\\");\\n _burn(_msgSender(), account, amount, data, operatorData);\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n *\\n * Note that operator and allowance concepts are orthogonal: operators may\\n * not have allowance, and accounts with allowance may not be operators\\n * themselves.\\n */\\n function allowance(address holder, address spender)\\n public view override(IERC20) returns (uint256) {\\n return _allowances[holder][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Note that accounts cannot have allowance issued by their operators.\\n */\\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\\n address holder = _msgSender();\\n _approve(holder, spender, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Note that operator and allowance concepts are orthogonal: operators cannot\\n * call `transferFrom` (unless they have allowance), and accounts with\\n * allowance cannot call `operatorSend` (unless they are operators).\\n *\\n * Emits {Sent}, {Transfer} and {Approval} events.\\n */\\n function transferFrom(address holder, address recipient, uint256 amount)\\n external override(IERC20) returns (bool) {\\n require(recipient != address(0), \\\"ERC777: transfer to zero address\\\");\\n require(holder != address(0), \\\"ERC777: transfer from zero address\\\");\\n\\n address spender = _msgSender();\\n\\n _callTokensToSend(spender, holder, recipient, amount, \\\"\\\", \\\"\\\");\\n\\n _move(spender, holder, recipient, amount, \\\"\\\", \\\"\\\");\\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \\\"ERC777: transfer amount exceeds allowance\\\"));\\n\\n _callTokensReceived(spender, holder, recipient, amount, \\\"\\\", \\\"\\\", false);\\n\\n return true;\\n }\\n\\n /**\\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * If a send hook is registered for `account`, the corresponding function\\n * will be called with `operator`, `data` and `operatorData`.\\n *\\n * See {IERC777Sender} and {IERC777Recipient}.\\n *\\n * Emits {Minted} and {Transfer} events.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - if `account` is a contract, it must implement the {IERC777Recipient}\\n * interface.\\n */\\n function _mint(\\n address operator,\\n address account,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData\\n )\\n internal\\n {\\n require(account != address(0), \\\"ERC777: mint to zero address\\\");\\n\\n // Update state variables\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n\\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\\n\\n emit Minted(operator, account, amount, userData, operatorData);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Send tokens\\n * @param operator address operator requesting the transfer\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\\n */\\n function _send(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData,\\n bool requireReceptionAck\\n )\\n internal\\n {\\n require(from != address(0), \\\"ERC777: send from zero address\\\");\\n require(to != address(0), \\\"ERC777: send to zero address\\\");\\n\\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\\n\\n _move(operator, from, to, amount, userData, operatorData);\\n\\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\\n }\\n\\n /**\\n * @dev Burn tokens\\n * @param operator address operator requesting the operation\\n * @param from address token holder address\\n * @param amount uint256 amount of tokens to burn\\n * @param data bytes extra information provided by the token holder\\n * @param operatorData bytes extra information provided by the operator (if any)\\n */\\n function _burn(\\n address operator,\\n address from,\\n uint256 amount,\\n bytes memory data,\\n bytes memory operatorData\\n )\\n internal\\n {\\n require(from != address(0), \\\"ERC777: burn from zero address\\\");\\n\\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\\n\\n // Update state variables\\n _balances[from] = _balances[from].sub(amount, \\\"ERC777: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n\\n emit Burned(operator, from, amount, data, operatorData);\\n emit Transfer(from, address(0), amount);\\n }\\n\\n function _move(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData\\n )\\n internal\\n {\\n _balances[from] = _balances[from].sub(amount, \\\"ERC777: transfer amount exceeds balance\\\");\\n _balances[to] = _balances[to].add(amount);\\n\\n emit Sent(operator, from, to, amount, userData, operatorData);\\n emit Transfer(from, to, amount);\\n }\\n\\n function _approve(address holder, address spender, uint256 value) internal {\\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\\n // currently unnecessary.\\n //require(holder != address(0), \\\"ERC777: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC777: approve to zero address\\\");\\n\\n _allowances[holder][spender] = value;\\n emit Approval(holder, spender, value);\\n }\\n\\n /**\\n * @dev Call from.tokensToSend() if the interface is registered\\n * @param operator address operator requesting the transfer\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n */\\n function _callTokensToSend(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData\\n )\\n internal\\n {\\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\\n if (implementer != address(0)) {\\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\\n }\\n }\\n\\n /**\\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\\n * tokensReceived() was not registered for the recipient\\n * @param operator address operator requesting the transfer\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\\n */\\n function _callTokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData,\\n bool requireReceptionAck\\n )\\n private\\n {\\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\\n if (implementer != address(0)) {\\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\\n } else if (requireReceptionAck) {\\n require(!to.isContract(), \\\"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf18fbdee798b2c3dd6b87d4e9e3d1486b7ab03a2380b253026db9ada3114fe4a\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777Token standard as defined in the EIP.\\n *\\n * This contract uses the\\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\\n * token holders and recipients react to token movements by using setting implementers\\n * for the associated interfaces in said registry. See `IERC1820Registry` and\\n * `ERC1820Implementer`.\\n */\\ninterface IERC777 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the smallest part of the token that is not divisible. This\\n * means all token operations (creation, movement and destruction) must have\\n * amounts that are a multiple of this number.\\n *\\n * For most token contracts, this value will equal 1.\\n */\\n function granularity() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by an account (`owner`).\\n */\\n function balanceOf(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * If send or receive hooks are registered for the caller and `recipient`,\\n * the corresponding functions will be called with `data` and empty\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function send(address recipient, uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Destroys `amount` tokens from the caller's account, reducing the\\n * total supply.\\n *\\n * If a send hook is registered for the caller, the corresponding function\\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n */\\n function burn(uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Returns true if an account is an operator of `tokenHolder`.\\n * Operators can send and burn tokens on behalf of their owners. All\\n * accounts are their own operator.\\n *\\n * See `operatorSend` and `operatorBurn`.\\n */\\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor`.\\n *\\n * Emits an `AuthorizedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function authorizeOperator(address operator) external;\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor` and `defaultOperators`.\\n *\\n * Emits a `RevokedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function revokeOperator(address operator) external;\\n\\n /**\\n * @dev Returns the list of default operators. These accounts are operators\\n * for all token holders, even if `authorizeOperator` was never called on\\n * them.\\n *\\n * This list is immutable, but individual holders may revoke these via\\n * `revokeOperator`, in which case `isOperatorFor` will return false.\\n */\\n function defaultOperators() external view returns (address[] memory);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\\n * be an operator of `sender`.\\n *\\n * If send or receive hooks are registered for `sender` and `recipient`,\\n * the corresponding functions will be called with `data` and\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - `sender` cannot be the zero address.\\n * - `sender` must have at least `amount` tokens.\\n * - the caller must be an operator for `sender`.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function operatorSend(\\n address sender,\\n address recipient,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n /**\\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\\n * The caller must be an operator of `account`.\\n *\\n * If a send hook is registered for `account`, the corresponding function\\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n * - the caller must be an operator for `account`.\\n */\\n function operatorBurn(\\n address account,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n event Sent(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256 amount,\\n bytes data,\\n bytes operatorData\\n );\\n\\n function decimals() external returns (uint8);\\n\\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\\n\\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\\n\\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\\n\\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\\n}\\n\",\"keccak256\":\"0xd8fb2f5bda9acc32af1bc5ed8a64c67a42ac7f32dd1195387535e8e148d40421\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\n *\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an `IERC777` token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0xc1e6f2d257d4973a27a86e590e01a3289317bd4b44ea040a622b4823c7793875\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Sender.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\\n *\\n * `IERC777` Token holders can be notified of operations performed on their\\n * tokens by having a contract implement this interface (contract holders can be\\n * their own implementer) and registering it on the\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\n *\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\n */\\ninterface IERC777Sender {\\n /**\\n * @dev Called by an `IERC777` token contract whenever a registered holder's\\n * (`from`) tokens are about to be moved or destroyed. The type of operation\\n * is conveyed by `to` being the zero address or not.\\n *\\n * This call occurs _before_ the token contract's state is updated, so\\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensToSend(\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x8707e3440e84839e68a5ff455f9fbd74f6a313111197493911fd100f436f1937\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x04801fc2398ee3370f3903f95389ea3a8da65a8df01f24b352e499e44d492e9b\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50600080546001600160a01b0319163390811790915560408051918252517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d99181900360200190a1612c5a806100676000396000f3fe60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b57806326d9e9631462000064578063c6dbdf611462000097575b600080fd5b620000626200005c36600462000296565b620000a9565b005b6200007b6200007536600462000314565b620001a7565b6040516001600160a01b03909116815260200160405180910390f35b6000546001600160a01b03166200007b565b6000546001600160a01b0316336001600160a01b031614620000e85760405162461bcd60e51b8152600401620000df906200038f565b60405180910390fd5b6001600160a01b038116620001535760405162461bcd60e51b815260206004820152602a60248201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604482015269726f206164647265737360b01b6064820152608401620000df565b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d99060200160405180910390a150565b600080546001600160a01b0316336001600160a01b031614620001de5760405162461bcd60e51b8152600401620000df906200038f565b600086868686620001f76000546001600160a01b031690565b87604051620002069062000288565b620002179695949392919062000404565b604051809103906000f08015801562000234573d6000803e3d6000fd5b509050806001600160a01b03167ff57d2ded8330a4affd2fa52378069be534fe22288536537d1a1cfc061518450786868660405162000276939291906200044e565b60405180910390a29695505050505050565b6127b0806200047583390190565b600060208284031215620002a957600080fd5b81356001600160a01b0381168114620002c157600080fd5b9392505050565b60008083601f840112620002db57600080fd5b50813567ffffffffffffffff811115620002f457600080fd5b6020830191508360208285010111156200030d57600080fd5b9250929050565b6000806000806000606086880312156200032d57600080fd5b853567ffffffffffffffff808211156200034657600080fd5b6200035489838a01620002c8565b909750955060208801359150808211156200036e57600080fd5b506200037d88828901620002c8565b96999598509660400135949350505050565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6080815260006200041a60808301888a620003db565b82810360208401526200042f818789620003db565b6001600160a01b03959095166040840152505060600152949350505050565b60408152600062000464604083018587620003db565b905082602083015294935050505056fe60806040523480156200001157600080fd5b50604051620027b0380380620027b08339810160408190526200003491620005ff565b60408051600081526020808201909252855186928692916200005d916002919086019062000434565b5081516200007390600390602085019062000434565b50805162000089906004906020840190620004c3565b5060005b600454811015620000fd5760016005600060048481548110620000b457620000b462000692565b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff191691151591909117905580620000f481620006a8565b9150506200008d565b506040516329965a1d60e01b815230600482018190527fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce217705460248301526044820152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90606401600060405180830381600087803b1580156200017857600080fd5b505af11580156200018d573d6000803e3d6000fd5b50506040516329965a1d60e01b815230600482018190527faea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a60248301526044820152731820a4b7618bde71dce8cdc73aab6c95905fad2492506329965a1d9150606401600060405180830381600087803b1580156200020b57600080fd5b505af115801562000220573d6000803e3d6000fd5b50505050506001600160a01b038416151591506200028790505760405162461bcd60e51b815260206004820152601760248201527f53696465546f6b656e3a20456d707479204d696e74657200000000000000000060448201526064015b60405180910390fd5b6001811015620002da5760405162461bcd60e51b815260206004820152601a60248201527f53696465546f6b656e3a204772616e756c6172697479203c203100000000000060448201526064016200027e565b600980546001600160a01b0319166001600160a01b038416179055600a819055620003356200030862000343565b604051806040016040528060018152602001603160f81b8152504630620003dd60201b620010201760201c565b600b55506200070f92505050565b6060600280546200035490620006d2565b80601f01602080910402602001604051908101604052809291908181526020018280546200038290620006d2565b8015620003d35780601f10620003a757610100808354040283529160200191620003d3565b820191906000526020600020905b815481529060010190602001808311620003b557829003601f168201915b5050505050905090565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b8280546200044290620006d2565b90600052602060002090601f016020900481019282620004665760008555620004b1565b82601f106200048157805160ff1916838001178555620004b1565b82800160010185558215620004b1579182015b82811115620004b157825182559160200191906001019062000494565b50620004bf9291506200051b565b5090565b828054828255906000526020600020908101928215620004b1579160200282015b82811115620004b157825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620004e4565b5b80821115620004bf57600081556001016200051c565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200055a57600080fd5b81516001600160401b038082111562000577576200057762000532565b604051601f8301601f19908116603f01168101908282118183101715620005a257620005a262000532565b81604052838152602092508683858801011115620005bf57600080fd5b600091505b83821015620005e35785820183015181830184015290820190620005c4565b83821115620005f55760008385830101525b9695505050505050565b600080600080608085870312156200061657600080fd5b84516001600160401b03808211156200062e57600080fd5b6200063c8883890162000548565b955060208701519150808211156200065357600080fd5b50620006628782880162000548565b604087015190945090506001600160a01b03811681146200068257600080fd5b6060959095015193969295505050565b634e487b7160e01b600052603260045260246000fd5b6000600019821415620006cb57634e487b7160e01b600052601160045260246000fd5b5060010190565b600181811c90821680620006e757607f821691505b602082108114156200070957634e487b7160e01b600052602260045260246000fd5b50919050565b612091806200071f6000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80637ecebe00116100de578063d95b637111610097578063f698da2511610071578063f698da2514610380578063fad8b32a14610389578063fc673c4f1461039c578063fe9d9303146103af57600080fd5b8063d95b637114610321578063dcdc7dd014610334578063dd62ed3e1461034757600080fd5b80637ecebe00146102ad578063959b8c3f146102cd57806395d89b41146102e05780639bd9bbc6146102e8578063a9059cbb146102fb578063d505accf1461030e57600080fd5b806330adf81f1161013057806330adf81f1461021e578063313ce567146102455780634000aea014610254578063556f0dc71461026757806362ad1b831461026f57806370a082311461028457600080fd5b806306e485381461017857806306fdde031461019657806307546172146101ab578063095ea7b3146101d657806318160ddd146101f957806323b872dd1461020b575b600080fd5b6101806103c2565b60405161018d91906119b5565b60405180910390f35b61019e610424565b60405161018d9190611a4f565b6009546101be906001600160a01b031681565b6040516001600160a01b03909116815260200161018d565b6101e96101e4366004611a7a565b6104ad565b604051901515815260200161018d565b6001545b60405190815260200161018d565b6101e9610219366004611aa6565b6104c5565b6101fd7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6040516012815260200161018d565b6101e9610262366004611b30565b61066d565b600a546101fd565b61028261027d366004611b8c565b610774565b005b6101fd610292366004611c2b565b6001600160a01b031660009081526020819052604090205490565b6101fd6102bb366004611c2b565b600c6020526000908152604090205481565b6102826102db366004611c2b565b61081d565b61019e61093b565b6102826102f6366004611b30565b61094a565b6101e9610309366004611a7a565b6109a4565b61028261031c366004611c48565b610a87565b6101e961032f366004611cbf565b610c84565b610282610342366004611cf8565b610d26565b6101fd610355366004611cbf565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b6101fd600b5481565b610282610397366004611c2b565b610e13565b6102826103aa366004611cf8565b610f2f565b6102826103bd366004611d84565b610fcb565b6060600480548060200260200160405190810160405280929190818152602001828054801561041a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116103fc575b5050505050905090565b60606002805461043390611dd0565b80601f016020809104026020016040519081016040528092919081815260200182805461045f90611dd0565b801561041a5780601f106104815761010080835404028352916020019161041a565b820191906000526020600020905b81548152906001019060200180831161048f57509395945050505050565b6000336104bb818585611077565b5060019392505050565b60006001600160a01b0383166105225760405162461bcd60e51b815260206004820181905260248201527f4552433737373a207472616e7366657220746f207a65726f206164647265737360448201526064015b60405180910390fd5b6001600160a01b0384166105835760405162461bcd60e51b815260206004820152602260248201527f4552433737373a207472616e736665722066726f6d207a65726f206164647265604482015261737360f01b6064820152608401610519565b60003390506105b481868686604051806020016040528060008152506040518060200160405280600081525061112e565b6105e0818686866040518060200160405280600081525060405180602001604052806000815250611264565b610634858261062f86604051806060016040528060298152602001612010602991396001600160a01b03808c166000908152600860209081526040808320938b16835292905220549190611386565b611077565b61066281868686604051806020016040528060008152506040518060200160405280600081525060006113c0565b506001949350505050565b6000803390506106c58182888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805160208101909152818152935091506115949050565b7fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1681878787876040516106fc959493929190611e34565b60405180910390a1604051635260769b60e11b81526001600160a01b0387169063a4c0ed3690610736908490899089908990600401611e73565b600060405180830381600087803b15801561075057600080fd5b505af1158015610764573d6000803e3d6000fd5b5060019998505050505050505050565b61077e3388610c84565b61079a5760405162461bcd60e51b815260040161051990611ea5565b6108143388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a915089908190840183828082843760009201919091525060019250611594915050565b50505050505050565b336001600160a01b03821614156108825760405162461bcd60e51b8152602060048201526024808201527f4552433737373a20617574686f72697a696e672073656c66206173206f70657260448201526330ba37b960e11b6064820152608401610519565b6001600160a01b03811660009081526005602052604090205460ff16156108d3573360009081526007602090815260408083206001600160a01b03851684529091529020805460ff19169055610902565b3360009081526006602090815260408083206001600160a01b03851684529091529020805460ff191660011790555b60405133906001600160a01b038316907ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f990600090a350565b60606003805461043390611dd0565b61099e3333868686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060408051602081019091529081529250600191506115949050565b50505050565b60006001600160a01b0383166109fc5760405162461bcd60e51b815260206004820181905260248201527f4552433737373a207472616e7366657220746f207a65726f20616464726573736044820152606401610519565b6000339050610a2d81828686604051806020016040528060008152506040518060200160405280600081525061112e565b610a59818286866040518060200160405280600081525060405180602001604052806000815250611264565b6104bb81828686604051806020016040528060008152506040518060200160405280600081525060006113c0565b42841015610acc5760405162461bcd60e51b815260206004820152601260248201527114da5919551bdad95b8e881156141254915160721b6044820152606401610519565b600b546001600160a01b0388166000908152600c6020526040812080549192610b949290917f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918c918c918c9188610b2383611efc565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810188905260e0016040516020818303038152906040528051906020012060405161190160f01b8152600281019290925260228201526042902090565b6040805160008082526020820180845284905260ff88169282019290925260608101869052608081018590529192509060019060a0016020604051602081039080840390855afa158015610bec573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610c225750886001600160a01b0316816001600160a01b0316145b610c6e5760405162461bcd60e51b815260206004820152601c60248201527f53696465546f6b656e3a20494e56414c49445f5349474e4154555245000000006044820152606401610519565b610c79898989611077565b505050505050505050565b6000816001600160a01b0316836001600160a01b03161480610cef57506001600160a01b03831660009081526005602052604090205460ff168015610cef57506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b80610d1f57506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b6009546001600160a01b0316336001600160a01b031614610d955760405162461bcd60e51b815260206004820152602360248201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6044820152623a32b960e91b6064820152608401610519565b610e0b33878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061166b92505050565b505050505050565b6001600160a01b038116331415610e765760405162461bcd60e51b815260206004820152602160248201527f4552433737373a207265766f6b696e672073656c66206173206f70657261746f6044820152603960f91b6064820152608401610519565b6001600160a01b03811660009081526005602052604090205460ff1615610eca573360009081526007602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610ef6565b3360009081526006602090815260408083206001600160a01b03851684529091529020805460ff191690555b60405133906001600160a01b038316907f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa190600090a350565b610f393387610c84565b610f555760405162461bcd60e51b815260040161051990611ea5565b610e0b33878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b0181900481028201810190925289815292508991508890819084018382808284376000920191909152506117b992505050565b61101b33338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604080516020810190915290815292506117b9915050565b505050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b6001600160a01b0382166110cd5760405162461bcd60e51b815260206004820152601f60248201527f4552433737373a20617070726f766520746f207a65726f2061646472657373006044820152606401610519565b6001600160a01b0383811660008181526008602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60405163555ddc6560e11b81526001600160a01b03861660048201527f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe8956024820152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca9060440160206040518083038186803b1580156111aa57600080fd5b505afa1580156111be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e29190611f17565b90506001600160a01b0381161561081457604051633ad5cbc160e11b81526001600160a01b038216906375ab978290611229908a908a908a908a908a908a90600401611f34565b600060405180830381600087803b15801561124357600080fd5b505af1158015611257573d6000803e3d6000fd5b5050505050505050505050565b6112a183604051806060016040528060278152602001611fe9602791396001600160a01b0388166000908152602081905260409020549190611386565b6001600160a01b0380871660009081526020819052604080822093909355908616815220546112d09084611914565b6001600160a01b0380861660008181526020819052604090819020939093559151878216918916907f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc826146779879061132990889088908890611f8e565b60405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161137691815260200190565b60405180910390a3505050505050565b600081848411156113aa5760405162461bcd60e51b81526004016105199190611a4f565b5060006113b78486611fb9565b95945050505050565b60405163555ddc6560e11b81526001600160a01b03861660048201527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b6024820152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca9060440160206040518083038186803b15801561143c57600080fd5b505afa158015611450573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114749190611f17565b90506001600160a01b038116156114f0576040516223de2960e01b81526001600160a01b038216906223de29906114b9908b908b908b908b908b908b90600401611f34565b600060405180830381600087803b1580156114d357600080fd5b505af11580156114e7573d6000803e3d6000fd5b5050505061158a565b811561158a576001600160a01b0386163b1561158a5760405162461bcd60e51b815260206004820152604d60248201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460448201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60648201526c1ad95b9cd49958da5c1a595b9d609a1b608482015260a401610519565b5050505050505050565b6001600160a01b0386166115ea5760405162461bcd60e51b815260206004820152601e60248201527f4552433737373a2073656e642066726f6d207a65726f206164647265737300006044820152606401610519565b6001600160a01b0385166116405760405162461bcd60e51b815260206004820152601c60248201527f4552433737373a2073656e6420746f207a65726f2061646472657373000000006044820152606401610519565b61164e87878787878761112e565b61165c878787878787611264565b610814878787878787876113c0565b6001600160a01b0384166116c15760405162461bcd60e51b815260206004820152601c60248201527f4552433737373a206d696e7420746f207a65726f2061646472657373000000006044820152606401610519565b6001546116ce9084611914565b6001556001600160a01b0384166000908152602081905260409020546116f49084611914565b6001600160a01b0385166000908152602081905260408120919091556117219086908686868660016113c0565b836001600160a01b0316856001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d85858560405161176893929190611f8e565b60405180910390a36040518381526001600160a01b038516906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050505050565b6001600160a01b03841661180f5760405162461bcd60e51b815260206004820152601e60248201527f4552433737373a206275726e2066726f6d207a65726f206164647265737300006044820152606401610519565b61181e8585600086868661112e565b61185b83604051806060016040528060238152602001612039602391396001600160a01b0387166000908152602081905260409020549190611386565b6001600160a01b0385166000908152602081905260409020556001546118819084611973565b600181905550836001600160a01b0316856001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a40988585856040516118ce93929190611f8e565b60405180910390a36040518381526000906001600160a01b038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016117aa565b6000806119218385611fd0565b905083811015610d1f5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610519565b6000610d1f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611386565b6020808252825182820181905260009190848201906040850190845b818110156119f65783516001600160a01b0316835292840192918401916001016119d1565b50909695505050505050565b6000815180845260005b81811015611a2857602081850181015186830182015201611a0c565b81811115611a3a576000602083870101525b50601f01601f19169290920160200192915050565b602081526000610d1f6020830184611a02565b6001600160a01b0381168114611a7757600080fd5b50565b60008060408385031215611a8d57600080fd5b8235611a9881611a62565b946020939093013593505050565b600080600060608486031215611abb57600080fd5b8335611ac681611a62565b92506020840135611ad681611a62565b929592945050506040919091013590565b60008083601f840112611af957600080fd5b50813567ffffffffffffffff811115611b1157600080fd5b602083019150836020828501011115611b2957600080fd5b9250929050565b60008060008060608587031215611b4657600080fd5b8435611b5181611a62565b935060208501359250604085013567ffffffffffffffff811115611b7457600080fd5b611b8087828801611ae7565b95989497509550505050565b600080600080600080600060a0888a031215611ba757600080fd5b8735611bb281611a62565b96506020880135611bc281611a62565b955060408801359450606088013567ffffffffffffffff80821115611be657600080fd5b611bf28b838c01611ae7565b909650945060808a0135915080821115611c0b57600080fd5b50611c188a828b01611ae7565b989b979a50959850939692959293505050565b600060208284031215611c3d57600080fd5b8135610d1f81611a62565b600080600080600080600060e0888a031215611c6357600080fd5b8735611c6e81611a62565b96506020880135611c7e81611a62565b95506040880135945060608801359350608088013560ff81168114611ca257600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611cd257600080fd5b8235611cdd81611a62565b91506020830135611ced81611a62565b809150509250929050565b60008060008060008060808789031215611d1157600080fd5b8635611d1c81611a62565b955060208701359450604087013567ffffffffffffffff80821115611d4057600080fd5b611d4c8a838b01611ae7565b90965094506060890135915080821115611d6557600080fd5b50611d7289828a01611ae7565b979a9699509497509295939492505050565b600080600060408486031215611d9957600080fd5b83359250602084013567ffffffffffffffff811115611db757600080fd5b611dc386828701611ae7565b9497909650939450505050565b600181811c90821680611de457607f821691505b60208210811415611e0557634e487b7160e01b600052602260045260246000fd5b50919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b0386811682528516602082015260408101849052608060608201819052600090611e689083018486611e0b565b979650505050505050565b60018060a01b0385168152836020820152606060408201526000611e9b606083018486611e0b565b9695505050505050565b60208082526021908201527f4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f6040820152603960f91b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b6000600019821415611f1057611f10611ee6565b5060010190565b600060208284031215611f2957600080fd5b8151610d1f81611a62565b6001600160a01b0387811682528681166020830152851660408201526060810184905260c060808201819052600090611f6f90830185611a02565b82810360a0840152611f818185611a02565b9998505050505050505050565b838152606060208201526000611fa76060830185611a02565b8281036040840152611e9b8185611a02565b600082821015611fcb57611fcb611ee6565b500390565b60008219821115611fe357611fe3611ee6565b50019056fe4552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a206275726e20616d6f756e7420657863656564732062616c616e6365a2646970667358221220d07cf24bc38047afdcc3c8d903ba34d15e81bcd0f38e12f84e15c87101aa436764736f6c63430008090033a2646970667358221220b32b8153fcd4189df904df49b98b5eab16be2d5867bd8abb9f6074ce91e7320c64736f6c63430008090033",
+ "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b57806326d9e9631462000064578063c6dbdf611462000097575b600080fd5b620000626200005c36600462000296565b620000a9565b005b6200007b6200007536600462000314565b620001a7565b6040516001600160a01b03909116815260200160405180910390f35b6000546001600160a01b03166200007b565b6000546001600160a01b0316336001600160a01b031614620000e85760405162461bcd60e51b8152600401620000df906200038f565b60405180910390fd5b6001600160a01b038116620001535760405162461bcd60e51b815260206004820152602a60248201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604482015269726f206164647265737360b01b6064820152608401620000df565b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d99060200160405180910390a150565b600080546001600160a01b0316336001600160a01b031614620001de5760405162461bcd60e51b8152600401620000df906200038f565b600086868686620001f76000546001600160a01b031690565b87604051620002069062000288565b620002179695949392919062000404565b604051809103906000f08015801562000234573d6000803e3d6000fd5b509050806001600160a01b03167ff57d2ded8330a4affd2fa52378069be534fe22288536537d1a1cfc061518450786868660405162000276939291906200044e565b60405180910390a29695505050505050565b6127b0806200047583390190565b600060208284031215620002a957600080fd5b81356001600160a01b0381168114620002c157600080fd5b9392505050565b60008083601f840112620002db57600080fd5b50813567ffffffffffffffff811115620002f457600080fd5b6020830191508360208285010111156200030d57600080fd5b9250929050565b6000806000806000606086880312156200032d57600080fd5b853567ffffffffffffffff808211156200034657600080fd5b6200035489838a01620002c8565b909750955060208801359150808211156200036e57600080fd5b506200037d88828901620002c8565b96999598509660400135949350505050565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6080815260006200041a60808301888a620003db565b82810360208401526200042f818789620003db565b6001600160a01b03959095166040840152505060600152949350505050565b60408152600062000464604083018587620003db565b905082602083015294935050505056fe60806040523480156200001157600080fd5b50604051620027b0380380620027b08339810160408190526200003491620005ff565b60408051600081526020808201909252855186928692916200005d916002919086019062000434565b5081516200007390600390602085019062000434565b50805162000089906004906020840190620004c3565b5060005b600454811015620000fd5760016005600060048481548110620000b457620000b462000692565b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff191691151591909117905580620000f481620006a8565b9150506200008d565b506040516329965a1d60e01b815230600482018190527fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce217705460248301526044820152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90606401600060405180830381600087803b1580156200017857600080fd5b505af11580156200018d573d6000803e3d6000fd5b50506040516329965a1d60e01b815230600482018190527faea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a60248301526044820152731820a4b7618bde71dce8cdc73aab6c95905fad2492506329965a1d9150606401600060405180830381600087803b1580156200020b57600080fd5b505af115801562000220573d6000803e3d6000fd5b50505050506001600160a01b038416151591506200028790505760405162461bcd60e51b815260206004820152601760248201527f53696465546f6b656e3a20456d707479204d696e74657200000000000000000060448201526064015b60405180910390fd5b6001811015620002da5760405162461bcd60e51b815260206004820152601a60248201527f53696465546f6b656e3a204772616e756c6172697479203c203100000000000060448201526064016200027e565b600980546001600160a01b0319166001600160a01b038416179055600a819055620003356200030862000343565b604051806040016040528060018152602001603160f81b8152504630620003dd60201b620010201760201c565b600b55506200070f92505050565b6060600280546200035490620006d2565b80601f01602080910402602001604051908101604052809291908181526020018280546200038290620006d2565b8015620003d35780601f10620003a757610100808354040283529160200191620003d3565b820191906000526020600020905b815481529060010190602001808311620003b557829003601f168201915b5050505050905090565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b8280546200044290620006d2565b90600052602060002090601f016020900481019282620004665760008555620004b1565b82601f106200048157805160ff1916838001178555620004b1565b82800160010185558215620004b1579182015b82811115620004b157825182559160200191906001019062000494565b50620004bf9291506200051b565b5090565b828054828255906000526020600020908101928215620004b1579160200282015b82811115620004b157825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620004e4565b5b80821115620004bf57600081556001016200051c565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200055a57600080fd5b81516001600160401b038082111562000577576200057762000532565b604051601f8301601f19908116603f01168101908282118183101715620005a257620005a262000532565b81604052838152602092508683858801011115620005bf57600080fd5b600091505b83821015620005e35785820183015181830184015290820190620005c4565b83821115620005f55760008385830101525b9695505050505050565b600080600080608085870312156200061657600080fd5b84516001600160401b03808211156200062e57600080fd5b6200063c8883890162000548565b955060208701519150808211156200065357600080fd5b50620006628782880162000548565b604087015190945090506001600160a01b03811681146200068257600080fd5b6060959095015193969295505050565b634e487b7160e01b600052603260045260246000fd5b6000600019821415620006cb57634e487b7160e01b600052601160045260246000fd5b5060010190565b600181811c90821680620006e757607f821691505b602082108114156200070957634e487b7160e01b600052602260045260246000fd5b50919050565b612091806200071f6000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80637ecebe00116100de578063d95b637111610097578063f698da2511610071578063f698da2514610380578063fad8b32a14610389578063fc673c4f1461039c578063fe9d9303146103af57600080fd5b8063d95b637114610321578063dcdc7dd014610334578063dd62ed3e1461034757600080fd5b80637ecebe00146102ad578063959b8c3f146102cd57806395d89b41146102e05780639bd9bbc6146102e8578063a9059cbb146102fb578063d505accf1461030e57600080fd5b806330adf81f1161013057806330adf81f1461021e578063313ce567146102455780634000aea014610254578063556f0dc71461026757806362ad1b831461026f57806370a082311461028457600080fd5b806306e485381461017857806306fdde031461019657806307546172146101ab578063095ea7b3146101d657806318160ddd146101f957806323b872dd1461020b575b600080fd5b6101806103c2565b60405161018d91906119b5565b60405180910390f35b61019e610424565b60405161018d9190611a4f565b6009546101be906001600160a01b031681565b6040516001600160a01b03909116815260200161018d565b6101e96101e4366004611a7a565b6104ad565b604051901515815260200161018d565b6001545b60405190815260200161018d565b6101e9610219366004611aa6565b6104c5565b6101fd7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6040516012815260200161018d565b6101e9610262366004611b30565b61066d565b600a546101fd565b61028261027d366004611b8c565b610774565b005b6101fd610292366004611c2b565b6001600160a01b031660009081526020819052604090205490565b6101fd6102bb366004611c2b565b600c6020526000908152604090205481565b6102826102db366004611c2b565b61081d565b61019e61093b565b6102826102f6366004611b30565b61094a565b6101e9610309366004611a7a565b6109a4565b61028261031c366004611c48565b610a87565b6101e961032f366004611cbf565b610c84565b610282610342366004611cf8565b610d26565b6101fd610355366004611cbf565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b6101fd600b5481565b610282610397366004611c2b565b610e13565b6102826103aa366004611cf8565b610f2f565b6102826103bd366004611d84565b610fcb565b6060600480548060200260200160405190810160405280929190818152602001828054801561041a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116103fc575b5050505050905090565b60606002805461043390611dd0565b80601f016020809104026020016040519081016040528092919081815260200182805461045f90611dd0565b801561041a5780601f106104815761010080835404028352916020019161041a565b820191906000526020600020905b81548152906001019060200180831161048f57509395945050505050565b6000336104bb818585611077565b5060019392505050565b60006001600160a01b0383166105225760405162461bcd60e51b815260206004820181905260248201527f4552433737373a207472616e7366657220746f207a65726f206164647265737360448201526064015b60405180910390fd5b6001600160a01b0384166105835760405162461bcd60e51b815260206004820152602260248201527f4552433737373a207472616e736665722066726f6d207a65726f206164647265604482015261737360f01b6064820152608401610519565b60003390506105b481868686604051806020016040528060008152506040518060200160405280600081525061112e565b6105e0818686866040518060200160405280600081525060405180602001604052806000815250611264565b610634858261062f86604051806060016040528060298152602001612010602991396001600160a01b03808c166000908152600860209081526040808320938b16835292905220549190611386565b611077565b61066281868686604051806020016040528060008152506040518060200160405280600081525060006113c0565b506001949350505050565b6000803390506106c58182888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805160208101909152818152935091506115949050565b7fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1681878787876040516106fc959493929190611e34565b60405180910390a1604051635260769b60e11b81526001600160a01b0387169063a4c0ed3690610736908490899089908990600401611e73565b600060405180830381600087803b15801561075057600080fd5b505af1158015610764573d6000803e3d6000fd5b5060019998505050505050505050565b61077e3388610c84565b61079a5760405162461bcd60e51b815260040161051990611ea5565b6108143388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a915089908190840183828082843760009201919091525060019250611594915050565b50505050505050565b336001600160a01b03821614156108825760405162461bcd60e51b8152602060048201526024808201527f4552433737373a20617574686f72697a696e672073656c66206173206f70657260448201526330ba37b960e11b6064820152608401610519565b6001600160a01b03811660009081526005602052604090205460ff16156108d3573360009081526007602090815260408083206001600160a01b03851684529091529020805460ff19169055610902565b3360009081526006602090815260408083206001600160a01b03851684529091529020805460ff191660011790555b60405133906001600160a01b038316907ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f990600090a350565b60606003805461043390611dd0565b61099e3333868686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060408051602081019091529081529250600191506115949050565b50505050565b60006001600160a01b0383166109fc5760405162461bcd60e51b815260206004820181905260248201527f4552433737373a207472616e7366657220746f207a65726f20616464726573736044820152606401610519565b6000339050610a2d81828686604051806020016040528060008152506040518060200160405280600081525061112e565b610a59818286866040518060200160405280600081525060405180602001604052806000815250611264565b6104bb81828686604051806020016040528060008152506040518060200160405280600081525060006113c0565b42841015610acc5760405162461bcd60e51b815260206004820152601260248201527114da5919551bdad95b8e881156141254915160721b6044820152606401610519565b600b546001600160a01b0388166000908152600c6020526040812080549192610b949290917f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918c918c918c9188610b2383611efc565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810188905260e0016040516020818303038152906040528051906020012060405161190160f01b8152600281019290925260228201526042902090565b6040805160008082526020820180845284905260ff88169282019290925260608101869052608081018590529192509060019060a0016020604051602081039080840390855afa158015610bec573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610c225750886001600160a01b0316816001600160a01b0316145b610c6e5760405162461bcd60e51b815260206004820152601c60248201527f53696465546f6b656e3a20494e56414c49445f5349474e4154555245000000006044820152606401610519565b610c79898989611077565b505050505050505050565b6000816001600160a01b0316836001600160a01b03161480610cef57506001600160a01b03831660009081526005602052604090205460ff168015610cef57506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b80610d1f57506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b6009546001600160a01b0316336001600160a01b031614610d955760405162461bcd60e51b815260206004820152602360248201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6044820152623a32b960e91b6064820152608401610519565b610e0b33878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061166b92505050565b505050505050565b6001600160a01b038116331415610e765760405162461bcd60e51b815260206004820152602160248201527f4552433737373a207265766f6b696e672073656c66206173206f70657261746f6044820152603960f91b6064820152608401610519565b6001600160a01b03811660009081526005602052604090205460ff1615610eca573360009081526007602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610ef6565b3360009081526006602090815260408083206001600160a01b03851684529091529020805460ff191690555b60405133906001600160a01b038316907f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa190600090a350565b610f393387610c84565b610f555760405162461bcd60e51b815260040161051990611ea5565b610e0b33878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b0181900481028201810190925289815292508991508890819084018382808284376000920191909152506117b992505050565b61101b33338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604080516020810190915290815292506117b9915050565b505050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b6001600160a01b0382166110cd5760405162461bcd60e51b815260206004820152601f60248201527f4552433737373a20617070726f766520746f207a65726f2061646472657373006044820152606401610519565b6001600160a01b0383811660008181526008602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60405163555ddc6560e11b81526001600160a01b03861660048201527f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe8956024820152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca9060440160206040518083038186803b1580156111aa57600080fd5b505afa1580156111be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e29190611f17565b90506001600160a01b0381161561081457604051633ad5cbc160e11b81526001600160a01b038216906375ab978290611229908a908a908a908a908a908a90600401611f34565b600060405180830381600087803b15801561124357600080fd5b505af1158015611257573d6000803e3d6000fd5b5050505050505050505050565b6112a183604051806060016040528060278152602001611fe9602791396001600160a01b0388166000908152602081905260409020549190611386565b6001600160a01b0380871660009081526020819052604080822093909355908616815220546112d09084611914565b6001600160a01b0380861660008181526020819052604090819020939093559151878216918916907f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc826146779879061132990889088908890611f8e565b60405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161137691815260200190565b60405180910390a3505050505050565b600081848411156113aa5760405162461bcd60e51b81526004016105199190611a4f565b5060006113b78486611fb9565b95945050505050565b60405163555ddc6560e11b81526001600160a01b03861660048201527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b6024820152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca9060440160206040518083038186803b15801561143c57600080fd5b505afa158015611450573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114749190611f17565b90506001600160a01b038116156114f0576040516223de2960e01b81526001600160a01b038216906223de29906114b9908b908b908b908b908b908b90600401611f34565b600060405180830381600087803b1580156114d357600080fd5b505af11580156114e7573d6000803e3d6000fd5b5050505061158a565b811561158a576001600160a01b0386163b1561158a5760405162461bcd60e51b815260206004820152604d60248201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460448201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60648201526c1ad95b9cd49958da5c1a595b9d609a1b608482015260a401610519565b5050505050505050565b6001600160a01b0386166115ea5760405162461bcd60e51b815260206004820152601e60248201527f4552433737373a2073656e642066726f6d207a65726f206164647265737300006044820152606401610519565b6001600160a01b0385166116405760405162461bcd60e51b815260206004820152601c60248201527f4552433737373a2073656e6420746f207a65726f2061646472657373000000006044820152606401610519565b61164e87878787878761112e565b61165c878787878787611264565b610814878787878787876113c0565b6001600160a01b0384166116c15760405162461bcd60e51b815260206004820152601c60248201527f4552433737373a206d696e7420746f207a65726f2061646472657373000000006044820152606401610519565b6001546116ce9084611914565b6001556001600160a01b0384166000908152602081905260409020546116f49084611914565b6001600160a01b0385166000908152602081905260408120919091556117219086908686868660016113c0565b836001600160a01b0316856001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d85858560405161176893929190611f8e565b60405180910390a36040518381526001600160a01b038516906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050505050565b6001600160a01b03841661180f5760405162461bcd60e51b815260206004820152601e60248201527f4552433737373a206275726e2066726f6d207a65726f206164647265737300006044820152606401610519565b61181e8585600086868661112e565b61185b83604051806060016040528060238152602001612039602391396001600160a01b0387166000908152602081905260409020549190611386565b6001600160a01b0385166000908152602081905260409020556001546118819084611973565b600181905550836001600160a01b0316856001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a40988585856040516118ce93929190611f8e565b60405180910390a36040518381526000906001600160a01b038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016117aa565b6000806119218385611fd0565b905083811015610d1f5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610519565b6000610d1f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611386565b6020808252825182820181905260009190848201906040850190845b818110156119f65783516001600160a01b0316835292840192918401916001016119d1565b50909695505050505050565b6000815180845260005b81811015611a2857602081850181015186830182015201611a0c565b81811115611a3a576000602083870101525b50601f01601f19169290920160200192915050565b602081526000610d1f6020830184611a02565b6001600160a01b0381168114611a7757600080fd5b50565b60008060408385031215611a8d57600080fd5b8235611a9881611a62565b946020939093013593505050565b600080600060608486031215611abb57600080fd5b8335611ac681611a62565b92506020840135611ad681611a62565b929592945050506040919091013590565b60008083601f840112611af957600080fd5b50813567ffffffffffffffff811115611b1157600080fd5b602083019150836020828501011115611b2957600080fd5b9250929050565b60008060008060608587031215611b4657600080fd5b8435611b5181611a62565b935060208501359250604085013567ffffffffffffffff811115611b7457600080fd5b611b8087828801611ae7565b95989497509550505050565b600080600080600080600060a0888a031215611ba757600080fd5b8735611bb281611a62565b96506020880135611bc281611a62565b955060408801359450606088013567ffffffffffffffff80821115611be657600080fd5b611bf28b838c01611ae7565b909650945060808a0135915080821115611c0b57600080fd5b50611c188a828b01611ae7565b989b979a50959850939692959293505050565b600060208284031215611c3d57600080fd5b8135610d1f81611a62565b600080600080600080600060e0888a031215611c6357600080fd5b8735611c6e81611a62565b96506020880135611c7e81611a62565b95506040880135945060608801359350608088013560ff81168114611ca257600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611cd257600080fd5b8235611cdd81611a62565b91506020830135611ced81611a62565b809150509250929050565b60008060008060008060808789031215611d1157600080fd5b8635611d1c81611a62565b955060208701359450604087013567ffffffffffffffff80821115611d4057600080fd5b611d4c8a838b01611ae7565b90965094506060890135915080821115611d6557600080fd5b50611d7289828a01611ae7565b979a9699509497509295939492505050565b600080600060408486031215611d9957600080fd5b83359250602084013567ffffffffffffffff811115611db757600080fd5b611dc386828701611ae7565b9497909650939450505050565b600181811c90821680611de457607f821691505b60208210811415611e0557634e487b7160e01b600052602260045260246000fd5b50919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b0386811682528516602082015260408101849052608060608201819052600090611e689083018486611e0b565b979650505050505050565b60018060a01b0385168152836020820152606060408201526000611e9b606083018486611e0b565b9695505050505050565b60208082526021908201527f4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f6040820152603960f91b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b6000600019821415611f1057611f10611ee6565b5060010190565b600060208284031215611f2957600080fd5b8151610d1f81611a62565b6001600160a01b0387811682528681166020830152851660408201526060810184905260c060808201819052600090611f6f90830185611a02565b82810360a0840152611f818185611a02565b9998505050505050505050565b838152606060208201526000611fa76060830185611a02565b8281036040840152611e9b8185611a02565b600082821015611fcb57611fcb611ee6565b500390565b60008219821115611fe357611fe3611ee6565b50019056fe4552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a206275726e20616d6f756e7420657863656564732062616c616e6365a2646970667358221220d07cf24bc38047afdcc3c8d903ba34d15e81bcd0f38e12f84e15c87101aa436764736f6c63430008090033a2646970667358221220b32b8153fcd4189df904df49b98b5eab16be2d5867bd8abb9f6074ce91e7320c64736f6c63430008090033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 11417,
+ "contract": "contracts/SideTokenFactory/SideTokenFactory.sol:SideTokenFactory",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/bsctestnet/solcInputs/f27c8e19ddc2cd2a95162a1eabc0e272.json b/bridge/deployments/bsctestnet/solcInputs/f27c8e19ddc2cd2a95162a1eabc0e272.json
new file mode 100644
index 000000000..3b6294411
--- /dev/null
+++ b/bridge/deployments/bsctestnet/solcInputs/f27c8e19ddc2cd2a95162a1eabc0e272.json
@@ -0,0 +1,294 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/math/SafeMath.sol\";\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\n\nimport \"../interface/IAllowTokens.sol\";\n\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\n\tusing SafeMath for uint256;\n\n\taddress constant private NULL_ADDRESS = address(0);\n\tuint256 constant public MAX_TYPES = 250;\n\tmapping (address => TokenInfo) public allowedTokens;\n\tmapping (uint256 => Limits) public typeLimits;\n\tuint256 public smallAmountConfirmations;\n\tuint256 public mediumAmountConfirmations;\n\tuint256 public largeAmountConfirmations;\n\tstring[] public typeDescriptions;\n\n\tevent SetToken(address indexed _tokenAddress, uint256 _typeId);\n\tevent AllowedTokenRemoved(address indexed _tokenAddress);\n\tevent TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\n\tevent TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\n\tevent UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\n\tevent ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\n\n\tmodifier notNull(address _address) {\n\t\trequire(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\n\t\t_;\n\t}\n\n\tfunction initialize(\n\t\taddress _manager,\n\t\taddress _primary,\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations,\n\t\tTypeInfo[] memory typesInfo) public initializer {\n\t\tUpgradableOwnable.initialize(_manager);\n\t\tUpgradableSecondary.__Secondary_init(_primary);\n\t\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t\tfor(uint i = 0; i < typesInfo.length; i = i + 1) {\n\t\t\t_addTokenType(typesInfo[i].description, typesInfo[i].limits);\n\t\t}\n\t}\n\n\tfunction version() override external pure returns (string memory) {\n\t\treturn \"v1\";\n\t}\n\n\tfunction tokenInfo(address tokenAddress) public view returns(TokenInfo memory) {\n\t\treturn allowedTokens[tokenAddress];\n\t}\n\n\tfunction setTokenInfoByTokenAddress(address tokenAddress, TokenInfo memory info) public {\n\t\trequire(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n\t\tallowedTokens[tokenAddress] = info;\n\t}\n\n\tfunction getInfoAndLimits(\n\t\taddress tokenAddress\n\t) public view override returns (\n\t\tTokenInfo memory info,\n\t\tLimits memory limit\n\t) {\n\t\tinfo = tokenInfo(tokenAddress);\n\t\tlimit = typeLimits[info.typeId];\n\t\treturn (info, limit);\n\t}\n\n\tfunction calcMaxWithdraw(address token) public view override returns (uint256 maxWithdraw) {\n\t\t(TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\n\t\treturn _calcMaxWithdraw(info, limits);\n\t}\n\n\tfunction _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\n\t\t// solium-disable-next-line security/no-block-members\n\t\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n\t\t\tinfo.spentToday = 0;\n\t\t}\n\t\tif (limits.daily <= info.spentToday) {\n\t\t\treturn 0;\n\t\t}\n\t\tmaxWithdraw = limits.daily - info.spentToday;\n\t\tif (maxWithdraw > limits.max) {\n\t\t\tmaxWithdraw = limits.max;\n\t\t}\n\t\treturn maxWithdraw;\n\t}\n\n\tfunction updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\n\t\t(TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\n\t\trequire(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\n\t\trequire(amount >= limit.min, \"AllowTokens: Lower than limit\");\n\n\t\t// solium-disable-next-line security/no-block-members\n\t\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n\t\t\t// solium-disable-next-line security/no-block-members\n\t\t\tinfo.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n\t\t\tinfo.spentToday = 0;\n\t\t}\n\t\tuint maxWithdraw = _calcMaxWithdraw(info, limit);\n\t\trequire(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\n\t\tinfo.spentToday = info.spentToday.add(amount);\n\t\tsetTokenInfoByTokenAddress(token, info);\n\n\t\temit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\n\t}\n\n\tfunction _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\n\t\trequire(bytes(description).length > 0, \"AllowTokens: Empty description\");\n\t\tlen = typeDescriptions.length;\n\t\trequire(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\n\t\ttypeDescriptions.push(description);\n\t\t_setTypeLimits(len, limits);\n\t\temit TokenTypeAdded(len, description);\n\t\treturn len;\n\t}\n\n\tfunction addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\n\t\treturn _addTokenType(description, limits);\n\t}\n\n\tfunction _setTypeLimits(uint256 typeId, Limits memory limits) private {\n\t\trequire(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\n\t\trequire(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\n\t\trequire(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\n\t\trequire(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\n\t\trequire(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\n\t\ttypeLimits[typeId] = limits;\n\t\temit TypeLimitsChanged(typeId, limits);\n\t}\n\n\tfunction setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\n\t\t_setTypeLimits(typeId, limits);\n\t}\n\n\tfunction getTypesLimits() external view override returns(Limits[] memory limits) {\n\t\tlimits = new Limits[](typeDescriptions.length);\n\t\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\n\t\t\tlimits[i] = typeLimits[i];\n\t\t}\n\t\treturn limits;\n\t}\n\n\tfunction getTypeDescriptionsLength() external view override returns(uint256) {\n\t\treturn typeDescriptions.length;\n\t}\n\n\tfunction getTypeDescriptions() external view override returns(string[] memory descriptions) {\n\t\tdescriptions = new string[](typeDescriptions.length);\n\t\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\n\t\t\tdescriptions[i] = typeDescriptions[i];\n\t\t}\n\t\treturn descriptions;\n\t}\n\n\tfunction isTokenAllowed(address token) public view notNull(token) override returns (bool) {\n\t\treturn tokenInfo(token).allowed;\n\t}\n\n\tfunction setToken(address token, uint256 typeId) override public notNull(token) {\n\t\trequire(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n\t\trequire(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\n\t\tTokenInfo memory info = tokenInfo(token);\n\t\tinfo.allowed = true;\n\t\tinfo.typeId = typeId;\n\t\tsetTokenInfoByTokenAddress(token, info);\n\t\temit SetToken(token, typeId);\n\t}\n\n\tfunction setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\n\t\trequire(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\n\t\tfor(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\n\t\t\tsetToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\n\t\t}\n\t}\n\n\tfunction removeAllowedToken(address token) external notNull(token) onlyOwner {\n\t\tTokenInfo memory info = tokenInfo(token);\n\t\trequire(info.allowed, \"AllowTokens: Not Allowed\");\n\t\tinfo.allowed = false;\n\t\tsetTokenInfoByTokenAddress(token, info);\n\t\temit AllowedTokenRemoved(token);\n\t}\n\n\tfunction setConfirmations(\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations) external onlyOwner {\n\t\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t}\n\n\tfunction _setConfirmations(\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations) private {\n\t\trequire(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\n\t\trequire(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\n\t\tsmallAmountConfirmations = _smallAmountConfirmations;\n\t\tmediumAmountConfirmations = _mediumAmountConfirmations;\n\t\tlargeAmountConfirmations = _largeAmountConfirmations;\n\t\temit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t}\n\n\tfunction getConfirmations() external view override\n\t\treturns (\n\t\tuint256 smallAmount,\n\t\tuint256 mediumAmount,\n\t\tuint256 largeAmount\n\t) {\n\t\treturn (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\n\t}\n\n}\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @title Initializable\n *\n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(initializing || !initialized, \"Contract instance is already initialized\");\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\n * the owner.\n */\ncontract UpgradableOwnable is Initializable, Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function initialize(address sender) public initializer {\n _owner = sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * > Note: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\ncontract UpgradableSecondary is Initializable, Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n function __Secondary_init(address sender) public initializer {\n _primary = sender;\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(recipient);\n }\n\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IAllowTokens {\n\n\tstruct Limits {\n\t\tuint256 min;\n\t\tuint256 max;\n\t\tuint256 daily;\n\t\tuint256 mediumAmount;\n\t\tuint256 largeAmount;\n\t}\n\n\tstruct TokenInfo {\n\t\tbool allowed;\n\t\tuint256 typeId;\n\t\tuint256 spentToday;\n\t\tuint256 lastDay;\n\t}\n\n\tstruct TypeInfo {\n\t\tstring description;\n\t\tLimits limits;\n\t}\n\n\tstruct TokensAndType {\n\t\taddress token;\n\t\tuint256 typeId;\n\t}\n\n\tfunction version() external pure returns (string memory);\n\n\tfunction getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\n\n\tfunction calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\n\n\tfunction getTypesLimits() external view returns(Limits[] memory limits);\n\n\tfunction getTypeDescriptionsLength() external view returns(uint256);\n\n\tfunction getTypeDescriptions() external view returns(string[] memory descriptions);\n\n\tfunction setToken(address token, uint256 typeId) external;\n\n\tfunction getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\n\n\tfunction isTokenAllowed(address token) external view returns (bool);\n\n\tfunction updateTokenTransfer(address token, uint256 amount) external;\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n\n function _msgSender() internal view returns (address payable) {\n return payable(msg.sender);\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
+ },
+ "contracts/nftbridge/NFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC721/IERC721.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Metadata.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Enumerable.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Receiver.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./INFTBridge.sol\";\nimport \"./ISideNFTToken.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract NFTBridge is\n Initializable,\n INFTBridge,\n UpgradablePausable,\n UpgradableOwnable,\n ReentrancyGuard,\n IERC721Receiver {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address internal constant NULL_ADDRESS = address(0);\n bytes32 internal constant NULL_HASH = bytes32(0);\n IERC1820Registry internal constant ERC1820 =\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address payable internal federation;\n uint256 internal fixedFee;\n\n mapping(uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain;\n mapping(address => OriginalNft) public originalTokenBySideToken;\n mapping(uint256 => mapping(address => bool)) public isAddressFromCrossedOriginalTokenByChain; // uint256 => address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n\n IAllowTokens public allowTokens;\n ISideNFTTokenFactory public sideTokenFactory;\n bool public isUpgrading;\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\n event Upgrading(bool _isUpgrading);\n\n function initialize(\n address _manager,\n address payable _federation,\n address _allowTokens,\n address _sideTokenFactory\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\n federation = _federation;\n ERC1820.setInterfaceImplementer(\n address(this),\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\n address(this)\n );\n }\n\n function version() external pure override returns (string memory) {\n return \"v1\";\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _tokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n uint256\t_destinationChainId\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"NFTBridge: Not Federation\");\n checkChainId(_originChainId);\n shouldBeCurrentChainId(_destinationChainId);\n require(\n isAddressFromCrossedOriginalToken(_originChainId, _tokenAddress) ||\n getSideTokenByOriginalToken(_originChainId, _tokenAddress) != NULL_ADDRESS,\n \"NFTBridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"NFTBridge: Null To\");\n require(_from != NULL_ADDRESS, \"NFTBridge: Null From\");\n require(_blockHash != NULL_HASH, \"NFTBridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"NFTBridge: Null TxHash\");\n require(\n transactionDataHashes[_transactionHash] == bytes32(0),\n \"NFTBridge: Already accepted\"\n );\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _blockHash,\n _transactionHash,\n _logIndex,\n _originChainId,\n\t _destinationChainId\n );\n\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\n require(!claimed[_transactionDataHash], \"NFTBridge: Already claimed\");\n transactionDataHashes[_transactionHash] = _transactionDataHash;\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\n// senderAddresses[_transactionHash] = _from;\n\n emit AcceptedNFTCrossTransfer(\n _transactionHash,\n _tokenAddress,\n _to,\n _from,\n _tokenId,\n _blockHash,\n _logIndex,\n _originChainId,\n\t _destinationChainId\n );\n }\n\n function shouldBeCurrentChainId(uint256 chainId) internal view {\n require(chainId == block.chainid, \"NFTBridge: Not block.chainid\");\n }\n\n function getSideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\n return sideTokenByOriginalTokenByChain[chainId][originalToken];\n }\n\n function _setSideTokenByOriginalToken(uint256 chainId, address originalToken, address sideToken) internal {\n sideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\n }\n\n function getOriginalTokenBySideToken(address sideToken) public view returns(OriginalNft memory) {\n return originalTokenBySideToken[sideToken];\n }\n\n function _setOriginalTokenBySideToken(address sideToken, OriginalNft memory originalToken) internal {\n originalTokenBySideToken[sideToken] = originalToken;\n }\n\n function isAddressFromCrossedOriginalToken(uint256 chainId, address originalToken) public view returns(bool addressHasCrossed) {\n return isAddressFromCrossedOriginalTokenByChain[chainId][originalToken];\n }\n\n function _setAddressFromCrossedOriginalToken(uint256 chainId, address originalToken, bool addressHasCrossed) internal {\n isAddressFromCrossedOriginalTokenByChain[chainId][originalToken] = addressHasCrossed;\n }\n\n function createSideNFTToken(\n address _originalTokenAddress,\n string calldata _tokenSymbol,\n string calldata _tokenName,\n string calldata _baseURI,\n string calldata _contractURI,\n uint256 originChainId\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"NFTBridge: Null original token address\");\n\n require(getSideTokenByOriginalToken(originChainId, _originalTokenAddress) == NULL_ADDRESS, \"NFTBridge: Side token already exists\");\n\n // Create side token\n address sideTokenAddress = sideTokenFactory.createSideNFTToken(_tokenName, _tokenSymbol, _baseURI, _contractURI);\n\n _setSideTokenByOriginalToken(originChainId, _originalTokenAddress, sideTokenAddress);\n\n OriginalNft memory originalNft;\n originalNft.originChainId = originChainId;\n originalNft.nftAddress = _originalTokenAddress;\n _setOriginalTokenBySideToken(sideTokenAddress, originalNft);\n\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, _tokenSymbol, originChainId);\n }\n\n function checkChainId(uint256 chainId) internal pure {\n require(chainId > 0, \"NFTBridge: ChainId is 0\");\n }\n\n function claim(NFTClaimData calldata _claimData) external override {\n _claim(_claimData, _claimData.to);\n }\n\n function claimFallback(NFTClaimData calldata _claimData) external override {\n require(_msgSender() == _claimData.from, \"NFTBridge: invalid sender\");\n _claim(_claimData, _msgSender());\n }\n\n function _claim(\n NFTClaimData calldata _claimData,\n address payable _receiver\n ) internal {\n address tokenAddress = _claimData.tokenAddress;\n uint256 tokenId = _claimData.tokenId;\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.from,\n tokenId,\n tokenAddress,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex,\n _claimData.originChainId,\n block.chainid\n );\n\n\n require(\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\n \"NFTBridge: Wrong txDataHash\"\n );\n require(!claimed[transactionDataHash], \"NFTBridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (isAddressFromCrossedOriginalToken(_claimData.originChainId, tokenAddress)) {\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\n } else {\n address sideTokenAddress = getSideTokenByOriginalToken(_claimData.originChainId, tokenAddress);\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\n }\n\n emit ClaimedNFTToken(\n _claimData.transactionHash,\n tokenAddress,\n _claimData.to,\n _claimData.from,\n _claimData.tokenId,\n _claimData.blockHash,\n _claimData.logIndex,\n _receiver,\n _claimData.originChainId,\n block.chainid\n );\n }\n\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\"creator()\"));\n if (success) {\n return abi.decode(data, (address));\n }\n\n return IERC721(tokenAddress).ownerOf(tokenId);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId,\n uint256 destinationChainId\n ) public payable override {\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\n address payable sender = _msgSender();\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\n\n crossTokens(tokenAddress, to, tokenCreator, tokenId, destinationChainId, \"\");\n\n if (fixedFee == 0) {\n return;\n }\n uint256 msgValue = msg.value;\n require(msgValue >= fixedFee, \"NFTBridge: value is smaller than fixed fee\");\n\n // Send the payment to the MultiSig of the Federation\n federation.transfer(fixedFee);\n\n if (msgValue > fixedFee) { // refund of unused value\n sender.transfer(msgValue.sub(fixedFee));\n }\n }\n\n function crossTokens(\n address tokenAddress,\n address to,\n address tokenCreator,\n uint256 tokenId,\n uint256 destinationChainId,\n bytes memory userData\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\n require(block.chainid != destinationChainId, \"NFTBridge: destination chain id equal current chain id\");\n _setAddressFromCrossedOriginalToken(destinationChainId, tokenAddress, true);\n\n string memory tokenURI = IERC721Metadata(tokenAddress).tokenURI(tokenId);\n\n OriginalNft memory originalToken = getOriginalTokenBySideToken(tokenAddress);\n address originalTokenAddress = tokenAddress;\n if (originalToken.nftAddress != NULL_ADDRESS) {\n ERC721Burnable(tokenAddress).burn(tokenId);\n originalTokenAddress = originalToken.nftAddress;\n }\n\n uint256 totalSupply = IERC721Enumerable(tokenAddress).totalSupply();\n emit Cross(\n originalTokenAddress,\n to,\n destinationChainId,\n _msgSender(),\n block.chainid,\n tokenCreator,\n totalSupply,\n tokenId,\n tokenURI,\n userData\n );\n }\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n ) public pure override returns (bytes32) {\n return keccak256(\n abi.encodePacked(\n _blockHash,\n _transactionHash,\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _logIndex,\n _originChainId,\n _destinationChainId\n )\n );\n }\n\n function setFixedFee(uint256 amount) external onlyOwner {\n fixedFee = amount;\n emit FixedFeeNFTChanged(fixedFee);\n }\n\n function getFixedFee() external view override returns (uint256) {\n return fixedFee;\n }\n\n function changeFederation(address payable newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"NFTBridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"NFTBridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns (address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\n require(\n newSideNFTTokenFactory != NULL_ADDRESS,\n \"NFTBridge: empty SideTokenFactory\"\n );\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionDataHashes[transactionHash]];\n }\n\n /**\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\n/**\n * @title Helps contracts guard against reentrancy attacks.\n * @author Remco Bloemen , Eenae \n * @dev If you mark a function `nonReentrant`, you should also\n * mark it `external`.\n */\ncontract ReentrancyGuard is Initializable {\n /// @dev counter to allow mutex lock with only one SSTORE operation\n uint256 private _guardCounter;\n\n function initialize() public initializer {\n // The counter starts at one to prevent changing it from zero to a non-zero\n // value, which is a more expensive operation.\n _guardCounter = 1;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _guardCounter += 1;\n uint256 localCounter = _guardCounter;\n _;\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\n }\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\nimport \"../access/roles/UpgradablePauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n function __Pausable_init(address sender) public initializer {\n UpgradablePauserRole.__PauserRol_init(sender);\n\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as `account`'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `_account`.\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `_implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\n\n /**\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `_account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {ERC20Detailed}.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeERC20: low-level call failed\");\n\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n */\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./ERC721.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721Burnable is Context, ERC721 {\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n _burn(tokenId);\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\nlibrary LibEIP712 {\n\n // Hash of the EIP712 Domain Separator Schema\n // keccak256(abi.encodePacked(\n // \"EIP712Domain(\",\n // \"string name,\",\n // \"string version,\",\n // \"uint256 chainId,\",\n // \"address verifyingContract\",\n // \")\"\n // ))\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n /// @dev Calculates a EIP712 domain separator.\n /// @param name The EIP712 domain name.\n /// @param version The EIP712 domain version.\n /// @param verifyingContract The EIP712 verifying contract.\n /// @return result EIP712 domain separator.\n function hashEIP712Domain(\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n // keccak256(bytes(name)),\n // keccak256(bytes(version)),\n // chainId,\n // uint256(verifyingContract)\n // ))\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Calculate hashes of dynamic data\n let nameHash := keccak256(add(name, 32), mload(name))\n let versionHash := keccak256(add(version, 32), mload(version))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n // Store params in memory\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), nameHash)\n mstore(add(memPtr, 64), versionHash)\n mstore(add(memPtr, 96), chainId)\n mstore(add(memPtr, 128), verifyingContract)\n\n // Compute hash\n result := keccak256(memPtr, 160)\n }\n return result;\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\n /// with getDomainHash().\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to the given EIP712 Domain.\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n internal\n pure\n returns (bytes32 result)\n {\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct\n // ));\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nlibrary LibUtils {\n\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\n return uint256(10)**(18-decimals);\n }\n\n function getDecimals(address tokenToUse) internal view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"LibUtils: No decimals\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n return uint8(abi.decode(data, (uint256)));\n }\n\n function getGranularity(address tokenToUse) internal view returns (uint256) {\n //support granularity if ERC777\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\n require(success, \"LibUtils: No granularity\");\n\n return abi.decode(data, (uint256));\n }\n\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n addr := mload(add(bys,20))\n }\n }\n\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\n require(_bytes.length >= _start + 20, \"LibUtils: toAddress_outOfBounds\");\n address tempAddress;\n\n assembly {\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n }\n\n return tempAddress;\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\n require(_bytes.length >= _start + 16, \"LibUtils: toUint128_outOfBounds\");\n uint128 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x10), _start))\n }\n\n return tempUint;\n }\n\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\n\t\trequire(_bytes.length >= _start + 32, \"LibUtils: toUint256_outOfBounds\");\n\t\tuint256 tempUint;\n\n // solium-disable-next-line security/no-inline-assembly\n\t\tassembly {\n\t\t\ttempUint := mload(add(add(_bytes, 0x20), _start))\n\t\t}\n\n\t\treturn tempUint;\n\t}\n}\n"
+ },
+ "contracts/nftbridge/INFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface INFTBridge {\n\n struct NFTClaimData {\n address payable to;\n address from;\n uint256 tokenId;\n address tokenAddress;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n uint256 originChainId;\n }\n\n\tstruct OriginalNft {\n\t\taddress nftAddress;\n\t\tuint256 originChainId;\n\t}\n\n function version() external pure returns (string memory);\n\n function getFixedFee() external view returns (uint256);\n\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId,\n uint256 destinationChainId\n ) external payable;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\n */\n function claim(NFTClaimData calldata _claimData) external;\n\n function claimFallback(NFTClaimData calldata _claimData) external;\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\t\tuint256\t_destinationChainId\n ) external returns (bytes32);\n\n event Cross(\n address indexed _originalTokenAddress,\n address indexed _to,\n uint256 indexed _destinationChainId,\n address _from,\n uint256 _originChainId,\n address _tokenCreator,\n uint256 _totalSupply,\n uint256 _tokenId,\n string _tokenURI,\n bytes _userData\n );\n\n event NewSideNFTToken(\n address indexed _newSideNFTTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 originChainId\n );\n event AcceptedNFTCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n );\n event FixedFeeNFTChanged(uint256 _amount);\n event ClaimedNFTToken(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _receiver,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n );\n}\n"
+ },
+ "contracts/nftbridge/ISideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideNFTToken {\n function mint(address account, uint256 tokenId) external;\n}"
+ },
+ "contracts/nftbridge/ISideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideNFTTokenFactory {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external returns(address);\n\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IWrapped {\n function balanceOf(address) external returns(uint);\n\n function deposit() external payable;\n\n function withdraw(uint wad) external;\n\n function totalSupply() external view returns (uint);\n\n function approve(address guy, uint wad) external returns (bool);\n\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad)\n external\n returns (bool);\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../Initializable.sol\";\n\nimport \"../../../GSN/Context.sol\";\nimport \"../../../access/Roles.sol\";\n\ncontract UpgradablePauserRole is Initializable, Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n function __PauserRol_init(address sender) public initializer {\n if (!isPauser(sender)) {\n _addPauser(sender);\n }\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @title Roles\n * @dev Library for managing addresses assigned to a Role.\n */\nlibrary Roles {\n struct Role {\n mapping (address => bool) bearer;\n }\n\n /**\n * @dev Give an account access to this role.\n */\n function add(Role storage role, address account) internal {\n require(!has(role, account), \"Roles: account already has role\");\n role.bearer[account] = true;\n }\n\n /**\n * @dev Remove an account's access to this role.\n */\n function remove(Role storage role, address account) internal {\n require(has(role, account), \"Roles: account doesn't have role\");\n role.bearer[account] = false;\n }\n\n /**\n * @dev Check if an account has this role.\n * @return bool\n */\n function has(Role storage role, address account) internal view returns (bool) {\n require(account != address(0), \"Roles: account is the zero address\");\n return role.bearer[account];\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _tokenOwners.contains(tokenId);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(tokenId);\n\n emit Transfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n}\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n}\n"
+ },
+ "contracts/test/nftbridge/NFTInheritedBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport \"../../nftbridge/NFTBridge.sol\";\n\ncontract NFTInheritedBridge is NFTBridge {\n function checkChainIdExposed(uint256 chainId) public pure {\n return checkChainId(chainId);\n } \n\n function shouldBeCurrentChainIdExposed(uint256 chainId) public view {\n return shouldBeCurrentChainId(chainId);\n } \n}"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract WRBTC is IWrapped {\n string public name = \"Wrapped RBTC\";\n string public symbol = \"WRBTC\";\n uint8 public decimals = 18;\n\n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n event Deposit(address indexed dst, uint wad);\n event Withdrawal(address indexed src, uint wad);\n\n mapping (address => uint) override public balanceOf;\n mapping (address => mapping (address => uint)) public allowance;\n\n receive () external payable {\n deposit();\n }\n function deposit() override public payable {\n balanceOf[msg.sender] += msg.value;\n emit Deposit(msg.sender, msg.value);\n }\n function withdraw(uint wad) override public {\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\n balanceOf[msg.sender] -= wad;\n (bool success, ) = msg.sender.call{value:wad, gas:23000}(\"\");\n require(success, \"WRBTC: transfer fail\");\n emit Withdrawal(msg.sender, wad);\n }\n\n function totalSupply() override public view returns (uint) {\n return address(this).balance;\n }\n\n function approve(address guy, uint wad) override public returns (bool) {\n allowance[msg.sender][guy] = wad;\n emit Approval(msg.sender, guy, wad);\n return true;\n }\n\n function transfer(address dst, uint wad) override public returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad)\n override public\n returns (bool)\n {\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\n\n if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\n allowance[src][msg.sender] -= wad;\n }\n\n balanceOf[src] -= wad;\n balanceOf[dst] += wad;\n\n emit Transfer(src, dst, wad);\n\n return true;\n }\n}"
+ },
+ "contracts/Bridge/BridgeV3.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// import \"hardhat/console.sol\";\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./IBridgeV3.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n\ncontract BridgeV3 is Initializable, IBridgeV3, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant internal NULL_ADDRESS = address(0);\n bytes32 constant internal NULL_HASH = bytes32(0);\n IERC1820Registry constant internal erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address internal federation;\n uint256 internal feePercentage;\n string public symbolPrefix;\n bytes32 public DOMAIN_SEPARATOR; // replaces uint256 internal _depprecatedLastDay;\n uint256 internal _deprecatedSpentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n uint256 constant public feePercentageDivider = 10000; // Porcentage with up to 2 decimals\n //Bridge_v3 variables\n bytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\");\n IWrapped public wrappedCurrency;\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n // keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\n mapping(address => uint) public nonces;\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool _isUpgrading);\n event WrappedCurrencyChanged(address _wrappedCurrency);\n\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n federation = _federation;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n initDomainSeparator();\n }\n\n receive () external payable {\n // The fallback function is needed to use WRBTC\n require(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n }\n\n function version() override external pure returns (string memory) {\n return \"v3\";\n }\n\n function initDomainSeparator() public {\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n DOMAIN_SEPARATOR = LibEIP712.hashEIP712Domain(\n \"RSK Token Bridge\",\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"Bridge: Not Federation\");\n require(knownTokens[_originalTokenAddress] ||\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\n \"Bridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"Bridge: Null To\");\n require(_amount > 0, \"Bridge: Amount 0\");\n require(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _amount,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed also has the previously processed using the older bridge version\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n require(!claimed[_transactionDataHash], \"Bridge: Already claimed\");\n\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\n senderAddresses[_transactionHash] = _from;\n\n emit AcceptedCrossTransfer(\n _transactionHash,\n _originalTokenAddress,\n _to,\n _from,\n _amount,\n _blockHash,\n _logIndex\n );\n }\n\n\n function createSideToken(\n uint256 _typeId,\n address _originalTokenAddress,\n uint8 _originalTokenDecimals,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n address sideToken = mappedTokens[_originalTokenAddress];\n require(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\n\n mappedTokens[_originalTokenAddress] = sideToken;\n originalTokens[sideToken] = _originalTokenAddress;\n allowTokens.setToken(sideToken, _typeId);\n\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\n }\n\n function claim(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function claimFallback(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n receivedAmount = _claim(\n _claimData,\n _msgSender(),\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function getDigest(\n ClaimData memory _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline\n ) internal returns (bytes32) {\n return LibEIP712.hashEIP712Message(\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n CLAIM_TYPEHASH,\n _claimData.to,\n _claimData.amount,\n _claimData.transactionHash,\n _relayer,\n _fee,\n nonces[_claimData.to]++,\n _deadline\n )\n )\n );\n }\n\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external override returns (uint256 receivedAmount) {\n require(_deadline >= block.timestamp, \"Bridge: EXPIRED\");\n\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claim(\n ClaimData calldata _claimData,\n address payable _reciever,\n address payable _relayer,\n uint256 _fee\n ) internal nonReentrant returns (uint256 receivedAmount) {\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n require(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.amount,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n require(!claimed[transactionDataHash], \"Bridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (knownTokens[originalTokenAddress]) {\n receivedAmount =_claimCrossBackToToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n } else {\n receivedAmount =_claimCrossToSideToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n }\n emit Claimed(\n _claimData.transactionHash,\n originalTokenAddress,\n _claimData.to,\n senderAddresses[_claimData.transactionHash],\n _claimData.amount,\n _claimData.blockHash,\n _claimData.logIndex,\n _reciever,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claimCrossToSideToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n address sideToken = mappedTokens[_originalTokenAddress];\n uint256 granularity = IERC777(sideToken).granularity();\n uint256 formattedAmount = _amount.mul(granularity);\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n ISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n if(_fee > 0) {\n ISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n }\n return receivedAmount;\n }\n\n function _claimCrossBackToToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n //As side tokens are ERC777 they will always have 18 decimals\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n if(address(wrappedCurrency) == _originalTokenAddress) {\n wrappedCurrency.withdraw(formattedAmount);\n _receiver.transfer(receivedAmount);\n if(_fee > 0) {\n _relayer.transfer(_fee);\n }\n } else {\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n if(_fee > 0) {\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n }\n }\n return receivedAmount;\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\n address sender = _msgSender();\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, to, amount, \"\");\n }\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) override external payable {\n address sender = _msgSender();\n require(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n wrappedCurrency.deposit{ value: msg.value }();\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \"\");\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external override(IBridgeV3, IERC777Recipient){\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to this address\");\n address tokenToUse = _msgSender();\n require(erc1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n require(userData.length != 0 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\n crossTokens(tokenToUse, from, receiver, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\n internal whenNotUpgrading whenNotPaused nonReentrant {\n knownTokens[tokenToUse] = true;\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n uint256 amountMinusFees = amount.sub(fee);\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n // We consider the amount before fees converted to 18 decimals to check the limits\n // updateTokenTransfer revert if token not allowed\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n address originalTokenAddress = tokenToUse;\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\n //Side Token Crossing\n originalTokenAddress = originalTokens[tokenToUse];\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\n uint256 modulo = amountMinusFees.mod(granularity);\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n }\n\n emit Cross(\n originalTokenAddress,\n from,\n to,\n amountMinusFees,\n userData\n );\n\n if (fee > 0) {\n //Send the payment to the MultiSig of the Federation\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n }\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n )\n public pure override returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n }\n\n function setFeePercentage(uint amount) external onlyOwner {\n require(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() external view override returns(uint) {\n return feePercentage;\n }\n\n function changeFederation(address newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n require(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n wrappedCurrency = IWrapped(_wrappedCurrency);\n emit WrappedCurrencyChanged(_wrappedCurrency);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionsDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionsDataHashes[transactionHash]];\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an `IERC777` token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See `IERC1820Registry` and\n * `ERC1820Implementer`.\n */\ninterface IERC777 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See `operatorSend` and `operatorBurn`.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor`.\n *\n * Emits an `AuthorizedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor` and `defaultOperators`.\n *\n * Emits a `RevokedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if `authorizeOperator` was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * `revokeOperator`, in which case `isOperatorFor` will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n\n function decimals() external returns (uint8);\n\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n}\n"
+ },
+ "contracts/Bridge/IBridgeV3.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IBridgeV3 {\n\n struct ClaimData {\n address payable to;\n uint256 amount;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) external payable;\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n */\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external returns (uint256 receivedAmount);\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns(bytes32);\n\n event Cross(\n address indexed _tokenAddress,\n address indexed _from,\n address indexed _to,\n uint256 _amount,\n bytes _userData\n );\n event NewSideToken(\n address indexed _newSideTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 _granularity\n );\n event AcceptedCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FeePercentageChanged(uint256 _amount);\n event Claimed(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _reciever,\n address _relayer,\n uint256 _fee\n );\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideToken {\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideTokenFactory {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\n\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../SideToken/SideToken.sol\";\n\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\n external onlyPrimary override returns(address) {\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\n emit SideTokenCreated(sideToken, symbol, granularity);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\nabstract contract Secondary is Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n constructor () {\n _primary = _msgSender();\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(_primary);\n }\n}\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\nimport \"../interface/IERC677Receiver.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../lib/LibEIP712.sol\";\n\ncontract SideToken is ISideToken, ERC777 {\n using SafeMath for uint256;\n\n address public minter;\n uint256 private _granularity;\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n bytes32 public domainSeparator;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n // ERC677 Transfer Event\n event Transfer(address,address,uint256,bytes);\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\n minter = _minterAddr;\n _granularity = _newGranularity;\n\n domainSeparator = LibEIP712.hashEIP712Domain(\n name(),\n \"1\",\n block.chainid,\n address(this)\n );\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter override\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n /**\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\n * @param recipient The address to transfer to.\n * @param amount The amount to be transferred.\n * @param data The extra data to be passed to the receiving contract.\n */\n function transferAndCall(address recipient, uint amount, bytes calldata data)\n external returns (bool success)\n {\n address from = _msgSender();\n\n _send(from, from, recipient, amount, data, \"\", false);\n emit Transfer(from, recipient, amount, data);\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\n return true;\n }\n\n function granularity() public view override returns (uint256) {\n return _granularity;\n }\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\n bytes32 digest = LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../../token/ERC20/IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\n // See https://github.com/ethereum/solidity/issues/4024.\n\n // keccak256(\"ERC777TokensSender\")\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\n\n // keccak256(\"ERC777TokensRecipient\")\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping (address => mapping (address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(\n string memory aName,\n string memory aSymbol,\n address[] memory theDefaultOperators\n ) {\n _name = aName;\n _symbol = aSymbol;\n\n _defaultOperatorsArray = theDefaultOperators;\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\n _defaultOperators[_defaultOperatorsArray[i]] = true;\n }\n\n // register interfaces\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view override(IERC777) returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view override(IERC777) returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20Detailed-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override(IERC777) returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n\n address from = _msgSender();\n\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\n\n _move(from, from, recipient, amount, \"\", \"\");\n\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(\n address operator,\n address tokenHolder\n ) public view override(IERC777) returns (bool) {\n return operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) external override(IERC777) {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) external override(IERC777) {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n )\n external override(IERC777)\n {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {Transfer} events.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\n external override(IERC777) {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\n _burn(_msgSender(), account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender)\n public view override(IERC20) returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {Transfer} and {Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount)\n external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n require(holder != address(0), \"ERC777: transfer from zero address\");\n\n address spender = _msgSender();\n\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\n\n _move(spender, holder, recipient, amount, \"\", \"\");\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\n\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address operator,\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n require(account != address(0), \"ERC777: mint to zero address\");\n\n // Update state variables\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n internal\n {\n require(from != address(0), \"ERC777: send from zero address\");\n require(to != address(0), \"ERC777: send to zero address\");\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param operator address operator requesting the operation\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(\n address operator,\n address from,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n )\n internal\n {\n require(from != address(0), \"ERC777: burn from zero address\");\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n // Update state variables\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\n _balances[to] = _balances[to].add(amount);\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n function _approve(address holder, address spender, uint256 value) internal {\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\n // currently unnecessary.\n //require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n private\n {\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n}\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * `IERC777` Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an `IERC777` token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// import \"hardhat/console.sol\";\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n\tusing SafeMath for uint256;\n\tusing SafeERC20 for IERC20;\n\tusing Address for address;\n\n\taddress constant internal NULL_ADDRESS = address(0);\n\tbytes32 constant internal NULL_HASH = bytes32(0);\n\tIERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n\taddress internal federation;\n\tuint256 internal feePercentage;\n\tstring public deprecatedSymbolPrefix;\n\t// domainSeparator replaces uint256 internal _depprecatedLastDay;\n\tbytes32 public domainSeparator;\n\tuint256 internal _deprecatedSpentToday;\n\n\tmapping (address => address) public deprecatedMappedTokens; // OriginalToken => SideToken\n\tmapping (address => address) public deprecatedOriginalTokens; // SideToken => OriginalToken\n\tmapping (address => bool) public deprecatedKnownTokens; // OriginalToken => true\n\n\t// claimed can use the same of bytes32\n\tmapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n\n\tIAllowTokens public allowTokens;\n\tISideTokenFactory public sideTokenFactory;\n\t//Bridge_v1 variables\n\tbool public isUpgrading;\n\t// Percentage with up to 2 decimals\n\tuint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\n\t//Bridge_v2 variables\n\tbytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\n\tIWrapped public wrappedCurrency;\n\tmapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n\tmapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n\tmapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n\t// keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,uint256 originChainId,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n\tbytes32 public constant CLAIM_TYPEHASH = 0xaf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c;\n\tmapping(address => uint) public nonces;\n\n\t//Bridge_v3 variables multichain\n\tmapping (uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain; // chainId => OriginalToken Address => SideToken Address\n\tmapping (address => OriginalToken) public originalTokenBySideToken; // SideTokenAddress => struct {}\n\tmapping (uint256 => mapping(address => bool)) public knownTokenByChain; // chainId => OriginalToken Address => Know\n\n\tevent AllowTokensChanged(address _newAllowTokens);\n\tevent FederationChanged(address _newFederation);\n\tevent SideTokenFactoryChanged(address _newSideTokenFactory);\n\tevent Upgrading(bool _isUpgrading);\n\tevent WrappedCurrencyChanged(address _wrappedCurrency);\n\n\tfunction initialize(\n\t\taddress _manager,\n\t\taddress _federation,\n\t\taddress _allowTokens,\n\t\taddress _sideTokenFactory\n\t) public initializer {\n\t\tUpgradableOwnable.initialize(_manager);\n\t\tUpgradablePausable.__Pausable_init(_manager);\n\t\tallowTokens = IAllowTokens(_allowTokens);\n\t\tsideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n\t\tfederation = _federation;\n\t\t//keccak256(\"ERC777TokensRecipient\")\n\t\tERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n\t\tinitDomainSeparator();\n\t}\n\n\treceive () external payable {\n\t\t// The fallback function is needed to use WRBTC\n\t\trequire(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n\t}\n\n\tfunction version() override external pure returns (string memory) {\n\t\treturn \"v4\";\n\t}\n\n\tfunction initDomainSeparator() public {\n\t\tdomainSeparator = LibEIP712.hashEIP712Domain(\n\t\t\t\"RSK Token Bridge\",\n\t\t\t\"1\",\n\t\t\tblock.chainid,\n\t\t\taddress(this)\n\t\t);\n\t}\n\n\tmodifier whenNotUpgrading() {\n\t\trequire(!isUpgrading, \"Bridge: Upgrading\");\n\t\t_;\n\t}\n\n\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\n\t\trequire(chainId == block.chainid, \"Bridge: Not block.chainid\");\n\t}\n\n\tfunction sideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\n\t\taddress sideTokenAddr = sideTokenByOriginalTokenByChain[chainId][originalToken];\n\n\t\tif (sideTokenAddr != NULL_ADDRESS) {\n\t\t\treturn sideTokenAddr;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\treturn deprecatedMappedTokens[originalToken];\n\t}\n\n\tfunction setSideTokenByOriginalAddressByChain(uint256 chainId, address originalToken, address sideToken) public onlyOwner {\n\t\tsideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\n\t}\n\n\tfunction getOriginalTokenBySideToken(address sideToken) public view returns(OriginalToken memory originalToken) {\n\t\toriginalToken = originalTokenBySideToken[sideToken];\n\t\tif (originalToken.tokenAddress != NULL_ADDRESS) {\n\t\t\treturn originalToken;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\toriginalToken.originChainId = 1; // ethereum main chain id\n\t\toriginalToken.tokenAddress = deprecatedOriginalTokens[sideToken];\n\t\treturn originalToken;\n\t}\n\n\tfunction setOriginalTokenBySideTokenByChain(address sideToken, OriginalToken memory originalToken) public onlyOwner {\n\t\toriginalTokenBySideToken[sideToken] = originalToken;\n\t}\n\n\tfunction knownToken(uint256 chainId, address originalToken) public view returns(bool) {\n\t\tbool knowToken = knownTokenByChain[chainId][originalToken];\n\t\tif (knowToken) {\n\t\t\treturn knowToken;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\treturn deprecatedKnownTokens[originalToken];\n\t}\n\n\tfunction _setKnownTokenByChain(uint256 chainId, address originalToken, bool knownTokenValue) internal {\n\t\tknownTokenByChain[chainId][originalToken] = knownTokenValue;\n\t}\n\n\tfunction acceptTransfer(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _from,\n\t\taddress payable _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) external whenNotPaused nonReentrant override {\n\t\trequire(_msgSender() == federation, \"Bridge: Not Federation\");\n\t\tcheckChainId(_originChainId);\n\t\tshouldBeCurrentChainId(_destinationChainId);\n\t\trequire(knownToken(_originChainId, _originalTokenAddress) ||\n\t\t\tsideTokenByOriginalToken(_originChainId, _originalTokenAddress) != NULL_ADDRESS,\n\t\t\t\"Bridge: Unknown token\"\n\t\t);\n\t\trequire(_to != NULL_ADDRESS, \"Bridge: Null To\");\n\t\trequire(_amount > 0, \"Bridge: Amount 0\");\n\t\trequire(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n\t\trequire(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n\t\trequire(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n\t\tbytes32 _transactionDataHash = getTransactionDataHash(\n\t\t\t_to,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_transactionHash,\n\t\t\t_logIndex\n\t\t);\n\n\t\tbytes32 _transactionDataHashMultichain = getTransactionDataHash(\n\t\t\t_to,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_transactionHash,\n\t\t\t_logIndex,\n\t\t\t_originChainId,\n\t\t\t_destinationChainId\n\t\t);\n\t\t// Do not remove, claimed also has the previously processed using the older bridge version\n\t\t// https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n\t\trequire(!isClaimed(_transactionDataHash, _transactionDataHashMultichain), \"Bridge: Already claimed\");\n\n\t\ttransactionsDataHashes[_transactionHash] = _transactionDataHashMultichain;\n\t\toriginalTokenAddresses[_transactionHash] = _originalTokenAddress;\n\t\tsenderAddresses[_transactionHash] = _from;\n\n\t\temit AcceptedCrossTransfer(\n\t\t\t_transactionHash,\n\t\t\t_originalTokenAddress,\n\t\t\t_to,\n\t\t\t_from,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_logIndex,\n\t\t\t_originChainId,\n\t\t\t_destinationChainId\n\t\t);\n\t}\n\n\tfunction checkChainId(uint256 chainId) internal pure {\n\t\trequire(chainId > 0, \"Bridge: ChainId is 0\");\n\t}\n\n\tfunction createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _tokenSymbol,\n\t\tstring calldata _tokenName,\n\t\tuint256 _originChainId\n\t) external onlyOwner override {\n\t\trequire(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n\t\tcheckChainId(_originChainId);\n\t\taddress sideToken = sideTokenByOriginalToken(_originChainId, _originalTokenAddress);\n\t\trequire(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n\n\t\tuint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n\n\t\t// Create side token\n\t\tsideToken = sideTokenFactory.createSideToken(_tokenName, _tokenSymbol, granularity);\n\n\t\tsetSideTokenByOriginalAddressByChain(_originChainId, _originalTokenAddress, sideToken);\n\n\t\tOriginalToken memory originalToken;\n\t\toriginalToken.originChainId = _originChainId;\n\t\toriginalToken.tokenAddress = _originalTokenAddress;\n\t\tsetOriginalTokenBySideTokenByChain(sideToken, originalToken);\n\t\tallowTokens.setToken(sideToken, _typeId);\n\n\t\temit NewSideToken(sideToken, _originalTokenAddress, _tokenSymbol, granularity, _originChainId);\n\t}\n\n\tfunction claim(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\n\t\treceivedAmount = _claim(\n\t\t\t_claimData,\n\t\t\t_claimData.to,\n\t\t\tpayable(address(0)),\n\t\t\t0\n\t\t);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction claimFallback(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\n\t\trequire(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n\t\treceivedAmount = _claim(\n\t\t\t_claimData,\n\t\t\t_msgSender(),\n\t\t\tpayable(address(0)),\n\t\t\t0\n\t\t);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction getDigest(\n\t\tClaimData memory _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline\n\t) internal returns (bytes32) {\n\t\treturn LibEIP712.hashEIP712Message(\n\t\t\tdomainSeparator,\n\t\t\tkeccak256(\n\t\t\t\tabi.encode(\n\t\t\t\t\tCLAIM_TYPEHASH,\n\t\t\t\t\t_claimData.to,\n\t\t\t\t\t_claimData.amount,\n\t\t\t\t\t_claimData.transactionHash,\n\t\t\t\t\t_claimData.originChainId,\n\t\t\t\t\t_relayer,\n\t\t\t\t\t_fee,\n\t\t\t\t\tnonces[_claimData.to]++,\n\t\t\t\t\t_deadline\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t}\n\n\t// Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n\tfunction claimGasless(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline,\n\t\tuint8 _v,\n\t\tbytes32 _r,\n\t\tbytes32 _s\n\t) external override returns (uint256 receivedAmount) {\n\t\trequire(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\n\n\t\tbytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n\t\taddress recoveredAddress = ecrecover(digest, _v, _r, _s);\n\t\trequire(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n\t\treturn _claim(\n\t\t\t_claimData,\n\t\t\t_claimData.to,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\t}\n\n\tfunction isClaimed(bytes32 transactionDataHash, bytes32 transactionDataHashMultichain) public view returns(bool) {\n\t\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\n\t}\n\n\tfunction isClaimed(ClaimData calldata _claimData, bytes32 transactionDataHashMultichain) public view returns(bool) {\n\t\tbytes32 transactionDataHash = getTransactionDataHash(\n\t\t\t_claimData.to,\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.transactionHash,\n\t\t\t_claimData.logIndex\n\t\t);\n\n\t\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\n\t}\n\n\tfunction _claim(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _reciever,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal nonReentrant returns (uint256 receivedAmount) {\n\t\taddress originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n\t\trequire(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n\t\tbytes32 transactionDataHash = getTransactionDataHash(\n\t\t\t_claimData.to,\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.transactionHash,\n\t\t\t_claimData.logIndex,\n\t\t\t_claimData.originChainId,\n\t\t\tblock.chainid\n\t\t);\n\n\t\trequire(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n\t\trequire(!isClaimed(_claimData, transactionDataHash), \"Bridge: Already claimed\");\n\t\tclaimed[transactionDataHash] = true;\n\n\t\treceivedAmount = _claimCross(\n\t\t\t_claimData.originChainId,\n\t\t\toriginalTokenAddress,\n\t\t\t_reciever,\n\t\t\t_claimData.amount,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\n\t\temitClaimed(_claimData, originalTokenAddress, _reciever, _relayer, _fee);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction emitClaimed(\n\t\tClaimData calldata _claimData,\n\t\taddress _originalTokenAddress,\n\t\taddress payable _reciever,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal {\n\t\temit Claimed(\n\t\t\t_claimData.transactionHash,\n\t\t\t_originalTokenAddress,\n\t\t\t_claimData.to,\n\t\t\tsenderAddresses[_claimData.transactionHash],\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.logIndex,\n\t\t\t_reciever,\n\t\t\t_relayer,\n\t\t\t_fee,\n\t\t\t_claimData.originChainId,\n\t\t\tblock.chainid\n\t\t);\n\t}\n\n\tfunction _claimCross(\n\t\tuint256 _originalChainId,\n\t\taddress _originalTokenAddress,\n\t\taddress payable _reciever,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256) {\n\t\tcheckChainId(_originalChainId);\n\t\tif (knownToken(_originalChainId, _originalTokenAddress)) {\n\t\t\treturn _claimCrossBackToToken(\n\t\t\t\t_originalTokenAddress,\n\t\t\t\t_reciever,\n\t\t\t\t_amount,\n\t\t\t\t_relayer,\n\t\t\t\t_fee\n\t\t\t);\n\t\t}\n\n\t\treturn _claimCrossToSideToken(\n\t\t\tsideTokenByOriginalToken(_originalChainId, _originalTokenAddress),\n\t\t\t_reciever,\n\t\t\t_amount,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\t}\n\n\tfunction _claimCrossToSideToken(\n\t\taddress _sideToken,\n\t\taddress payable _receiver,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256 receivedAmount) {\n\t\trequire(_sideToken != NULL_ADDRESS, \"Bridge: side token is null\");\n\t\tuint256 granularity = IERC777(_sideToken).granularity();\n\t\tuint256 formattedAmount = _amount.mul(granularity);\n\t\trequire(_fee <= formattedAmount, \"Bridge: fee too high\");\n\t\treceivedAmount = formattedAmount.sub(_fee);\n\t\tISideToken(_sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n\t\tif (_fee > 0) {\n\t\t\tISideToken(_sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n\t\t}\n\t\treturn receivedAmount;\n\t}\n\n\tfunction _claimCrossBackToToken(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _receiver,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256 receivedAmount) {\n\t\tuint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n\t\t//As side tokens are ERC777 they will always have 18 decimals\n\t\tuint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n\t\trequire(_fee <= formattedAmount, \"Bridge: fee too high\");\n\t\treceivedAmount = formattedAmount.sub(_fee);\n\t\tif (address(wrappedCurrency) == _originalTokenAddress) {\n\t\t\twrappedCurrency.withdraw(formattedAmount);\n\t\t\t_receiver.transfer(receivedAmount);\n\t\t\tif(_fee > 0) {\n\t\t\t\t_relayer.transfer(_fee);\n\t\t\t}\n\t\t} else {\n\t\t\tIERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n\t\t\tif(_fee > 0) {\n\t\t\t\tIERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n\t\t\t}\n\t\t}\n\t\treturn receivedAmount;\n\t}\n\n\t/**\n\t\t* ERC-20 tokens approve and transferFrom pattern\n\t\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n\t\t*/\n\tfunction receiveTokensTo(uint256 destinationChainId, address tokenToUse, address to, uint256 amount) external override {\n\t\taddress sender = _msgSender();\n\t\t//Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n\t\tIERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n\t\tcrossTokens(tokenToUse, sender, to, amount, \"\", destinationChainId);\n\t}\n\n\t/**\n\t\t* Use network currency and cross it.\n\t\t*/\n\tfunction depositTo(uint256 chainId, address to) external payable override {\n\t\taddress sender = _msgSender();\n\t\trequire(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n\t\twrappedCurrency.deposit{ value: msg.value }();\n\t\tcrossTokens(address(wrappedCurrency), sender, to, msg.value, \"\", chainId);\n\t}\n\n\t/**\n\t\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n\t\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n\t\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\n\t\t* const userData = web3.eth.abi.encodeParameters(\n * [\"address\", \"uint256\"],\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\n * );\n\t\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\n\t\t* const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\n\t\t*/\n\tfunction tokensReceived(\n\t\taddress operator,\n\t\taddress from,\n\t\taddress to,\n\t\tuint amount,\n\t\tbytes calldata userData, // [address,uint256] user addrest receiver, destinationChainId || [uint256] same as from, destinationChainId\n\t\tbytes calldata\n\t) external override(IBridge, IERC777Recipient) {\n\t\t//Hook from ERC777address\n\t\tif(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n\t\trequire(to == address(this), \"Bridge: Not to this address\");\n\t\taddress tokenToUse = _msgSender();\n\t\trequire(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n\t\trequire(userData.length >= 32, \"Bridge: user data with at least the destinationChainId\");\n\t\trequire(userData.length == 64 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n\t\taddress receiver = userData.length == 32 ? from : LibUtils.toAddress(userData, 12);\n\t\tuint256 destinationChainId = LibUtils.toUint256(userData, userData.length - 32);\n\t\tcrossTokens(tokenToUse, from, receiver, amount, userData, destinationChainId);\n\t}\n\n\tfunction crossTokens(\n\t\taddress tokenToUse,\n\t\taddress from,\n\t\taddress to,\n\t\tuint256 amount,\n\t\tbytes memory userData,\n\t\tuint256 destinationChainId\n\t) internal whenNotUpgrading whenNotPaused nonReentrant {\n\t\trequire(block.chainid != destinationChainId, \"Bridge: destination chain id equal current chain id\");\n\t\tcheckChainId(destinationChainId);\n\t\t_setKnownTokenByChain(destinationChainId, tokenToUse, true);\n\t\tuint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n\t\tuint256 amountMinusFees = amount.sub(fee);\n\t\tuint8 decimals = LibUtils.getDecimals(tokenToUse);\n\t\tuint formattedAmount = amount;\n\t\tif (decimals != 18) {\n\t\t\tformattedAmount = amount.mul(uint256(10)**(18-decimals));\n\t\t}\n\t\t// We consider the amount before fees converted to 18 decimals to check the limits\n\t\t// updateTokenTransfer revert if token not allowed\n\t\tallowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n\n\t\tOriginalToken memory sideToken = getOriginalTokenBySideToken(tokenToUse);\n\t\tif (sideToken.tokenAddress != NULL_ADDRESS) {\n\t\t\t// Side Token Crossing back\n\t\t\t{ // Created scope to avoid stack too deep\n\t\t\t\tuint256 granularity = LibUtils.getGranularity(tokenToUse);\n\t\t\t\tuint256 modulo = amountMinusFees.mod(granularity);\n\t\t\t\tfee = fee.add(modulo);\n\t\t\t\tamountMinusFees = amountMinusFees.sub(modulo);\n\t\t\t\tIERC777(tokenToUse).burn(amountMinusFees, userData);\n\t\t\t}\n\t\t\temit Cross(\n\t\t\t\tsideToken.tokenAddress,\n\t\t\t\tto,\n\t\t\t\tdestinationChainId,\n\t\t\t\tfrom,\n\t\t\t\tblock.chainid,\n\t\t\t\tamountMinusFees,\n\t\t\t\tuserData\n\t\t\t);\n\t\t} else {\n\t\t\temit Cross(\n\t\t\t\ttokenToUse,\n\t\t\t\tto,\n\t\t\t\tdestinationChainId,\n\t\t\t\tfrom,\n\t\t\t\tblock.chainid,\n\t\t\t\tamountMinusFees,\n\t\t\t\tuserData\n\t\t\t);\n\t\t}\n\n\t\tif (fee > 0) {\n\t\t\t//Send the payment to the MultiSig of the Federation\n\t\t\tIERC20(tokenToUse).safeTransfer(owner(), fee);\n\t\t}\n\t}\n\n\t// function for retrocompatibility\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex\n\t) internal pure returns(bytes32) {\n\t\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n\t}\n\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) public pure override returns(bytes32) {\n\t\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex, _originChainId, _destinationChainId));\n\t}\n\n\tfunction setFeePercentage(uint amount) external onlyOwner {\n\t\trequire(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n\t\tfeePercentage = amount;\n\t\temit FeePercentageChanged(feePercentage);\n\t}\n\n\tfunction getFeePercentage() external view override returns(uint) {\n\t\treturn feePercentage;\n\t}\n\n\tfunction changeFederation(address newFederation) external onlyOwner {\n\t\trequire(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n\t\tfederation = newFederation;\n\t\temit FederationChanged(federation);\n\t}\n\n\tfunction changeAllowTokens(address newAllowTokens) external onlyOwner {\n\t\trequire(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n\t\tallowTokens = IAllowTokens(newAllowTokens);\n\t\temit AllowTokensChanged(newAllowTokens);\n\t}\n\n\tfunction getFederation() external view returns(address) {\n\t\treturn federation;\n\t}\n\n\tfunction changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n\t\trequire(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n\t\tsideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n\t\temit SideTokenFactoryChanged(newSideTokenFactory);\n\t}\n\n\tfunction setUpgrading(bool _isUpgrading) external onlyOwner {\n\t\tisUpgrading = _isUpgrading;\n\t\temit Upgrading(isUpgrading);\n\t}\n\n\tfunction setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n\t\trequire(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n\t\twrappedCurrency = IWrapped(_wrappedCurrency);\n\t\temit WrappedCurrencyChanged(_wrappedCurrency);\n\t}\n\n\tfunction hasCrossed(bytes32 transactionHash) public view returns (bool) {\n\t\treturn transactionsDataHashes[transactionHash] != bytes32(0);\n\t}\n\n\tfunction hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n\t\treturn claimed[transactionsDataHashes[transactionHash]];\n\t}\n\n}\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IBridge {\n\n\tstruct ClaimData {\n\t\taddress payable to;\n\t\tuint256 amount;\n\t\tbytes32 blockHash;\n\t\tbytes32 transactionHash;\n\t\tuint32 logIndex;\n\t\tuint256 originChainId;\n\t}\n\n\tstruct OriginalToken {\n\t\taddress tokenAddress;\n\t\tuint256 originChainId;\n\t}\n\n\tfunction version() external pure returns (string memory);\n\n\tfunction getFeePercentage() external view returns(uint);\n\n\t/**\n\t\t* ERC-20 tokens approve and transferFrom pattern\n\t\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n\t\t*/\n\tfunction receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;\n\n\t/**\n\t\t* Use network currency and cross it.\n\t\t*/\n\tfunction depositTo(uint256 chainId, address to) external payable;\n\n\t/**\n\t\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n\t\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n\t\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\n\t\t* const userData = web3.eth.abi.encodeParameters(\n * [\"address\", \"uint256\"],\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\n * );\n\t\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\n\t\t* const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\n\t\t*/\n\tfunction tokensReceived (\n\t\taddress operator,\n\t\taddress from,\n\t\taddress to,\n\t\tuint amount,\n\t\tbytes calldata userData,\n\t\tbytes calldata operatorData\n\t) external;\n\n\t/**\n\t\t* Accepts the transaction from the other chain that was voted and sent by the Federation contract\n\t\t*/\n\tfunction acceptTransfer(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _from,\n\t\taddress payable _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) external;\n\n\t/**\n\t\t* Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n\t\t*/\n\tfunction claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n\tfunction claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n\tfunction claimGasless(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline,\n\t\tuint8 _v,\n\t\tbytes32 _r,\n\t\tbytes32 _s\n\t) external returns (uint256 receivedAmount);\n\n\tfunction createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _originalTokenSymbol,\n\t\tstring calldata _originalTokenName,\n\t\tuint256 _chainId\n\t) external;\n\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256 _destinationChainId\n\t) external returns(bytes32);\n\n\tevent Cross(\n\t\taddress indexed _tokenAddress,\n\t\taddress indexed _to,\n\t\tuint256 indexed _destinationChainId,\n\t\taddress _from,\n\t\tuint256 _originChainId,\n\t\tuint256 _amount,\n\t\tbytes _userData\n\t);\n\n\tevent NewSideToken(\n\t\taddress indexed _newSideTokenAddress,\n\t\taddress indexed _originalTokenAddress,\n\t\tstring _newSymbol,\n\t\tuint256 _granularity,\n\t\tuint256 _chainId\n\t);\n\tevent AcceptedCrossTransfer(\n\t\tbytes32 indexed _transactionHash,\n\t\taddress indexed _originalTokenAddress,\n\t\taddress indexed _to,\n\t\taddress _from,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tuint256 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t);\n\tevent FeePercentageChanged(uint256 _amount);\n\tevent Claimed(\n\t\tbytes32 indexed _transactionHash,\n\t\taddress indexed _originalTokenAddress,\n\t\taddress indexed _to,\n\t\taddress _sender,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tuint256 _logIndex,\n\t\taddress _reciever,\n\t\taddress _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _destinationChainId,\n\t\tuint256 _originChainId\n\t);\n}"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IBridge.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockReceiveTokensCall is IERC777Recipient {\n address public bridge;\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor(address _bridge) {\n bridge = _bridge;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount, uint256 destinationChainId) external {\n IERC20(tokenToUse).approve(bridge, amount);\n IBridge(bridge).receiveTokensTo(destinationChainId, tokenToUse, receiver, amount);\n }\n\n function callDepositTo(address receiver, uint256 destinationChainId) external payable {\n IBridge(bridge).depositTo{ value: msg.value }(destinationChainId, receiver);\n }\n\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\n IERC777(tokenToUse).send(bridge, amount, data);\n }\n\n // Mandatory for IERC777Recipient\n function tokensReceived(\n address,\n address,\n address,\n uint,\n bytes calldata,\n bytes calldata\n ) override external view {\n this;\n }\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockERC777Recipient is IERC777Recipient {\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor() {\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\n }\n\n event Success(\n address operator,\n address from,\n address to,\n uint amount,\n bytes userData,\n bytes operatorData);\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) override external {\n emit Success(operator, from, to, amount, userData, operatorData);\n }\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\n\ncontract SideTokenV1 is ERC777 {\n address public minter;\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\n minter = _minterAddr;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../SideToken/SideTokenV1.sol\";\n\ncontract SideTokenFactoryV1 is Secondary {\n event CreatedSideToken(address sideToken, string symbol);\n\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\n emit CreatedSideToken(address(sideToken), symbol);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using SafeMath for uint256;\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping (uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /*\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri_) {\n _setURI(uri_);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) external view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: balance query for the zero address\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(amount);\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, address(0), id, amount);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\n /**\n @dev Handles the receipt of a single ERC1155 token type. This function is\n called at the end of a `safeTransferFrom` after the balance has been updated.\n To accept the transfer, this must return\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n (i.e. 0xf23a6e61, or its own function selector).\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n )\n external\n returns(bytes4);\n\n /**\n @dev Handles the receipt of a multiple ERC1155 token types. This function\n is called at the end of a `safeBatchTransferFrom` after the balances have\n been updated. To accept the transfer(s), this must return\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n (i.e. 0xbc197c81, or its own function selector).\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match values array)\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n )\n external\n returns(bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC1155 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Pausable is ERC1155, Pausable {\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\nimport \"../access/roles/PauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context, PauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n constructor () {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract PauserRole is Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n constructor () {\n _addPauser(_msgSender());\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC721.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC721 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC721Pausable is ERC721, Pausable {\n /**\n * @dev See {ERC721-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../../zeppelin/ownership/Ownable.sol\";\nimport \"../../zeppelin/math/SafeMath.sol\";\nimport \"../../zeppelin/utils/Strings.sol\";\nimport \"./OpenSeaEIP712Base.sol\";\n\n\n/**\n * @title OpenSea721\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\n */\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\n using SafeMath for uint256;\n\n uint256 private _currentTokenId = 0;\n\n constructor(\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n _initializeEIP712(_name);\n }\n\n function baseTokenURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/api/creature/\";\n }\n\n function contractURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\n }\n\n /**\n * @dev Mints a token to an address with a tokenURI.\n * @param _to address of the future owner of the token\n */\n function mintTo(address _to) public onlyOwner {\n uint256 newTokenId = _getNextTokenId();\n _mint(_to, newTokenId);\n _incrementTokenId();\n }\n\n /**\n * @dev calculates the next token ID based on value of _currentTokenId\n * @return uint256 for the next token ID\n */\n function _getNextTokenId() private view returns (uint256) {\n return _currentTokenId.add(1);\n }\n\n /**\n * @dev increments the value of _currentTokenId\n */\n function _incrementTokenId() private {\n _currentTokenId++;\n }\n\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\n }\n\n}"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () {\n _owner = _msgSender();\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../zeppelin/upgradable/Initializable.sol\";\n\ncontract OpenSeaEIP712Base is Initializable {\n struct EIP712Domain {\n string name;\n string version;\n address verifyingContract;\n bytes32 salt;\n }\n\n string constant public ERC712_VERSION = \"1\";\n\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\n bytes(\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\n )\n );\n bytes32 internal domainSeperator;\n\n // supposed to be called once while initializing.\n // one of the contracts that inherits this contract follows proxy pattern\n // so it is not possible to do this in a constructor\n function _initializeEIP712(\n string memory name\n )\n internal\n initializer\n {\n _setDomainSeperator(name);\n }\n\n function _setDomainSeperator(string memory name) internal {\n domainSeperator = keccak256(\n abi.encode(\n EIP712_DOMAIN_TYPEHASH,\n keccak256(bytes(name)),\n keccak256(bytes(ERC712_VERSION)),\n address(this),\n bytes32(block.chainid)\n )\n );\n }\n\n function getDomainSeperator() public view returns (bytes32) {\n return domainSeperator;\n }\n\n /**\n * Accept message hash and returns hash message in EIP712 compatible form\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\n * https://eips.ethereum.org/EIPS/eip-712\n * \"\\\\x19\" makes the encoding deterministic\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\n */\n function toTypedMessageHash(bytes32 messageHash)\n internal\n view\n returns (bytes32)\n {\n return\n keccak256(\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\n );\n }\n}\n"
+ },
+ "contracts/federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../Bridge/IBridgeV3.sol\";\n\ncontract FederationV2 is Initializable, UpgradableOwnable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridgeV3 public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\n validRequirement(_members.length, _required) public initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n }\n\n function version() external pure returns (string memory) {\n return \"v2\";\n }\n\n function setBridge(address _bridge) external onlyOwner {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridgeV3(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n )\n public onlyMember returns(bool)\n {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32)\n {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}"
+ },
+ "contracts/federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../nftbridge/INFTBridge.sol\";\nimport \"../interface/IBridge.sol\";\nimport \"../interface/IFederation.sol\";\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\n\tuint constant public MAX_MEMBER_COUNT = 50;\n\taddress constant private NULL_ADDRESS = address(0);\n\n\tIBridge public bridge;\n\taddress[] public members;\n\n\t/**\n\t\t@notice The minimum amount of votes to approve a transaction\n\t\t@dev It should have at least the required amount of members\n\t\t*/\n\tuint public required;\n\n\t/**\n\t\t@notice All the addresses that are members of the federation\n\t\t@dev The address should be a member to vote in transactions\n\t\t*/\n\tmapping (address => bool) public isMember;\n\n\t/**\n\t\t(bytes32) transactionId = keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tamount,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex\n\t\t\t)\n\t\t) => (\n\t\t\t(address) members => (bool) voted\n\t\t)\n\t\t@notice Votes by members by the transaction ID\n\t\t@dev the members should approve the transaction by 50% + 1\n\t\t*/\n\tmapping (bytes32 => mapping (address => bool)) public votes;\n\n\t/**\n\t\t(bytes32) transactionId => (bool) voted\n\t\t@notice Check if that transaction was already processed\n\t*/\n\tmapping(bytes32 => bool) public processed;\n\n\t/** Federator v3 variables */\n\tINFTBridge public bridgeNFT;\n\n\tmodifier onlyMember() {\n\t\trequire(isMember[_msgSender()], \"Federation: Not Federator\");\n\t\t_;\n\t}\n\n\tmodifier validRequirement(uint membersCount, uint _required) {\n\t\trequire(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n\t\t_;\n\t}\n\n\tfunction initialize(\n\t\taddress[] calldata _members,\n\t\tuint _required,\n\t\taddress _bridge,\n\t\taddress owner,\n\t\taddress _bridgeNFT\n\t) public validRequirement(_members.length, _required) initializer {\n\t\tUpgradableOwnable.initialize(owner);\n\t\trequire(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n\t\tmembers = _members;\n\t\tfor (uint i = 0; i < _members.length; i++) {\n\t\t\trequire(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n\t\t\tisMember[_members[i]] = true;\n\t\t\temit MemberAddition(_members[i]);\n\t\t}\n\t\trequired = _required;\n\t\temit RequirementChange(required);\n\t\t_setBridge(_bridge);\n\t\t_setNFTBridge(_bridgeNFT);\n\t}\n\n\t/**\n\t\t@notice Current version of the contract\n\t\t@return version in v{Number}\n\t\t*/\n\tfunction version() external pure override returns (string memory) {\n\t\treturn \"v3\";\n\t}\n\n\t/**\n\t\t@notice Sets a new bridge contract\n\t\t@dev Emits BridgeChanged event\n\t\t@param _bridge the new bridge contract address that should implement the IBridge interface\n\t\t*/\n\tfunction setBridge(address _bridge) external onlyOwner override {\n\t\t_setBridge(_bridge);\n\t}\n\n\tfunction _setBridge(address _bridge) internal {\n\t\trequire(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n\t\tbridge = IBridge(_bridge);\n\t\temit BridgeChanged(_bridge);\n\t}\n\n\t/**\n\t\t@notice Sets a new NFT bridge contract\n\t\t@dev Emits NFTBridgeChanged event\n\t\t@param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n\t\t*/\n\tfunction setNFTBridge(address _bridgeNFT) external onlyOwner override {\n\t\trequire(_bridgeNFT != NULL_ADDRESS, \"Federation: Empty NFT bridge\");\n\t\t_setNFTBridge(_bridgeNFT);\n\t}\n\n\tfunction _setNFTBridge(address _bridgeNFT) internal {\n\t\tbridgeNFT = INFTBridge(_bridgeNFT);\n\t\temit NFTBridgeChanged(_bridgeNFT);\n\t}\n\n\tfunction validateTransaction(bytes32 transactionId, bytes32 transactionIdMultichain) internal view returns(bool) {\n\t\tuint256 minimumVotes = getMinimalNumberOfVotes();\n\t\tuint256 amountVotes = 0;\n\n for (uint256 i = 0; i < members.length; i++) {\n if (votes[transactionIdMultichain][members[i]]) {\n amountVotes += 1;\n\t\t\t} else if (votes[transactionId][members[i]]) {\n amountVotes += 1;\n\t\t\t}\n\n\t\t\tif (amountVotes >= minimumVotes && amountVotes >= required) {\n\t\t\t\treturn true;\n\t\t\t}\n }\n\n\t\treturn false;\n\t}\n\n\tfunction getMinimalNumberOfVotes() internal view returns(uint256) {\n\t\treturn members.length / 2 + 1;\n\t}\n\n\tfunction isProcessed(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\n\t\treturn processed[transactionIdMultichain] || processed[transactionId];\n\t}\n\n\tfunction isVoted(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\n\t\treturn votes[transactionIdMultichain][_msgSender()] || votes[transactionId][_msgSender()];\n\t}\n\n\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\n\t\trequire(chainId == block.chainid, \"Federation: Not block.chainid\");\n\t}\n\n\t/**\n\t\t@notice Vote in a transaction, if it has enough votes it accepts the transfer\n\t\t@param originalTokenAddress The address of the token in the origin (main) chain\n\t\t@param sender The address who solicited the cross token\n\t\t@param receiver Who is going to receive the token in the opposite chain\n\t\t@param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n\t\t@param blockHash The block hash in which the transaction with the cross event occurred\n\t\t@param transactionHash The transaction in which the cross event occurred\n\t\t@param logIndex Index of the event in the logs\n\t\t@param tokenType Is the type of bridge to be used\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n\t\t*/\n\tfunction voteTransaction(\n\t\taddress originalTokenAddress,\n\t\taddress payable sender,\n\t\taddress payable receiver,\n\t\tuint256 value,\n\t\tbytes32 blockHash,\n\t\tbytes32 transactionHash,\n\t\tuint32 logIndex,\n\t\tTokenType tokenType,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n\t) external onlyMember override {\n\t\tshouldBeCurrentChainId(destinationChainId);\n\t\tbytes32 transactionId = keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex\n\t\t\t)\n\t\t);\n\n\t\tbytes32 transactionIdMultichain = getTransactionId(\n\t\t\toriginalTokenAddress,\n\t\t\tsender,\n\t\t\treceiver,\n\t\t\tvalue,\n\t\t\tblockHash,\n\t\t\ttransactionHash,\n\t\t\tlogIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n\t\t);\n\n\t\tif (isProcessed(transactionId, transactionIdMultichain))\n\t\t\treturn;\n\n\t\tif (isVoted(transactionId, transactionIdMultichain))\n\t\t\treturn;\n\n\t\tvotes[transactionIdMultichain][_msgSender()] = true;\n\t\temit Voted(\n\t\t\t_msgSender(),\n\t\t\ttransactionHash,\n\t\t\ttransactionIdMultichain,\n\t\t\toriginalTokenAddress,\n\t\t\tsender,\n\t\t\treceiver,\n\t\t\tvalue,\n\t\t\tblockHash,\n\t\t\tlogIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n\t\t);\n\n\t\tif (validateTransaction(transactionId, transactionIdMultichain)) {\n\t\t\tprocessed[transactionIdMultichain] = true;\n\n\t\t\tacceptTransfer(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex,\n\t\t\t\ttokenType,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\n\t\t\temit Executed(\n\t\t\t\t_msgSender(),\n\t\t\t\ttransactionHash,\n\t\t\t\ttransactionIdMultichain,\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\tlogIndex,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\t\t}\n\t}\n\n function acceptTransfer(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType,\n\tuint256 originChainId,\n\tuint256\tdestinationChainId\n ) internal {\n if (tokenType == TokenType.NFT) {\n require(address(bridgeNFT) != NULL_ADDRESS, \"Federation: Empty NFTBridge\");\n bridgeNFT.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex,\n\t\toriginChainId,\n\t\tdestinationChainId\n );\n } else {\n\t bridge.acceptTransfer(\n\t\toriginalTokenAddress,\n\t\tsender,\n\t\treceiver,\n\t\tvalue,\n\t\tblockHash,\n\t\ttransactionHash,\n\t\tlogIndex,\n\t\toriginChainId,\n\t\tdestinationChainId\n\t );\n\t}\n }\n\n /**\n @notice Get the amount of approved votes for that transactionId\n @param transactionId The transaction hashed from getTransactionId function\n */\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n\tfunction hasVoted(bytes32 transactionId) external view returns(bool) {\n\t\treturn votes[transactionId][_msgSender()];\n\t}\n\n\tfunction transactionWasProcessed(bytes32 transactionId) external view returns(bool) {\n\t\treturn processed[transactionId];\n\t}\n\n\t/**\n\t\t@notice Gets the hash of transaction from the following parameters encoded and keccaked\n\t\t@dev It encodes and applies keccak256 to the parameters received in the same order\n\t\t@param originalTokenAddress The address of the token in the origin (main) chain\n\t\t@param sender The address who solicited the cross token\n\t\t@param receiver Who is going to receive the token in the opposite chain\n\t\t@param amount Could be the amount or the tokenId\n\t\t@param blockHash The block hash in which the transaction with the cross event occurred\n\t\t@param transactionHash The transaction in which the cross event occurred\n\t\t@param logIndex Index of the event in the logs\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n\t\t@return The hash generated by the parameters.\n\t*/\n\tfunction getTransactionId(\n\t\taddress originalTokenAddress,\n\t\taddress sender,\n\t\taddress receiver,\n\t\tuint256 amount,\n\t\tbytes32 blockHash,\n\t\tbytes32 transactionHash,\n\t\tuint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n\t) public pure returns(bytes32) {\n\t\treturn keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tamount,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t)\n\t\t);\n\t}\n\n\tfunction addMember(address _newMember) external onlyOwner override {\n\t\trequire(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n\t\trequire(!isMember[_newMember], \"Federation: Member already exists\");\n\t\trequire(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n\t\tisMember[_newMember] = true;\n\t\tmembers.push(_newMember);\n\t\temit MemberAddition(_newMember);\n\t}\n\n\tfunction removeMember(address _oldMember) external onlyOwner override {\n\t\trequire(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n\t\trequire(isMember[_oldMember], \"Federation: Member doesn't exists\");\n\t\trequire(members.length > 1, \"Federation: Can't remove all the members\");\n\t\trequire(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n\t\tisMember[_oldMember] = false;\n\t\tfor (uint i = 0; i < members.length - 1; i++) {\n\t\t\tif (members[i] == _oldMember) {\n\t\t\t\tmembers[i] = members[members.length - 1];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tmembers.pop(); // remove an element from the end of the array.\n\t\temit MemberRemoval(_oldMember);\n\t}\n\n\t/**\n\t\t@notice Return all the current members of the federation\n\t\t@return Current members\n\t\t*/\n\tfunction getMembers() external view override returns (address[] memory) {\n\t\treturn members;\n\t}\n\n\t/**\n\t\t@notice Changes the number of required members to vote and approve an transaction\n\t\t@dev Emits the RequirementChange event\n\t\t@param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n\t\t*/\n\tfunction changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\n\t\trequire(_required >= 2, \"Federation: Requires at least 2\");\n\t\trequired = _required;\n\t\temit RequirementChange(_required);\n\t}\n\n\t/**\n\t\t@notice It emits an HeartBeat like an health check\n\t\t@dev Emits HeartBeat event\n\t\t*/\n\tfunction emitHeartbeat(\n\t\tstring calldata fedVersion,\n\t\tuint256[] calldata fedChainsIds,\n\t\tuint256[] calldata fedChainsBlocks,\n\t\tstring[] calldata fedChainsInfo\n\t) external onlyMember override {\n\t\trequire(fedChainsIds.length == fedChainsBlocks.length &&\n\t\t\tfedChainsIds.length == fedChainsInfo.length, \"Federation: Length missmatch\");\n\t\temit HeartBeat(\n\t\t\t_msgSender(),\n\t\t\tblock.chainid,\n\t\t\tblock.number,\n\t\t\tfedVersion,\n\t\t\tfedChainsIds,\n\t\t\tfedChainsBlocks,\n\t\t\tfedChainsInfo\n\t\t);\n\t}\n}\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface IFederation {\n enum TokenType{ COIN, NFT }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure returns (string memory);\n\n /**\n @notice Sets a new bridge contract\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external;\n\n /**\n @notice Sets a new NFT bridge contract\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external;\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType,\n\t uint256 originChainId,\n\t uint256\tdestinationChainId\n ) external;\n\n /**\n @notice Add a new member to the federation\n @param _newMember address of the new member\n */\n function addMember(address _newMember) external;\n\n /**\n @notice Remove a member of the federation\n @param _oldMember address of the member to be removed from federation\n */\n function removeMember(address _oldMember) external;\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view returns (address[] memory);\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external;\n\n /**\n @notice It emmits an HeartBeat like an healthy check\n */\n function emitHeartbeat(\n string calldata federatorVersion,\n\t\tuint256[] calldata fedChainsIds,\n\t\tuint256[] calldata fedChainsBlocks,\n\t\tstring[] calldata fedChainsInfo\n ) external;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event NFTBridgeChanged(address bridgeNFT);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex,\n uint256 originChainId,\n\t\tuint256\tdestinationChainId\n );\n event HeartBeat(\n address indexed sender,\n uint256 currentChainId,\n uint256 currentBlock,\n string fedVersion,\n uint256[] fedChainsIds,\n\t\tuint256[] fedChainsBlocks,\n\t\tstring[] fedChainsInfo\n );\n\n}\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract MinterRole is Context {\n using Roles for Roles.Role;\n\n event MinterAdded(address indexed account);\n event MinterRemoved(address indexed account);\n\n Roles.Role private _minters;\n\n constructor () {\n _addMinter(_msgSender());\n }\n\n modifier onlyMinter() {\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\n _;\n }\n\n function isMinter(address account) public view returns (bool) {\n return _minters.has(account);\n }\n\n function addMinter(address account) public onlyMinter {\n _addMinter(account);\n }\n\n function renounceMinter() public {\n _removeMinter(_msgSender());\n }\n\n function _addMinter(address account) internal {\n _minters.add(account);\n emit MinterAdded(account);\n }\n\n function _removeMinter(address account) internal {\n _minters.remove(account);\n emit MinterRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20Mintable}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() override public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) override public view returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) override public returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) override public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) override public returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal {\n require(sender != address(0), \"ERC20: transfer from zero address\");\n require(recipient != address(0), \"ERC20: transfer to zero address\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: mint to zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: burn from zero address\");\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n *\n * This is internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal {\n require(owner != address(0), \"ERC20: approve from zero address\");\n require(spender != address(0), \"ERC20: approve to zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\n * from the caller's allowance.\n *\n * See {_burn} and {_approve}.\n */\n function _burnFrom(address account, uint256 amount) internal {\n _burn(account, amount);\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\n }\n}\n"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\nimport \"../interface/IERC677Receiver.sol\";\n\ncontract mockERC677Receiver is IERC677Receiver {\n event Success(address _sender, uint _value, bytes _data);\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\n emit Success(_sender, _value, _data);\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Optional functions from the ERC20 standard.\n */\nabstract contract ERC20Detailed is IERC20 {\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\n * these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\n _name = aName;\n _symbol = aSymbol;\n _decimals = theDecimals;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./Proxy.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n *\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\n * {TransparentUpgradeableProxy}.\n */\ncontract UpgradeableProxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _setImplementation(_logic);\n if(_data.length > 0) {\n Address.functionDelegateCall(_logic, _data);\n }\n }\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n bytes32 slot = _IMPLEMENTATION_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n impl := sload(slot)\n }\n }\n\n /**\n * @dev Upgrades the proxy to a new implementation.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal virtual {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\n\n bytes32 slot = _IMPLEMENTATION_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newImplementation)\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./UpgradeableProxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _setAdmin(admin_);\n }\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _admin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _admin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\n emit AdminChanged(_admin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external virtual ifAdmin {\n _upgradeTo(newImplementation);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\n _upgradeTo(newImplementation);\n Address.functionDelegateCall(newImplementation, data);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address adm) {\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n adm := sload(slot)\n }\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n bytes32 slot = _ADMIN_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newAdmin)\n }\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../ownership/Ownable.sol\";\nimport \"./TransparentUpgradeableProxy.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract AllowTokensV0 is Ownable {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n\n mapping (address => bool) public allowedTokens;\n bool private validateAllowedTokens;\n uint256 private maxTokensAllowed;\n uint256 private minTokensAllowed;\n uint256 public dailyLimit;\n\n event AllowedTokenAdded(address indexed _tokenAddress);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event AllowedTokenValidation(bool _enabled);\n event MaxTokensAllowedChanged(uint256 _maxTokens);\n event MinTokensAllowedChanged(uint256 _minTokens);\n event DailyLimitChanged(uint256 dailyLimit);\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\n _;\n }\n\n constructor(address _manager) {\n transferOwnership(_manager);\n validateAllowedTokens = true;\n maxTokensAllowed = 10000 ether;\n minTokensAllowed = 1 ether;\n dailyLimit = 100000 ether;\n }\n\n function isValidatingAllowedTokens() external view returns(bool) {\n return validateAllowedTokens;\n }\n\n function getMaxTokensAllowed() external view returns(uint256) {\n return maxTokensAllowed;\n }\n\n function getMinTokensAllowed() external view returns(uint256) {\n return minTokensAllowed;\n }\n\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\n return allowedTokens[token];\n }\n\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\n if (validateAllowedTokens) {\n return allowedTokenExist(token);\n }\n return true;\n }\n\n function addAllowedToken(address token) external onlyOwner {\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\n allowedTokens[token] = true;\n emit AllowedTokenAdded(token);\n }\n\n function removeAllowedToken(address token) external onlyOwner {\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\n allowedTokens[token] = false;\n emit AllowedTokenRemoved(token);\n }\n\n function enableAllowedTokensValidation() external onlyOwner {\n validateAllowedTokens = true;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function disableAllowedTokensValidation() external onlyOwner {\n // Before disabling Allowed Tokens Validations some kind of contract validation system\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\n validateAllowedTokens = false;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\n maxTokensAllowed = maxTokens;\n emit MaxTokensAllowedChanged(maxTokensAllowed);\n }\n\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\n minTokensAllowed = minTokens;\n emit MinTokensAllowedChanged(minTokensAllowed);\n }\n\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\n dailyLimit = _dailyLimit;\n emit DailyLimitChanged(_dailyLimit);\n }\n\n // solium-disable-next-line max-len\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\n if(amount > maxTokensAllowed)\n return false;\n if(amount < minTokensAllowed)\n return false;\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\n return false;\n if(!isSideToken && !isTokenAllowed(tokenToUse))\n return false;\n return true;\n }\n\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\n uint maxWithrow = dailyLimit - spentToday;\n if (dailyLimit < spentToday)\n return 0;\n if(maxWithrow > maxTokensAllowed)\n maxWithrow = maxTokensAllowed;\n return maxWithrow;\n }\n\n}\n"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\n\ncontract BridgeProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract FederationProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract MainToken is ERC20Detailed, ERC20 {\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\n ERC20Detailed(name, symbol, decimals)\n {\n _mint(msg.sender, totalSupply);\n }\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\n bool result = transfer(_to, _value);\n if (!result) return false;\n\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\n receiver.tokenFallback(msg.sender, _value, _data);\n\n // IMPORTANT: the ERC-677 specification does not say\n // anything about the use of the receiver contract's\n // tokenFallback method return value. Given\n // its return type matches with this method's return\n // type, returning it could be a possibility.\n // We here take the more conservative approach and\n // ignore the return value, returning true\n // to signal a succesful transfer despite tokenFallback's\n // return value -- fact being tokens are transferred\n // in any case.\n return true;\n }\n}\n\ninterface ERC677TransferReceiver {\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\n}"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract AlternativeERC20Detailed is ERC20 {\n string private _name;\n bytes32 private _symbol;\n uint256 private _decimals;\n\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\n {\n _name = aName;\n _symbol = aSymbol;\n _decimals = someDecimals;\n _mint(msg.sender, aTotalSupply);\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (bytes32) {\n return _symbol;\n }\n\n function decimals() public view returns (uint256) {\n return _decimals;\n }\n}"
+ },
+ "contracts/test/nftbridge/NFTERC721TestToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\n\ncontract NFTERC721TestToken is ERC721 {\n\n string private _contractURI;\n\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\n\n function safeMint(address to, uint256 tokenId) public {\n _safeMint(to, tokenId);\n }\n\n function setBaseURI(string memory baseURI) public {\n _setBaseURI(baseURI);\n }\n\n function setContractURI(string memory contractURI_) public {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n function setTokenURI(uint256 tokenId, string memory _tokenURI) public {\n _setTokenURI(tokenId, _tokenURI);\n }\n\n}\n"
+ },
+ "contracts/nftbridge/SideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./ISideNFTToken.sol\";\nimport \"../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\n\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\n address public minter;\n string private _contractURI;\n\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\n require(_minter != address(0), \"SideToken: Empty Minter\");\n minter = _minter;\n _setBaseURI(_baseURI);\n _setContractURI(contractURI_);\n }\n\n function _setContractURI(string memory contractURI_) internal {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(address account, uint256 tokenId) external onlyMinter override {\n _mint(account, tokenId);\n }\n}"
+ },
+ "contracts/nftbridge/SideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"./SideNFTToken.sol\";\n\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external onlyPrimary override returns(address) {\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\n return sideTokenAddress;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() {\n _registerInterface(\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\n );\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Receiver.sol\";\n\n /**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers. \n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Burnable is ERC1155 {\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n}\n"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../lib/LibUtils.sol\";\n\ncontract LibUtilsHarness {\n\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\n return LibUtils.decimalsToGranularity(decimals);\n }\n\n function getDecimals(address tokenToUse) external view returns (uint8) {\n return LibUtils.getDecimals(tokenToUse);\n }\n\n function getGranularity(address tokenToUse) external view returns (uint256) {\n return LibUtils.getGranularity(tokenToUse);\n }\n\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\n return LibUtils.bytesToAddress(bys);\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) external pure returns (uint128) {\n return LibUtils.toUint128(_bytes, _start);\n }\n\n}\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/.chainId b/bridge/deployments/kovan/.chainId
new file mode 100644
index 000000000..f70d7bba4
--- /dev/null
+++ b/bridge/deployments/kovan/.chainId
@@ -0,0 +1 @@
+42
\ No newline at end of file
diff --git a/bridge/deployments/kovan/AllowTokens.json b/bridge/deployments/kovan/AllowTokens.json
new file mode 100644
index 000000000..2a31ccaed
--- /dev/null
+++ b/bridge/deployments/kovan/AllowTokens.json
@@ -0,0 +1,1196 @@
+{
+ "address": "0x37f1087591D4685Eb440aCB2Fb2f71a56144A7Db",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ }
+ ],
+ "name": "AllowedTokenRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "ConfirmationsChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ }
+ ],
+ "name": "SetToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_typeDescription",
+ "type": "string"
+ }
+ ],
+ "name": "TokenTypeAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "indexed": false,
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "TypeLimitsChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_lastDay",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_spentToday",
+ "type": "uint256"
+ }
+ ],
+ "name": "UpdateTokensTransfered",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_TYPES",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Secondary_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "description",
+ "type": "string"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "addTokenType",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "len",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "allowedTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "calcMaxWithdraw",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "maxWithdraw",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "smallAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "getInfoAndLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokenInfo",
+ "name": "info",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limit",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypeDescriptions",
+ "outputs": [
+ {
+ "internalType": "string[]",
+ "name": "descriptions",
+ "type": "string[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypeDescriptionsLength",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypesLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits[]",
+ "name": "limits",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_primary",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "string",
+ "name": "description",
+ "type": "string"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TypeInfo[]",
+ "name": "typesInfo",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "isTokenAllowed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "largeAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "mediumAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "removeAllowedToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "setConfirmations",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokensAndType[]",
+ "name": "tokensAndTypes",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "setMultipleTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ }
+ ],
+ "name": "setToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "setTypeLimits",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "smallAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "typeDescriptions",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "typeLimits",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "updateTokenTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x2d1158799ed192bce68c3676ba7833a087251423290c4423e3a16134a6fa6978",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x11804f8DeADb1803603278156AA1e6602949e8b2",
+ "transactionIndex": 0,
+ "gasUsed": "2459902",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x09f2374a7b81dbe264dfb6095f10fe185c7c9a4e0cb0457a68f63b30f06121b2",
+ "transactionHash": "0x2d1158799ed192bce68c3676ba7833a087251423290c4423e3a16134a6fa6978",
+ "logs": [],
+ "blockNumber": 2152254,
+ "cumulativeGasUsed": "2459902",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"}],\"name\":\"AllowedTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"}],\"name\":\"ConfirmationsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"}],\"name\":\"SetToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_typeDescription\",\"type\":\"string\"}],\"name\":\"TokenTypeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"TypeLimitsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_lastDay\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_spentToday\",\"type\":\"uint256\"}],\"name\":\"UpdateTokensTransfered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_TYPES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__Secondary_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"addTokenType\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"len\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowedTokens\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"spentToday\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastDay\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"calcMaxWithdraw\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"maxWithdraw\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"smallAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getInfoAndLimits\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"spentToday\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastDay\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.TokenInfo\",\"name\":\"info\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limit\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypeDescriptions\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"descriptions\",\"type\":\"string[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypeDescriptionsLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypesLimits\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits[]\",\"name\":\"limits\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_primary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"internalType\":\"struct IAllowTokens.TypeInfo[]\",\"name\":\"typesInfo\",\"type\":\"tuple[]\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isTokenAllowed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"largeAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mediumAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"removeAllowedToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"}],\"name\":\"setConfirmations\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.TokensAndType[]\",\"name\":\"tokensAndTypes\",\"type\":\"tuple[]\"}],\"name\":\"setMultipleTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"}],\"name\":\"setToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"setTypeLimits\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"smallAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"typeDescriptions\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"typeLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"updateTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"__Secondary_init(address)\":{\"details\":\"Sets the primary account to the one that is creating the Secondary contract.\"},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/AllowTokens/AllowTokens.sol\":\"AllowTokens\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/AllowTokens/AllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../zeppelin/math/SafeMath.sol\\\";\\n// Upgradables\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\\\";\\n\\nimport \\\"../interface/IAllowTokens.sol\\\";\\n\\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\\n using SafeMath for uint256;\\n\\n address constant private NULL_ADDRESS = address(0);\\n uint256 constant public MAX_TYPES = 250;\\n mapping (address => TokenInfo) public allowedTokens;\\n mapping (uint256 => Limits) public typeLimits;\\n uint256 public smallAmountConfirmations;\\n uint256 public mediumAmountConfirmations;\\n uint256 public largeAmountConfirmations;\\n string[] public typeDescriptions;\\n\\n event SetToken(address indexed _tokenAddress, uint256 _typeId);\\n event AllowedTokenRemoved(address indexed _tokenAddress);\\n event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\\n event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\\n event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\\n event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\\n\\n\\n modifier notNull(address _address) {\\n require(_address != NULL_ADDRESS, \\\"AllowTokens: Null Address\\\");\\n _;\\n }\\n\\n function initialize(\\n address _manager,\\n address _primary,\\n uint256 _smallAmountConfirmations,\\n uint256 _mediumAmountConfirmations,\\n uint256 _largeAmountConfirmations,\\n TypeInfo[] memory typesInfo) public initializer {\\n UpgradableOwnable.initialize(_manager);\\n UpgradableSecondary.__Secondary_init(_primary);\\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\n for(uint i = 0; i < typesInfo.length; i = i + 1) {\\n _addTokenType(typesInfo[i].description, typesInfo[i].limits);\\n }\\n }\\n\\n function version() override external pure returns (string memory) {\\n return \\\"v1\\\";\\n }\\n\\n function getInfoAndLimits(address token) override public view\\n returns (TokenInfo memory info, Limits memory limit) {\\n info = allowedTokens[token];\\n limit = typeLimits[info.typeId];\\n return (info, limit);\\n }\\n function calcMaxWithdraw(address token) override public view returns (uint256 maxWithdraw) {\\n (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\\n return _calcMaxWithdraw(info, limits);\\n }\\n\\n function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\\n // solium-disable-next-line security/no-block-members\\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\\n info.spentToday = 0;\\n }\\n if (limits.daily <= info.spentToday)\\n return 0;\\n maxWithdraw = limits.daily - info.spentToday;\\n if(maxWithdraw > limits.max)\\n maxWithdraw = limits.max;\\n return maxWithdraw;\\n }\\n\\n // solium-disable-next-line max-len\\n function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\\n (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\\n require(isTokenAllowed(token), \\\"AllowTokens: Not whitelisted\\\");\\n require(amount >= limit.min, \\\"AllowTokens: Lower than limit\\\");\\n\\n // solium-disable-next-line security/no-block-members\\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\\n // solium-disable-next-line security/no-block-members\\n info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\\n info.spentToday = 0;\\n }\\n uint maxWithdraw = _calcMaxWithdraw(info, limit);\\n require(amount <= maxWithdraw, \\\"AllowTokens: Exceeded limit\\\");\\n info.spentToday = info.spentToday.add(amount);\\n allowedTokens[token] = info;\\n\\n emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\\n }\\n\\n function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\\n require(bytes(description).length > 0, \\\"AllowTokens: Empty description\\\");\\n len = typeDescriptions.length;\\n require(len + 1 <= MAX_TYPES, \\\"AllowTokens: Reached MAX_TYPES\\\");\\n typeDescriptions.push(description);\\n _setTypeLimits(len, limits);\\n emit TokenTypeAdded(len, description);\\n return len;\\n }\\n\\n function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\\n return _addTokenType(description, limits);\\n }\\n\\n function _setTypeLimits(uint256 typeId, Limits memory limits) private {\\n require(typeId < typeDescriptions.length, \\\"AllowTokens: bigger than typeDescriptions\\\");\\n require(limits.max >= limits.min, \\\"AllowTokens: maxTokens smaller than minTokens\\\");\\n require(limits.daily >= limits.max, \\\"AllowTokens: dailyLimit smaller than maxTokens\\\");\\n require(limits.mediumAmount > limits.min, \\\"AllowTokens: limits.mediumAmount smaller than min\\\");\\n require(limits.largeAmount > limits.mediumAmount, \\\"AllowTokens: limits.largeAmount smaller than mediumAmount\\\");\\n typeLimits[typeId] = limits;\\n emit TypeLimitsChanged(typeId, limits);\\n }\\n\\n function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\\n _setTypeLimits(typeId, limits);\\n }\\n\\n function getTypesLimits() external view override returns(Limits[] memory limits) {\\n limits = new Limits[](typeDescriptions.length);\\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\\n limits[i] = typeLimits[i];\\n }\\n return limits;\\n }\\n\\n function getTypeDescriptionsLength() external view override returns(uint256) {\\n return typeDescriptions.length;\\n }\\n\\n function getTypeDescriptions() external view override returns(string[] memory descriptions) {\\n descriptions = new string[](typeDescriptions.length);\\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\\n descriptions[i] = typeDescriptions[i];\\n }\\n return descriptions;\\n }\\n\\n function isTokenAllowed(address token) public view notNull(token) override returns (bool) {\\n return allowedTokens[token].allowed;\\n }\\n\\n function setToken(address token, uint256 typeId) override public notNull(token) {\\n require(isOwner() || _msgSender() == primary(), \\\"AllowTokens: unauthorized sender\\\");\\n require(typeId < typeDescriptions.length, \\\"AllowTokens: typeId does not exist\\\");\\n TokenInfo memory info = allowedTokens[token];\\n info.allowed = true;\\n info.typeId = typeId;\\n allowedTokens[token] = info;\\n emit SetToken(token, typeId);\\n }\\n\\n function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\\n require(tokensAndTypes.length > 0, \\\"AllowTokens: empty tokens\\\");\\n for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\\n setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\\n }\\n }\\n\\n function removeAllowedToken(address token) external notNull(token) onlyOwner {\\n TokenInfo memory info = allowedTokens[token];\\n require(info.allowed, \\\"AllowTokens: Not Allowed\\\");\\n info.allowed = false;\\n allowedTokens[token] = info;\\n emit AllowedTokenRemoved(token);\\n }\\n\\n function setConfirmations(\\n uint256 _smallAmountConfirmations,\\n uint256 _mediumAmountConfirmations,\\n uint256 _largeAmountConfirmations) external onlyOwner {\\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\n }\\n\\n function _setConfirmations(\\n uint256 _smallAmountConfirmations,\\n uint256 _mediumAmountConfirmations,\\n uint256 _largeAmountConfirmations) private {\\n require(_smallAmountConfirmations <= _mediumAmountConfirmations, \\\"AllowTokens: small bigger than medium confirmations\\\");\\n require(_mediumAmountConfirmations <= _largeAmountConfirmations, \\\"AllowTokens: medium bigger than large confirmations\\\");\\n smallAmountConfirmations = _smallAmountConfirmations;\\n mediumAmountConfirmations = _mediumAmountConfirmations;\\n largeAmountConfirmations = _largeAmountConfirmations;\\n emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\n }\\n\\n function getConfirmations() external view override\\n returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount) {\\n return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\\n }\\n\\n}\\n\",\"keccak256\":\"0x0d9f9d1c4e2185846e9c2f9aa41db513f647983d3497366ab327872f99010b65\",\"license\":\"MIT\"},\"contracts/interface/IAllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\ninterface IAllowTokens {\\n\\n struct Limits {\\n uint256 min;\\n uint256 max;\\n uint256 daily;\\n uint256 mediumAmount;\\n uint256 largeAmount;\\n }\\n\\n struct TokenInfo {\\n bool allowed;\\n uint256 typeId;\\n uint256 spentToday;\\n uint256 lastDay;\\n }\\n\\n struct TypeInfo {\\n string description;\\n Limits limits;\\n }\\n\\n struct TokensAndType {\\n address token;\\n uint256 typeId;\\n }\\n\\n function version() external pure returns (string memory);\\n\\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\\n\\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\\n\\n function getTypesLimits() external view returns(Limits[] memory limits);\\n\\n function getTypeDescriptionsLength() external view returns(uint256);\\n\\n function getTypeDescriptions() external view returns(string[] memory descriptions);\\n\\n function setToken(address token, uint256 typeId) external;\\n\\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\\n\\n function isTokenAllowed(address token) external view returns (bool);\\n\\n function updateTokenTransfer(address token, uint256 amount) external;\\n}\",\"keccak256\":\"0x5a2aaa285c400917cd72fafe61ce409f200c3fc13d984843bccfb97563489a61\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x09ca2716452528a6e69ac9f83f874292a1e547630473f3133038314a2f16029e\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\",\"keccak256\":\"0x3eeeb5ea6bf7d3458bb36acebd4268b406e6a1525e009d4d8a90626c277a37d1\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract UpgradableOwnable is Initializable, Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function initialize(address sender) public initializer {\\n _owner = sender;\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * > Note: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n\\n}\\n\",\"keccak256\":\"0x2e0e58f4a3991801550e6a52512a3c1bbcaa5cb824120c177cb6ec1b4fa0ce97\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\n */\\ncontract UpgradableSecondary is Initializable, Context {\\n address private _primary;\\n\\n /**\\n * @dev Emitted when the primary contract changes.\\n */\\n event PrimaryTransferred(\\n address recipient\\n );\\n\\n /**\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\n */\\n function __Secondary_init(address sender) public initializer {\\n _primary = sender;\\n emit PrimaryTransferred(_primary);\\n }\\n\\n /**\\n * @dev Reverts if called from any account other than the primary.\\n */\\n modifier onlyPrimary() {\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\n _;\\n }\\n\\n /**\\n * @return the address of the primary.\\n */\\n function primary() public view returns (address) {\\n return _primary;\\n }\\n\\n /**\\n * @dev Transfers contract to a new primary.\\n * @param recipient The address of new primary.\\n */\\n function transferPrimary(address recipient) public onlyPrimary {\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\n _primary = recipient;\\n emit PrimaryTransferred(recipient);\\n }\\n\\n}\",\"keccak256\":\"0x156eff0cfa1a0b99fcc5a710688fd8d3038552a380e3687a70e9d75e4bb59315\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50612331806100206000396000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80638f32d59b1161010f578063c4d66de8116100a2578063e4f89ae411610071578063e4f89ae4146103e3578063e744092e146103f6578063f2fde38b14610419578063f9eaee0d1461042c576101e5565b8063c4d66de8146103ad578063c6dbdf61146103c0578063d4164b5d146103c8578063d7516faa146103db576101e5565b8063adfeb5eb116100de578063adfeb5eb1461035d578063b348a29f14610370578063bb698dad14610383578063c361ce8314610396576101e5565b80638f32d59b1461030c57806390469a9d146103215780639d27d22614610334578063a81a8b1f14610355576101e5565b806354fd4d50116101875780637d496be9116101565780637d496be9146102d45780638c34bc55146102dc5780638da5cb5b146102ef5780638de52dd714610304576101e5565b806354fd4d501461029e578063601ad4c9146102a6578063715018a6146102b957806378bf2b53146102c1576101e5565b80632348238c116101c35780632348238c1461024c578063250540cf146102615780633777804f1461027457806353a8b57414610289576101e5565b806307fc9eb9146101ea5780630a9763d7146102175780631c21a08f1461022c575b600080fd5b6101fd6101f8366004611a65565b61043f565b60405161020e9594939291906122b4565b60405180910390f35b61021f61046e565b60405161020e9190612287565b61023f61023a366004611a65565b610473565b60405161020e9190611c39565b61025f61025a366004611725565b61051c565b005b61021f61026f366004611725565b6105db565b61027c610601565b60405161020e9190611bc3565b6102916106da565b60405161020e9190611b63565b61023f6107f9565b61025f6102b4366004611aa9565b610815565b61025f610849565b61025f6102cf366004611928565b6108b7565b61021f610a00565b61025f6102ea366004611928565b610a06565b6102f7610b7f565b60405161020e9190611b4f565b61021f610b8e565b610314610b94565b60405161020e9190611c11565b61025f61032f366004611725565b610bba565b610347610342366004611725565b610ce7565b60405161020e92919061224d565b61021f610d93565b61025f61036b366004611725565b610d99565b61025f61037e366004611a7d565b610e68565b61021f6103913660046119c1565b610e96565b61039e610f14565b60405161020e9392919061229e565b61025f6103bb366004611725565b610f22565b6102f7610fe6565b61025f6103d636600461173f565b610ff5565b61021f6110db565b61025f6103f1366004611951565b6110e1565b610409610404366004611725565b611175565b60405161020e9493929190611c1c565b61025f610427366004611725565b6111a0565b61031461043a366004611725565b6111d0565b603660205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b60fa81565b603a818154811061048357600080fd5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152935090918301828280156105145780601f106104e957610100808354040283529160200191610514565b820191906000526020600020905b8154815290600101906020018083116104f757829003601f168201915b505050505081565b6034546001600160a01b0316610530611219565b6001600160a01b03161461055f5760405162461bcd60e51b815260040161055690612143565b60405180910390fd5b6001600160a01b0381166105855760405162461bcd60e51b815260040161055690611f4b565b603480546001600160a01b0319166001600160a01b0383161790556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9906105d0908390611b4f565b60405180910390a150565b60008060006105e984610ce7565b915091506105f7828261121d565b925050505b919050565b603a5460609067ffffffffffffffff8111801561061d57600080fd5b5060405190808252806020026020018201604052801561065757816020015b6106446115b4565b81526020019060019003908161063c5790505b50905060005b603a548110156106d657603660008281526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250508282815181106106c357fe5b602090810291909101015260010161065d565b5090565b603a5460609067ffffffffffffffff811180156106f657600080fd5b5060405190808252806020026020018201604052801561072a57816020015b60608152602001906001900390816107155790505b50905060005b603a548110156106d657603a818154811061074757fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156107d55780601f106107aa576101008083540402835291602001916107d5565b820191906000526020600020905b8154815290600101906020018083116107b857829003601f168201915b50505050508282815181106107e657fe5b6020908102919091010152600101610730565b604080518082019091526002815261763160f01b602082015290565b61081d610b94565b6108395760405162461bcd60e51b815260040161055690611eb9565b610844838383611275565b505050565b610851610b94565b61086d5760405162461bcd60e51b815260040161055690611eb9565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b816001600160a01b0381166108de5760405162461bcd60e51b815260040161055690611e4d565b6108e6610b94565b8061091057506108f4610fe6565b6001600160a01b0316610905611219565b6001600160a01b0316145b61092c5760405162461bcd60e51b815260040161055690611e84565b603a54821061094d5760405162461bcd60e51b815260040161055690611cf1565b6001600160a01b038316600081815260356020818152604080842081516080810183528154600283018054838601908152600385018054606086019081526001808752868a018f81529b8d9052999098528451151560ff1990941693909317855597519690930195909555945190559051909155519091907f720764556647dd167f4229d6a4255ac86018e302a50fc29dd67a70edb7b314d0906109f2908690612287565b60405180910390a250505050565b60395481565b6034546001600160a01b0316610a1a611219565b6001600160a01b031614610a405760405162461bcd60e51b815260040161055690612143565b600080610a4c84610ce7565b91509150610a59846111d0565b610a755760405162461bcd60e51b8152600401610556906121d1565b8051831015610a965760405162461bcd60e51b815260040161055690612208565b81606001516201518001421115610ab557426060830152600060408301525b6000610ac1838361121d565b905080841115610ae35760405162461bcd60e51b815260040161055690611c4c565b6040830151610af29085611305565b60408481019182526001600160a01b038716600081815260356020908152908390208751815460ff191690151517815590870151600182015592516002840181905560608701516003909401849055915190927f84480cc6a063ffd72c3eddf21e3ffd30db3e2b8e386ec3abf09c98ee9e0e8d3492610b7092612290565b60405180910390a25050505050565b6033546001600160a01b031690565b60385481565b6033546000906001600160a01b0316610bab611219565b6001600160a01b031614905090565b806001600160a01b038116610be15760405162461bcd60e51b815260040161055690611e4d565b610be9610b94565b610c055760405162461bcd60e51b815260040161055690611eb9565b6001600160a01b0382166000908152603560209081526040918290208251608081018452815460ff161515808252600183015493820193909352600282015493810193909352600301546060830152610c705760405162461bcd60e51b815260040161055690612068565b60008082526001600160a01b0384168082526035602090815260408084208551815460ff191690151517815591850151600183015580850151600283015560608501516003909201919091555190917fbf996b4fd74f0c7159bb017b1db415b0d9a6f13129f46d0b93309d170b78df3191a2505050565b610cef6115e3565b610cf76115b4565b50506001600160a01b03166000908152603560209081526040808320815160808082018452825460ff1615158252600180840154838701819052600280860154858801526003958601546060808701919091529189526036885297869020865160a08101885281548152928101549783019790975296860154948101949094529184015494830194909452600490920154918101919091529091565b60375481565b600054610100900460ff1680610db2575060005460ff16155b610dce5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610df9576000805460ff1961ff0019909116610100171660011790555b603480546001600160a01b0319166001600160a01b0384811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610e4a921690611b4f565b60405180910390a18015610e64576000805461ff00191690555b5050565b610e70610b94565b610e8c5760405162461bcd60e51b815260040161055690611eb9565b610e64828261132a565b6000610ea0610b94565b610ebc5760405162461bcd60e51b815260040161055690611eb9565b610f0a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f059250505036859003850185611a4a565b61145c565b90505b9392505050565b603754603854603954909192565b600054610100900460ff1680610f3b575060005460ff16155b610f575760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610f82576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e64576000805461ff00191690555050565b6034546001600160a01b031690565b600054610100900460ff168061100e575060005460ff16155b61102a5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015611055576000805460ff1961ff0019909116610100171660011790555b61105e87610f22565b61106786610d99565b611072858585611275565b60005b82518110156110bf576110b683828151811061108d57fe5b6020026020010151600001518483815181106110a557fe5b60200260200101516020015161145c565b50600101611075565b5080156110d2576000805461ff00191690555b50505050505050565b603a5490565b6110e9610b94565b6111055760405162461bcd60e51b815260040161055690611eb9565b806111225760405162461bcd60e51b815260040161055690611dc8565b60005b818110156108445761116d83838381811061113c57fe5b6111529260206040909202019081019150611725565b84848481811061115e57fe5b905060400201602001356108b7565b600101611125565b603560205260009081526040902080546001820154600283015460039093015460ff90921692909184565b6111a8610b94565b6111c45760405162461bcd60e51b815260040161055690611eb9565b6111cd81611532565b50565b6000816001600160a01b0381166111f95760405162461bcd60e51b815260040161055690611e4d565b50506001600160a01b031660009081526035602052604090205460ff1690565b3390565b60008260600151620151800142111561123857600060408401525b826040015182604001511161124f5750600061126f565b82604001518260400151039050816020015181111561126f575060208101515b92915050565b818311156112955760405162461bcd60e51b815260040161055690611fde565b808211156112b55760405162461bcd60e51b8152600401610556906120f0565b6037839055603882905560398190556040517ffcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219906112f89085908590859061229e565b60405180910390a1505050565b600082820183811015610f0d5760405162461bcd60e51b815260040161055690611cba565b603a54821061134b5760405162461bcd60e51b815260040161055690611f95565b8051602082015110156113705760405162461bcd60e51b815260040161055690611d7b565b8060200151816040015110156113985760405162461bcd60e51b815260040161055690611dff565b80516060820151116113bc5760405162461bcd60e51b81526004016105569061209f565b80606001518160800151116113e35760405162461bcd60e51b815260040161055690611eee565b600082815260366020908152604091829020835181559083015160018201558183015160028201556060830151600382015560808301516004909101555182907f1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb9061145090849061223f565b60405180910390a25050565b60008083511161147e5760405162461bcd60e51b815260040161055690611c83565b50603a5460fa6001820111156114a65760405162461bcd60e51b815260040161055690612031565b603a805460018101825560009190915283516114e9917fa2999d817b6757290b50e8ecf3fa939673403dd35c97de392fdb343b4015ce9e0190602086019061160d565b506114f4818361132a565b807fb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0846040516115249190611c39565b60405180910390a292915050565b6001600160a01b0381166115585760405162461bcd60e51b81526004016105569061218f565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806000151581526020016000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826116435760008555611689565b82601f1061165c57805160ff1916838001178555611689565b82800160010185558215611689579182015b8281111561168957825182559160200191906001019061166e565b506106d69291505b808211156106d65760008155600101611691565b80356001600160a01b03811681146105fc57600080fd5b600060a082840312156116cd578081fd5b60405160a0810181811067ffffffffffffffff821117156116ea57fe5b806040525080915082358152602083013560208201526040830135604082015260608301356060820152608083013560808201525092915050565b600060208284031215611736578081fd5b610f0d826116a5565b60008060008060008060c08789031215611757578182fd5b611760876116a5565b955061176e602088016116a5565b945060408701359350606087013592506080870135915067ffffffffffffffff60a0880135111561179d578081fd5b60a0870135870188601f8201126117b2578182fd5b67ffffffffffffffff813511156117c557fe5b6117d4602080833502016122d7565b81358152602080820191908301845b84358110156119165760c0823586018e03601f19011215611802578586fd5b60405180604082011067ffffffffffffffff6040830111171561182157fe5b6040810160405267ffffffffffffffff60208435880101351115611843578687fd5b82358601602081013501603f018e1361185a578687fd5b67ffffffffffffffff60208435880181810135010135111561187857fe5b61189883358701602081810135909101810135601f01601f1916016122d7565b60208435880181810135019081013580835260409101018f10156118ba578788fd5b602084358801818101350180820135916040909101908301378335870160208181013582018101358301018990529082526118f9908f906040016116bc565b6020828101919091529085529384019391909101906001016117e3565b50508093505050509295509295509295565b6000806040838503121561193a578182fd5b611943836116a5565b946020939093013593505050565b60008060208385031215611963578182fd5b823567ffffffffffffffff8082111561197a578384fd5b818501915085601f83011261198d578384fd5b81358181111561199b578485fd5b8660206040830285010111156119af578485fd5b60209290920196919550909350505050565b600080600083850360c08112156119d6578384fd5b843567ffffffffffffffff808211156119ed578586fd5b818701915087601f830112611a00578586fd5b813581811115611a0e578687fd5b886020828501011115611a1f578687fd5b60209290920195509093505060a0601f1982011215611a3c578182fd5b506020840190509250925092565b600060a08284031215611a5b578081fd5b610f0d83836116bc565b600060208284031215611a76578081fd5b5035919050565b60008060c08385031215611a8f578182fd5b82359150611aa084602085016116bc565b90509250929050565b600080600060608486031215611abd578283fd5b505081359360208301359350604090920135919050565b60008151808452815b81811015611af957602081850181015186830182015201611add565b81811115611b0a5782602083870101525b50601f01601f19169290920160200192915050565b80518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b6001600160a01b0391909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611bb657603f19888603018452611ba4858351611ad4565b94509285019290850190600101611b88565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611c0557611bf2838551611b1f565b9284019260a09290920191600101611bdf565b50909695505050505050565b901515815260200190565b931515845260208401929092526040830152606082015260800190565b600060208252610f0d6020830184611ad4565b6020808252601b908201527f416c6c6f77546f6b656e733a204578636565646564206c696d69740000000000604082015260600190565b6020808252601e908201527f416c6c6f77546f6b656e733a20456d707479206465736372697074696f6e0000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526022908201527f416c6c6f77546f6b656e733a2074797065496420646f6573206e6f74206578696040820152611cdd60f21b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252602d908201527f416c6c6f77546f6b656e733a206d6178546f6b656e7320736d616c6c6572207460408201526c68616e206d696e546f6b656e7360981b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a20656d70747920746f6b656e7300000000000000604082015260600190565b6020808252602e908201527f416c6c6f77546f6b656e733a206461696c794c696d697420736d616c6c65722060408201526d7468616e206d6178546f6b656e7360901b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a204e756c6c204164647265737300000000000000604082015260600190565b6020808252818101527f416c6c6f77546f6b656e733a20756e617574686f72697a65642073656e646572604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526039908201527f416c6c6f77546f6b656e733a206c696d6974732e6c61726765416d6f756e742060408201527f736d616c6c6572207468616e206d656469756d416d6f756e7400000000000000606082015260800190565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f416c6c6f77546f6b656e733a20626967676572207468616e20747970654465736040820152686372697074696f6e7360b81b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a20736d616c6c20626967676572207468616e206d604082015272656469756d20636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252601e908201527f416c6c6f77546f6b656e733a2052656163686564204d41585f54595045530000604082015260600190565b60208082526018908201527f416c6c6f77546f6b656e733a204e6f7420416c6c6f7765640000000000000000604082015260600190565b60208082526031908201527f416c6c6f77546f6b656e733a206c696d6974732e6d656469756d416d6f756e746040820152701039b6b0b63632b9103a3430b71036b4b760791b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a206d656469756d20626967676572207468616e206040820152726c6172676520636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601c908201527f416c6c6f77546f6b656e733a204e6f742077686974656c697374656400000000604082015260600190565b6020808252601d908201527f416c6c6f77546f6b656e733a204c6f776572207468616e206c696d6974000000604082015260600190565b60a0810161126f8284611b1f565b600061012082019050835115158252602084015160208301526040840151604083015260608401516060830152610f0d6080830184611b1f565b90815260200190565b918252602082015260400190565b9283526020830191909152604082015260600190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff811182821017156122f357fe5b60405291905056fea26469706673582212201e8e7daaf66204df917383a3310c7fd1c18b921bb77f19ca1a9103a1dcd8335864736f6c63430007060033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101e55760003560e01c80638f32d59b1161010f578063c4d66de8116100a2578063e4f89ae411610071578063e4f89ae4146103e3578063e744092e146103f6578063f2fde38b14610419578063f9eaee0d1461042c576101e5565b8063c4d66de8146103ad578063c6dbdf61146103c0578063d4164b5d146103c8578063d7516faa146103db576101e5565b8063adfeb5eb116100de578063adfeb5eb1461035d578063b348a29f14610370578063bb698dad14610383578063c361ce8314610396576101e5565b80638f32d59b1461030c57806390469a9d146103215780639d27d22614610334578063a81a8b1f14610355576101e5565b806354fd4d50116101875780637d496be9116101565780637d496be9146102d45780638c34bc55146102dc5780638da5cb5b146102ef5780638de52dd714610304576101e5565b806354fd4d501461029e578063601ad4c9146102a6578063715018a6146102b957806378bf2b53146102c1576101e5565b80632348238c116101c35780632348238c1461024c578063250540cf146102615780633777804f1461027457806353a8b57414610289576101e5565b806307fc9eb9146101ea5780630a9763d7146102175780631c21a08f1461022c575b600080fd5b6101fd6101f8366004611a65565b61043f565b60405161020e9594939291906122b4565b60405180910390f35b61021f61046e565b60405161020e9190612287565b61023f61023a366004611a65565b610473565b60405161020e9190611c39565b61025f61025a366004611725565b61051c565b005b61021f61026f366004611725565b6105db565b61027c610601565b60405161020e9190611bc3565b6102916106da565b60405161020e9190611b63565b61023f6107f9565b61025f6102b4366004611aa9565b610815565b61025f610849565b61025f6102cf366004611928565b6108b7565b61021f610a00565b61025f6102ea366004611928565b610a06565b6102f7610b7f565b60405161020e9190611b4f565b61021f610b8e565b610314610b94565b60405161020e9190611c11565b61025f61032f366004611725565b610bba565b610347610342366004611725565b610ce7565b60405161020e92919061224d565b61021f610d93565b61025f61036b366004611725565b610d99565b61025f61037e366004611a7d565b610e68565b61021f6103913660046119c1565b610e96565b61039e610f14565b60405161020e9392919061229e565b61025f6103bb366004611725565b610f22565b6102f7610fe6565b61025f6103d636600461173f565b610ff5565b61021f6110db565b61025f6103f1366004611951565b6110e1565b610409610404366004611725565b611175565b60405161020e9493929190611c1c565b61025f610427366004611725565b6111a0565b61031461043a366004611725565b6111d0565b603660205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b60fa81565b603a818154811061048357600080fd5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152935090918301828280156105145780601f106104e957610100808354040283529160200191610514565b820191906000526020600020905b8154815290600101906020018083116104f757829003601f168201915b505050505081565b6034546001600160a01b0316610530611219565b6001600160a01b03161461055f5760405162461bcd60e51b815260040161055690612143565b60405180910390fd5b6001600160a01b0381166105855760405162461bcd60e51b815260040161055690611f4b565b603480546001600160a01b0319166001600160a01b0383161790556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9906105d0908390611b4f565b60405180910390a150565b60008060006105e984610ce7565b915091506105f7828261121d565b925050505b919050565b603a5460609067ffffffffffffffff8111801561061d57600080fd5b5060405190808252806020026020018201604052801561065757816020015b6106446115b4565b81526020019060019003908161063c5790505b50905060005b603a548110156106d657603660008281526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250508282815181106106c357fe5b602090810291909101015260010161065d565b5090565b603a5460609067ffffffffffffffff811180156106f657600080fd5b5060405190808252806020026020018201604052801561072a57816020015b60608152602001906001900390816107155790505b50905060005b603a548110156106d657603a818154811061074757fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156107d55780601f106107aa576101008083540402835291602001916107d5565b820191906000526020600020905b8154815290600101906020018083116107b857829003601f168201915b50505050508282815181106107e657fe5b6020908102919091010152600101610730565b604080518082019091526002815261763160f01b602082015290565b61081d610b94565b6108395760405162461bcd60e51b815260040161055690611eb9565b610844838383611275565b505050565b610851610b94565b61086d5760405162461bcd60e51b815260040161055690611eb9565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b816001600160a01b0381166108de5760405162461bcd60e51b815260040161055690611e4d565b6108e6610b94565b8061091057506108f4610fe6565b6001600160a01b0316610905611219565b6001600160a01b0316145b61092c5760405162461bcd60e51b815260040161055690611e84565b603a54821061094d5760405162461bcd60e51b815260040161055690611cf1565b6001600160a01b038316600081815260356020818152604080842081516080810183528154600283018054838601908152600385018054606086019081526001808752868a018f81529b8d9052999098528451151560ff1990941693909317855597519690930195909555945190559051909155519091907f720764556647dd167f4229d6a4255ac86018e302a50fc29dd67a70edb7b314d0906109f2908690612287565b60405180910390a250505050565b60395481565b6034546001600160a01b0316610a1a611219565b6001600160a01b031614610a405760405162461bcd60e51b815260040161055690612143565b600080610a4c84610ce7565b91509150610a59846111d0565b610a755760405162461bcd60e51b8152600401610556906121d1565b8051831015610a965760405162461bcd60e51b815260040161055690612208565b81606001516201518001421115610ab557426060830152600060408301525b6000610ac1838361121d565b905080841115610ae35760405162461bcd60e51b815260040161055690611c4c565b6040830151610af29085611305565b60408481019182526001600160a01b038716600081815260356020908152908390208751815460ff191690151517815590870151600182015592516002840181905560608701516003909401849055915190927f84480cc6a063ffd72c3eddf21e3ffd30db3e2b8e386ec3abf09c98ee9e0e8d3492610b7092612290565b60405180910390a25050505050565b6033546001600160a01b031690565b60385481565b6033546000906001600160a01b0316610bab611219565b6001600160a01b031614905090565b806001600160a01b038116610be15760405162461bcd60e51b815260040161055690611e4d565b610be9610b94565b610c055760405162461bcd60e51b815260040161055690611eb9565b6001600160a01b0382166000908152603560209081526040918290208251608081018452815460ff161515808252600183015493820193909352600282015493810193909352600301546060830152610c705760405162461bcd60e51b815260040161055690612068565b60008082526001600160a01b0384168082526035602090815260408084208551815460ff191690151517815591850151600183015580850151600283015560608501516003909201919091555190917fbf996b4fd74f0c7159bb017b1db415b0d9a6f13129f46d0b93309d170b78df3191a2505050565b610cef6115e3565b610cf76115b4565b50506001600160a01b03166000908152603560209081526040808320815160808082018452825460ff1615158252600180840154838701819052600280860154858801526003958601546060808701919091529189526036885297869020865160a08101885281548152928101549783019790975296860154948101949094529184015494830194909452600490920154918101919091529091565b60375481565b600054610100900460ff1680610db2575060005460ff16155b610dce5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610df9576000805460ff1961ff0019909116610100171660011790555b603480546001600160a01b0319166001600160a01b0384811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610e4a921690611b4f565b60405180910390a18015610e64576000805461ff00191690555b5050565b610e70610b94565b610e8c5760405162461bcd60e51b815260040161055690611eb9565b610e64828261132a565b6000610ea0610b94565b610ebc5760405162461bcd60e51b815260040161055690611eb9565b610f0a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f059250505036859003850185611a4a565b61145c565b90505b9392505050565b603754603854603954909192565b600054610100900460ff1680610f3b575060005460ff16155b610f575760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610f82576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e64576000805461ff00191690555050565b6034546001600160a01b031690565b600054610100900460ff168061100e575060005460ff16155b61102a5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015611055576000805460ff1961ff0019909116610100171660011790555b61105e87610f22565b61106786610d99565b611072858585611275565b60005b82518110156110bf576110b683828151811061108d57fe5b6020026020010151600001518483815181106110a557fe5b60200260200101516020015161145c565b50600101611075565b5080156110d2576000805461ff00191690555b50505050505050565b603a5490565b6110e9610b94565b6111055760405162461bcd60e51b815260040161055690611eb9565b806111225760405162461bcd60e51b815260040161055690611dc8565b60005b818110156108445761116d83838381811061113c57fe5b6111529260206040909202019081019150611725565b84848481811061115e57fe5b905060400201602001356108b7565b600101611125565b603560205260009081526040902080546001820154600283015460039093015460ff90921692909184565b6111a8610b94565b6111c45760405162461bcd60e51b815260040161055690611eb9565b6111cd81611532565b50565b6000816001600160a01b0381166111f95760405162461bcd60e51b815260040161055690611e4d565b50506001600160a01b031660009081526035602052604090205460ff1690565b3390565b60008260600151620151800142111561123857600060408401525b826040015182604001511161124f5750600061126f565b82604001518260400151039050816020015181111561126f575060208101515b92915050565b818311156112955760405162461bcd60e51b815260040161055690611fde565b808211156112b55760405162461bcd60e51b8152600401610556906120f0565b6037839055603882905560398190556040517ffcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219906112f89085908590859061229e565b60405180910390a1505050565b600082820183811015610f0d5760405162461bcd60e51b815260040161055690611cba565b603a54821061134b5760405162461bcd60e51b815260040161055690611f95565b8051602082015110156113705760405162461bcd60e51b815260040161055690611d7b565b8060200151816040015110156113985760405162461bcd60e51b815260040161055690611dff565b80516060820151116113bc5760405162461bcd60e51b81526004016105569061209f565b80606001518160800151116113e35760405162461bcd60e51b815260040161055690611eee565b600082815260366020908152604091829020835181559083015160018201558183015160028201556060830151600382015560808301516004909101555182907f1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb9061145090849061223f565b60405180910390a25050565b60008083511161147e5760405162461bcd60e51b815260040161055690611c83565b50603a5460fa6001820111156114a65760405162461bcd60e51b815260040161055690612031565b603a805460018101825560009190915283516114e9917fa2999d817b6757290b50e8ecf3fa939673403dd35c97de392fdb343b4015ce9e0190602086019061160d565b506114f4818361132a565b807fb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0846040516115249190611c39565b60405180910390a292915050565b6001600160a01b0381166115585760405162461bcd60e51b81526004016105569061218f565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806000151581526020016000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826116435760008555611689565b82601f1061165c57805160ff1916838001178555611689565b82800160010185558215611689579182015b8281111561168957825182559160200191906001019061166e565b506106d69291505b808211156106d65760008155600101611691565b80356001600160a01b03811681146105fc57600080fd5b600060a082840312156116cd578081fd5b60405160a0810181811067ffffffffffffffff821117156116ea57fe5b806040525080915082358152602083013560208201526040830135604082015260608301356060820152608083013560808201525092915050565b600060208284031215611736578081fd5b610f0d826116a5565b60008060008060008060c08789031215611757578182fd5b611760876116a5565b955061176e602088016116a5565b945060408701359350606087013592506080870135915067ffffffffffffffff60a0880135111561179d578081fd5b60a0870135870188601f8201126117b2578182fd5b67ffffffffffffffff813511156117c557fe5b6117d4602080833502016122d7565b81358152602080820191908301845b84358110156119165760c0823586018e03601f19011215611802578586fd5b60405180604082011067ffffffffffffffff6040830111171561182157fe5b6040810160405267ffffffffffffffff60208435880101351115611843578687fd5b82358601602081013501603f018e1361185a578687fd5b67ffffffffffffffff60208435880181810135010135111561187857fe5b61189883358701602081810135909101810135601f01601f1916016122d7565b60208435880181810135019081013580835260409101018f10156118ba578788fd5b602084358801818101350180820135916040909101908301378335870160208181013582018101358301018990529082526118f9908f906040016116bc565b6020828101919091529085529384019391909101906001016117e3565b50508093505050509295509295509295565b6000806040838503121561193a578182fd5b611943836116a5565b946020939093013593505050565b60008060208385031215611963578182fd5b823567ffffffffffffffff8082111561197a578384fd5b818501915085601f83011261198d578384fd5b81358181111561199b578485fd5b8660206040830285010111156119af578485fd5b60209290920196919550909350505050565b600080600083850360c08112156119d6578384fd5b843567ffffffffffffffff808211156119ed578586fd5b818701915087601f830112611a00578586fd5b813581811115611a0e578687fd5b886020828501011115611a1f578687fd5b60209290920195509093505060a0601f1982011215611a3c578182fd5b506020840190509250925092565b600060a08284031215611a5b578081fd5b610f0d83836116bc565b600060208284031215611a76578081fd5b5035919050565b60008060c08385031215611a8f578182fd5b82359150611aa084602085016116bc565b90509250929050565b600080600060608486031215611abd578283fd5b505081359360208301359350604090920135919050565b60008151808452815b81811015611af957602081850181015186830182015201611add565b81811115611b0a5782602083870101525b50601f01601f19169290920160200192915050565b80518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b6001600160a01b0391909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611bb657603f19888603018452611ba4858351611ad4565b94509285019290850190600101611b88565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611c0557611bf2838551611b1f565b9284019260a09290920191600101611bdf565b50909695505050505050565b901515815260200190565b931515845260208401929092526040830152606082015260800190565b600060208252610f0d6020830184611ad4565b6020808252601b908201527f416c6c6f77546f6b656e733a204578636565646564206c696d69740000000000604082015260600190565b6020808252601e908201527f416c6c6f77546f6b656e733a20456d707479206465736372697074696f6e0000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526022908201527f416c6c6f77546f6b656e733a2074797065496420646f6573206e6f74206578696040820152611cdd60f21b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252602d908201527f416c6c6f77546f6b656e733a206d6178546f6b656e7320736d616c6c6572207460408201526c68616e206d696e546f6b656e7360981b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a20656d70747920746f6b656e7300000000000000604082015260600190565b6020808252602e908201527f416c6c6f77546f6b656e733a206461696c794c696d697420736d616c6c65722060408201526d7468616e206d6178546f6b656e7360901b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a204e756c6c204164647265737300000000000000604082015260600190565b6020808252818101527f416c6c6f77546f6b656e733a20756e617574686f72697a65642073656e646572604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526039908201527f416c6c6f77546f6b656e733a206c696d6974732e6c61726765416d6f756e742060408201527f736d616c6c6572207468616e206d656469756d416d6f756e7400000000000000606082015260800190565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f416c6c6f77546f6b656e733a20626967676572207468616e20747970654465736040820152686372697074696f6e7360b81b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a20736d616c6c20626967676572207468616e206d604082015272656469756d20636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252601e908201527f416c6c6f77546f6b656e733a2052656163686564204d41585f54595045530000604082015260600190565b60208082526018908201527f416c6c6f77546f6b656e733a204e6f7420416c6c6f7765640000000000000000604082015260600190565b60208082526031908201527f416c6c6f77546f6b656e733a206c696d6974732e6d656469756d416d6f756e746040820152701039b6b0b63632b9103a3430b71036b4b760791b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a206d656469756d20626967676572207468616e206040820152726c6172676520636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601c908201527f416c6c6f77546f6b656e733a204e6f742077686974656c697374656400000000604082015260600190565b6020808252601d908201527f416c6c6f77546f6b656e733a204c6f776572207468616e206c696d6974000000604082015260600190565b60a0810161126f8284611b1f565b600061012082019050835115158252602084015160208301526040840151604083015260608401516060830152610f0d6080830184611b1f565b90815260200190565b918252602082015260400190565b9283526020830191909152604082015260600190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff811182821017156122f357fe5b60405291905056fea26469706673582212201e8e7daaf66204df917383a3310c7fd1c18b921bb77f19ca1a9103a1dcd8335864736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "__Secondary_init(address)": {
+ "details": "Sets the primary account to the one that is creating the Secondary contract."
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15785,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15788,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15828,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16072,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 16205,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_address"
+ },
+ {
+ "astId": 31,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "allowedTokens",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_mapping(t_address,t_struct(TokenInfo)7131_storage)"
+ },
+ {
+ "astId": 35,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeLimits",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_mapping(t_uint256,t_struct(Limits)7122_storage)"
+ },
+ {
+ "astId": 37,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "smallAmountConfirmations",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 39,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "mediumAmountConfirmations",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 41,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "largeAmountConfirmations",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 44,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeDescriptions",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_array(t_string_storage)dyn_storage"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "base": "t_string_storage",
+ "encoding": "dynamic_array",
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_struct(TokenInfo)7131_storage)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => struct IAllowTokens.TokenInfo)",
+ "numberOfBytes": "32",
+ "value": "t_struct(TokenInfo)7131_storage"
+ },
+ "t_mapping(t_uint256,t_struct(Limits)7122_storage)": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => struct IAllowTokens.Limits)",
+ "numberOfBytes": "32",
+ "value": "t_struct(Limits)7122_storage"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(Limits)7122_storage": {
+ "encoding": "inplace",
+ "label": "struct IAllowTokens.Limits",
+ "members": [
+ {
+ "astId": 7113,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "min",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7115,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "max",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7117,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "daily",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7119,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "mediumAmount",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7121,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "largeAmount",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "160"
+ },
+ "t_struct(TokenInfo)7131_storage": {
+ "encoding": "inplace",
+ "label": "struct IAllowTokens.TokenInfo",
+ "members": [
+ {
+ "astId": 7124,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "allowed",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 7126,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeId",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7128,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "spentToday",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7130,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "lastDay",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/AllowTokensProxy.json b/bridge/deployments/kovan/AllowTokensProxy.json
new file mode 100644
index 000000000..51e2397cd
--- /dev/null
+++ b/bridge/deployments/kovan/AllowTokensProxy.json
@@ -0,0 +1,426 @@
+{
+ "address": "0x92BF86334583909B60F9b798A9Dd7Debd899fEc4",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "transactionIndex": 0,
+ "gasUsed": "1808069",
+ "logsBloom": "0x04000000000000000000000000010000000100000000200000800000000000000000000000000000000000000000000000002000020400000000000000040000000010000000000000000000000000000001000100040000000000000100000008000000020000000000800000000800000000000000000000000000000000400004000400000000000000000004001800000800000000000000000000000000000000000000000000000100000004000000000000c00000002000080000400000000000000004000000000000000000000008008000000000000000000060200000000080200000000000000000000000000000008000000000000000100000",
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f",
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ],
+ "data": "0x0000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf63",
+ "logIndex": 1,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xfcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 2,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "data": "0x00000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000015af1d78b58c400000000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a0000",
+ "logIndex": 3,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034254430000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 4,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000001"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000028a857425466f800000000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000429d069189e0000",
+ "logIndex": 5,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000001"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034554480000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 6,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000002"
+ ],
+ "data": "0x00000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000878678326eac90000000000000000000000000000000000000000000000000010f0cf064dd59200000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a0000",
+ "logIndex": 7,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000002"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000083c31303030757364000000000000000000000000000000000000000000000000",
+ "logIndex": 8,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000003"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000054b40b1f852bda00000000000000000000000000000000000000000000000000a968163f0a57b4000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000008ac7230489e80000",
+ "logIndex": 9,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000003"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000073c31303075736400000000000000000000000000000000000000000000000000",
+ "logIndex": 10,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000004"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000002116545850052128000000000000000000000000000000000000000000000000422ca8b0a00a4250000000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000056bc75e2d63100000",
+ "logIndex": 11,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000004"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000053d31757364000000000000000000000000000000000000000000000000000000",
+ "logIndex": 12,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000005"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000cecb8f27f4200f3a0000000000000000000000000000000000000000000000019d971e4fe8401e740000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea00000",
+ "logIndex": 13,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000005"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000053c31757364000000000000000000000000000000000000000000000000000000",
+ "logIndex": 14,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000006"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000050c783eb9b5c85f2a80000000000000000000000000000000000000000000000a18f07d736b90be5500000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea00000",
+ "logIndex": 15,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000006"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000063c3163656e740000000000000000000000000000000000000000000000000000",
+ "logIndex": 16,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ }
+ ],
+ "blockNumber": 2152255,
+ "cumulativeGasUsed": "1808069",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0x11804f8DeADb1803603278156AA1e6602949e8b2",
+ "0x8c35e166d2dea7a8a28aaea11ad7933cdae4b0ab",
+ "0xd4164b5d000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e80000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf6300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000015af1d78b58c400000000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000000003425443000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000028a857425466f800000000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000429d069189e00000000000000000000000000000000000000000000000000000000000000000003455448000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000878678326eac90000000000000000000000000000000000000000000000000010f0cf064dd59200000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000083c3130303075736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000054b40b1f852bda00000000000000000000000000000000000000000000000000a968163f0a57b4000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000073c3130307573640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000002116545850052128000000000000000000000000000000000000000000000000422ca8b0a00a4250000000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000053d3175736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000cecb8f27f4200f3a0000000000000000000000000000000000000000000000019d971e4fe8401e740000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000053c3175736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000050c783eb9b5c85f2a80000000000000000000000000000000000000000000000a18f07d736b90be5500000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000063c3163656e740000000000000000000000000000000000000000000000000000"
+ ],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"stateVariables\":{\"_ADMIN_SLOT\":{\"details\":\"Storage slot with the admin of the contract. This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0x590a4d952d39a99972cbcb691b472c5d58af9ae8fd142355ad26200affdd2a51\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x0d5202a38732881d576fe3831605fe2633e1bc9f981ebea9c3a368af027e0b71\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x53b00bc48bd4eac1e100195c494267c0ca082bd91ac3018e2ee6155fbcbbb14f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000c9f38038062000c9f83398101604081905262000026916200022e565b8281620000338262000071565b8051156200005457620000528282620000d360201b620002ca1760201c565b505b506200005d9050565b620000688262000102565b5050506200041d565b62000087816200012660201b620002f61760201c565b620000af5760405162461bcd60e51b8152600401620000a69062000347565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6060620000fb838360405180606001604052806027815260200162000c786027913962000130565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b60606200013d8462000126565b6200015c5760405162461bcd60e51b8152600401620000a690620003a4565b600080856001600160a01b031685604051620001799190620002f4565b600060405180830381855af49150503d8060008114620001b6576040519150601f19603f3d011682016040523d82523d6000602084013e620001bb565b606091505b509092509050620001ce828286620001d8565b9695505050505050565b60608315620001e9575081620000fb565b825115620001fa5782518084602001fd5b8160405162461bcd60e51b8152600401620000a6919062000312565b80516001600160a01b03811681146200012b57600080fd5b60008060006060848603121562000243578283fd5b6200024e8462000216565b92506200025e6020850162000216565b60408501519092506001600160401b03808211156200027b578283fd5b818601915086601f8301126200028f578283fd5b8151818111156200029c57fe5b604051601f8201601f191681016020018381118282101715620002bb57fe5b604052818152838201602001891015620002d3578485fd5b620002e6826020830160208701620003ea565b809450505050509250925092565b6000825162000308818460208701620003ea565b9190910192915050565b600060208252825180602084015262000333816040850160208701620003ea565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b8381101562000407578181015183820152602001620003ed565b8381111562000417576000848401525b50505050565b61084b806200042d6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fabbc30a04f636413f38ca4eda3e460473659576ddb6aaf9066d31235c793fc064736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fabbc30a04f636413f38ca4eda3e460473659576ddb6aaf9066d31235c793fc064736f6c63430007060033",
+ "devdoc": {
+ "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.",
+ "events": {
+ "AdminChanged(address,address)": {
+ "details": "Emitted when the admin account has changed."
+ }
+ },
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "constructor": {
+ "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "stateVariables": {
+ "_ADMIN_SLOT": {
+ "details": "Storage slot with the admin of the contract. This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/Bridge.json b/bridge/deployments/kovan/Bridge.json
new file mode 100644
index 000000000..8fcd2b38a
--- /dev/null
+++ b/bridge/deployments/kovan/Bridge.json
@@ -0,0 +1,2174 @@
+{
+ "address": "0xb374422c39172cCB134E4988e434b7BCcAA14c78",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "AcceptedCrossTransfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "AllowTokensChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_reciever",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Claimed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "_userData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Cross",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "FederationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "FeePercentageChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_newSideTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_newSymbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_granularity",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_chainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "NewSideToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Paused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "SideTokenFactoryChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Unpaused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "Upgrading",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "WrappedCurrencyChanged",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "CLAIM_TYPEHASH",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Pausable_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__PauserRol_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "acceptTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "addPauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "allowTokens",
+ "outputs": [
+ {
+ "internalType": "contract IAllowTokens",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "changeAllowTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "changeFederation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "changeSideTokenFactory",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claim",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claimFallback",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_deadline",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_v",
+ "type": "uint8"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_r",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_s",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimGasless",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_originalTokenDecimals",
+ "type": "uint8"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenName",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.CreateSideTokenStruct[]",
+ "name": "createSideTokenStruct",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "createMultipleSideTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_originalTokenDecimals",
+ "type": "uint8"
+ },
+ {
+ "internalType": "string",
+ "name": "_tokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_tokenName",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deprecatedKnownTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deprecatedMappedTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deprecatedOriginalTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "deprecatedSymbolPrefix",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "domainSeparator",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "feePercentageDivider",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFederation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFeePercentage",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ }
+ ],
+ "name": "getOriginalTokenBySideToken",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.OriginalToken",
+ "name": "originalToken",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getTransactionDataHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasBeenClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasCrossed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initDomainSeparator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_federation",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_allowTokens",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_sideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionDataHashMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionDataHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionDataHashMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isPauser",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isUpgrading",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "originalToken",
+ "type": "address"
+ }
+ ],
+ "name": "knownToken",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "knownTokenByChain",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "nonces",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "originalTokenAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "originalTokenBySideToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "pause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "paused",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "tokenToUse",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "receiveTokensTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renouncePauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "senderAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "setFeePercentage",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ },
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.OriginalToken",
+ "name": "originalToken",
+ "type": "tuple"
+ }
+ ],
+ "name": "setOriginalTokenBySideTokenByChain",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "originalToken",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ }
+ ],
+ "name": "setSideTokenByOriginalAddressByChain",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "setUpgrading",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "setWrappedCurrency",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "originalToken",
+ "type": "address"
+ }
+ ],
+ "name": "sideTokenByOriginalToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "sideTokenByOriginalTokenByChain",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "sideTokenFactory",
+ "outputs": [
+ {
+ "internalType": "contract ISideTokenFactory",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "userData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "tokensReceived",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionsDataHashes",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unpause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "wrappedCurrency",
+ "outputs": [
+ {
+ "internalType": "contract IWrapped",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x6e8176ca7f907ecf386d11a9b9822be7a4c7c604c8c960a9dcde90583a1fadf3",
+ "receipt": {
+ "to": null,
+ "from": "0x63C46fBf3183B0a230833a7076128bdf3D5Bc03F",
+ "contractAddress": "0xb374422c39172cCB134E4988e434b7BCcAA14c78",
+ "transactionIndex": 0,
+ "gasUsed": "4394597",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x0ba7495beb722759583ca2356b921d10adba6fd1f63c310e634a98be1a9cc4ee",
+ "transactionHash": "0x6e8176ca7f907ecf386d11a9b9822be7a4c7c604c8c960a9dcde90583a1fadf3",
+ "logs": [],
+ "blockNumber": 31420455,
+ "cumulativeGasUsed": "4394597",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "numDeployments": 2,
+ "solcInputHash": "257bf35cfef475bad06cad6d9dd245f2",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"}],\"name\":\"AcceptedCrossTransfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newAllowTokens\",\"type\":\"address\"}],\"name\":\"AllowTokensChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_reciever\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_relayer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"}],\"name\":\"Claimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_userData\",\"type\":\"bytes\"}],\"name\":\"Cross\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newFederation\",\"type\":\"address\"}],\"name\":\"FederationChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"FeePercentageChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newSideTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_newSymbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_granularity\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_chainId\",\"type\":\"uint256\"}],\"name\":\"NewSideToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newSideTokenFactory\",\"type\":\"address\"}],\"name\":\"SideTokenFactoryChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"Upgrading\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_wrappedCurrency\",\"type\":\"address\"}],\"name\":\"WrappedCurrencyChanged\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"CLAIM_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__Pausable_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__PauserRol_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"}],\"name\":\"acceptTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"addPauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allowTokens\",\"outputs\":[{\"internalType\":\"contract IAllowTokens\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAllowTokens\",\"type\":\"address\"}],\"name\":\"changeAllowTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFederation\",\"type\":\"address\"}],\"name\":\"changeFederation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newSideTokenFactory\",\"type\":\"address\"}],\"name\":\"changeSideTokenFactory\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claim\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claimFallback\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"},{\"internalType\":\"address payable\",\"name\":\"_relayer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_s\",\"type\":\"bytes32\"}],\"name\":\"claimGasless\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"claimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"_originalTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"_originalTokenSymbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_originalTokenName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.CreateSideTokenStruct[]\",\"name\":\"createSideTokenStruct\",\"type\":\"tuple[]\"}],\"name\":\"createMultipleSideTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"_originalTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"_tokenSymbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_tokenName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"}],\"name\":\"createSideToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deprecatedKnownTokens\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deprecatedMappedTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deprecatedOriginalTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deprecatedSymbolPrefix\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"domainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePercentageDivider\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFederation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeePercentage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"}],\"name\":\"getOriginalTokenBySideToken\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.OriginalToken\",\"name\":\"originalToken\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"}],\"name\":\"getTransactionDataHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasBeenClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasCrossed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initDomainSeparator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_federation\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_allowTokens\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_sideTokenFactory\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"transactionDataHashMultichain\",\"type\":\"bytes32\"}],\"name\":\"isClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionDataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionDataHashMultichain\",\"type\":\"bytes32\"}],\"name\":\"isClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isPauser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUpgrading\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalToken\",\"type\":\"address\"}],\"name\":\"knownToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"knownTokenByChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"originalTokenAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"originalTokenBySideToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenToUse\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"receiveTokensTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renouncePauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"senderAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"setFeePercentage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.OriginalToken\",\"name\":\"originalToken\",\"type\":\"tuple\"}],\"name\":\"setOriginalTokenBySideTokenByChain\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"}],\"name\":\"setSideTokenByOriginalAddressByChain\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"setUpgrading\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_wrappedCurrency\",\"type\":\"address\"}],\"name\":\"setWrappedCurrency\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalToken\",\"type\":\"address\"}],\"name\":\"sideTokenByOriginalToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"sideTokenByOriginalTokenByChain\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sideTokenFactory\",\"outputs\":[{\"internalType\":\"contract ISideTokenFactory\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"userData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transactionsDataHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wrappedCurrency\",\"outputs\":[{\"internalType\":\"contract IWrapped\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"__Pausable_init(address)\":{\"details\":\"Initializes the contract in unpaused state. Assigns the Pauser role to the deployer.\"},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pause()\":{\"details\":\"Called by a pauser to pause, triggers stopped state.\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"params\":{\"userData\":\"it can be 2 options in the first one you can send the receiver and the chain id of the destination const userData = web3.eth.abi.encodeParameters( [\\\"address\\\", \\\"uint256\\\"], [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID] ); or you also can send only the destination chain id, and the receiver would be the same as the from parameter const userData = web3.eth.abi.encodeParameters([\\\"uint256\\\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"unpause()\":{\"details\":\"Called by a pauser to unpause, returns to normal state.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"acceptTransfer(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)\":{\"notice\":\"Accepts the transaction from the other chain that was voted and sent by the Federation contract\"},\"claim((address,uint256,bytes32,bytes32,uint32,uint256))\":{\"notice\":\"Claims the crossed transaction using the hash, this sends the funds to the address indicated in\"},\"depositTo(uint256,address)\":{\"notice\":\"Use network currency and cross it.\"},\"receiveTokensTo(uint256,address,address,uint256)\":{\"notice\":\"ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction See https://eips.ethereum.org/EIPS/eip-777#motivation for details\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Bridge/Bridge.sol\":\"Bridge\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Bridge/Bridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n// import \\\"hardhat/console.sol\\\";\\n// Import base Initializable contract\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\n// Import interface and library from OpenZeppelin contracts\\nimport \\\"../zeppelin/upgradable/utils/ReentrancyGuard.sol\\\";\\nimport \\\"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\n\\nimport \\\"../zeppelin/introspection/IERC1820Registry.sol\\\";\\nimport \\\"../zeppelin/token/ERC777/IERC777Recipient.sol\\\";\\nimport \\\"../zeppelin/token/ERC20/IERC20.sol\\\";\\nimport \\\"../zeppelin/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"../zeppelin/utils/Address.sol\\\";\\nimport \\\"../zeppelin/math/SafeMath.sol\\\";\\nimport \\\"../zeppelin/token/ERC777/IERC777.sol\\\";\\n\\nimport \\\"../lib/LibEIP712.sol\\\";\\nimport \\\"../lib/LibUtils.sol\\\";\\n\\nimport \\\"../interface/IBridge.sol\\\";\\nimport \\\"../interface/ISideToken.sol\\\";\\nimport \\\"../interface/ISideTokenFactory.sol\\\";\\nimport \\\"../interface/IAllowTokens.sol\\\";\\nimport \\\"../interface/IWrapped.sol\\\";\\n\\n// solhint-disable-next-line max-states-count\\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\\n\\tusing SafeMath for uint256;\\n\\tusing SafeERC20 for IERC20;\\n\\tusing Address for address;\\n\\n\\taddress constant internal NULL_ADDRESS = address(0);\\n\\tbytes32 constant internal NULL_HASH = bytes32(0);\\n\\tIERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\n\\n\\taddress internal federation;\\n\\tuint256 internal feePercentage;\\n\\tstring public deprecatedSymbolPrefix;\\n\\t// domainSeparator replaces uint256 internal _depprecatedLastDay;\\n\\tbytes32 public domainSeparator;\\n\\tuint256 internal _deprecatedSpentToday;\\n\\n\\tmapping (address => address) public deprecatedMappedTokens; // OriginalToken => SideToken\\n\\tmapping (address => address) public deprecatedOriginalTokens; // SideToken => OriginalToken\\n\\tmapping (address => bool) public deprecatedKnownTokens; // OriginalToken => true\\n\\n\\t// claimed can use the same of bytes32\\n\\tmapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\\n\\n\\tIAllowTokens public allowTokens;\\n\\tISideTokenFactory public sideTokenFactory;\\n\\t//Bridge_v1 variables\\n\\tbool public isUpgrading;\\n\\t// Percentage with up to 2 decimals\\n\\tuint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\\n\\t//Bridge_v2 variables\\n\\tbytes32 constant internal _erc777Interface = keccak256(\\\"ERC777Token\\\"); // solhint-disable-line const-name-snakecase\\n\\tIWrapped public wrappedCurrency;\\n\\tmapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\\n\\tmapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\\n\\tmapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\\n\\n\\t// keccak256(\\\"Claim(address to,uint256 amount,bytes32 transactionHash,uint256 originChainId,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\\\");\\n\\tbytes32 public constant CLAIM_TYPEHASH = 0xaf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c;\\n\\tmapping(address => uint) public nonces;\\n\\n\\t//Bridge_v3 variables multichain\\n\\tmapping (uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain; // chainId => OriginalToken Address => SideToken Address\\n\\tmapping (address => OriginalToken) public originalTokenBySideToken; // SideTokenAddress => struct {}\\n\\tmapping (uint256 => mapping(address => bool)) public knownTokenByChain; // chainId => OriginalToken Address => Know\\n\\n\\tevent AllowTokensChanged(address _newAllowTokens);\\n\\tevent FederationChanged(address _newFederation);\\n\\tevent SideTokenFactoryChanged(address _newSideTokenFactory);\\n\\tevent Upgrading(bool _isUpgrading);\\n\\tevent WrappedCurrencyChanged(address _wrappedCurrency);\\n\\n\\tfunction initialize(\\n\\t\\taddress _manager,\\n\\t\\taddress _federation,\\n\\t\\taddress _allowTokens,\\n\\t\\taddress _sideTokenFactory\\n\\t) public initializer {\\n\\t\\tUpgradableOwnable.initialize(_manager);\\n\\t\\tUpgradablePausable.__Pausable_init(_manager);\\n\\t\\tallowTokens = IAllowTokens(_allowTokens);\\n\\t\\tsideTokenFactory = ISideTokenFactory(_sideTokenFactory);\\n\\t\\tfederation = _federation;\\n\\t\\t//keccak256(\\\"ERC777TokensRecipient\\\")\\n\\t\\tERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\\n\\t\\tinitDomainSeparator();\\n\\t}\\n\\n\\treceive () external payable {\\n\\t\\t// The fallback function is needed to use WRBTC\\n\\t\\trequire(_msgSender() == address(wrappedCurrency), \\\"Bridge: not wrappedCurrency\\\");\\n\\t}\\n\\n\\tfunction version() override external pure returns (string memory) {\\n\\t\\treturn \\\"v4\\\";\\n\\t}\\n\\n\\tfunction initDomainSeparator() public {\\n\\t\\tdomainSeparator = LibEIP712.hashEIP712Domain(\\n\\t\\t\\t\\\"RSK Token Bridge\\\",\\n\\t\\t\\t\\\"1\\\",\\n\\t\\t\\tblock.chainid,\\n\\t\\t\\taddress(this)\\n\\t\\t);\\n\\t}\\n\\n\\tmodifier whenNotUpgrading() {\\n\\t\\trequire(!isUpgrading, \\\"Bridge: Upgrading\\\");\\n\\t\\t_;\\n\\t}\\n\\n\\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\\n\\t\\trequire(chainId == block.chainid, \\\"Bridge: Not block.chainid\\\");\\n\\t}\\n\\n\\tfunction sideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\\n\\t\\taddress sideTokenAddr = sideTokenByOriginalTokenByChain[chainId][originalToken];\\n\\n\\t\\tif (sideTokenAddr != NULL_ADDRESS) {\\n\\t\\t\\treturn sideTokenAddr;\\n\\t\\t}\\n\\n\\t\\t// specification for retrocompatibility\\n\\t\\treturn deprecatedMappedTokens[originalToken];\\n\\t}\\n\\n\\tfunction setSideTokenByOriginalAddressByChain(uint256 chainId, address originalToken, address sideToken) public onlyOwner {\\n\\t\\tsideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\\n\\t}\\n\\n\\tfunction getOriginalTokenBySideToken(address sideToken) public view returns(OriginalToken memory originalToken) {\\n\\t\\toriginalToken = originalTokenBySideToken[sideToken];\\n\\t\\tif (originalToken.tokenAddress != NULL_ADDRESS) {\\n\\t\\t\\treturn originalToken;\\n\\t\\t}\\n\\n\\t\\t// specification for retrocompatibility\\n\\t\\toriginalToken.originChainId = 1; // ethereum main chain id\\n\\t\\toriginalToken.tokenAddress = deprecatedOriginalTokens[sideToken];\\n\\t\\treturn originalToken;\\n\\t}\\n\\n\\tfunction setOriginalTokenBySideTokenByChain(address sideToken, OriginalToken memory originalToken) public onlyOwner {\\n\\t\\toriginalTokenBySideToken[sideToken] = originalToken;\\n\\t}\\n\\n\\tfunction knownToken(uint256 chainId, address originalToken) public view returns(bool) {\\n\\t\\tbool knowToken = knownTokenByChain[chainId][originalToken];\\n\\t\\tif (knowToken) {\\n\\t\\t\\treturn knowToken;\\n\\t\\t}\\n\\n\\t\\t// specification for retrocompatibility\\n\\t\\treturn deprecatedKnownTokens[originalToken];\\n\\t}\\n\\n\\tfunction _setKnownTokenByChain(uint256 chainId, address originalToken, bool knownTokenValue) internal {\\n\\t\\tknownTokenByChain[chainId][originalToken] = knownTokenValue;\\n\\t}\\n\\n\\tfunction acceptTransfer(\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _from,\\n\\t\\taddress payable _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t) external whenNotPaused nonReentrant override {\\n\\t\\trequire(_msgSender() == federation, \\\"Bridge: Not Federation\\\");\\n\\t\\tcheckChainId(_originChainId);\\n\\t\\tshouldBeCurrentChainId(_destinationChainId);\\n\\t\\trequire(knownToken(_originChainId, _originalTokenAddress) ||\\n\\t\\t\\tsideTokenByOriginalToken(_originChainId, _originalTokenAddress) != NULL_ADDRESS,\\n\\t\\t\\t\\\"Bridge: Unknown token\\\"\\n\\t\\t);\\n\\t\\trequire(_to != NULL_ADDRESS, \\\"Bridge: Null To\\\");\\n\\t\\trequire(_amount > 0, \\\"Bridge: Amount 0\\\");\\n\\t\\trequire(_blockHash != NULL_HASH, \\\"Bridge: Null BlockHash\\\");\\n\\t\\trequire(_transactionHash != NULL_HASH, \\\"Bridge: Null TxHash\\\");\\n\\t\\trequire(transactionsDataHashes[_transactionHash] == bytes32(0), \\\"Bridge: Already accepted\\\");\\n\\n\\t\\tbytes32 _transactionDataHash = getTransactionDataHash(\\n\\t\\t\\t_to,\\n\\t\\t\\t_amount,\\n\\t\\t\\t_blockHash,\\n\\t\\t\\t_transactionHash,\\n\\t\\t\\t_logIndex\\n\\t\\t);\\n\\n\\t\\tbytes32 _transactionDataHashMultichain = getTransactionDataHash(\\n\\t\\t\\t_to,\\n\\t\\t\\t_amount,\\n\\t\\t\\t_blockHash,\\n\\t\\t\\t_transactionHash,\\n\\t\\t\\t_logIndex,\\n\\t\\t\\t_originChainId,\\n\\t\\t\\t_destinationChainId\\n\\t\\t);\\n\\t\\t// Do not remove, claimed also has the previously processed using the older bridge version\\n\\t\\t// https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\\n\\t\\trequire(!isClaimed(_transactionDataHash, _transactionDataHashMultichain), \\\"Bridge: Already claimed\\\");\\n\\n\\t\\ttransactionsDataHashes[_transactionHash] = _transactionDataHashMultichain;\\n\\t\\toriginalTokenAddresses[_transactionHash] = _originalTokenAddress;\\n\\t\\tsenderAddresses[_transactionHash] = _from;\\n\\n\\t\\temit AcceptedCrossTransfer(\\n\\t\\t\\t_transactionHash,\\n\\t\\t\\t_originalTokenAddress,\\n\\t\\t\\t_to,\\n\\t\\t\\t_from,\\n\\t\\t\\t_amount,\\n\\t\\t\\t_blockHash,\\n\\t\\t\\t_logIndex,\\n\\t\\t\\t_originChainId,\\n\\t\\t\\t_destinationChainId\\n\\t\\t);\\n\\t}\\n\\n\\tfunction checkChainId(uint256 chainId) internal pure {\\n\\t\\trequire(chainId > 0, \\\"Bridge: ChainId is 0\\\");\\n\\t}\\n\\n\\tfunction _createSideToken(\\n\\t\\tuint256 _typeId,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\tuint8 _originalTokenDecimals,\\n\\t\\tstring calldata _tokenSymbol,\\n\\t\\tstring calldata _tokenName,\\n\\t\\tuint256 _originChainId\\n\\t) internal {\\n\\t\\trequire(_originalTokenAddress != NULL_ADDRESS, \\\"Bridge: Null token\\\");\\n\\t\\tcheckChainId(_originChainId);\\n\\t\\taddress sideToken = sideTokenByOriginalToken(_originChainId, _originalTokenAddress);\\n\\t\\trequire(sideToken == NULL_ADDRESS, \\\"Bridge: Already exists\\\");\\n\\n\\t\\tuint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\\n\\n\\t\\t// Create side token\\n\\t\\tsideToken = sideTokenFactory.createSideToken(_tokenName, _tokenSymbol, granularity);\\n\\n\\t\\tsetSideTokenByOriginalAddressByChain(_originChainId, _originalTokenAddress, sideToken);\\n\\n\\t\\tOriginalToken memory originalToken;\\n\\t\\toriginalToken.originChainId = _originChainId;\\n\\t\\toriginalToken.tokenAddress = _originalTokenAddress;\\n\\t\\tsetOriginalTokenBySideTokenByChain(sideToken, originalToken);\\n\\t\\tallowTokens.setToken(sideToken, _typeId);\\n\\n\\t\\temit NewSideToken(sideToken, _originalTokenAddress, _tokenSymbol, granularity, _originChainId);\\n\\t}\\n\\n\\tfunction createSideToken(\\n\\t\\tuint256 _typeId,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\tuint8 _originalTokenDecimals,\\n\\t\\tstring calldata _tokenSymbol,\\n\\t\\tstring calldata _tokenName,\\n\\t\\tuint256 _originChainId\\n\\t) external onlyOwner override {\\n\\t\\t_createSideToken(\\n\\t\\t\\t_typeId,\\n\\t\\t\\t_originalTokenAddress,\\n\\t\\t\\t_originalTokenDecimals,\\n\\t\\t\\t_tokenSymbol,\\n\\t\\t\\t_tokenName,\\n\\t\\t\\t_originChainId\\n\\t\\t);\\n\\t}\\n\\n\\tfunction createMultipleSideTokens(\\n\\t\\tCreateSideTokenStruct[] calldata createSideTokenStruct\\n\\t) external onlyOwner {\\n\\t\\tfor(uint256 i = 0; i < createSideTokenStruct.length; i++) {\\n\\t\\t\\t_createSideToken(\\n\\t\\t\\t\\tcreateSideTokenStruct[i]._typeId,\\n\\t\\t\\t\\tcreateSideTokenStruct[i]._originalTokenAddress,\\n\\t\\t\\t\\tcreateSideTokenStruct[i]._originalTokenDecimals,\\n\\t\\t\\t\\tcreateSideTokenStruct[i]._originalTokenSymbol,\\n\\t\\t\\t\\tcreateSideTokenStruct[i]._originalTokenName,\\n\\t\\t\\t\\tcreateSideTokenStruct[i]._originChainId\\n\\t\\t\\t);\\n\\t\\t}\\n\\t}\\n\\n\\tfunction claim(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\\n\\t\\treceivedAmount = _claim(\\n\\t\\t\\t_claimData,\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\tpayable(address(0)),\\n\\t\\t\\t0\\n\\t\\t);\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\tfunction claimFallback(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\\n\\t\\trequire(_msgSender() == senderAddresses[_claimData.transactionHash],\\\"Bridge: invalid sender\\\");\\n\\t\\treceivedAmount = _claim(\\n\\t\\t\\t_claimData,\\n\\t\\t\\t_msgSender(),\\n\\t\\t\\tpayable(address(0)),\\n\\t\\t\\t0\\n\\t\\t);\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\tfunction getDigest(\\n\\t\\tClaimData memory _claimData,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _deadline\\n\\t) internal returns (bytes32) {\\n\\t\\treturn LibEIP712.hashEIP712Message(\\n\\t\\t\\tdomainSeparator,\\n\\t\\t\\tkeccak256(\\n\\t\\t\\t\\tabi.encode(\\n\\t\\t\\t\\t\\tCLAIM_TYPEHASH,\\n\\t\\t\\t\\t\\t_claimData.to,\\n\\t\\t\\t\\t\\t_claimData.amount,\\n\\t\\t\\t\\t\\t_claimData.transactionHash,\\n\\t\\t\\t\\t\\t_claimData.originChainId,\\n\\t\\t\\t\\t\\t_relayer,\\n\\t\\t\\t\\t\\t_fee,\\n\\t\\t\\t\\t\\tnonces[_claimData.to]++,\\n\\t\\t\\t\\t\\t_deadline\\n\\t\\t\\t\\t)\\n\\t\\t\\t)\\n\\t\\t);\\n\\t}\\n\\n\\t// Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\\n\\tfunction claimGasless(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _deadline,\\n\\t\\tuint8 _v,\\n\\t\\tbytes32 _r,\\n\\t\\tbytes32 _s\\n\\t) external override returns (uint256 receivedAmount) {\\n\\t\\trequire(_deadline >= block.timestamp, \\\"Bridge: EXPIRED\\\"); // solhint-disable-line not-rely-on-time\\n\\n\\t\\tbytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\\n\\t\\taddress recoveredAddress = ecrecover(digest, _v, _r, _s);\\n\\t\\trequire(_claimData.to != address(0) && recoveredAddress == _claimData.to, \\\"Bridge: INVALID_SIGNATURE\\\");\\n\\n\\t\\treturn _claim(\\n\\t\\t\\t_claimData,\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\t_relayer,\\n\\t\\t\\t_fee\\n\\t\\t);\\n\\t}\\n\\n\\tfunction isClaimed(bytes32 transactionDataHash, bytes32 transactionDataHashMultichain) public view returns(bool) {\\n\\t\\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\\n\\t}\\n\\n\\tfunction isClaimed(ClaimData calldata _claimData, bytes32 transactionDataHashMultichain) public view returns(bool) {\\n\\t\\tbytes32 transactionDataHash = getTransactionDataHash(\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\t_claimData.amount,\\n\\t\\t\\t_claimData.blockHash,\\n\\t\\t\\t_claimData.transactionHash,\\n\\t\\t\\t_claimData.logIndex\\n\\t\\t);\\n\\n\\t\\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\\n\\t}\\n\\n\\tfunction _claim(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress payable _reciever,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal nonReentrant returns (uint256 receivedAmount) {\\n\\t\\taddress originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\\n\\t\\trequire(originalTokenAddress != NULL_ADDRESS, \\\"Bridge: Tx not crossed\\\");\\n\\n\\t\\tbytes32 transactionDataHash = getTransactionDataHash(\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\t_claimData.amount,\\n\\t\\t\\t_claimData.blockHash,\\n\\t\\t\\t_claimData.transactionHash,\\n\\t\\t\\t_claimData.logIndex,\\n\\t\\t\\t_claimData.originChainId,\\n\\t\\t\\tblock.chainid\\n\\t\\t);\\n\\n\\t\\trequire(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \\\"Bridge: Wrong transactionDataHash\\\");\\n\\t\\trequire(!isClaimed(_claimData, transactionDataHash), \\\"Bridge: Already claimed\\\");\\n\\t\\tclaimed[transactionDataHash] = true;\\n\\n\\t\\treceivedAmount = _claimCross(\\n\\t\\t\\t_claimData.originChainId,\\n\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t_reciever,\\n\\t\\t\\t_claimData.amount,\\n\\t\\t\\t_relayer,\\n\\t\\t\\t_fee\\n\\t\\t);\\n\\n\\t\\temitClaimed(_claimData, originalTokenAddress, _reciever, _relayer, _fee);\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\tfunction emitClaimed(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _reciever,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal {\\n\\t\\temit Claimed(\\n\\t\\t\\t_claimData.transactionHash,\\n\\t\\t\\t_originalTokenAddress,\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\tsenderAddresses[_claimData.transactionHash],\\n\\t\\t\\t_claimData.amount,\\n\\t\\t\\t_claimData.blockHash,\\n\\t\\t\\t_claimData.logIndex,\\n\\t\\t\\t_reciever,\\n\\t\\t\\t_relayer,\\n\\t\\t\\t_fee,\\n\\t\\t\\t_claimData.originChainId,\\n\\t\\t\\tblock.chainid\\n\\t\\t);\\n\\t}\\n\\n\\tfunction _claimCross(\\n\\t\\tuint256 _originalChainId,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _reciever,\\n\\t\\tuint256 _amount,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal returns (uint256) {\\n\\t\\tcheckChainId(_originalChainId);\\n\\t\\tif (knownToken(_originalChainId, _originalTokenAddress)) {\\n\\t\\t\\treturn _claimCrossBackToToken(\\n\\t\\t\\t\\t_originalTokenAddress,\\n\\t\\t\\t\\t_reciever,\\n\\t\\t\\t\\t_amount,\\n\\t\\t\\t\\t_relayer,\\n\\t\\t\\t\\t_fee\\n\\t\\t\\t);\\n\\t\\t}\\n\\n\\t\\treturn _claimCrossToSideToken(\\n\\t\\t\\tsideTokenByOriginalToken(_originalChainId, _originalTokenAddress),\\n\\t\\t\\t_reciever,\\n\\t\\t\\t_amount,\\n\\t\\t\\t_relayer,\\n\\t\\t\\t_fee\\n\\t\\t);\\n\\t}\\n\\n\\tfunction _claimCrossToSideToken(\\n\\t\\taddress _sideToken,\\n\\t\\taddress payable _receiver,\\n\\t\\tuint256 _amount,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal returns (uint256 receivedAmount) {\\n\\t\\trequire(_sideToken != NULL_ADDRESS, \\\"Bridge: side token is null\\\");\\n\\t\\tuint256 granularity = IERC777(_sideToken).granularity();\\n\\t\\tuint256 formattedAmount = _amount.mul(granularity);\\n\\t\\trequire(_fee <= formattedAmount, \\\"Bridge: fee too high\\\");\\n\\t\\treceivedAmount = formattedAmount.sub(_fee);\\n\\t\\tISideToken(_sideToken).mint(_receiver, receivedAmount, \\\"\\\", \\\"\\\");\\n\\t\\tif (_fee > 0) {\\n\\t\\t\\tISideToken(_sideToken).mint(_relayer, _fee, \\\"\\\", \\\"relayer fee\\\");\\n\\t\\t}\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\tfunction _claimCrossBackToToken(\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _receiver,\\n\\t\\tuint256 _amount,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal returns (uint256 receivedAmount) {\\n\\t\\tuint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\\n\\t\\t//As side tokens are ERC777 they will always have 18 decimals\\n\\t\\tuint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\\n\\t\\trequire(_fee <= formattedAmount, \\\"Bridge: fee too high\\\");\\n\\t\\treceivedAmount = formattedAmount.sub(_fee);\\n\\t\\tif (address(wrappedCurrency) == _originalTokenAddress) {\\n\\t\\t\\twrappedCurrency.withdraw(formattedAmount);\\n\\t\\t\\t_receiver.transfer(receivedAmount);\\n\\t\\t\\tif(_fee > 0) {\\n\\t\\t\\t\\t_relayer.transfer(_fee);\\n\\t\\t\\t}\\n\\t\\t} else {\\n\\t\\t\\tIERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\\n\\t\\t\\tif(_fee > 0) {\\n\\t\\t\\t\\tIERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\t/**\\n\\t\\t* ERC-20 tokens approve and transferFrom pattern\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\n\\t\\t*/\\n\\tfunction receiveTokensTo(uint256 destinationChainId, address tokenToUse, address to, uint256 amount) external override {\\n\\t\\taddress sender = _msgSender();\\n\\t\\t//Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\\n\\t\\tIERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\\n\\t\\tcrossTokens(tokenToUse, sender, to, amount, \\\"\\\", destinationChainId);\\n\\t}\\n\\n\\t/**\\n\\t\\t* Use network currency and cross it.\\n\\t\\t*/\\n\\tfunction depositTo(uint256 chainId, address to) external payable override {\\n\\t\\taddress sender = _msgSender();\\n\\t\\trequire(address(wrappedCurrency) != NULL_ADDRESS, \\\"Bridge: wrappedCurrency empty\\\");\\n\\t\\twrappedCurrency.deposit{ value: msg.value }();\\n\\t\\tcrossTokens(address(wrappedCurrency), sender, to, msg.value, \\\"\\\", chainId);\\n\\t}\\n\\n\\t/**\\n\\t\\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\n\\t\\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\\n\\t\\t* const userData = web3.eth.abi.encodeParameters(\\n * [\\\"address\\\", \\\"uint256\\\"],\\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\\n * );\\n\\t\\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\\n\\t\\t* const userData = web3.eth.abi.encodeParameters([\\\"uint256\\\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\\n\\t\\t*/\\n\\tfunction tokensReceived(\\n\\t\\taddress operator,\\n\\t\\taddress from,\\n\\t\\taddress to,\\n\\t\\tuint amount,\\n\\t\\tbytes calldata userData, // [address,uint256] user addrest receiver, destinationChainId || [uint256] same as from, destinationChainId\\n\\t\\tbytes calldata\\n\\t) external override(IBridge, IERC777Recipient) {\\n\\t\\t//Hook from ERC777address\\n\\t\\tif(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\\n\\t\\trequire(to == address(this), \\\"Bridge: Not to this address\\\");\\n\\t\\taddress tokenToUse = _msgSender();\\n\\t\\trequire(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \\\"Bridge: Not ERC777 token\\\");\\n\\t\\trequire(userData.length >= 32, \\\"Bridge: user data with at least the destinationChainId\\\");\\n\\t\\trequire(userData.length == 64 || !from.isContract(), \\\"Bridge: Specify receiver address in data\\\");\\n\\t\\taddress receiver = userData.length == 32 ? from : LibUtils.toAddress(userData, 12);\\n\\t\\tuint256 destinationChainId = LibUtils.toUint256(userData, userData.length - 32);\\n\\t\\tcrossTokens(tokenToUse, from, receiver, amount, userData, destinationChainId);\\n\\t}\\n\\n\\tfunction crossTokens(\\n\\t\\taddress tokenToUse,\\n\\t\\taddress from,\\n\\t\\taddress to,\\n\\t\\tuint256 amount,\\n\\t\\tbytes memory userData,\\n\\t\\tuint256 destinationChainId\\n\\t) internal whenNotUpgrading whenNotPaused nonReentrant {\\n\\t\\trequire(block.chainid != destinationChainId, \\\"Bridge: destination chain id equal current chain id\\\");\\n\\t\\tcheckChainId(destinationChainId);\\n\\t\\t_setKnownTokenByChain(destinationChainId, tokenToUse, true);\\n\\t\\tuint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\\n\\t\\tuint256 amountMinusFees = amount.sub(fee);\\n\\t\\tuint8 decimals = LibUtils.getDecimals(tokenToUse);\\n\\t\\tuint formattedAmount = amount;\\n\\t\\tif (decimals != 18) {\\n\\t\\t\\tformattedAmount = amount.mul(uint256(10)**(18-decimals));\\n\\t\\t}\\n\\t\\t// We consider the amount before fees converted to 18 decimals to check the limits\\n\\t\\t// updateTokenTransfer revert if token not allowed\\n\\t\\tallowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\\n\\n\\t\\tOriginalToken memory sideToken = getOriginalTokenBySideToken(tokenToUse);\\n\\t\\tif (sideToken.tokenAddress != NULL_ADDRESS) {\\n\\t\\t\\t// Side Token Crossing back\\n\\t\\t\\t{ // Created scope to avoid stack too deep\\n\\t\\t\\t\\tuint256 granularity = LibUtils.getGranularity(tokenToUse);\\n\\t\\t\\t\\tuint256 modulo = amountMinusFees.mod(granularity);\\n\\t\\t\\t\\tfee = fee.add(modulo);\\n\\t\\t\\t\\tamountMinusFees = amountMinusFees.sub(modulo);\\n\\t\\t\\t\\tIERC777(tokenToUse).burn(amountMinusFees, userData);\\n\\t\\t\\t}\\n\\t\\t\\temit Cross(\\n\\t\\t\\t\\tsideToken.tokenAddress,\\n\\t\\t\\t\\tto,\\n\\t\\t\\t\\tdestinationChainId,\\n\\t\\t\\t\\tfrom,\\n\\t\\t\\t\\tblock.chainid,\\n\\t\\t\\t\\tamountMinusFees,\\n\\t\\t\\t\\tuserData\\n\\t\\t\\t);\\n\\t\\t} else {\\n\\t\\t\\temit Cross(\\n\\t\\t\\t\\ttokenToUse,\\n\\t\\t\\t\\tto,\\n\\t\\t\\t\\tdestinationChainId,\\n\\t\\t\\t\\tfrom,\\n\\t\\t\\t\\tblock.chainid,\\n\\t\\t\\t\\tamountMinusFees,\\n\\t\\t\\t\\tuserData\\n\\t\\t\\t);\\n\\t\\t}\\n\\n\\t\\tif (fee > 0) {\\n\\t\\t\\t//Send the payment to the MultiSig of the Federation\\n\\t\\t\\tIERC20(tokenToUse).safeTransfer(owner(), fee);\\n\\t\\t}\\n\\t}\\n\\n\\t// function for retrocompatibility\\n\\tfunction getTransactionDataHash(\\n\\t\\taddress _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex\\n\\t) internal pure returns(bytes32) {\\n\\t\\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\\n\\t}\\n\\n\\tfunction getTransactionDataHash(\\n\\t\\taddress _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t) public pure override returns(bytes32) {\\n\\t\\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex, _originChainId, _destinationChainId));\\n\\t}\\n\\n\\tfunction setFeePercentage(uint amount) external onlyOwner {\\n\\t\\trequire(amount < (feePercentageDivider/10), \\\"Bridge: bigger than 10%\\\");\\n\\t\\tfeePercentage = amount;\\n\\t\\temit FeePercentageChanged(feePercentage);\\n\\t}\\n\\n\\tfunction getFeePercentage() external view override returns(uint) {\\n\\t\\treturn feePercentage;\\n\\t}\\n\\n\\tfunction changeFederation(address newFederation) external onlyOwner {\\n\\t\\trequire(newFederation != NULL_ADDRESS, \\\"Bridge: Federation is empty\\\");\\n\\t\\tfederation = newFederation;\\n\\t\\temit FederationChanged(federation);\\n\\t}\\n\\n\\tfunction changeAllowTokens(address newAllowTokens) external onlyOwner {\\n\\t\\trequire(newAllowTokens != NULL_ADDRESS, \\\"Bridge: AllowTokens is empty\\\");\\n\\t\\tallowTokens = IAllowTokens(newAllowTokens);\\n\\t\\temit AllowTokensChanged(newAllowTokens);\\n\\t}\\n\\n\\tfunction getFederation() external view returns(address) {\\n\\t\\treturn federation;\\n\\t}\\n\\n\\tfunction changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\\n\\t\\trequire(newSideTokenFactory != NULL_ADDRESS, \\\"Bridge: SideTokenFactory is empty\\\");\\n\\t\\tsideTokenFactory = ISideTokenFactory(newSideTokenFactory);\\n\\t\\temit SideTokenFactoryChanged(newSideTokenFactory);\\n\\t}\\n\\n\\tfunction setUpgrading(bool _isUpgrading) external onlyOwner {\\n\\t\\tisUpgrading = _isUpgrading;\\n\\t\\temit Upgrading(isUpgrading);\\n\\t}\\n\\n\\tfunction setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\\n\\t\\trequire(_wrappedCurrency != NULL_ADDRESS, \\\"Bridge: wrapp is empty\\\");\\n\\t\\twrappedCurrency = IWrapped(_wrappedCurrency);\\n\\t\\temit WrappedCurrencyChanged(_wrappedCurrency);\\n\\t}\\n\\n\\tfunction hasCrossed(bytes32 transactionHash) public view returns (bool) {\\n\\t\\treturn transactionsDataHashes[transactionHash] != bytes32(0);\\n\\t}\\n\\n\\tfunction hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\\n\\t\\treturn claimed[transactionsDataHashes[transactionHash]];\\n\\t}\\n\\n}\\n\",\"keccak256\":\"0xb86625857e1fbf57abe4356692a4a550fbe53e1ead4ecc09de069cad3807706e\",\"license\":\"MIT\"},\"contracts/interface/IAllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\ninterface IAllowTokens {\\n\\n\\tstruct Limits {\\n\\t\\tuint256 min;\\n\\t\\tuint256 max;\\n\\t\\tuint256 daily;\\n\\t\\tuint256 mediumAmount;\\n\\t\\tuint256 largeAmount;\\n\\t}\\n\\n\\tstruct TokenInfo {\\n\\t\\tbool allowed;\\n\\t\\tuint256 typeId;\\n\\t\\tuint256 spentToday;\\n\\t\\tuint256 lastDay;\\n\\t}\\n\\n\\tstruct TypeInfo {\\n\\t\\tstring description;\\n\\t\\tLimits limits;\\n\\t}\\n\\n\\tstruct TokensAndType {\\n\\t\\taddress token;\\n\\t\\tuint256 typeId;\\n\\t}\\n\\n\\tfunction version() external pure returns (string memory);\\n\\n\\tfunction getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\\n\\n\\tfunction calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\\n\\n\\tfunction getTypesLimits() external view returns(Limits[] memory limits);\\n\\n\\tfunction getTypeDescriptionsLength() external view returns(uint256);\\n\\n\\tfunction getTypeDescriptions() external view returns(string[] memory descriptions);\\n\\n\\tfunction setToken(address token, uint256 typeId) external;\\n\\n\\tfunction getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\\n\\n\\tfunction isTokenAllowed(address token) external view returns (bool);\\n\\n\\tfunction updateTokenTransfer(address token, uint256 amount) external;\\n}\",\"keccak256\":\"0x7a68f098e5efaad2d9d84314b2df76897fa9dbbe65c64d629b02b1dc4d9d36b5\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\ninterface IBridge {\\n\\n\\tstruct ClaimData {\\n\\t\\taddress payable to;\\n\\t\\tuint256 amount;\\n\\t\\tbytes32 blockHash;\\n\\t\\tbytes32 transactionHash;\\n\\t\\tuint32 logIndex;\\n\\t\\tuint256 originChainId;\\n\\t}\\n\\n\\tstruct OriginalToken {\\n\\t\\taddress tokenAddress;\\n\\t\\tuint256 originChainId;\\n\\t}\\n\\t\\n\\tstruct CreateSideTokenStruct {\\n\\t\\tuint256 _typeId;\\n\\t\\taddress _originalTokenAddress;\\n\\t\\tuint8 _originalTokenDecimals;\\n\\t\\tstring _originalTokenSymbol;\\n\\t\\tstring _originalTokenName;\\n\\t\\tuint256 _originChainId;\\n\\t}\\n\\n\\tfunction version() external pure returns (string memory);\\n\\n\\tfunction getFeePercentage() external view returns(uint);\\n\\n\\t/**\\n\\t\\t* ERC-20 tokens approve and transferFrom pattern\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\n\\t\\t*/\\n\\tfunction receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;\\n\\n\\t/**\\n\\t\\t* Use network currency and cross it.\\n\\t\\t*/\\n\\tfunction depositTo(uint256 chainId, address to) external payable;\\n\\n\\t/**\\n\\t\\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\n\\t\\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\\n\\t\\t* const userData = web3.eth.abi.encodeParameters(\\n * [\\\"address\\\", \\\"uint256\\\"],\\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\\n * );\\n\\t\\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\\n\\t\\t* const userData = web3.eth.abi.encodeParameters([\\\"uint256\\\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\\n\\t\\t*/\\n\\tfunction tokensReceived (\\n\\t\\taddress operator,\\n\\t\\taddress from,\\n\\t\\taddress to,\\n\\t\\tuint amount,\\n\\t\\tbytes calldata userData,\\n\\t\\tbytes calldata operatorData\\n\\t) external;\\n\\n\\t/**\\n\\t\\t* Accepts the transaction from the other chain that was voted and sent by the Federation contract\\n\\t\\t*/\\n\\tfunction acceptTransfer(\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _from,\\n\\t\\taddress payable _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t) external;\\n\\n\\t/**\\n\\t\\t* Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\n\\t\\t*/\\n\\tfunction claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n\\tfunction claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n\\tfunction claimGasless(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _deadline,\\n\\t\\tuint8 _v,\\n\\t\\tbytes32 _r,\\n\\t\\tbytes32 _s\\n\\t) external returns (uint256 receivedAmount);\\n\\n\\tfunction createSideToken(\\n\\t\\tuint256 _typeId,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\tuint8 _originalTokenDecimals,\\n\\t\\tstring calldata _originalTokenSymbol,\\n\\t\\tstring calldata _originalTokenName,\\n\\t\\tuint256 _chainId\\n\\t) external;\\n\\n\\tfunction createMultipleSideTokens(\\n\\t\\tCreateSideTokenStruct[] calldata createSideTokenStruct\\n\\t) external;\\n\\n\\tfunction getTransactionDataHash(\\n\\t\\taddress _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256 _destinationChainId\\n\\t) external returns(bytes32);\\n\\n\\tevent Cross(\\n\\t\\taddress indexed _tokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\tuint256 indexed _destinationChainId,\\n\\t\\taddress _from,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes _userData\\n\\t);\\n\\n\\tevent NewSideToken(\\n\\t\\taddress indexed _newSideTokenAddress,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\tstring _newSymbol,\\n\\t\\tuint256 _granularity,\\n\\t\\tuint256 _chainId\\n\\t);\\n\\tevent AcceptedCrossTransfer(\\n\\t\\tbytes32 indexed _transactionHash,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\taddress _from,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tuint256 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t);\\n\\tevent FeePercentageChanged(uint256 _amount);\\n\\tevent Claimed(\\n\\t\\tbytes32 indexed _transactionHash,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\taddress _sender,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tuint256 _logIndex,\\n\\t\\taddress _reciever,\\n\\t\\taddress _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _destinationChainId,\\n\\t\\tuint256 _originChainId\\n\\t);\\n}\",\"keccak256\":\"0x1c5d6422edd509f1abc62bc29b41b1c6f80df08235ca289da81c661b8aa33044\",\"license\":\"MIT\"},\"contracts/interface/ISideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\ninterface ISideToken {\\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\\n}\",\"keccak256\":\"0x43d96442dcb622e7efbad6ff3fcfe109d9f881c18415b571511f326b39d7a70e\",\"license\":\"MIT\"},\"contracts/interface/ISideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\ninterface ISideTokenFactory {\\n\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\\n\\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\\n}\",\"keccak256\":\"0x5c3c0db3ad07c2cb9933ea8a37e01b83d4ec77c7bc0ac684de87f6b1e09d25dc\",\"license\":\"MIT\"},\"contracts/interface/IWrapped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\ninterface IWrapped {\\n function balanceOf(address) external returns(uint);\\n\\n function deposit() external payable;\\n\\n function withdraw(uint wad) external;\\n\\n function totalSupply() external view returns (uint);\\n\\n function approve(address guy, uint wad) external returns (bool);\\n\\n function transfer(address dst, uint wad) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint wad)\\n external\\n returns (bool);\\n}\",\"keccak256\":\"0xea9894370181d2b7a43d973e033d1ceb8d8d229fed2b775d267ca23b58836e7f\",\"license\":\"MIT\"},\"contracts/lib/LibEIP712.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\\nlibrary LibEIP712 {\\n\\n // Hash of the EIP712 Domain Separator Schema\\n // keccak256(abi.encodePacked(\\n // \\\"EIP712Domain(\\\",\\n // \\\"string name,\\\",\\n // \\\"string version,\\\",\\n // \\\"uint256 chainId,\\\",\\n // \\\"address verifyingContract\\\",\\n // \\\")\\\"\\n // ))\\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\\n\\n /// @dev Calculates a EIP712 domain separator.\\n /// @param name The EIP712 domain name.\\n /// @param version The EIP712 domain version.\\n /// @param verifyingContract The EIP712 verifying contract.\\n /// @return result EIP712 domain separator.\\n function hashEIP712Domain(\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract\\n )\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\\n\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\\n // keccak256(bytes(name)),\\n // keccak256(bytes(version)),\\n // chainId,\\n // uint256(verifyingContract)\\n // ))\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Calculate hashes of dynamic data\\n let nameHash := keccak256(add(name, 32), mload(name))\\n let versionHash := keccak256(add(version, 32), mload(version))\\n\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n // Store params in memory\\n mstore(memPtr, schemaHash)\\n mstore(add(memPtr, 32), nameHash)\\n mstore(add(memPtr, 64), versionHash)\\n mstore(add(memPtr, 96), chainId)\\n mstore(add(memPtr, 128), verifyingContract)\\n\\n // Compute hash\\n result := keccak256(memPtr, 160)\\n }\\n return result;\\n }\\n\\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\\n /// with getDomainHash().\\n /// @param hashStruct The EIP712 hash struct.\\n /// @return result EIP712 hash applied to the given EIP712 Domain.\\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // EIP191_HEADER,\\n // EIP712_DOMAIN_HASH,\\n // hashStruct\\n // ));\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\\n\\n // Compute hash\\n result := keccak256(memPtr, 66)\\n }\\n return result;\\n }\\n}\",\"keccak256\":\"0x0314f8cfcab5979a2d713b4863bf5783b1181151ac144091d23f802d3f8ac7c5\",\"license\":\"MIT\"},\"contracts/lib/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nlibrary LibUtils {\\n\\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\\n require(decimals <= 18, \\\"LibUtils: Decimals not <= 18\\\");\\n return uint256(10)**(18-decimals);\\n }\\n\\n function getDecimals(address tokenToUse) internal view returns (uint8) {\\n //support decimals as uint256 or uint8\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"decimals()\\\"));\\n require(success, \\\"LibUtils: No decimals\\\");\\n // uint: enc(X) is the big-endian encoding of X,\\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\\n return uint8(abi.decode(data, (uint256)));\\n }\\n\\n function getGranularity(address tokenToUse) internal view returns (uint256) {\\n //support granularity if ERC777\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"granularity()\\\"));\\n require(success, \\\"LibUtils: No granularity\\\");\\n\\n return abi.decode(data, (uint256));\\n }\\n\\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n addr := mload(add(bys,20))\\n }\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"LibUtils: toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"LibUtils: toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n\\t\\trequire(_bytes.length >= _start + 32, \\\"LibUtils: toUint256_outOfBounds\\\");\\n\\t\\tuint256 tempUint;\\n\\n // solium-disable-next-line security/no-inline-assembly\\n\\t\\tassembly {\\n\\t\\t\\ttempUint := mload(add(add(_bytes, 0x20), _start))\\n\\t\\t}\\n\\n\\t\\treturn tempUint;\\n\\t}\\n}\\n\",\"keccak256\":\"0xf9495f9e5371f47c7ae2a3ce423598414ee24e60983602d76563a782b2562104\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return payable(msg.sender);\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x6f3f274a2270bfe073339370edfa2485e2d515a2656039937f6b972fae96d297\",\"license\":\"MIT\"},\"contracts/zeppelin/access/Roles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Roles\\n * @dev Library for managing addresses assigned to a Role.\\n */\\nlibrary Roles {\\n struct Role {\\n mapping (address => bool) bearer;\\n }\\n\\n /**\\n * @dev Give an account access to this role.\\n */\\n function add(Role storage role, address account) internal {\\n require(!has(role, account), \\\"Roles: account already has role\\\");\\n role.bearer[account] = true;\\n }\\n\\n /**\\n * @dev Remove an account's access to this role.\\n */\\n function remove(Role storage role, address account) internal {\\n require(has(role, account), \\\"Roles: account doesn't have role\\\");\\n role.bearer[account] = false;\\n }\\n\\n /**\\n * @dev Check if an account has this role.\\n * @return bool\\n */\\n function has(Role storage role, address account) internal view returns (bool) {\\n require(account != address(0), \\\"Roles: account is the zero address\\\");\\n return role.bearer[account];\\n }\\n}\\n\",\"keccak256\":\"0x932fc31748c82142ad9f51abd8c9bbaa562c7e6183b967b78a61884ee18e3474\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC1820Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\n * implementers for interfaces in this registry, as well as query support.\\n *\\n * Implementers may be shared by multiple accounts, and can also implement more\\n * than a single interface for each account. Contracts can implement interfaces\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\n * contract.\\n *\\n * {IERC165} interfaces can also be queried via the registry.\\n *\\n * For an in-depth explanation and source code analysis, see the EIP text.\\n */\\ninterface IERC1820Registry {\\n /**\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\n * account is able to set interface implementers for it.\\n *\\n * By default, each account is its own manager. Passing a value of `0x0` in\\n * `newManager` will reset the manager to this initial state.\\n *\\n * Emits a {ManagerChanged} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `account`.\\n */\\n function setManager(address account, address newManager) external;\\n\\n /**\\n * @dev Returns the manager for `account`.\\n *\\n * See {setManager}.\\n */\\n function getManager(address account) external view returns (address);\\n\\n /**\\n * @dev Sets the `implementer` contract as `account`'s implementer for\\n * `interfaceHash`.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n * The zero address can also be used in `implementer` to remove an old one.\\n *\\n * See {interfaceHash} to learn how these are created.\\n *\\n * Emits an {InterfaceImplementerSet} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `_account`.\\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\n * end in 28 zeroes).\\n * - `_implementer` must implement {IERC1820Implementer} and return true when\\n * queried for support, unless `implementer` is the caller. See\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\n */\\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\\n\\n /**\\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\\n * implementer is registered, returns the zero address.\\n *\\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\n * zeroes), `_account` will be queried for support of it.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n */\\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\\n\\n /**\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\n * corresponding\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\n */\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\n\\n /**\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\n * @param account Address of the contract for which to update the cache.\\n * @param interfaceId ERC165 interface for which to update the cache.\\n */\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\n * If the result is not cached a direct lookup on the contract address is performed.\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\n * {updateERC165Cache} with the contract address.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\n\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\n\\n event ManagerChanged(address indexed account, address indexed newManager);\\n}\\n\",\"keccak256\":\"0x8877787cbe99ab8e2dcb85e9b22066b7e62bcea328091c1ff9ae462e54afa66e\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x8038a6eca31e013b0c7f248c7a4eb5846ab0d52bb3f7636fafcf00b075643afe\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {ERC20Detailed}.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xdb194e173849ac56dbc15eaf0c01848361748ff8e4679985c3d11013ee4fa4b6\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeERC20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeERC20: low-level call failed\\\");\\n\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb7197e89889e574b9774604c7583b7226b06f6ebf8327c462fb15d5f8465ab8b\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777Token standard as defined in the EIP.\\n *\\n * This contract uses the\\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\\n * token holders and recipients react to token movements by using setting implementers\\n * for the associated interfaces in said registry. See `IERC1820Registry` and\\n * `ERC1820Implementer`.\\n */\\ninterface IERC777 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the smallest part of the token that is not divisible. This\\n * means all token operations (creation, movement and destruction) must have\\n * amounts that are a multiple of this number.\\n *\\n * For most token contracts, this value will equal 1.\\n */\\n function granularity() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by an account (`owner`).\\n */\\n function balanceOf(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * If send or receive hooks are registered for the caller and `recipient`,\\n * the corresponding functions will be called with `data` and empty\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function send(address recipient, uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Destroys `amount` tokens from the caller's account, reducing the\\n * total supply.\\n *\\n * If a send hook is registered for the caller, the corresponding function\\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n */\\n function burn(uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Returns true if an account is an operator of `tokenHolder`.\\n * Operators can send and burn tokens on behalf of their owners. All\\n * accounts are their own operator.\\n *\\n * See `operatorSend` and `operatorBurn`.\\n */\\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor`.\\n *\\n * Emits an `AuthorizedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function authorizeOperator(address operator) external;\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor` and `defaultOperators`.\\n *\\n * Emits a `RevokedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function revokeOperator(address operator) external;\\n\\n /**\\n * @dev Returns the list of default operators. These accounts are operators\\n * for all token holders, even if `authorizeOperator` was never called on\\n * them.\\n *\\n * This list is immutable, but individual holders may revoke these via\\n * `revokeOperator`, in which case `isOperatorFor` will return false.\\n */\\n function defaultOperators() external view returns (address[] memory);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\\n * be an operator of `sender`.\\n *\\n * If send or receive hooks are registered for `sender` and `recipient`,\\n * the corresponding functions will be called with `data` and\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - `sender` cannot be the zero address.\\n * - `sender` must have at least `amount` tokens.\\n * - the caller must be an operator for `sender`.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function operatorSend(\\n address sender,\\n address recipient,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n /**\\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\\n * The caller must be an operator of `account`.\\n *\\n * If a send hook is registered for `account`, the corresponding function\\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n * - the caller must be an operator for `account`.\\n */\\n function operatorBurn(\\n address account,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n event Sent(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256 amount,\\n bytes data,\\n bytes operatorData\\n );\\n\\n function decimals() external returns (uint8);\\n\\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\\n\\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\\n\\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\\n\\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\\n}\\n\",\"keccak256\":\"0xd8fb2f5bda9acc32af1bc5ed8a64c67a42ac7f32dd1195387535e8e148d40421\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\n *\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an `IERC777` token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0xc1e6f2d257d4973a27a86e590e01a3289317bd4b44ea040a622b4823c7793875\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\",\"keccak256\":\"0x14063a689bff5eecf0f36cb519feb575f60349ecf0d425ead5b931b77dd599d4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../../Initializable.sol\\\";\\n\\nimport \\\"../../../GSN/Context.sol\\\";\\nimport \\\"../../../access/Roles.sol\\\";\\n\\ncontract UpgradablePauserRole is Initializable, Context {\\n using Roles for Roles.Role;\\n\\n event PauserAdded(address indexed account);\\n event PauserRemoved(address indexed account);\\n\\n Roles.Role private _pausers;\\n\\n function __PauserRol_init(address sender) public initializer {\\n if (!isPauser(sender)) {\\n _addPauser(sender);\\n }\\n }\\n\\n modifier onlyPauser() {\\n require(isPauser(_msgSender()), \\\"PauserRole: caller doesn't have the role\\\");\\n _;\\n }\\n\\n function isPauser(address account) public view returns (bool) {\\n return _pausers.has(account);\\n }\\n\\n function addPauser(address account) public onlyPauser {\\n _addPauser(account);\\n }\\n\\n function renouncePauser() public {\\n _removePauser(_msgSender());\\n }\\n\\n function _addPauser(address account) internal {\\n _pausers.add(account);\\n emit PauserAdded(account);\\n }\\n\\n function _removePauser(address account) internal {\\n _pausers.remove(account);\\n emit PauserRemoved(account);\\n }\\n}\\n\",\"keccak256\":\"0xb484fd9ca5d28b46ec2c0d765cd592786a5a2c796987b5a7000e0b3d8b2a0ac9\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"../access/roles/UpgradablePauserRole.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\\n /**\\n * @dev Emitted when the pause is triggered by a pauser (`account`).\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by a pauser (`account`).\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\\n * to the deployer.\\n */\\n function __Pausable_init(address sender) public initializer {\\n UpgradablePauserRole.__PauserRol_init(sender);\\n\\n _paused = false;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n */\\n modifier whenNotPaused() {\\n require(!_paused, \\\"Pausable: paused\\\");\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n */\\n modifier whenPaused() {\\n require(_paused, \\\"Pausable: not paused\\\");\\n _;\\n }\\n\\n /**\\n * @dev Called by a pauser to pause, triggers stopped state.\\n */\\n function pause() public onlyPauser whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Called by a pauser to unpause, returns to normal state.\\n */\\n function unpause() public onlyPauser whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n}\\n\",\"keccak256\":\"0xdc64aa92b0dd6c6d4dc898bee62b70ebf64449b8c27fac6dff027e2fb367e6c0\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract UpgradableOwnable is Initializable, Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function initialize(address sender) public initializer {\\n _owner = sender;\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * > Note: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n\\n}\\n\",\"keccak256\":\"0xdf439a167ae82e7e3dd241ea0c831a1bb0329432ceb4fa889778d1f2d196ce00\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\n/**\\n * @title Helps contracts guard against reentrancy attacks.\\n * @author Remco Bloemen , Eenae \\n * @dev If you mark a function `nonReentrant`, you should also\\n * mark it `external`.\\n */\\ncontract ReentrancyGuard is Initializable {\\n /// @dev counter to allow mutex lock with only one SSTORE operation\\n uint256 private _guardCounter;\\n\\n function initialize() public initializer {\\n // The counter starts at one to prevent changing it from zero to a non-zero\\n // value, which is a more expensive operation.\\n _guardCounter = 1;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n _guardCounter += 1;\\n uint256 localCounter = _guardCounter;\\n _;\\n require(localCounter == _guardCounter, \\\"ReentrancyGuard: no reentrant allowed\\\");\\n }\\n}\",\"keccak256\":\"0x56f7b326ffaf9484cbcad316cb3344153584065d5b33da5698e3eedce30565fa\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x04801fc2398ee3370f3903f95389ea3a8da65a8df01f24b352e499e44d492e9b\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50614e8d806100206000396000f3fe6080604052600436106103bb5760003560e01c806382a0b8cb116101f2578063c4d66de81161010d578063e4e5bbcb116100a0578063f2fde38b1161006f578063f2fde38b14610ce0578063f698da2514610d00578063f8c8765e14610d16578063fa0caa1614610d3657600080fd5b8063e4e5bbcb14610c6c578063e6fc774414610c8c578063ea21709114610ca2578063eb16136f14610cc057600080fd5b8063d12e825d116100dc578063d12e825d14610be8578063d3401a2214610bfd578063da67703714610c1d578063e07801d014610c4c57600080fd5b8063c4d66de814610b42578063ca07140c14610b62578063cbc7328014610b98578063cc3c0f0614610bb857600080fd5b8063a53d6e6e11610185578063b0e1268e11610154578063b0e1268e14610a9d578063b794726214610abd578063b86f60d214610ade578063b984a40414610afe57600080fd5b8063a53d6e6e14610a1d578063a89f298a14610a3d578063ae06c1b714610a5d578063b048c4fb14610a7d57600080fd5b80638ca01082116101c15780638ca010821461099f5780638da5cb5b146109b45780638f32d59b146109d7578063916dc59d146109fd57600080fd5b806382a0b8cb1461091a57806382dc1ec41461094a5780638456cb591461096a57806388710e2e1461097f57600080fd5b80633f4ba83a116102e25780636b0509b1116102755780637a0ab28f116102445780637a0ab28f146108435780637a98187b146108795780637ecebe00146108d85780638129fc1c1461090557600080fd5b80636b0509b1146107d25780636ef8d66d1461080657806370aff70f1461081b578063715018a61461082e57600080fd5b80634c739509116102b15780634c7395091461074657806354fd4d50146107665780635c975abb1461079a578063615bfd6e146107b257600080fd5b80633f4ba83a146106d157806342cdb2c6146106e657806346fbf68e1461070657806347f8bbd41461072657600080fd5b806322f89ba41161035a5780633a1cbbcb116103295780633a1cbbcb146105ec5780633c3f63f41461063a5780633c7e0cb71461067b5780633cf3058b1461069b57600080fd5b806322f89ba4146105245780632f3cca4e1461056f5780633500c1dc1461058f57806337e76109146105af57600080fd5b80630ed928af116103965780630ed928af146104af5780630ef1335c146104cf57806311efbf61146104ef578063122aa5d41461050457600080fd5b806223de291461042f578063026976191461044f57806307c8f7b01461048f57600080fd5b3661042a576041546001600160a01b0316336001600160a01b0316146104285760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a206e6f74207772617070656443757272656e6379000000000060448201526064015b60405180910390fd5b005b600080fd5b34801561043b57600080fd5b5061042861044a36600461424b565b610d56565b34801561045b57600080fd5b5061047c61046a3660046142fc565b60426020526000908152604090205481565b6040519081526020015b60405180910390f35b34801561049b57600080fd5b506104286104aa366004614323565b6110b1565b3480156104bb57600080fd5b5061047c6104ca366004614358565b611140565b3480156104db57600080fd5b5061047c6104ea366004614358565b611161565b3480156104fb57600080fd5b5060375461047c565b34801561051057600080fd5b5061042861051f36600461438d565b6111d8565b34801561053057600080fd5b5061055f61053f366004614418565b604860209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610486565b34801561057b57600080fd5b5061042861058a366004614448565b611616565b34801561059b57600080fd5b506104286105aa366004614448565b611696565b3480156105bb57600080fd5b5061055f6105ca3660046142fc565b6000908152604260209081526040808320548352603e90915290205460ff1690565b3480156105f857600080fd5b50610622610607366004614448565b603b602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610486565b34801561064657600080fd5b50610622610655366004614418565b60466020908152600092835260408084209091529082529020546001600160a01b031681565b34801561068757600080fd5b50610428610696366004614465565b611768565b3480156106a757600080fd5b506106226106b63660046142fc565b6044602052600090815260409020546001600160a01b031681565b3480156106dd57600080fd5b506104286118e2565b3480156106f257600080fd5b50610428610701366004614448565b61199a565b34801561071257600080fd5b5061055f610721366004614448565b611a7b565b34801561073257600080fd5b506104286107413660046144da565b611a88565b34801561075257600080fd5b50610428610761366004614565565b611af9565b34801561077257600080fd5b506040805180820190915260028152611d8d60f21b60208201525b60405161048691906145ff565b3480156107a657600080fd5b5060345460ff1661055f565b3480156107be57600080fd5b5061055f6107cd366004614612565b611b69565b3480156107de57600080fd5b5061047c7faf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c81565b34801561081257600080fd5b50610428611bd6565b610428610829366004614418565b611be1565b34801561083a57600080fd5b50610428611cd6565b34801561084f57600080fd5b5061062261085e366004614448565b603c602052600090815260409020546001600160a01b031681565b34801561088557600080fd5b506108b9610894366004614448565b604760205260009081526040902080546001909101546001600160a01b039091169082565b604080516001600160a01b039093168352602083019190915201610486565b3480156108e457600080fd5b5061047c6108f3366004614448565b60456020526000908152604090205481565b34801561091157600080fd5b50610428611d5b565b34801561092657600080fd5b5061055f610935366004614448565b603d6020526000908152604090205460ff1681565b34801561095657600080fd5b50610428610965366004614448565b611dcc565b34801561097657600080fd5b50610428611dfa565b34801561098b57600080fd5b5061047c61099a36600461464e565b611e77565b3480156109ab57600080fd5b5061078d611ff2565b3480156109c057600080fd5b5060345461010090046001600160a01b0316610622565b3480156109e357600080fd5b5061055f60345461010090046001600160a01b0316331490565b348015610a0957600080fd5b50610428610a18366004614448565b612080565b348015610a2957600080fd5b50603f54610622906001600160a01b031681565b348015610a4957600080fd5b5061047c610a583660046146c0565b612159565b348015610a6957600080fd5b50610428610a783660046142fc565b6121cb565b348015610a8957600080fd5b5061055f610a98366004614725565b612290565b348015610aa957600080fd5b50604154610622906001600160a01b031681565b348015610ac957600080fd5b5060405461055f90600160a01b900460ff1681565b348015610aea57600080fd5b50604054610622906001600160a01b031681565b348015610b0a57600080fd5b50610b1e610b19366004614448565b6122c2565b6040805182516001600160a01b031681526020928301519281019290925201610486565b348015610b4e57600080fd5b50610428610b5d366004614448565b612341565b348015610b6e57600080fd5b50610622610b7d3660046142fc565b6043602052600090815260409020546001600160a01b031681565b348015610ba457600080fd5b50610428610bb3366004614747565b612403565b348015610bc457600080fd5b5061055f610bd33660046142fc565b603e6020526000908152604090205460ff1681565b348015610bf457600080fd5b50610428612448565b348015610c0957600080fd5b50610622610c18366004614418565b6124ef565b348015610c2957600080fd5b5061055f610c383660046142fc565b600090815260426020526040902054151590565b348015610c5857600080fd5b5061055f610c67366004614418565b612542565b348015610c7857600080fd5b50610428610c873660046147eb565b612597565b348015610c9857600080fd5b5061047c61271081565b348015610cae57600080fd5b506036546001600160a01b0316610622565b348015610ccc57600080fd5b50610428610cdb366004614448565b6125d1565b348015610cec57600080fd5b50610428610cfb366004614448565b612653565b348015610d0c57600080fd5b5061047c60395481565b348015610d2257600080fd5b50610428610d31366004614833565b612691565b348015610d4257600080fd5b50610428610d51366004614448565b6127e6565b6001600160a01b038816301415610d6c576110a7565b6001600160a01b0386163014610dc45760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a204e6f7420746f207468697320616464726573730000000000604482015260640161041f565b60003360405163555ddc6560e11b81526001600160a01b03821660048201527fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce21770546024820152909150600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca9060440160206040518083038186803b158015610e4657600080fd5b505afa158015610e5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7e919061488f565b6001600160a01b03161415610ed55760405162461bcd60e51b815260206004820152601860248201527f4272696467653a204e6f742045524337373720746f6b656e0000000000000000604482015260640161041f565b6020841015610f455760405162461bcd60e51b815260206004820152603660248201527f4272696467653a207573657220646174612077697468206174206c65617374206044820152751d1a194819195cdd1a5b985d1a5bdb90da185a5b925960521b606482015260840161041f565b6040841480610f5c57506001600160a01b0388163b155b610fb95760405162461bcd60e51b815260206004820152602860248201527f4272696467653a2053706563696679207265636569766572206164647265737360448201526720696e206461746160c01b606482015260840161041f565b60006020851461100a5761100586868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600c92506128bf915050565b61100c565b885b9050600061105c87878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506110579250602091508a90506148c2565b61292c565b90506110a3838b848b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250899250612992915050565b5050505b5050505050505050565b6110ca60345461010090046001600160a01b0316331490565b6110e65760405162461bcd60e51b815260040161041f906148d9565b6040805460ff60a01b1916600160a01b831515810291909117808355915160ff9190920416151581527f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad9906020015b60405180910390a150565b600061115b826111536020820182614448565b600080612d52565b92915050565b60608101356000908152604460205260408120546001600160a01b0316336001600160a01b0316146111ce5760405162461bcd60e51b8152602060048201526016602482015275213934b233b29d1034b73b30b634b21039b2b73232b960511b604482015260640161041f565b61115b8233611153565b60345460ff16156111fb5760405162461bcd60e51b815260040161041f9061490e565b60016035600082825461120e9190614938565b90915550506035546036546001600160a01b0316336001600160a01b0316146112725760405162461bcd60e51b8152602060048201526016602482015275213934b233b29d102737ba102332b232b930ba34b7b760511b604482015260640161041f565b61127b83612f3d565b61128482612f84565b61128e838b612542565b806112ac575060006112a0848c6124ef565b6001600160a01b031614155b6112f05760405162461bcd60e51b8152602060048201526015602482015274213934b233b29d102ab735b737bbb7103a37b5b2b760591b604482015260640161041f565b6001600160a01b0388166113385760405162461bcd60e51b815260206004820152600f60248201526e4272696467653a204e756c6c20546f60881b604482015260640161041f565b6000871161137b5760405162461bcd60e51b815260206004820152601060248201526f04272696467653a20416d6f756e7420360841b604482015260640161041f565b856113c15760405162461bcd60e51b8152602060048201526016602482015275084e4d2c8ceca74409cead8d84084d8dec6d690c2e6d60531b604482015260640161041f565b846114045760405162461bcd60e51b8152602060048201526013602482015272084e4d2c8ceca74409cead8d840a8f090c2e6d606b1b604482015260640161041f565b600085815260426020526040902054156114605760405162461bcd60e51b815260206004820152601860248201527f4272696467653a20416c72656164792061636365707465640000000000000000604482015260640161041f565b600061146f8989898989612fd3565b905060006114828a8a8a8a8a8a8a612159565b905061148e8282612290565b156114d55760405162461bcd60e51b8152602060048201526017602482015276109c9a5919d94e88105b1c9958591e4818db185a5b5959604a1b604482015260640161041f565b8060426000898152602001908152602001600020819055508b6043600089815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508a6044600089815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550896001600160a01b03168c6001600160a01b0316887fddae5e892ad96ac0e35e9018a1a3e32ecd7f3dfe55ea34d9ab1e8faecd6ccb5a8e8d8d8c8c8c6040516115df969594939291906001600160a01b039690961686526020860194909452604085019290925263ffffffff166060840152608083015260a082015260c00190565b60405180910390a45050603554811461160a5760405162461bcd60e51b815260040161041f90614950565b50505050505050505050565b600054610100900460ff168061162f575060005460ff16155b61164b5760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff1615801561166d576000805461ffff19166101011790555b611676826125d1565b6034805460ff191690558015611692576000805461ff00191690555b5050565b6116af60345461010090046001600160a01b0316331490565b6116cb5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b03811661171a5760405162461bcd60e51b81526020600482015260166024820152754272696467653a20777261707020697320656d70747960501b604482015260640161041f565b604180546001600160a01b0319166001600160a01b0383169081179091556040519081527f0966c958966f6fac9ff807af074f8117eb2e9ce2b76390db7a158e9bdeb2485c90602001611135565b61178160345461010090046001600160a01b0316331490565b61179d5760405162461bcd60e51b815260040161041f906148d9565b60005b818110156118dd576118cb8383838181106117bd576117bd6149dd565b90506020028101906117cf91906149f3565b358484848181106117e2576117e26149dd565b90506020028101906117f491906149f3565b611805906040810190602001614448565b858585818110611817576118176149dd565b905060200281019061182991906149f3565b61183a906060810190604001614a13565b86868681811061184c5761184c6149dd565b905060200281019061185e91906149f3565b61186c906060810190614a2e565b88888881811061187e5761187e6149dd565b905060200281019061189091906149f3565b61189e906080810190614a2e565b8a8a8a8181106118b0576118b06149dd565b90506020028101906118c291906149f3565b60a0013561303e565b806118d581614a75565b9150506117a0565b505050565b6118eb33611a7b565b6119075760405162461bcd60e51b815260040161041f90614a90565b60345460ff166119505760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161041f565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6119b360345461010090046001600160a01b0316331490565b6119cf5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b038116611a2f5760405162461bcd60e51b815260206004820152602160248201527f4272696467653a2053696465546f6b656e466163746f727920697320656d70746044820152607960f81b606482015260840161041f565b604080546001600160a01b0319166001600160a01b038316908117825590519081527f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e318369252162590602001611135565b600061115b60338361327e565b611aa160345461010090046001600160a01b0316331490565b611abd5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b039182166000908152604760209081526040909120825181546001600160a01b03191694169390931783550151600190910155565b611b1260345461010090046001600160a01b0316331490565b611b2e5760405162461bcd60e51b815260040161041f906148d9565b60009283526046602090815260408085206001600160a01b0394851686529091529092208054919092166001600160a01b0319909116179055565b600080611ba0611b7c6020860186614448565b602086013560408701356060880135611b9b60a08a0160808b01614ad8565b612fd3565b6000818152603e602052604090205490915060ff1680611bce57506000838152603e602052604090205460ff165b949350505050565b611bdf33613301565b565b60415433906001600160a01b0316611c3b5760405162461bcd60e51b815260206004820152601d60248201527f4272696467653a207772617070656443757272656e637920656d707479000000604482015260640161041f565b604160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611c8b57600080fd5b505af1158015611c9f573d6000803e3d6000fd5b50505050506118dd604160009054906101000a90046001600160a01b03168284346040518060200160405280600081525088612992565b611cef60345461010090046001600160a01b0316331490565b611d0b5760405162461bcd60e51b815260040161041f906148d9565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b600054610100900460ff1680611d74575060005460ff16155b611d905760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff16158015611db2576000805461ffff19166101011790555b60016035558015611dc9576000805461ff00191690555b50565b611dd533611a7b565b611df15760405162461bcd60e51b815260040161041f90614a90565b611dc981613343565b611e0333611a7b565b611e1f5760405162461bcd60e51b815260040161041f90614a90565b60345460ff1615611e425760405162461bcd60e51b815260040161041f9061490e565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861197d3390565b600042851015611ebb5760405162461bcd60e51b815260206004820152600f60248201526e109c9a5919d94e8811561412549151608a1b604482015260640161041f565b6000611ed7611ecf368b90038b018b614af3565b898989613385565b6040805160008082526020820180845284905260ff89169282019290925260608101879052608081018690529192509060019060a0016020604051602081039080840390855afa158015611f2f573d6000803e3d6000fd5b5050604051601f190151915060009050611f4c60208c018c614448565b6001600160a01b031614158015611f805750611f6b60208b018b614448565b6001600160a01b0316816001600160a01b0316145b611fcc5760405162461bcd60e51b815260206004820152601960248201527f4272696467653a20494e56414c49445f5349474e415455524500000000000000604482015260640161041f565b611fe48a611fdd6020820182614448565b8b8b612d52565b9a9950505050505050505050565b60388054611fff90614b8b565b80601f016020809104026020016040519081016040528092919081815260200182805461202b90614b8b565b80156120785780601f1061204d57610100808354040283529160200191612078565b820191906000526020600020905b81548152906001019060200180831161205b57829003601f168201915b505050505081565b61209960345461010090046001600160a01b0316331490565b6120b55760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b03811661210b5760405162461bcd60e51b815260206004820152601c60248201527f4272696467653a20416c6c6f77546f6b656e7320697320656d70747900000000604482015260640161041f565b603f80546001600160a01b0319166001600160a01b0383169081179091556040519081527f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e390602001611135565b6040805160208082019790975280820195909552606097881b6bffffffffffffffffffffffff191697850197909752607484019590955260e09190911b6001600160e01b0319166094830152609882015260b8808201939093528351808203909301835260d801909252805191012090565b6121e460345461010090046001600160a01b0316331490565b6122005760405162461bcd60e51b815260040161041f906148d9565b61220d600a612710614bd6565b811061225b5760405162461bcd60e51b815260206004820152601760248201527f4272696467653a20626967676572207468616e20313025000000000000000000604482015260640161041f565b60378190556040518181527f97e97c577f03bda90e2c9739011ec065ed5fbfb36ae217d20bb0d9be95e160cd90602001611135565b6000828152603e602052604081205460ff16806122bb57506000828152603e602052604090205460ff165b9392505050565b604080518082018252600080825260209182018190526001600160a01b038481168252604783529083902083518085019094528054909116808452600190910154918301919091521561231457919050565b60016020808301919091526001600160a01b039283166000908152603c9091526040902054909116815290565b600054610100900460ff168061235a575060005460ff16155b6123765760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff16158015612398576000805461ffff19166101011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015611692576000805461ff00191690555050565b61241c60345461010090046001600160a01b0316331490565b6124385760405162461bcd60e51b815260040161041f906148d9565b6110a7888888888888888861303e565b604080518082018252601081526f52534b20546f6b656e2042726964676560801b60208083019182528351808501855260018152603160f81b908201529151902082517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8152918201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc69181019190915246606082015230608082015260a09020603955565b60008281526046602090815260408083206001600160a01b038086168552925282205416801561252057905061115b565b50506001600160a01b039081166000908152603b602052604090205416919050565b60008281526048602090815260408083206001600160a01b038516845290915281205460ff16801561257557905061115b565b50506001600160a01b03166000908152603d602052604090205460ff16919050565b336125ad6001600160a01b038516823085613489565b6125ca84828585604051806020016040528060008152508a612992565b5050505050565b600054610100900460ff16806125ea575060005460ff16155b6126065760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff16158015612628576000805461ffff19166101011790555b61263182611a7b565b61263e5761263e82613343565b8015611692576000805461ff00191690555050565b61266c60345461010090046001600160a01b0316331490565b6126885760405162461bcd60e51b815260040161041f906148d9565b611dc9816134fa565b600054610100900460ff16806126aa575060005460ff16155b6126c65760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff161580156126e8576000805461ffff19166101011790555b6126f185612341565b6126fa85611616565b603f80546001600160a01b038581166001600160a01b031992831617909255604080548584169083161781556036805493881693909216929092179055516329965a1d60e01b815230600482018190527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b60248301526044820152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90606401600060405180830381600087803b1580156127ae57600080fd5b505af11580156127c2573d6000803e3d6000fd5b505050506127ce612448565b80156125ca576000805461ff00191690555050505050565b6127ff60345461010090046001600160a01b0316331490565b61281b5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b0381166128715760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a2046656465726174696f6e20697320656d7074790000000000604482015260640161041f565b603680546001600160a01b0319166001600160a01b0383169081179091556040519081527f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb90602001611135565b60006128cc826014614938565b8351101561291c5760405162461bcd60e51b815260206004820152601f60248201527f4c69625574696c733a20746f416464726573735f6f75744f66426f756e647300604482015260640161041f565b500160200151600160601b900490565b6000612939826020614938565b835110156129895760405162461bcd60e51b815260206004820152601f60248201527f4c69625574696c733a20746f55696e743235365f6f75744f66426f756e647300604482015260640161041f565b50016020015190565b604054600160a01b900460ff16156129e05760405162461bcd60e51b81526020600482015260116024820152704272696467653a20557067726164696e6760781b604482015260640161041f565b60345460ff1615612a035760405162461bcd60e51b815260040161041f9061490e565b600160356000828254612a169190614938565b909155505060355446821415612a8a5760405162461bcd60e51b815260206004820152603360248201527f4272696467653a2064657374696e6174696f6e20636861696e20696420657175604482015272185b0818dd5c9c995b9d0818da185a5b881a59606a1b606482015260840161041f565b612a9382612f3d565b60008281526048602090815260408083206001600160a01b038b1684529091529020805460ff191660011790556000612ae3612710612add603754886135c290919063ffffffff16565b90613641565b90506000612af18683613683565b90506000612afe8a6136c5565b905086601260ff831614612b2f57612b2c612b1a836012614bea565b612b2590600a614cf1565b89906135c2565b90505b603f54604051638c34bc5560e01b81526001600160a01b038d811660048301526024820184905290911690638c34bc5590604401600060405180830381600087803b158015612b7d57600080fd5b505af1158015612b91573d6000803e3d6000fd5b505050506000612ba08c6122c2565b80519091506001600160a01b031615612ca4576000612bbe8d6137a9565b90506000612bcc8683613881565b9050612bd887826138c3565b9650612be48682613683565b60405163fe9d930360e01b81529096506001600160a01b038f169063fe9d930390612c159089908e90600401614d00565b600060405180830381600087803b158015612c2f57600080fd5b505af1158015612c43573d6000803e3d6000fd5b505050505050868a6001600160a01b031682600001516001600160a01b03167fb2320a1ad388e1e16b142f7d2e822f31d8a2bbdd7d4f29260e7c203c5f45e8498e46898e604051612c979493929190614d19565b60405180910390a4612cf7565b868a6001600160a01b03168d6001600160a01b03167fb2320a1ad388e1e16b142f7d2e822f31d8a2bbdd7d4f29260e7c203c5f45e8498e46898e604051612cee9493929190614d19565b60405180910390a45b8415612d2357603454612d239061010090046001600160a01b03166001600160a01b038e169087613922565b50505050506035548114612d495760405162461bcd60e51b815260040161041f90614950565b50505050505050565b6000600160356000828254612d679190614938565b909155505060355460608601356000908152604360205260409020546001600160a01b031680612dd25760405162461bcd60e51b8152602060048201526016602482015275109c9a5919d94e88151e081b9bdd0818dc9bdcdcd95960521b604482015260640161041f565b6000612e0e612de460208a018a614448565b60208a013560408b013560608c0135612e0360a08e0160808f01614ad8565b8d60a0013546612159565b60608901356000908152604260205260409020549091508114612e7d5760405162461bcd60e51b815260206004820152602160248201527f4272696467653a2057726f6e67207472616e73616374696f6e446174614861736044820152600d60fb1b606482015260840161041f565b612e878882611b69565b15612ece5760405162461bcd60e51b8152602060048201526017602482015276109c9a5919d94e88105b1c9958591e4818db185a5b5959604a1b604482015260640161041f565b6000818152603e60209081526040909120805460ff19166001179055612f029060a08a01359084908a908c01358a8a613952565b9350612f1188838989896139a3565b50506035548114612f345760405162461bcd60e51b815260040161041f90614950565b50949350505050565b60008111611dc95760405162461bcd60e51b815260206004820152601460248201527304272696467653a20436861696e496420697320360641b604482015260640161041f565b468114611dc95760405162461bcd60e51b815260206004820152601960248201527f4272696467653a204e6f7420626c6f636b2e636861696e696400000000000000604482015260640161041f565b6040805160208101859052908101839052606086811b6bffffffffffffffffffffffff1916908201526074810185905260e082901b6001600160e01b031916609482015260009060980160405160208183030381529060405280519060200120905095945050505050565b6001600160a01b0387166130895760405162461bcd60e51b8152602060048201526012602482015271213934b233b29d10273ab636103a37b5b2b760711b604482015260640161041f565b61309281612f3d565b600061309e82896124ef565b90506001600160a01b038116156130f05760405162461bcd60e51b81526020600482015260166024820152754272696467653a20416c72656164792065786973747360501b604482015260640161041f565b60006130fb88613a7e565b6040805490516326d9e96360e01b81529192506001600160a01b0316906326d9e9639061313490889088908c908c908890600401614d6f565b602060405180830381600087803b15801561314e57600080fd5b505af1158015613162573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613186919061488f565b9150613193838a84611af9565b60408051808201909152602081018490526001600160a01b038a1681526131ba8382611a88565b603f546040516378bf2b5360e01b81526001600160a01b038581166004830152602482018e9052909116906378bf2b5390604401600060405180830381600087803b15801561320857600080fd5b505af115801561321c573d6000803e3d6000fd5b50505050896001600160a01b0316836001600160a01b03167f88dcf8b72e53287db29df3fee9a0f2cb07d1f986cee153aa7d7554405d5db0178a8a86896040516132699493929190614da9565b60405180910390a35050505050505050505050565b60006001600160a01b0382166132e15760405162461bcd60e51b815260206004820152602260248201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604482015261737360f01b606482015260840161041f565b506001600160a01b03166000908152602091909152604090205460ff1690565b61330c603382613aea565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b61334e603382613b62565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6039548451602080870151606088015160a08901516001600160a01b0385166000908152604590945260408420805494966134809690957faf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c959194919391928c918c918b6133f283614a75565b909155506040805160208101999099526001600160a01b03978816908901526060880195909552608087019390935260a086019190915290921660c084015260e08301919091526101008201526101208101859052610140016040516020818303038152906040528051906020012060405161190160f01b8152600281019290925260228201526042902090565b95945050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526134f49085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613bde565b50505050565b6001600160a01b03811661355b5760405162461bcd60e51b815260206004820152602260248201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604482015261737360f01b606482015260840161041f565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6000826135d15750600061115b565b60006135dd8385614dd0565b9050826135ea8583614bd6565b146122bb5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b606482015260840161041f565b60006122bb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613d5e565b60006122bb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613d8c565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b0386169161370b9190614def565b600060405180830381855afa9150503d8060008114613746576040519150601f19603f3d011682016040523d82523d6000602084013e61374b565b606091505b5091509150816137955760405162461bcd60e51b81526020600482015260156024820152744c69625574696c733a204e6f20646563696d616c7360581b604482015260640161041f565b80806020019051810190611bce9190614e01565b60408051600481526024810182526020810180516001600160e01b031663556f0dc760e01b1790529051600091829182916001600160a01b038616916137ef9190614def565b600060405180830381855afa9150503d806000811461382a576040519150601f19603f3d011682016040523d82523d6000602084013e61382f565b606091505b5091509150816137955760405162461bcd60e51b815260206004820152601860248201527f4c69625574696c733a204e6f206772616e756c61726974790000000000000000604482015260640161041f565b60006122bb83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250613dbd565b6000806138d08385614938565b9050838110156122bb5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015260640161041f565b6040516001600160a01b0383166024820152604481018290526118dd90849063a9059cbb60e01b906064016134bd565b600061395d87612f3d565b6139678787612542565b15613980576139798686868686613de9565b9050613999565b61399661398d88886124ef565b86868686613f99565b90505b9695505050505050565b6139b06020860186614448565b6060860135600081815260446020908152604091829020546001600160a01b039485169489811694937fa7a84dcc6757cdf9b9122d3bbc42d58358c28dc4b09cc24349599a63c56c62fd9392909116918b0135908b0135613a1760a08d0160808e01614ad8565b604080516001600160a01b039586168152602081019490945283019190915263ffffffff166060820152818916608082015290871660a08281019190915260c082018790528a013560e0820152466101008201526101200160405180910390a45050505050565b600060128260ff161115613ad45760405162461bcd60e51b815260206004820152601c60248201527f4c69625574696c733a20446563696d616c73206e6f74203c3d20313800000000604482015260640161041f565b613adf826012614bea565b61115b90600a614cf1565b613af4828261327e565b613b405760405162461bcd60e51b815260206004820181905260248201527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c65604482015260640161041f565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b613b6c828261327e565b15613bb95760405162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015260640161041f565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6001600160a01b0382163b613c355760405162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015260640161041f565b600080836001600160a01b031683604051613c509190614def565b6000604051808303816000865af19150503d8060008114613c8d576040519150601f19603f3d011682016040523d82523d6000602084013e613c92565b606091505b509150915081613ce45760405162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015260640161041f565b8051156134f45780806020019051810190613cff9190614e1a565b6134f45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161041f565b60008183613d7f5760405162461bcd60e51b815260040161041f91906145ff565b5060006134808486614bd6565b60008184841115613db05760405162461bcd60e51b815260040161041f91906145ff565b50600061348084866148c2565b60008183613dde5760405162461bcd60e51b815260040161041f91906145ff565b50611bce8385614e37565b600080613df5876136c5565b60ff1690506000613e1c613e0a8360126148c2565b613e1590600a614e4b565b8790613641565b905080841115613e655760405162461bcd60e51b8152602060048201526014602482015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b604482015260640161041f565b613e6f8185613683565b6041549093506001600160a01b0389811691161415613f6057604154604051632e1a7d4d60e01b8152600481018390526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b158015613ece57600080fd5b505af1158015613ee2573d6000803e3d6000fd5b50506040516001600160a01b038a16925085156108fc02915085906000818181858888f19350505050158015613f1c573d6000803e3d6000fd5b508315613f5b576040516001600160a01b0386169085156108fc029086906000818181858888f19350505050158015613f59573d6000803e3d6000fd5b505b613f8e565b613f746001600160a01b0389168885613922565b8315613f8e57613f8e6001600160a01b0389168686613922565b505095945050505050565b60006001600160a01b038616613ff15760405162461bcd60e51b815260206004820152601a60248201527f4272696467653a207369646520746f6b656e206973206e756c6c000000000000604482015260640161041f565b6000866001600160a01b031663556f0dc76040518163ffffffff1660e01b815260040160206040518083038186803b15801561402c57600080fd5b505afa158015614040573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140649190614e01565b9050600061407286836135c2565b9050808411156140bb5760405162461bcd60e51b8152602060048201526014602482015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b604482015260640161041f565b6140c58185613683565b604051630dcdc7dd60e41b81526001600160a01b038981166004830152602482018390526080604483015260006084830181905260a0606484015260a48301529194509089169063dcdc7dd09060c401600060405180830381600087803b15801561412f57600080fd5b505af1158015614143573d6000803e3d6000fd5b505050506000841115613f8e57604051630dcdc7dd60e41b81526001600160a01b03868116600483015260248201869052608060448301526000608483015260a06064830152600b60a48301526a72656c617965722066656560a81b60c483015289169063dcdc7dd09060e401600060405180830381600087803b1580156141ca57600080fd5b505af11580156141de573d6000803e3d6000fd5b50505050505095945050505050565b6001600160a01b0381168114611dc957600080fd5b60008083601f84011261421457600080fd5b50813567ffffffffffffffff81111561422c57600080fd5b60208301915083602082850101111561424457600080fd5b9250929050565b60008060008060008060008060c0898b03121561426757600080fd5b8835614272816141ed565b97506020890135614282816141ed565b96506040890135614292816141ed565b955060608901359450608089013567ffffffffffffffff808211156142b657600080fd5b6142c28c838d01614202565b909650945060a08b01359150808211156142db57600080fd5b506142e88b828c01614202565b999c989b5096995094979396929594505050565b60006020828403121561430e57600080fd5b5035919050565b8015158114611dc957600080fd5b60006020828403121561433557600080fd5b81356122bb81614315565b600060c0828403121561435257600080fd5b50919050565b600060c0828403121561436a57600080fd5b6122bb8383614340565b803563ffffffff8116811461438857600080fd5b919050565b60008060008060008060008060006101208a8c0312156143ac57600080fd5b89356143b7816141ed565b985060208a01356143c7816141ed565b975060408a01356143d7816141ed565b965060608a0135955060808a0135945060a08a013593506143fa60c08b01614374565b925060e08a013591506101008a013590509295985092959850929598565b6000806040838503121561442b57600080fd5b82359150602083013561443d816141ed565b809150509250929050565b60006020828403121561445a57600080fd5b81356122bb816141ed565b6000806020838503121561447857600080fd5b823567ffffffffffffffff8082111561449057600080fd5b818501915085601f8301126144a457600080fd5b8135818111156144b357600080fd5b8660208260051b85010111156144c857600080fd5b60209290920196919550909350505050565b60008082840360608112156144ee57600080fd5b83356144f9816141ed565b92506040601f198201121561450d57600080fd5b506040516040810181811067ffffffffffffffff8211171561453f57634e487b7160e01b600052604160045260246000fd5b6040526020840135614550816141ed565b81526040939093013560208401525092909150565b60008060006060848603121561457a57600080fd5b83359250602084013561458c816141ed565b9150604084013561459c816141ed565b809150509250925092565b60005b838110156145c25781810151838201526020016145aa565b838111156134f45750506000910152565b600081518084526145eb8160208601602086016145a7565b601f01601f19169290920160200192915050565b6020815260006122bb60208301846145d3565b60008060e0838503121561462557600080fd5b61462f8484614340565b9460c0939093013593505050565b803560ff8116811461438857600080fd5b6000806000806000806000610180888a03121561466a57600080fd5b6146748989614340565b965060c0880135614684816141ed565b955060e0880135945061010088013593506146a2610120890161463d565b92506101408801359150610160880135905092959891949750929550565b600080600080600080600060e0888a0312156146db57600080fd5b87356146e6816141ed565b965060208801359550604088013594506060880135935061470960808901614374565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561473857600080fd5b50508035926020909101359150565b60008060008060008060008060c0898b03121561476357600080fd5b883597506020890135614775816141ed565b965061478360408a0161463d565b9550606089013567ffffffffffffffff808211156147a057600080fd5b6147ac8c838d01614202565b909750955060808b01359150808211156147c557600080fd5b506147d28b828c01614202565b999c989b50969995989497949560a00135949350505050565b6000806000806080858703121561480157600080fd5b843593506020850135614813816141ed565b92506040850135614823816141ed565b9396929550929360600135925050565b6000806000806080858703121561484957600080fd5b8435614854816141ed565b93506020850135614864816141ed565b92506040850135614874816141ed565b91506060850135614884816141ed565b939692955090935050565b6000602082840312156148a157600080fd5b81516122bb816141ed565b634e487b7160e01b600052601160045260246000fd5b6000828210156148d4576148d46148ac565b500390565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6000821982111561494b5761494b6148ac565b500190565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b6000823560be19833603018112614a0957600080fd5b9190910192915050565b600060208284031215614a2557600080fd5b6122bb8261463d565b6000808335601e19843603018112614a4557600080fd5b83018035915067ffffffffffffffff821115614a6057600080fd5b60200191503681900382131561424457600080fd5b6000600019821415614a8957614a896148ac565b5060010190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b600060208284031215614aea57600080fd5b6122bb82614374565b600060c08284031215614b0557600080fd5b60405160c0810181811067ffffffffffffffff82111715614b3657634e487b7160e01b600052604160045260246000fd5b6040528235614b44816141ed565b80825250602083013560208201526040830135604082015260608301356060820152614b7260808401614374565b608082015260a083013560a08201528091505092915050565b600181811c90821680614b9f57607f821691505b6020821081141561435257634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b600082614be557614be5614bc0565b500490565b600060ff821660ff841680821015614c0457614c046148ac565b90039392505050565b600181815b80851115614c48578160001904821115614c2e57614c2e6148ac565b80851615614c3b57918102915b93841c9390800290614c12565b509250929050565b600082614c5f5750600161115b565b81614c6c5750600061115b565b8160018114614c825760028114614c8c57614ca8565b600191505061115b565b60ff841115614c9d57614c9d6148ac565b50506001821b61115b565b5060208310610133831016604e8410600b8410161715614ccb575081810a61115b565b614cd58383614c0d565b8060001904821115614ce957614ce96148ac565b029392505050565b60006122bb60ff841683614c50565b828152604060208201526000611bce60408301846145d3565b60018060a01b038516815283602082015282604082015260806060820152600061399960808301846145d3565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b606081526000614d83606083018789614d46565b8281036020840152614d96818688614d46565b9150508260408301529695505050505050565b606081526000614dbd606083018688614d46565b6020830194909452506040015292915050565b6000816000190483118215151615614dea57614dea6148ac565b500290565b60008251614a098184602087016145a7565b600060208284031215614e1357600080fd5b5051919050565b600060208284031215614e2c57600080fd5b81516122bb81614315565b600082614e4657614e46614bc0565b500690565b60006122bb8383614c5056fea264697066735822122056e9c6d68b936a7b2c66545886a13f33f54fec9bc3a8a09c82fde6ed9811029364736f6c63430008090033",
+ "deployedBytecode": "0x6080604052600436106103bb5760003560e01c806382a0b8cb116101f2578063c4d66de81161010d578063e4e5bbcb116100a0578063f2fde38b1161006f578063f2fde38b14610ce0578063f698da2514610d00578063f8c8765e14610d16578063fa0caa1614610d3657600080fd5b8063e4e5bbcb14610c6c578063e6fc774414610c8c578063ea21709114610ca2578063eb16136f14610cc057600080fd5b8063d12e825d116100dc578063d12e825d14610be8578063d3401a2214610bfd578063da67703714610c1d578063e07801d014610c4c57600080fd5b8063c4d66de814610b42578063ca07140c14610b62578063cbc7328014610b98578063cc3c0f0614610bb857600080fd5b8063a53d6e6e11610185578063b0e1268e11610154578063b0e1268e14610a9d578063b794726214610abd578063b86f60d214610ade578063b984a40414610afe57600080fd5b8063a53d6e6e14610a1d578063a89f298a14610a3d578063ae06c1b714610a5d578063b048c4fb14610a7d57600080fd5b80638ca01082116101c15780638ca010821461099f5780638da5cb5b146109b45780638f32d59b146109d7578063916dc59d146109fd57600080fd5b806382a0b8cb1461091a57806382dc1ec41461094a5780638456cb591461096a57806388710e2e1461097f57600080fd5b80633f4ba83a116102e25780636b0509b1116102755780637a0ab28f116102445780637a0ab28f146108435780637a98187b146108795780637ecebe00146108d85780638129fc1c1461090557600080fd5b80636b0509b1146107d25780636ef8d66d1461080657806370aff70f1461081b578063715018a61461082e57600080fd5b80634c739509116102b15780634c7395091461074657806354fd4d50146107665780635c975abb1461079a578063615bfd6e146107b257600080fd5b80633f4ba83a146106d157806342cdb2c6146106e657806346fbf68e1461070657806347f8bbd41461072657600080fd5b806322f89ba41161035a5780633a1cbbcb116103295780633a1cbbcb146105ec5780633c3f63f41461063a5780633c7e0cb71461067b5780633cf3058b1461069b57600080fd5b806322f89ba4146105245780632f3cca4e1461056f5780633500c1dc1461058f57806337e76109146105af57600080fd5b80630ed928af116103965780630ed928af146104af5780630ef1335c146104cf57806311efbf61146104ef578063122aa5d41461050457600080fd5b806223de291461042f578063026976191461044f57806307c8f7b01461048f57600080fd5b3661042a576041546001600160a01b0316336001600160a01b0316146104285760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a206e6f74207772617070656443757272656e6379000000000060448201526064015b60405180910390fd5b005b600080fd5b34801561043b57600080fd5b5061042861044a36600461424b565b610d56565b34801561045b57600080fd5b5061047c61046a3660046142fc565b60426020526000908152604090205481565b6040519081526020015b60405180910390f35b34801561049b57600080fd5b506104286104aa366004614323565b6110b1565b3480156104bb57600080fd5b5061047c6104ca366004614358565b611140565b3480156104db57600080fd5b5061047c6104ea366004614358565b611161565b3480156104fb57600080fd5b5060375461047c565b34801561051057600080fd5b5061042861051f36600461438d565b6111d8565b34801561053057600080fd5b5061055f61053f366004614418565b604860209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610486565b34801561057b57600080fd5b5061042861058a366004614448565b611616565b34801561059b57600080fd5b506104286105aa366004614448565b611696565b3480156105bb57600080fd5b5061055f6105ca3660046142fc565b6000908152604260209081526040808320548352603e90915290205460ff1690565b3480156105f857600080fd5b50610622610607366004614448565b603b602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610486565b34801561064657600080fd5b50610622610655366004614418565b60466020908152600092835260408084209091529082529020546001600160a01b031681565b34801561068757600080fd5b50610428610696366004614465565b611768565b3480156106a757600080fd5b506106226106b63660046142fc565b6044602052600090815260409020546001600160a01b031681565b3480156106dd57600080fd5b506104286118e2565b3480156106f257600080fd5b50610428610701366004614448565b61199a565b34801561071257600080fd5b5061055f610721366004614448565b611a7b565b34801561073257600080fd5b506104286107413660046144da565b611a88565b34801561075257600080fd5b50610428610761366004614565565b611af9565b34801561077257600080fd5b506040805180820190915260028152611d8d60f21b60208201525b60405161048691906145ff565b3480156107a657600080fd5b5060345460ff1661055f565b3480156107be57600080fd5b5061055f6107cd366004614612565b611b69565b3480156107de57600080fd5b5061047c7faf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c81565b34801561081257600080fd5b50610428611bd6565b610428610829366004614418565b611be1565b34801561083a57600080fd5b50610428611cd6565b34801561084f57600080fd5b5061062261085e366004614448565b603c602052600090815260409020546001600160a01b031681565b34801561088557600080fd5b506108b9610894366004614448565b604760205260009081526040902080546001909101546001600160a01b039091169082565b604080516001600160a01b039093168352602083019190915201610486565b3480156108e457600080fd5b5061047c6108f3366004614448565b60456020526000908152604090205481565b34801561091157600080fd5b50610428611d5b565b34801561092657600080fd5b5061055f610935366004614448565b603d6020526000908152604090205460ff1681565b34801561095657600080fd5b50610428610965366004614448565b611dcc565b34801561097657600080fd5b50610428611dfa565b34801561098b57600080fd5b5061047c61099a36600461464e565b611e77565b3480156109ab57600080fd5b5061078d611ff2565b3480156109c057600080fd5b5060345461010090046001600160a01b0316610622565b3480156109e357600080fd5b5061055f60345461010090046001600160a01b0316331490565b348015610a0957600080fd5b50610428610a18366004614448565b612080565b348015610a2957600080fd5b50603f54610622906001600160a01b031681565b348015610a4957600080fd5b5061047c610a583660046146c0565b612159565b348015610a6957600080fd5b50610428610a783660046142fc565b6121cb565b348015610a8957600080fd5b5061055f610a98366004614725565b612290565b348015610aa957600080fd5b50604154610622906001600160a01b031681565b348015610ac957600080fd5b5060405461055f90600160a01b900460ff1681565b348015610aea57600080fd5b50604054610622906001600160a01b031681565b348015610b0a57600080fd5b50610b1e610b19366004614448565b6122c2565b6040805182516001600160a01b031681526020928301519281019290925201610486565b348015610b4e57600080fd5b50610428610b5d366004614448565b612341565b348015610b6e57600080fd5b50610622610b7d3660046142fc565b6043602052600090815260409020546001600160a01b031681565b348015610ba457600080fd5b50610428610bb3366004614747565b612403565b348015610bc457600080fd5b5061055f610bd33660046142fc565b603e6020526000908152604090205460ff1681565b348015610bf457600080fd5b50610428612448565b348015610c0957600080fd5b50610622610c18366004614418565b6124ef565b348015610c2957600080fd5b5061055f610c383660046142fc565b600090815260426020526040902054151590565b348015610c5857600080fd5b5061055f610c67366004614418565b612542565b348015610c7857600080fd5b50610428610c873660046147eb565b612597565b348015610c9857600080fd5b5061047c61271081565b348015610cae57600080fd5b506036546001600160a01b0316610622565b348015610ccc57600080fd5b50610428610cdb366004614448565b6125d1565b348015610cec57600080fd5b50610428610cfb366004614448565b612653565b348015610d0c57600080fd5b5061047c60395481565b348015610d2257600080fd5b50610428610d31366004614833565b612691565b348015610d4257600080fd5b50610428610d51366004614448565b6127e6565b6001600160a01b038816301415610d6c576110a7565b6001600160a01b0386163014610dc45760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a204e6f7420746f207468697320616464726573730000000000604482015260640161041f565b60003360405163555ddc6560e11b81526001600160a01b03821660048201527fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce21770546024820152909150600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca9060440160206040518083038186803b158015610e4657600080fd5b505afa158015610e5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7e919061488f565b6001600160a01b03161415610ed55760405162461bcd60e51b815260206004820152601860248201527f4272696467653a204e6f742045524337373720746f6b656e0000000000000000604482015260640161041f565b6020841015610f455760405162461bcd60e51b815260206004820152603660248201527f4272696467653a207573657220646174612077697468206174206c65617374206044820152751d1a194819195cdd1a5b985d1a5bdb90da185a5b925960521b606482015260840161041f565b6040841480610f5c57506001600160a01b0388163b155b610fb95760405162461bcd60e51b815260206004820152602860248201527f4272696467653a2053706563696679207265636569766572206164647265737360448201526720696e206461746160c01b606482015260840161041f565b60006020851461100a5761100586868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600c92506128bf915050565b61100c565b885b9050600061105c87878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506110579250602091508a90506148c2565b61292c565b90506110a3838b848b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250899250612992915050565b5050505b5050505050505050565b6110ca60345461010090046001600160a01b0316331490565b6110e65760405162461bcd60e51b815260040161041f906148d9565b6040805460ff60a01b1916600160a01b831515810291909117808355915160ff9190920416151581527f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad9906020015b60405180910390a150565b600061115b826111536020820182614448565b600080612d52565b92915050565b60608101356000908152604460205260408120546001600160a01b0316336001600160a01b0316146111ce5760405162461bcd60e51b8152602060048201526016602482015275213934b233b29d1034b73b30b634b21039b2b73232b960511b604482015260640161041f565b61115b8233611153565b60345460ff16156111fb5760405162461bcd60e51b815260040161041f9061490e565b60016035600082825461120e9190614938565b90915550506035546036546001600160a01b0316336001600160a01b0316146112725760405162461bcd60e51b8152602060048201526016602482015275213934b233b29d102737ba102332b232b930ba34b7b760511b604482015260640161041f565b61127b83612f3d565b61128482612f84565b61128e838b612542565b806112ac575060006112a0848c6124ef565b6001600160a01b031614155b6112f05760405162461bcd60e51b8152602060048201526015602482015274213934b233b29d102ab735b737bbb7103a37b5b2b760591b604482015260640161041f565b6001600160a01b0388166113385760405162461bcd60e51b815260206004820152600f60248201526e4272696467653a204e756c6c20546f60881b604482015260640161041f565b6000871161137b5760405162461bcd60e51b815260206004820152601060248201526f04272696467653a20416d6f756e7420360841b604482015260640161041f565b856113c15760405162461bcd60e51b8152602060048201526016602482015275084e4d2c8ceca74409cead8d84084d8dec6d690c2e6d60531b604482015260640161041f565b846114045760405162461bcd60e51b8152602060048201526013602482015272084e4d2c8ceca74409cead8d840a8f090c2e6d606b1b604482015260640161041f565b600085815260426020526040902054156114605760405162461bcd60e51b815260206004820152601860248201527f4272696467653a20416c72656164792061636365707465640000000000000000604482015260640161041f565b600061146f8989898989612fd3565b905060006114828a8a8a8a8a8a8a612159565b905061148e8282612290565b156114d55760405162461bcd60e51b8152602060048201526017602482015276109c9a5919d94e88105b1c9958591e4818db185a5b5959604a1b604482015260640161041f565b8060426000898152602001908152602001600020819055508b6043600089815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508a6044600089815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550896001600160a01b03168c6001600160a01b0316887fddae5e892ad96ac0e35e9018a1a3e32ecd7f3dfe55ea34d9ab1e8faecd6ccb5a8e8d8d8c8c8c6040516115df969594939291906001600160a01b039690961686526020860194909452604085019290925263ffffffff166060840152608083015260a082015260c00190565b60405180910390a45050603554811461160a5760405162461bcd60e51b815260040161041f90614950565b50505050505050505050565b600054610100900460ff168061162f575060005460ff16155b61164b5760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff1615801561166d576000805461ffff19166101011790555b611676826125d1565b6034805460ff191690558015611692576000805461ff00191690555b5050565b6116af60345461010090046001600160a01b0316331490565b6116cb5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b03811661171a5760405162461bcd60e51b81526020600482015260166024820152754272696467653a20777261707020697320656d70747960501b604482015260640161041f565b604180546001600160a01b0319166001600160a01b0383169081179091556040519081527f0966c958966f6fac9ff807af074f8117eb2e9ce2b76390db7a158e9bdeb2485c90602001611135565b61178160345461010090046001600160a01b0316331490565b61179d5760405162461bcd60e51b815260040161041f906148d9565b60005b818110156118dd576118cb8383838181106117bd576117bd6149dd565b90506020028101906117cf91906149f3565b358484848181106117e2576117e26149dd565b90506020028101906117f491906149f3565b611805906040810190602001614448565b858585818110611817576118176149dd565b905060200281019061182991906149f3565b61183a906060810190604001614a13565b86868681811061184c5761184c6149dd565b905060200281019061185e91906149f3565b61186c906060810190614a2e565b88888881811061187e5761187e6149dd565b905060200281019061189091906149f3565b61189e906080810190614a2e565b8a8a8a8181106118b0576118b06149dd565b90506020028101906118c291906149f3565b60a0013561303e565b806118d581614a75565b9150506117a0565b505050565b6118eb33611a7b565b6119075760405162461bcd60e51b815260040161041f90614a90565b60345460ff166119505760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161041f565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6119b360345461010090046001600160a01b0316331490565b6119cf5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b038116611a2f5760405162461bcd60e51b815260206004820152602160248201527f4272696467653a2053696465546f6b656e466163746f727920697320656d70746044820152607960f81b606482015260840161041f565b604080546001600160a01b0319166001600160a01b038316908117825590519081527f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e318369252162590602001611135565b600061115b60338361327e565b611aa160345461010090046001600160a01b0316331490565b611abd5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b039182166000908152604760209081526040909120825181546001600160a01b03191694169390931783550151600190910155565b611b1260345461010090046001600160a01b0316331490565b611b2e5760405162461bcd60e51b815260040161041f906148d9565b60009283526046602090815260408085206001600160a01b0394851686529091529092208054919092166001600160a01b0319909116179055565b600080611ba0611b7c6020860186614448565b602086013560408701356060880135611b9b60a08a0160808b01614ad8565b612fd3565b6000818152603e602052604090205490915060ff1680611bce57506000838152603e602052604090205460ff165b949350505050565b611bdf33613301565b565b60415433906001600160a01b0316611c3b5760405162461bcd60e51b815260206004820152601d60248201527f4272696467653a207772617070656443757272656e637920656d707479000000604482015260640161041f565b604160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611c8b57600080fd5b505af1158015611c9f573d6000803e3d6000fd5b50505050506118dd604160009054906101000a90046001600160a01b03168284346040518060200160405280600081525088612992565b611cef60345461010090046001600160a01b0316331490565b611d0b5760405162461bcd60e51b815260040161041f906148d9565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b600054610100900460ff1680611d74575060005460ff16155b611d905760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff16158015611db2576000805461ffff19166101011790555b60016035558015611dc9576000805461ff00191690555b50565b611dd533611a7b565b611df15760405162461bcd60e51b815260040161041f90614a90565b611dc981613343565b611e0333611a7b565b611e1f5760405162461bcd60e51b815260040161041f90614a90565b60345460ff1615611e425760405162461bcd60e51b815260040161041f9061490e565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861197d3390565b600042851015611ebb5760405162461bcd60e51b815260206004820152600f60248201526e109c9a5919d94e8811561412549151608a1b604482015260640161041f565b6000611ed7611ecf368b90038b018b614af3565b898989613385565b6040805160008082526020820180845284905260ff89169282019290925260608101879052608081018690529192509060019060a0016020604051602081039080840390855afa158015611f2f573d6000803e3d6000fd5b5050604051601f190151915060009050611f4c60208c018c614448565b6001600160a01b031614158015611f805750611f6b60208b018b614448565b6001600160a01b0316816001600160a01b0316145b611fcc5760405162461bcd60e51b815260206004820152601960248201527f4272696467653a20494e56414c49445f5349474e415455524500000000000000604482015260640161041f565b611fe48a611fdd6020820182614448565b8b8b612d52565b9a9950505050505050505050565b60388054611fff90614b8b565b80601f016020809104026020016040519081016040528092919081815260200182805461202b90614b8b565b80156120785780601f1061204d57610100808354040283529160200191612078565b820191906000526020600020905b81548152906001019060200180831161205b57829003601f168201915b505050505081565b61209960345461010090046001600160a01b0316331490565b6120b55760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b03811661210b5760405162461bcd60e51b815260206004820152601c60248201527f4272696467653a20416c6c6f77546f6b656e7320697320656d70747900000000604482015260640161041f565b603f80546001600160a01b0319166001600160a01b0383169081179091556040519081527f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e390602001611135565b6040805160208082019790975280820195909552606097881b6bffffffffffffffffffffffff191697850197909752607484019590955260e09190911b6001600160e01b0319166094830152609882015260b8808201939093528351808203909301835260d801909252805191012090565b6121e460345461010090046001600160a01b0316331490565b6122005760405162461bcd60e51b815260040161041f906148d9565b61220d600a612710614bd6565b811061225b5760405162461bcd60e51b815260206004820152601760248201527f4272696467653a20626967676572207468616e20313025000000000000000000604482015260640161041f565b60378190556040518181527f97e97c577f03bda90e2c9739011ec065ed5fbfb36ae217d20bb0d9be95e160cd90602001611135565b6000828152603e602052604081205460ff16806122bb57506000828152603e602052604090205460ff165b9392505050565b604080518082018252600080825260209182018190526001600160a01b038481168252604783529083902083518085019094528054909116808452600190910154918301919091521561231457919050565b60016020808301919091526001600160a01b039283166000908152603c9091526040902054909116815290565b600054610100900460ff168061235a575060005460ff16155b6123765760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff16158015612398576000805461ffff19166101011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015611692576000805461ff00191690555050565b61241c60345461010090046001600160a01b0316331490565b6124385760405162461bcd60e51b815260040161041f906148d9565b6110a7888888888888888861303e565b604080518082018252601081526f52534b20546f6b656e2042726964676560801b60208083019182528351808501855260018152603160f81b908201529151902082517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8152918201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc69181019190915246606082015230608082015260a09020603955565b60008281526046602090815260408083206001600160a01b038086168552925282205416801561252057905061115b565b50506001600160a01b039081166000908152603b602052604090205416919050565b60008281526048602090815260408083206001600160a01b038516845290915281205460ff16801561257557905061115b565b50506001600160a01b03166000908152603d602052604090205460ff16919050565b336125ad6001600160a01b038516823085613489565b6125ca84828585604051806020016040528060008152508a612992565b5050505050565b600054610100900460ff16806125ea575060005460ff16155b6126065760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff16158015612628576000805461ffff19166101011790555b61263182611a7b565b61263e5761263e82613343565b8015611692576000805461ff00191690555050565b61266c60345461010090046001600160a01b0316331490565b6126885760405162461bcd60e51b815260040161041f906148d9565b611dc9816134fa565b600054610100900460ff16806126aa575060005460ff16155b6126c65760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff161580156126e8576000805461ffff19166101011790555b6126f185612341565b6126fa85611616565b603f80546001600160a01b038581166001600160a01b031992831617909255604080548584169083161781556036805493881693909216929092179055516329965a1d60e01b815230600482018190527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b60248301526044820152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90606401600060405180830381600087803b1580156127ae57600080fd5b505af11580156127c2573d6000803e3d6000fd5b505050506127ce612448565b80156125ca576000805461ff00191690555050505050565b6127ff60345461010090046001600160a01b0316331490565b61281b5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b0381166128715760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a2046656465726174696f6e20697320656d7074790000000000604482015260640161041f565b603680546001600160a01b0319166001600160a01b0383169081179091556040519081527f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb90602001611135565b60006128cc826014614938565b8351101561291c5760405162461bcd60e51b815260206004820152601f60248201527f4c69625574696c733a20746f416464726573735f6f75744f66426f756e647300604482015260640161041f565b500160200151600160601b900490565b6000612939826020614938565b835110156129895760405162461bcd60e51b815260206004820152601f60248201527f4c69625574696c733a20746f55696e743235365f6f75744f66426f756e647300604482015260640161041f565b50016020015190565b604054600160a01b900460ff16156129e05760405162461bcd60e51b81526020600482015260116024820152704272696467653a20557067726164696e6760781b604482015260640161041f565b60345460ff1615612a035760405162461bcd60e51b815260040161041f9061490e565b600160356000828254612a169190614938565b909155505060355446821415612a8a5760405162461bcd60e51b815260206004820152603360248201527f4272696467653a2064657374696e6174696f6e20636861696e20696420657175604482015272185b0818dd5c9c995b9d0818da185a5b881a59606a1b606482015260840161041f565b612a9382612f3d565b60008281526048602090815260408083206001600160a01b038b1684529091529020805460ff191660011790556000612ae3612710612add603754886135c290919063ffffffff16565b90613641565b90506000612af18683613683565b90506000612afe8a6136c5565b905086601260ff831614612b2f57612b2c612b1a836012614bea565b612b2590600a614cf1565b89906135c2565b90505b603f54604051638c34bc5560e01b81526001600160a01b038d811660048301526024820184905290911690638c34bc5590604401600060405180830381600087803b158015612b7d57600080fd5b505af1158015612b91573d6000803e3d6000fd5b505050506000612ba08c6122c2565b80519091506001600160a01b031615612ca4576000612bbe8d6137a9565b90506000612bcc8683613881565b9050612bd887826138c3565b9650612be48682613683565b60405163fe9d930360e01b81529096506001600160a01b038f169063fe9d930390612c159089908e90600401614d00565b600060405180830381600087803b158015612c2f57600080fd5b505af1158015612c43573d6000803e3d6000fd5b505050505050868a6001600160a01b031682600001516001600160a01b03167fb2320a1ad388e1e16b142f7d2e822f31d8a2bbdd7d4f29260e7c203c5f45e8498e46898e604051612c979493929190614d19565b60405180910390a4612cf7565b868a6001600160a01b03168d6001600160a01b03167fb2320a1ad388e1e16b142f7d2e822f31d8a2bbdd7d4f29260e7c203c5f45e8498e46898e604051612cee9493929190614d19565b60405180910390a45b8415612d2357603454612d239061010090046001600160a01b03166001600160a01b038e169087613922565b50505050506035548114612d495760405162461bcd60e51b815260040161041f90614950565b50505050505050565b6000600160356000828254612d679190614938565b909155505060355460608601356000908152604360205260409020546001600160a01b031680612dd25760405162461bcd60e51b8152602060048201526016602482015275109c9a5919d94e88151e081b9bdd0818dc9bdcdcd95960521b604482015260640161041f565b6000612e0e612de460208a018a614448565b60208a013560408b013560608c0135612e0360a08e0160808f01614ad8565b8d60a0013546612159565b60608901356000908152604260205260409020549091508114612e7d5760405162461bcd60e51b815260206004820152602160248201527f4272696467653a2057726f6e67207472616e73616374696f6e446174614861736044820152600d60fb1b606482015260840161041f565b612e878882611b69565b15612ece5760405162461bcd60e51b8152602060048201526017602482015276109c9a5919d94e88105b1c9958591e4818db185a5b5959604a1b604482015260640161041f565b6000818152603e60209081526040909120805460ff19166001179055612f029060a08a01359084908a908c01358a8a613952565b9350612f1188838989896139a3565b50506035548114612f345760405162461bcd60e51b815260040161041f90614950565b50949350505050565b60008111611dc95760405162461bcd60e51b815260206004820152601460248201527304272696467653a20436861696e496420697320360641b604482015260640161041f565b468114611dc95760405162461bcd60e51b815260206004820152601960248201527f4272696467653a204e6f7420626c6f636b2e636861696e696400000000000000604482015260640161041f565b6040805160208101859052908101839052606086811b6bffffffffffffffffffffffff1916908201526074810185905260e082901b6001600160e01b031916609482015260009060980160405160208183030381529060405280519060200120905095945050505050565b6001600160a01b0387166130895760405162461bcd60e51b8152602060048201526012602482015271213934b233b29d10273ab636103a37b5b2b760711b604482015260640161041f565b61309281612f3d565b600061309e82896124ef565b90506001600160a01b038116156130f05760405162461bcd60e51b81526020600482015260166024820152754272696467653a20416c72656164792065786973747360501b604482015260640161041f565b60006130fb88613a7e565b6040805490516326d9e96360e01b81529192506001600160a01b0316906326d9e9639061313490889088908c908c908890600401614d6f565b602060405180830381600087803b15801561314e57600080fd5b505af1158015613162573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613186919061488f565b9150613193838a84611af9565b60408051808201909152602081018490526001600160a01b038a1681526131ba8382611a88565b603f546040516378bf2b5360e01b81526001600160a01b038581166004830152602482018e9052909116906378bf2b5390604401600060405180830381600087803b15801561320857600080fd5b505af115801561321c573d6000803e3d6000fd5b50505050896001600160a01b0316836001600160a01b03167f88dcf8b72e53287db29df3fee9a0f2cb07d1f986cee153aa7d7554405d5db0178a8a86896040516132699493929190614da9565b60405180910390a35050505050505050505050565b60006001600160a01b0382166132e15760405162461bcd60e51b815260206004820152602260248201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604482015261737360f01b606482015260840161041f565b506001600160a01b03166000908152602091909152604090205460ff1690565b61330c603382613aea565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b61334e603382613b62565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6039548451602080870151606088015160a08901516001600160a01b0385166000908152604590945260408420805494966134809690957faf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c959194919391928c918c918b6133f283614a75565b909155506040805160208101999099526001600160a01b03978816908901526060880195909552608087019390935260a086019190915290921660c084015260e08301919091526101008201526101208101859052610140016040516020818303038152906040528051906020012060405161190160f01b8152600281019290925260228201526042902090565b95945050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526134f49085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613bde565b50505050565b6001600160a01b03811661355b5760405162461bcd60e51b815260206004820152602260248201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604482015261737360f01b606482015260840161041f565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6000826135d15750600061115b565b60006135dd8385614dd0565b9050826135ea8583614bd6565b146122bb5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b606482015260840161041f565b60006122bb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613d5e565b60006122bb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613d8c565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b0386169161370b9190614def565b600060405180830381855afa9150503d8060008114613746576040519150601f19603f3d011682016040523d82523d6000602084013e61374b565b606091505b5091509150816137955760405162461bcd60e51b81526020600482015260156024820152744c69625574696c733a204e6f20646563696d616c7360581b604482015260640161041f565b80806020019051810190611bce9190614e01565b60408051600481526024810182526020810180516001600160e01b031663556f0dc760e01b1790529051600091829182916001600160a01b038616916137ef9190614def565b600060405180830381855afa9150503d806000811461382a576040519150601f19603f3d011682016040523d82523d6000602084013e61382f565b606091505b5091509150816137955760405162461bcd60e51b815260206004820152601860248201527f4c69625574696c733a204e6f206772616e756c61726974790000000000000000604482015260640161041f565b60006122bb83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250613dbd565b6000806138d08385614938565b9050838110156122bb5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015260640161041f565b6040516001600160a01b0383166024820152604481018290526118dd90849063a9059cbb60e01b906064016134bd565b600061395d87612f3d565b6139678787612542565b15613980576139798686868686613de9565b9050613999565b61399661398d88886124ef565b86868686613f99565b90505b9695505050505050565b6139b06020860186614448565b6060860135600081815260446020908152604091829020546001600160a01b039485169489811694937fa7a84dcc6757cdf9b9122d3bbc42d58358c28dc4b09cc24349599a63c56c62fd9392909116918b0135908b0135613a1760a08d0160808e01614ad8565b604080516001600160a01b039586168152602081019490945283019190915263ffffffff166060820152818916608082015290871660a08281019190915260c082018790528a013560e0820152466101008201526101200160405180910390a45050505050565b600060128260ff161115613ad45760405162461bcd60e51b815260206004820152601c60248201527f4c69625574696c733a20446563696d616c73206e6f74203c3d20313800000000604482015260640161041f565b613adf826012614bea565b61115b90600a614cf1565b613af4828261327e565b613b405760405162461bcd60e51b815260206004820181905260248201527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c65604482015260640161041f565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b613b6c828261327e565b15613bb95760405162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015260640161041f565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6001600160a01b0382163b613c355760405162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015260640161041f565b600080836001600160a01b031683604051613c509190614def565b6000604051808303816000865af19150503d8060008114613c8d576040519150601f19603f3d011682016040523d82523d6000602084013e613c92565b606091505b509150915081613ce45760405162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015260640161041f565b8051156134f45780806020019051810190613cff9190614e1a565b6134f45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161041f565b60008183613d7f5760405162461bcd60e51b815260040161041f91906145ff565b5060006134808486614bd6565b60008184841115613db05760405162461bcd60e51b815260040161041f91906145ff565b50600061348084866148c2565b60008183613dde5760405162461bcd60e51b815260040161041f91906145ff565b50611bce8385614e37565b600080613df5876136c5565b60ff1690506000613e1c613e0a8360126148c2565b613e1590600a614e4b565b8790613641565b905080841115613e655760405162461bcd60e51b8152602060048201526014602482015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b604482015260640161041f565b613e6f8185613683565b6041549093506001600160a01b0389811691161415613f6057604154604051632e1a7d4d60e01b8152600481018390526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b158015613ece57600080fd5b505af1158015613ee2573d6000803e3d6000fd5b50506040516001600160a01b038a16925085156108fc02915085906000818181858888f19350505050158015613f1c573d6000803e3d6000fd5b508315613f5b576040516001600160a01b0386169085156108fc029086906000818181858888f19350505050158015613f59573d6000803e3d6000fd5b505b613f8e565b613f746001600160a01b0389168885613922565b8315613f8e57613f8e6001600160a01b0389168686613922565b505095945050505050565b60006001600160a01b038616613ff15760405162461bcd60e51b815260206004820152601a60248201527f4272696467653a207369646520746f6b656e206973206e756c6c000000000000604482015260640161041f565b6000866001600160a01b031663556f0dc76040518163ffffffff1660e01b815260040160206040518083038186803b15801561402c57600080fd5b505afa158015614040573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140649190614e01565b9050600061407286836135c2565b9050808411156140bb5760405162461bcd60e51b8152602060048201526014602482015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b604482015260640161041f565b6140c58185613683565b604051630dcdc7dd60e41b81526001600160a01b038981166004830152602482018390526080604483015260006084830181905260a0606484015260a48301529194509089169063dcdc7dd09060c401600060405180830381600087803b15801561412f57600080fd5b505af1158015614143573d6000803e3d6000fd5b505050506000841115613f8e57604051630dcdc7dd60e41b81526001600160a01b03868116600483015260248201869052608060448301526000608483015260a06064830152600b60a48301526a72656c617965722066656560a81b60c483015289169063dcdc7dd09060e401600060405180830381600087803b1580156141ca57600080fd5b505af11580156141de573d6000803e3d6000fd5b50505050505095945050505050565b6001600160a01b0381168114611dc957600080fd5b60008083601f84011261421457600080fd5b50813567ffffffffffffffff81111561422c57600080fd5b60208301915083602082850101111561424457600080fd5b9250929050565b60008060008060008060008060c0898b03121561426757600080fd5b8835614272816141ed565b97506020890135614282816141ed565b96506040890135614292816141ed565b955060608901359450608089013567ffffffffffffffff808211156142b657600080fd5b6142c28c838d01614202565b909650945060a08b01359150808211156142db57600080fd5b506142e88b828c01614202565b999c989b5096995094979396929594505050565b60006020828403121561430e57600080fd5b5035919050565b8015158114611dc957600080fd5b60006020828403121561433557600080fd5b81356122bb81614315565b600060c0828403121561435257600080fd5b50919050565b600060c0828403121561436a57600080fd5b6122bb8383614340565b803563ffffffff8116811461438857600080fd5b919050565b60008060008060008060008060006101208a8c0312156143ac57600080fd5b89356143b7816141ed565b985060208a01356143c7816141ed565b975060408a01356143d7816141ed565b965060608a0135955060808a0135945060a08a013593506143fa60c08b01614374565b925060e08a013591506101008a013590509295985092959850929598565b6000806040838503121561442b57600080fd5b82359150602083013561443d816141ed565b809150509250929050565b60006020828403121561445a57600080fd5b81356122bb816141ed565b6000806020838503121561447857600080fd5b823567ffffffffffffffff8082111561449057600080fd5b818501915085601f8301126144a457600080fd5b8135818111156144b357600080fd5b8660208260051b85010111156144c857600080fd5b60209290920196919550909350505050565b60008082840360608112156144ee57600080fd5b83356144f9816141ed565b92506040601f198201121561450d57600080fd5b506040516040810181811067ffffffffffffffff8211171561453f57634e487b7160e01b600052604160045260246000fd5b6040526020840135614550816141ed565b81526040939093013560208401525092909150565b60008060006060848603121561457a57600080fd5b83359250602084013561458c816141ed565b9150604084013561459c816141ed565b809150509250925092565b60005b838110156145c25781810151838201526020016145aa565b838111156134f45750506000910152565b600081518084526145eb8160208601602086016145a7565b601f01601f19169290920160200192915050565b6020815260006122bb60208301846145d3565b60008060e0838503121561462557600080fd5b61462f8484614340565b9460c0939093013593505050565b803560ff8116811461438857600080fd5b6000806000806000806000610180888a03121561466a57600080fd5b6146748989614340565b965060c0880135614684816141ed565b955060e0880135945061010088013593506146a2610120890161463d565b92506101408801359150610160880135905092959891949750929550565b600080600080600080600060e0888a0312156146db57600080fd5b87356146e6816141ed565b965060208801359550604088013594506060880135935061470960808901614374565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561473857600080fd5b50508035926020909101359150565b60008060008060008060008060c0898b03121561476357600080fd5b883597506020890135614775816141ed565b965061478360408a0161463d565b9550606089013567ffffffffffffffff808211156147a057600080fd5b6147ac8c838d01614202565b909750955060808b01359150808211156147c557600080fd5b506147d28b828c01614202565b999c989b50969995989497949560a00135949350505050565b6000806000806080858703121561480157600080fd5b843593506020850135614813816141ed565b92506040850135614823816141ed565b9396929550929360600135925050565b6000806000806080858703121561484957600080fd5b8435614854816141ed565b93506020850135614864816141ed565b92506040850135614874816141ed565b91506060850135614884816141ed565b939692955090935050565b6000602082840312156148a157600080fd5b81516122bb816141ed565b634e487b7160e01b600052601160045260246000fd5b6000828210156148d4576148d46148ac565b500390565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6000821982111561494b5761494b6148ac565b500190565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b6000823560be19833603018112614a0957600080fd5b9190910192915050565b600060208284031215614a2557600080fd5b6122bb8261463d565b6000808335601e19843603018112614a4557600080fd5b83018035915067ffffffffffffffff821115614a6057600080fd5b60200191503681900382131561424457600080fd5b6000600019821415614a8957614a896148ac565b5060010190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b600060208284031215614aea57600080fd5b6122bb82614374565b600060c08284031215614b0557600080fd5b60405160c0810181811067ffffffffffffffff82111715614b3657634e487b7160e01b600052604160045260246000fd5b6040528235614b44816141ed565b80825250602083013560208201526040830135604082015260608301356060820152614b7260808401614374565b608082015260a083013560a08201528091505092915050565b600181811c90821680614b9f57607f821691505b6020821081141561435257634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b600082614be557614be5614bc0565b500490565b600060ff821660ff841680821015614c0457614c046148ac565b90039392505050565b600181815b80851115614c48578160001904821115614c2e57614c2e6148ac565b80851615614c3b57918102915b93841c9390800290614c12565b509250929050565b600082614c5f5750600161115b565b81614c6c5750600061115b565b8160018114614c825760028114614c8c57614ca8565b600191505061115b565b60ff841115614c9d57614c9d6148ac565b50506001821b61115b565b5060208310610133831016604e8410600b8410161715614ccb575081810a61115b565b614cd58383614c0d565b8060001904821115614ce957614ce96148ac565b029392505050565b60006122bb60ff841683614c50565b828152604060208201526000611bce60408301846145d3565b60018060a01b038516815283602082015282604082015260806060820152600061399960808301846145d3565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b606081526000614d83606083018789614d46565b8281036020840152614d96818688614d46565b9150508260408301529695505050505050565b606081526000614dbd606083018688614d46565b6020830194909452506040015292915050565b6000816000190483118215151615614dea57614dea6148ac565b500290565b60008251614a098184602087016145a7565b600060208284031215614e1357600080fd5b5051919050565b600060208284031215614e2c57600080fd5b81516122bb81614315565b600082614e4657614e46614bc0565b500690565b60006122bb8383614c5056fea264697066735822122056e9c6d68b936a7b2c66545886a13f33f54fec9bc3a8a09c82fde6ed9811029364736f6c63430008090033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "__Pausable_init(address)": {
+ "details": "Initializes the contract in unpaused state. Assigns the Pauser role to the deployer."
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "pause()": {
+ "details": "Called by a pauser to pause, triggers stopped state."
+ },
+ "paused()": {
+ "details": "Returns true if the contract is paused, and false otherwise."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "tokensReceived(address,address,address,uint256,bytes,bytes)": {
+ "params": {
+ "userData": "it can be 2 options in the first one you can send the receiver and the chain id of the destination const userData = web3.eth.abi.encodeParameters( [\"address\", \"uint256\"], [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID] ); or you also can send only the destination chain id, and the receiver would be the same as the from parameter const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);"
+ }
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "unpause()": {
+ "details": "Called by a pauser to unpause, returns to normal state."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "acceptTransfer(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)": {
+ "notice": "Accepts the transaction from the other chain that was voted and sent by the Federation contract"
+ },
+ "claim((address,uint256,bytes32,bytes32,uint32,uint256))": {
+ "notice": "Claims the crossed transaction using the hash, this sends the funds to the address indicated in"
+ },
+ "depositTo(uint256,address)": {
+ "notice": "Use network currency and cross it."
+ },
+ "receiveTokensTo(uint256,address,address,uint256)": {
+ "notice": "ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom"
+ },
+ "tokensReceived(address,address,address,uint256,bytes,bytes)": {
+ "notice": "ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction See https://eips.ethereum.org/EIPS/eip-777#motivation for details"
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 14589,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 14592,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 14632,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 14658,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_pausers",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_struct(Role)8915_storage"
+ },
+ {
+ "astId": 14780,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_paused",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_bool"
+ },
+ {
+ "astId": 14878,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_owner",
+ "offset": 1,
+ "slot": "52",
+ "type": "t_address"
+ },
+ {
+ "astId": 15597,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_guardCounter",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1344,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "federation",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_address"
+ },
+ {
+ "astId": 1346,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "feePercentage",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1348,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "deprecatedSymbolPrefix",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 1350,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "domainSeparator",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_bytes32"
+ },
+ {
+ "astId": 1352,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_deprecatedSpentToday",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1356,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "deprecatedMappedTokens",
+ "offset": 0,
+ "slot": "59",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 1360,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "deprecatedOriginalTokens",
+ "offset": 0,
+ "slot": "60",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 1364,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "deprecatedKnownTokens",
+ "offset": 0,
+ "slot": "61",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 1368,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "claimed",
+ "offset": 0,
+ "slot": "62",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ },
+ {
+ "astId": 1371,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "allowTokens",
+ "offset": 0,
+ "slot": "63",
+ "type": "t_contract(IAllowTokens)7176"
+ },
+ {
+ "astId": 1374,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "sideTokenFactory",
+ "offset": 0,
+ "slot": "64",
+ "type": "t_contract(ISideTokenFactory)7647"
+ },
+ {
+ "astId": 1376,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "isUpgrading",
+ "offset": 20,
+ "slot": "64",
+ "type": "t_bool"
+ },
+ {
+ "astId": 1387,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "wrappedCurrency",
+ "offset": 0,
+ "slot": "65",
+ "type": "t_contract(IWrapped)7700"
+ },
+ {
+ "astId": 1391,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "transactionsDataHashes",
+ "offset": 0,
+ "slot": "66",
+ "type": "t_mapping(t_bytes32,t_bytes32)"
+ },
+ {
+ "astId": 1395,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originalTokenAddresses",
+ "offset": 0,
+ "slot": "67",
+ "type": "t_mapping(t_bytes32,t_address)"
+ },
+ {
+ "astId": 1399,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "senderAddresses",
+ "offset": 0,
+ "slot": "68",
+ "type": "t_mapping(t_bytes32,t_address)"
+ },
+ {
+ "astId": 1406,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "nonces",
+ "offset": 0,
+ "slot": "69",
+ "type": "t_mapping(t_address,t_uint256)"
+ },
+ {
+ "astId": 1412,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "sideTokenByOriginalTokenByChain",
+ "offset": 0,
+ "slot": "70",
+ "type": "t_mapping(t_uint256,t_mapping(t_address,t_address))"
+ },
+ {
+ "astId": 1417,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originalTokenBySideToken",
+ "offset": 0,
+ "slot": "71",
+ "type": "t_mapping(t_address,t_struct(OriginalToken)7197_storage)"
+ },
+ {
+ "astId": 1423,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "knownTokenByChain",
+ "offset": 0,
+ "slot": "72",
+ "type": "t_mapping(t_uint256,t_mapping(t_address,t_bool))"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IAllowTokens)7176": {
+ "encoding": "inplace",
+ "label": "contract IAllowTokens",
+ "numberOfBytes": "20"
+ },
+ "t_contract(ISideTokenFactory)7647": {
+ "encoding": "inplace",
+ "label": "contract ISideTokenFactory",
+ "numberOfBytes": "20"
+ },
+ "t_contract(IWrapped)7700": {
+ "encoding": "inplace",
+ "label": "contract IWrapped",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_address)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_address,t_struct(OriginalToken)7197_storage)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => struct IBridge.OriginalToken)",
+ "numberOfBytes": "32",
+ "value": "t_struct(OriginalToken)7197_storage"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_mapping(t_bytes32,t_address)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bytes32)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bytes32)",
+ "numberOfBytes": "32",
+ "value": "t_bytes32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_address,t_address))": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => mapping(address => address))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_address)"
+ },
+ "t_mapping(t_uint256,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(OriginalToken)7197_storage": {
+ "encoding": "inplace",
+ "label": "struct IBridge.OriginalToken",
+ "members": [
+ {
+ "astId": 7194,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "tokenAddress",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ },
+ {
+ "astId": 7196,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originChainId",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Role)8915_storage": {
+ "encoding": "inplace",
+ "label": "struct Roles.Role",
+ "members": [
+ {
+ "astId": 8914,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "bearer",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_address,t_bool)"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/BridgeProxy.json b/bridge/deployments/kovan/BridgeProxy.json
new file mode 100644
index 000000000..1853d8422
--- /dev/null
+++ b/bridge/deployments/kovan/BridgeProxy.json
@@ -0,0 +1,234 @@
+{
+ "address": "0x12ed69359919fc775bc2674860e8fe2d2b6a7b5d",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_admin",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x4ec10A50801f89266F0F1FA7fd3fa320106bBF63",
+ "transactionIndex": 0,
+ "gasUsed": "947465",
+ "logsBloom": "0x00000000020000000000000000008000000000000000004000800000000000001000000000000000000000000020002000000000000000000000000000000000000000000080000000000000000000000081000000000000000000000000000000000000020008000000000000040800000010004020000000000000000000400000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000240801000000000000000000000000000000000000000100000000000000000000000000000020000000000000000000000000000000000000000000000000008000000000000000",
+ "blockHash": "0x36083a7b34699ea6db1b1a64eeba40a5a29fa7d8c9c873e7e1361e02bb124f42",
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152250,
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "address": "0x4ec10A50801f89266F0F1FA7fd3fa320106bBF63",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x00000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x36083a7b34699ea6db1b1a64eeba40a5a29fa7d8c9c873e7e1361e02bb124f42"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152250,
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "address": "0x4ec10A50801f89266F0F1FA7fd3fa320106bBF63",
+ "topics": [
+ "0x6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f8",
+ "0x00000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a"
+ ],
+ "data": "0x",
+ "logIndex": 1,
+ "blockHash": "0x36083a7b34699ea6db1b1a64eeba40a5a29fa7d8c9c873e7e1361e02bb124f42"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152250,
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "address": "0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24",
+ "topics": [
+ "0x93baa6efbd2244243bfee6ce4cfdd1d04fc4c0e9a786abd3a41313bd352db153",
+ "0x0000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf63",
+ "0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b",
+ "0x0000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf63"
+ ],
+ "data": "0x",
+ "logIndex": 2,
+ "blockHash": "0x36083a7b34699ea6db1b1a64eeba40a5a29fa7d8c9c873e7e1361e02bb124f42"
+ }
+ ],
+ "blockNumber": 2152250,
+ "cumulativeGasUsed": "947465",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0xCEA4F7E9a2080D206be1fa7E4245BDecff7102dF",
+ "0x8c35e166d2dea7a8a28aaea11ad7933cdae4b0ab",
+ "0x2fb3b36100000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8000000000000000000000000bb74098e1f6f95198209ba30ba92725a6ccd5eab00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000016200000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Proxies.sol\":\"BridgeProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Proxies.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\\\";\\n\\ncontract BridgeProxy is TransparentUpgradeableProxy {\\n // solhint-disable-next-line no-empty-blocks\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\n}\\n\\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\\n // solhint-disable-next-line no-empty-blocks\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\n}\\n\\ncontract FederationProxy is TransparentUpgradeableProxy {\\n // solhint-disable-next-line no-empty-blocks\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\n}\",\"keccak256\":\"0x58e34ea4864c39b1d234084bc49b12bd7835c0a23f2604e450526eaa7581a554\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0x590a4d952d39a99972cbcb691b472c5d58af9ae8fd142355ad26200affdd2a51\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x0d5202a38732881d576fe3831605fe2633e1bc9f981ebea9c3a368af027e0b71\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x53b00bc48bd4eac1e100195c494267c0ca082bd91ac3018e2ee6155fbcbbb14f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000ca538038062000ca5833981016040819052620000269162000234565b8282828281620000368262000077565b8051156200005757620000558282620000d960201b620002ca1760201c565b505b50620000609050565b6200006b8262000108565b50505050505062000423565b6200008d816200012c60201b620002f61760201c565b620000b55760405162461bcd60e51b8152600401620000ac906200034d565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606062000101838360405180606001604052806027815260200162000c7e6027913962000136565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b606062000143846200012c565b620001625760405162461bcd60e51b8152600401620000ac90620003aa565b600080856001600160a01b0316856040516200017f9190620002fa565b600060405180830381855af49150503d8060008114620001bc576040519150601f19603f3d011682016040523d82523d6000602084013e620001c1565b606091505b509092509050620001d4828286620001de565b9695505050505050565b60608315620001ef57508162000101565b825115620002005782518084602001fd5b8160405162461bcd60e51b8152600401620000ac919062000318565b80516001600160a01b03811681146200013157600080fd5b60008060006060848603121562000249578283fd5b62000254846200021c565b925062000264602085016200021c565b60408501519092506001600160401b038082111562000281578283fd5b818601915086601f83011262000295578283fd5b815181811115620002a257fe5b604051601f8201601f191681016020018381118282101715620002c157fe5b604052818152838201602001891015620002d9578485fd5b620002ec826020830160208701620003f0565b809450505050509250925092565b600082516200030e818460208701620003f0565b9190910192915050565b600060208252825180602084015262000339816040850160208701620003f0565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b838110156200040d578181015183820152602001620003f3565b838111156200041d576000848401525b50505050565b61084b80620004336000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e3ec70ca139aef33041f9d7a058cc6501b5f73e931f4077b7f513ef7e0b3bf5c64736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e3ec70ca139aef33041f9d7a058cc6501b5f73e931f4077b7f513ef7e0b3bf5c64736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/Federation.json b/bridge/deployments/kovan/Federation.json
new file mode 100644
index 000000000..44e741e01
--- /dev/null
+++ b/bridge/deployments/kovan/Federation.json
@@ -0,0 +1,1117 @@
+{
+ "address": "0xe124e4aAFD055Df3e861dB0260F678AEcdaC52e3",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridge",
+ "type": "address"
+ }
+ ],
+ "name": "BridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Executed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "currentChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "currentBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "fedVersion",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256[]",
+ "name": "fedChainsIds",
+ "type": "uint256[]"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256[]",
+ "name": "fedChainsBlocks",
+ "type": "uint256[]"
+ },
+ {
+ "indexed": false,
+ "internalType": "string[]",
+ "name": "fedChainsInfo",
+ "type": "string[]"
+ }
+ ],
+ "name": "HeartBeat",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Voted",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_MEMBER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_newMember",
+ "type": "address"
+ }
+ ],
+ "name": "addMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridge",
+ "outputs": [
+ {
+ "internalType": "contract IBridge",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "fedVersion",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "fedChainsIds",
+ "type": "uint256[]"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "fedChainsBlocks",
+ "type": "uint256[]"
+ },
+ {
+ "internalType": "string[]",
+ "name": "fedChainsInfo",
+ "type": "string[]"
+ }
+ ],
+ "name": "emitHeartbeat",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getMembers",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getTransactionId",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_members",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isMember",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionIdMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionIdMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "members",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "processed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_oldMember",
+ "type": "address"
+ }
+ ],
+ "name": "removeMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ }
+ ],
+ "name": "setBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionWasProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "voteTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "votes",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x08e8c0687f1456acdaa261164adf2aa7d8fd463d31bdb3fd73b5e9bb63f273c1",
+ "receipt": {
+ "to": null,
+ "from": "0x63C46fBf3183B0a230833a7076128bdf3D5Bc03F",
+ "contractAddress": "0xe124e4aAFD055Df3e861dB0260F678AEcdaC52e3",
+ "transactionIndex": 0,
+ "gasUsed": "1780593",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xa61afe58a388a84b25e81a3594fe9ee24ba7b986e5af9df5e4db1dd20eafe788",
+ "transactionHash": "0x08e8c0687f1456acdaa261164adf2aa7d8fd463d31bdb3fd73b5e9bb63f273c1",
+ "logs": [],
+ "blockNumber": 31420571,
+ "cumulativeGasUsed": "1780593",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "numDeployments": 2,
+ "solcInputHash": "257bf35cfef475bad06cad6d9dd245f2",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"bridge\",\"type\":\"address\"}],\"name\":\"BridgeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"}],\"name\":\"Executed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"currentChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"currentBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"fedVersion\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"fedChainsIds\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"fedChainsBlocks\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"fedChainsInfo\",\"type\":\"string[]\"}],\"name\":\"HeartBeat\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"}],\"name\":\"Voted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MEMBER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newMember\",\"type\":\"address\"}],\"name\":\"addMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contract IBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"fedVersion\",\"type\":\"string\"},{\"internalType\":\"uint256[]\",\"name\":\"fedChainsIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"fedChainsBlocks\",\"type\":\"uint256[]\"},{\"internalType\":\"string[]\",\"name\":\"fedChainsInfo\",\"type\":\"string[]\"}],\"name\":\"emitHeartbeat\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMembers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"}],\"name\":\"getTransactionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"hasVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_members\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMember\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionIdMultichain\",\"type\":\"bytes32\"}],\"name\":\"isProcessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionIdMultichain\",\"type\":\"bytes32\"}],\"name\":\"isVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"members\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"processed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_oldMember\",\"type\":\"address\"}],\"name\":\"removeMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"name\":\"setBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"transactionWasProcessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"}],\"name\":\"voteTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"votes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addMember(address)\":{\"params\":{\"_newMember\":\"address of the new member\"}},\"changeRequirement(uint256)\":{\"details\":\"Emits the RequirementChange event\",\"params\":{\"_required\":\"the number of minimum members to approve an transaction, it has to be bigger than 1\"}},\"emitHeartbeat(string,uint256[],uint256[],string[])\":{\"details\":\"Emits HeartBeat event\"},\"getMembers()\":{\"returns\":{\"_0\":\"Current members\"}},\"getTransactionCount(bytes32)\":{\"params\":{\"transactionId\":\"The transaction hashed from getTransactionId function\"}},\"getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)\":{\"details\":\"It encodes and applies keccak256 to the parameters received in the same order\",\"params\":{\"amount\":\"Could be the amount or the tokenId\",\"blockHash\":\"The block hash in which the transaction with the cross event occurred\",\"destinationChainId\":\"Is chainId of the destination chain\",\"logIndex\":\"Index of the event in the logs\",\"originChainId\":\"Is chainId of the original chain\",\"originalTokenAddress\":\"The address of the token in the origin (main) chain\",\"receiver\":\"Who is going to receive the token in the opposite chain\",\"sender\":\"The address who solicited the cross token\",\"transactionHash\":\"The transaction in which the cross event occurred\"},\"returns\":{\"_0\":\"The hash generated by the parameters.\"}},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"removeMember(address)\":{\"params\":{\"_oldMember\":\"address of the member to be removed from federation\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setBridge(address)\":{\"details\":\"Emits BridgeChanged event\",\"params\":{\"_bridge\":\"the new bridge contract address that should implement the IBridge interface\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"version()\":{\"returns\":{\"_0\":\"version in v{Number}\"}},\"voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)\":{\"params\":{\"blockHash\":\"The block hash in which the transaction with the cross event occurred\",\"destinationChainId\":\"Is chainId of the destination chain\",\"logIndex\":\"Index of the event in the logs\",\"originChainId\":\"Is chainId of the original chain\",\"originalTokenAddress\":\"The address of the token in the origin (main) chain\",\"receiver\":\"Who is going to receive the token in the opposite chain\",\"sender\":\"The address who solicited the cross token\",\"transactionHash\":\"The transaction in which the cross event occurred\",\"value\":\"Amount\"}}},\"stateVariables\":{\"isMember\":{\"details\":\"The address should be a member to vote in transactions\"},\"required\":{\"details\":\"It should have at least the required amount of members\"},\"votes\":{\"details\":\"the members should approve the transaction by 50% + 1\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addMember(address)\":{\"notice\":\"Add a new member to the federation\"},\"changeRequirement(uint256)\":{\"notice\":\"Changes the number of required members to vote and approve an transaction\"},\"emitHeartbeat(string,uint256[],uint256[],string[])\":{\"notice\":\"It emits an HeartBeat like an health check\"},\"getMembers()\":{\"notice\":\"Return all the current members of the federation\"},\"getTransactionCount(bytes32)\":{\"notice\":\"Get the amount of approved votes for that transactionId\"},\"getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)\":{\"notice\":\"Gets the hash of transaction from the following parameters encoded and keccaked\"},\"isMember(address)\":{\"notice\":\"All the addresses that are members of the federation\"},\"processed(bytes32)\":{\"notice\":\"(bytes32) transactionId => (bool) votedCheck if that transaction was already processed\"},\"removeMember(address)\":{\"notice\":\"Remove a member of the federation\"},\"required()\":{\"notice\":\"The minimum amount of votes to approve a transaction\"},\"setBridge(address)\":{\"notice\":\"Sets a new bridge contract\"},\"version()\":{\"notice\":\"Current version of the contract\"},\"voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)\":{\"notice\":\"Vote in a transaction, if it has enough votes it accepts the transfer\"},\"votes(bytes32,address)\":{\"notice\":\"(bytes32) transactionId = keccak256( abi.encodePacked( originalTokenAddress, sender, receiver, amount, blockHash, transactionHash, logIndex ) ) => ( (address) members => (bool) voted )Votes by members by the transaction ID\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Federation/Federation.sol\":\"Federation\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Federation/Federation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n// Upgradables\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\n\\nimport \\\"../interface/IBridge.sol\\\";\\nimport \\\"../interface/IFederation.sol\\\";\\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\\n\\tuint constant public MAX_MEMBER_COUNT = 50;\\n\\taddress constant private NULL_ADDRESS = address(0);\\n\\n\\tIBridge public bridge;\\n\\taddress[] public members;\\n\\n\\t/**\\n\\t\\t@notice The minimum amount of votes to approve a transaction\\n\\t\\t@dev It should have at least the required amount of members\\n\\t\\t*/\\n\\tuint public required;\\n\\n\\t/**\\n\\t\\t@notice All the addresses that are members of the federation\\n\\t\\t@dev The address should be a member to vote in transactions\\n\\t\\t*/\\n\\tmapping (address => bool) public isMember;\\n\\n\\t/**\\n\\t\\t(bytes32) transactionId = keccak256(\\n\\t\\t\\tabi.encodePacked(\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tamount,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\tlogIndex\\n\\t\\t\\t)\\n\\t\\t) => (\\n\\t\\t\\t(address) members => (bool) voted\\n\\t\\t)\\n\\t\\t@notice Votes by members by the transaction ID\\n\\t\\t@dev the members should approve the transaction by 50% + 1\\n\\t\\t*/\\n\\tmapping (bytes32 => mapping (address => bool)) public votes;\\n\\n\\t/**\\n\\t\\t(bytes32) transactionId => (bool) voted\\n\\t\\t@notice Check if that transaction was already processed\\n\\t*/\\n\\tmapping(bytes32 => bool) public processed;\\n\\n\\tmodifier onlyMember() {\\n\\t\\trequire(isMember[_msgSender()], \\\"Federation: Not Federator\\\");\\n\\t\\t_;\\n\\t}\\n\\n\\tmodifier validRequirement(uint membersCount, uint _required) {\\n\\t\\trequire(_required <= membersCount && _required != 0 && membersCount != 0, \\\"Federation: Invalid requirements\\\");\\n\\t\\t_;\\n\\t}\\n\\n\\tfunction initialize(\\n\\t\\taddress[] calldata _members,\\n\\t\\tuint _required,\\n\\t\\taddress _bridge,\\n\\t\\taddress owner\\n\\t) public validRequirement(_members.length, _required) initializer {\\n\\t\\tUpgradableOwnable.initialize(owner);\\n\\t\\trequire(_members.length <= MAX_MEMBER_COUNT, \\\"Federation: Too many members\\\");\\n\\t\\tmembers = _members;\\n\\t\\tfor (uint i = 0; i < _members.length; i++) {\\n\\t\\t\\trequire(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \\\"Federation: Invalid members\\\");\\n\\t\\t\\tisMember[_members[i]] = true;\\n\\t\\t\\temit MemberAddition(_members[i]);\\n\\t\\t}\\n\\t\\trequired = _required;\\n\\t\\temit RequirementChange(required);\\n\\t\\t_setBridge(_bridge);\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Current version of the contract\\n\\t\\t@return version in v{Number}\\n\\t\\t*/\\n\\tfunction version() external pure override returns (string memory) {\\n\\t\\treturn \\\"v3\\\";\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Sets a new bridge contract\\n\\t\\t@dev Emits BridgeChanged event\\n\\t\\t@param _bridge the new bridge contract address that should implement the IBridge interface\\n\\t\\t*/\\n\\tfunction setBridge(address _bridge) external onlyOwner override {\\n\\t\\t_setBridge(_bridge);\\n\\t}\\n\\n\\tfunction _setBridge(address _bridge) internal {\\n\\t\\trequire(_bridge != NULL_ADDRESS, \\\"Federation: Empty bridge\\\");\\n\\t\\tbridge = IBridge(_bridge);\\n\\t\\temit BridgeChanged(_bridge);\\n\\t}\\n\\n\\tfunction validateTransaction(bytes32 transactionId, bytes32 transactionIdMultichain) internal view returns(bool) {\\n\\t\\tuint256 minimumVotes = getMinimalNumberOfVotes();\\n\\t\\tuint256 amountVotes = 0;\\n\\n for (uint256 i = 0; i < members.length; i++) {\\n if (votes[transactionIdMultichain][members[i]]) {\\n amountVotes += 1;\\n\\t\\t\\t} else if (votes[transactionId][members[i]]) {\\n amountVotes += 1;\\n\\t\\t\\t}\\n\\n\\t\\t\\tif (amountVotes >= minimumVotes && amountVotes >= required) {\\n\\t\\t\\t\\treturn true;\\n\\t\\t\\t}\\n }\\n\\n\\t\\treturn false;\\n\\t}\\n\\n\\tfunction getMinimalNumberOfVotes() internal view returns(uint256) {\\n\\t\\treturn members.length / 2 + 1;\\n\\t}\\n\\n\\tfunction isProcessed(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\\n\\t\\treturn processed[transactionIdMultichain] || processed[transactionId];\\n\\t}\\n\\n\\tfunction isVoted(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\\n\\t\\treturn votes[transactionIdMultichain][_msgSender()] || votes[transactionId][_msgSender()];\\n\\t}\\n\\n\\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\\n\\t\\trequire(chainId == block.chainid, \\\"Federation: Not block.chainid\\\");\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Vote in a transaction, if it has enough votes it accepts the transfer\\n\\t\\t@param originalTokenAddress The address of the token in the origin (main) chain\\n\\t\\t@param sender The address who solicited the cross token\\n\\t\\t@param receiver Who is going to receive the token in the opposite chain\\n\\t\\t@param value Amount\\n\\t\\t@param blockHash The block hash in which the transaction with the cross event occurred\\n\\t\\t@param transactionHash The transaction in which the cross event occurred\\n\\t\\t@param logIndex Index of the event in the logs\\n\\t\\t@param originChainId Is chainId of the original chain\\n\\t\\t@param destinationChainId Is chainId of the destination chain\\n\\t\\t*/\\n\\tfunction voteTransaction(\\n\\t\\taddress originalTokenAddress,\\n\\t\\taddress payable sender,\\n\\t\\taddress payable receiver,\\n\\t\\tuint256 value,\\n\\t\\tbytes32 blockHash,\\n\\t\\tbytes32 transactionHash,\\n\\t\\tuint32 logIndex,\\n\\t\\tuint256 originChainId,\\n\\t\\tuint256\\tdestinationChainId\\n\\t) external onlyMember override {\\n\\t\\tshouldBeCurrentChainId(destinationChainId);\\n\\t\\tbytes32 transactionId = keccak256(\\n\\t\\t\\tabi.encodePacked(\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tvalue,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\tlogIndex\\n\\t\\t\\t)\\n\\t\\t);\\n\\n\\t\\tbytes32 transactionIdMultichain = getTransactionId(\\n\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\tsender,\\n\\t\\t\\treceiver,\\n\\t\\t\\tvalue,\\n\\t\\t\\tblockHash,\\n\\t\\t\\ttransactionHash,\\n\\t\\t\\tlogIndex,\\n\\t\\t\\toriginChainId,\\n\\t\\t\\tdestinationChainId\\n\\t\\t);\\n\\n\\t\\tif (isProcessed(transactionId, transactionIdMultichain))\\n\\t\\t\\treturn;\\n\\n\\t\\tif (isVoted(transactionId, transactionIdMultichain))\\n\\t\\t\\treturn;\\n\\n\\t\\tvotes[transactionIdMultichain][_msgSender()] = true;\\n\\t\\temit Voted(\\n\\t\\t\\t_msgSender(),\\n\\t\\t\\ttransactionHash,\\n\\t\\t\\ttransactionIdMultichain,\\n\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\tsender,\\n\\t\\t\\treceiver,\\n\\t\\t\\tvalue,\\n\\t\\t\\tblockHash,\\n\\t\\t\\tlogIndex,\\n\\t\\t\\toriginChainId,\\n\\t\\t\\tdestinationChainId\\n\\t\\t);\\n\\n\\t\\tif (validateTransaction(transactionId, transactionIdMultichain)) {\\n\\t\\t\\tprocessed[transactionIdMultichain] = true;\\n\\n\\t\\t\\tacceptTransfer(\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tvalue,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\tlogIndex,\\n\\t\\t\\t\\t\\n\\t\\t\\t\\toriginChainId,\\n\\t\\t\\t\\tdestinationChainId\\n\\t\\t\\t);\\n\\n\\t\\t\\temit Executed(\\n\\t\\t\\t\\t_msgSender(),\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\ttransactionIdMultichain,\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tvalue,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\tlogIndex,\\n\\t\\t\\t\\toriginChainId,\\n\\t\\t\\t\\tdestinationChainId\\n\\t\\t\\t);\\n\\t\\t}\\n\\t}\\n\\n function acceptTransfer(\\n address originalTokenAddress,\\n address payable sender,\\n address payable receiver,\\n uint256 value,\\n bytes32 blockHash,\\n bytes32 transactionHash,\\n uint32 logIndex,\\n\\tuint256 originChainId,\\n\\tuint256\\tdestinationChainId\\n ) internal {\\n\\t bridge.acceptTransfer(\\n\\t\\toriginalTokenAddress,\\n\\t\\tsender,\\n\\t\\treceiver,\\n\\t\\tvalue,\\n\\t\\tblockHash,\\n\\t\\ttransactionHash,\\n\\t\\tlogIndex,\\n\\t\\toriginChainId,\\n\\t\\tdestinationChainId\\n\\t );\\n }\\n\\n /**\\n @notice Get the amount of approved votes for that transactionId\\n @param transactionId The transaction hashed from getTransactionId function\\n */\\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\\n uint count = 0;\\n for (uint i = 0; i < members.length; i++) {\\n if (votes[transactionId][members[i]])\\n count += 1;\\n }\\n return count;\\n }\\n\\n\\tfunction hasVoted(bytes32 transactionId) external view returns(bool) {\\n\\t\\treturn votes[transactionId][_msgSender()];\\n\\t}\\n\\n\\tfunction transactionWasProcessed(bytes32 transactionId) external view returns(bool) {\\n\\t\\treturn processed[transactionId];\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Gets the hash of transaction from the following parameters encoded and keccaked\\n\\t\\t@dev It encodes and applies keccak256 to the parameters received in the same order\\n\\t\\t@param originalTokenAddress The address of the token in the origin (main) chain\\n\\t\\t@param sender The address who solicited the cross token\\n\\t\\t@param receiver Who is going to receive the token in the opposite chain\\n\\t\\t@param amount Could be the amount or the tokenId\\n\\t\\t@param blockHash The block hash in which the transaction with the cross event occurred\\n\\t\\t@param transactionHash The transaction in which the cross event occurred\\n\\t\\t@param logIndex Index of the event in the logs\\n\\t\\t@param originChainId Is chainId of the original chain\\n\\t\\t@param destinationChainId Is chainId of the destination chain\\n\\t\\t@return The hash generated by the parameters.\\n\\t*/\\n\\tfunction getTransactionId(\\n\\t\\taddress originalTokenAddress,\\n\\t\\taddress sender,\\n\\t\\taddress receiver,\\n\\t\\tuint256 amount,\\n\\t\\tbytes32 blockHash,\\n\\t\\tbytes32 transactionHash,\\n\\t\\tuint32 logIndex,\\n\\t\\tuint256 originChainId,\\n\\t\\tuint256\\tdestinationChainId\\n\\t) public pure returns(bytes32) {\\n\\t\\treturn keccak256(\\n\\t\\t\\tabi.encodePacked(\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tamount,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\tlogIndex,\\n\\t\\t\\t\\toriginChainId,\\n\\t\\t\\t\\tdestinationChainId\\n\\t\\t\\t)\\n\\t\\t);\\n\\t}\\n\\n\\tfunction addMember(address _newMember) external onlyOwner override {\\n\\t\\trequire(_newMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\n\\t\\trequire(!isMember[_newMember], \\\"Federation: Member already exists\\\");\\n\\t\\trequire(members.length < MAX_MEMBER_COUNT, \\\"Federation: Max members reached\\\");\\n\\n\\t\\tisMember[_newMember] = true;\\n\\t\\tmembers.push(_newMember);\\n\\t\\temit MemberAddition(_newMember);\\n\\t}\\n\\n\\tfunction removeMember(address _oldMember) external onlyOwner override {\\n\\t\\trequire(_oldMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\n\\t\\trequire(isMember[_oldMember], \\\"Federation: Member doesn't exists\\\");\\n\\t\\trequire(members.length > 1, \\\"Federation: Can't remove all the members\\\");\\n\\t\\trequire(members.length - 1 >= required, \\\"Federation: Can't have less than required members\\\");\\n\\n\\t\\tisMember[_oldMember] = false;\\n\\t\\tfor (uint i = 0; i < members.length - 1; i++) {\\n\\t\\t\\tif (members[i] == _oldMember) {\\n\\t\\t\\t\\tmembers[i] = members[members.length - 1];\\n\\t\\t\\t\\tbreak;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\tmembers.pop(); // remove an element from the end of the array.\\n\\t\\temit MemberRemoval(_oldMember);\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Return all the current members of the federation\\n\\t\\t@return Current members\\n\\t\\t*/\\n\\tfunction getMembers() external view override returns (address[] memory) {\\n\\t\\treturn members;\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Changes the number of required members to vote and approve an transaction\\n\\t\\t@dev Emits the RequirementChange event\\n\\t\\t@param _required the number of minimum members to approve an transaction, it has to be bigger than 1\\n\\t\\t*/\\n\\tfunction changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\\n\\t\\trequire(_required >= 2, \\\"Federation: Requires at least 2\\\");\\n\\t\\trequired = _required;\\n\\t\\temit RequirementChange(_required);\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice It emits an HeartBeat like an health check\\n\\t\\t@dev Emits HeartBeat event\\n\\t\\t*/\\n\\tfunction emitHeartbeat(\\n\\t\\tstring calldata fedVersion,\\n\\t\\tuint256[] calldata fedChainsIds,\\n\\t\\tuint256[] calldata fedChainsBlocks,\\n\\t\\tstring[] calldata fedChainsInfo\\n\\t) external onlyMember override {\\n\\t\\trequire(fedChainsIds.length == fedChainsBlocks.length &&\\n\\t\\t\\tfedChainsIds.length == fedChainsInfo.length, \\\"Federation: Length missmatch\\\");\\n\\t\\temit HeartBeat(\\n\\t\\t\\t_msgSender(),\\n\\t\\t\\tblock.chainid,\\n\\t\\t\\tblock.number,\\n\\t\\t\\tfedVersion,\\n\\t\\t\\tfedChainsIds,\\n\\t\\t\\tfedChainsBlocks,\\n\\t\\t\\tfedChainsInfo\\n\\t\\t);\\n\\t}\\n}\\n\",\"keccak256\":\"0x2a10301f1d5d923b68ccb895b7d6e1ec4c41afa204f8466f20b2702665ef8769\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\ninterface IBridge {\\n\\n\\tstruct ClaimData {\\n\\t\\taddress payable to;\\n\\t\\tuint256 amount;\\n\\t\\tbytes32 blockHash;\\n\\t\\tbytes32 transactionHash;\\n\\t\\tuint32 logIndex;\\n\\t\\tuint256 originChainId;\\n\\t}\\n\\n\\tstruct OriginalToken {\\n\\t\\taddress tokenAddress;\\n\\t\\tuint256 originChainId;\\n\\t}\\n\\t\\n\\tstruct CreateSideTokenStruct {\\n\\t\\tuint256 _typeId;\\n\\t\\taddress _originalTokenAddress;\\n\\t\\tuint8 _originalTokenDecimals;\\n\\t\\tstring _originalTokenSymbol;\\n\\t\\tstring _originalTokenName;\\n\\t\\tuint256 _originChainId;\\n\\t}\\n\\n\\tfunction version() external pure returns (string memory);\\n\\n\\tfunction getFeePercentage() external view returns(uint);\\n\\n\\t/**\\n\\t\\t* ERC-20 tokens approve and transferFrom pattern\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\n\\t\\t*/\\n\\tfunction receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;\\n\\n\\t/**\\n\\t\\t* Use network currency and cross it.\\n\\t\\t*/\\n\\tfunction depositTo(uint256 chainId, address to) external payable;\\n\\n\\t/**\\n\\t\\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\n\\t\\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\\n\\t\\t* const userData = web3.eth.abi.encodeParameters(\\n * [\\\"address\\\", \\\"uint256\\\"],\\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\\n * );\\n\\t\\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\\n\\t\\t* const userData = web3.eth.abi.encodeParameters([\\\"uint256\\\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\\n\\t\\t*/\\n\\tfunction tokensReceived (\\n\\t\\taddress operator,\\n\\t\\taddress from,\\n\\t\\taddress to,\\n\\t\\tuint amount,\\n\\t\\tbytes calldata userData,\\n\\t\\tbytes calldata operatorData\\n\\t) external;\\n\\n\\t/**\\n\\t\\t* Accepts the transaction from the other chain that was voted and sent by the Federation contract\\n\\t\\t*/\\n\\tfunction acceptTransfer(\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _from,\\n\\t\\taddress payable _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t) external;\\n\\n\\t/**\\n\\t\\t* Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\n\\t\\t*/\\n\\tfunction claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n\\tfunction claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n\\tfunction claimGasless(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _deadline,\\n\\t\\tuint8 _v,\\n\\t\\tbytes32 _r,\\n\\t\\tbytes32 _s\\n\\t) external returns (uint256 receivedAmount);\\n\\n\\tfunction createSideToken(\\n\\t\\tuint256 _typeId,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\tuint8 _originalTokenDecimals,\\n\\t\\tstring calldata _originalTokenSymbol,\\n\\t\\tstring calldata _originalTokenName,\\n\\t\\tuint256 _chainId\\n\\t) external;\\n\\n\\tfunction createMultipleSideTokens(\\n\\t\\tCreateSideTokenStruct[] calldata createSideTokenStruct\\n\\t) external;\\n\\n\\tfunction getTransactionDataHash(\\n\\t\\taddress _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256 _destinationChainId\\n\\t) external returns(bytes32);\\n\\n\\tevent Cross(\\n\\t\\taddress indexed _tokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\tuint256 indexed _destinationChainId,\\n\\t\\taddress _from,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes _userData\\n\\t);\\n\\n\\tevent NewSideToken(\\n\\t\\taddress indexed _newSideTokenAddress,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\tstring _newSymbol,\\n\\t\\tuint256 _granularity,\\n\\t\\tuint256 _chainId\\n\\t);\\n\\tevent AcceptedCrossTransfer(\\n\\t\\tbytes32 indexed _transactionHash,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\taddress _from,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tuint256 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t);\\n\\tevent FeePercentageChanged(uint256 _amount);\\n\\tevent Claimed(\\n\\t\\tbytes32 indexed _transactionHash,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\taddress _sender,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tuint256 _logIndex,\\n\\t\\taddress _reciever,\\n\\t\\taddress _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _destinationChainId,\\n\\t\\tuint256 _originChainId\\n\\t);\\n}\",\"keccak256\":\"0x1c5d6422edd509f1abc62bc29b41b1c6f80df08235ca289da81c661b8aa33044\",\"license\":\"MIT\"},\"contracts/interface/IFederation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\ninterface IFederation {\\n\\n /**\\n @notice Current version of the contract\\n @return version in v{Number}\\n */\\n function version() external pure returns (string memory);\\n\\n /**\\n @notice Sets a new bridge contract\\n @param _bridge the new bridge contract address that should implement the IBridge interface\\n */\\n function setBridge(address _bridge) external;\\n\\n /**\\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\\n @param originalTokenAddress The address of the token in the origin (main) chain\\n @param sender The address who solicited the cross token\\n @param receiver Who is going to receive the token in the opposite chain\\n @param value Amount\\n @param blockHash The block hash in which the transaction with the cross event occurred\\n @param transactionHash The transaction in which the cross event occurred\\n @param logIndex Index of the event in the logs\\n\\t\\t@param originChainId Is chainId of the original chain\\n\\t\\t@param destinationChainId Is chainId of the destination chain\\n */\\n function voteTransaction(\\n address originalTokenAddress,\\n address payable sender,\\n address payable receiver,\\n uint256 value,\\n bytes32 blockHash,\\n bytes32 transactionHash,\\n uint32 logIndex,\\n\\t uint256 originChainId,\\n\\t uint256\\tdestinationChainId\\n ) external;\\n\\n /**\\n @notice Add a new member to the federation\\n @param _newMember address of the new member\\n */\\n function addMember(address _newMember) external;\\n\\n /**\\n @notice Remove a member of the federation\\n @param _oldMember address of the member to be removed from federation\\n */\\n function removeMember(address _oldMember) external;\\n\\n /**\\n @notice Return all the current members of the federation\\n @return Current members\\n */\\n function getMembers() external view returns (address[] memory);\\n\\n /**\\n @notice Changes the number of required members to vote and approve an transaction\\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\\n */\\n function changeRequirement(uint _required) external;\\n\\n /**\\n @notice It emmits an HeartBeat like an healthy check\\n */\\n function emitHeartbeat(\\n string calldata federatorVersion,\\n\\t\\tuint256[] calldata fedChainsIds,\\n\\t\\tuint256[] calldata fedChainsBlocks,\\n\\t\\tstring[] calldata fedChainsInfo\\n ) external;\\n\\n event Executed(\\n address indexed federator,\\n bytes32 indexed transactionHash,\\n bytes32 indexed transactionId,\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n uint32 logIndex,\\n\\t\\tuint256 originChainId,\\n\\t\\tuint256\\tdestinationChainId\\n );\\n event MemberAddition(address indexed member);\\n event MemberRemoval(address indexed member);\\n event RequirementChange(uint required);\\n event BridgeChanged(address bridge);\\n event Voted(\\n address indexed federator,\\n bytes32 indexed transactionHash,\\n bytes32 indexed transactionId,\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n uint32 logIndex,\\n uint256 originChainId,\\n\\t\\tuint256\\tdestinationChainId\\n );\\n event HeartBeat(\\n address indexed sender,\\n uint256 currentChainId,\\n uint256 currentBlock,\\n string fedVersion,\\n uint256[] fedChainsIds,\\n\\t\\tuint256[] fedChainsBlocks,\\n\\t\\tstring[] fedChainsInfo\\n );\\n\\n}\\n\",\"keccak256\":\"0x22ef32d3798dc52fcf55286858f0a12e0f99fb9c1f0d35c6cfbc3e99b70b0744\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return payable(msg.sender);\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x6f3f274a2270bfe073339370edfa2485e2d515a2656039937f6b972fae96d297\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\",\"keccak256\":\"0x14063a689bff5eecf0f36cb519feb575f60349ecf0d425ead5b931b77dd599d4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract UpgradableOwnable is Initializable, Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function initialize(address sender) public initializer {\\n _owner = sender;\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * > Note: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n\\n}\\n\",\"keccak256\":\"0xdf439a167ae82e7e3dd241ea0c831a1bb0329432ceb4fa889778d1f2d196ce00\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50611f3f806100206000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c80639386775a116100f9578063c1b4a1e311610097578063ca6d56dc11610071578063ca6d56dc14610401578063dc8452cd14610414578063e78cea921461041d578063f2fde38b1461043057600080fd5b8063c1b4a1e3146103b8578063c1f0808a146103cb578063c4d66de8146103ee57600080fd5b8063a1fb4acb116100d3578063a1fb4acb1461034c578063a230c5241461035f578063a93585f014610382578063ba51a6df146103a557600080fd5b80639386775a146102f65780639dc8f9c8146103245780639eab52531461033757600080fd5b8063681fc921116101665780637b6d343a116101405780637b6d343a146102ac5780638da5cb5b146102bf5780638dd14802146102d05780638f32d59b146102e357600080fd5b8063681fc9211461027b578063715018a61461029157806379d9ee721461029957600080fd5b806309c69cfa146101ae5780630b1ca49a146101d65780631b4613cb146101eb5780633f78f0691461021957806354fd4d501461022c5780635daf08ca14610250575b600080fd5b6101c16101bc3660046118ac565b610443565b60405190151581526020015b60405180910390f35b6101e96101e43660046118e3565b61048d565b005b6101c16101f9366004611907565b600090815260386020908152604080832033845290915290205460ff1690565b6101e9610227366004611939565b6107cb565b6040805180820182526002815261763360f01b602082015290516101cd91906119c4565b61026361025e366004611907565b610a0b565b6040516001600160a01b0390911681526020016101cd565b610283603281565b6040519081526020016101cd565b6101e9610a35565b6101e96102a7366004611a65565b610aa9565b6101c16102ba3660046118ac565b610bbb565b6033546001600160a01b0316610263565b6101e96102de3660046118e3565b610bea565b6033546001600160a01b031633146101c1565b6101c1610304366004611b54565b603860209081526000928352604080842090915290825290205460ff1681565b610283610332366004611939565b610c20565b61033f610cad565b6040516101cd9190611b84565b61028361035a366004611907565b610d0f565b6101c161036d3660046118e3565b60376020526000908152604090205460ff1681565b6101c1610390366004611907565b60009081526039602052604090205460ff1690565b6101e96103b3366004611907565b610d97565b6101e96103c6366004611bd1565b610eb9565b6101c16103d9366004611907565b60396020526000908152604090205460ff1681565b6101e96103fc3660046118e3565b6111dc565b6101e961040f3660046118e3565b611292565b61028360365481565b603454610263906001600160a01b031681565b6101e961043e3660046118e3565b61145e565b600081815260386020908152604080832033845290915281205460ff16806104845750600083815260386020908152604080832033845290915290205460ff165b90505b92915050565b6033546001600160a01b031633146104c05760405162461bcd60e51b81526004016104b790611c45565b60405180910390fd5b6001600160a01b0381166105115760405162461bcd60e51b81526020600482015260186024820152772332b232b930ba34b7b71d1022b6b83a3c9036b2b6b132b960411b60448201526064016104b7565b6001600160a01b03811660009081526037602052604090205460ff166105835760405162461bcd60e51b815260206004820152602160248201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746044820152607360f81b60648201526084016104b7565b6035546001106105e65760405162461bcd60e51b815260206004820152602860248201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604482015267206d656d6265727360c01b60648201526084016104b7565b6036546035546105f890600190611c90565b10156106605760405162461bcd60e51b815260206004820152603160248201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604482015270207265717569726564206d656d6265727360781b60648201526084016104b7565b6001600160a01b0381166000908152603760205260408120805460ff191690555b60355461069090600190611c90565b81101561076057816001600160a01b0316603582815481106106b4576106b4611ca7565b6000918252602090912001546001600160a01b0316141561074e57603580546106df90600190611c90565b815481106106ef576106ef611ca7565b600091825260209091200154603580546001600160a01b03909216918390811061071b5761071b611ca7565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610760565b8061075881611cbd565b915050610681565b50603580548061077257610772611cd8565b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b3360009081526037602052604090205460ff166108265760405162461bcd60e51b81526020600482015260196024820152782332b232b930ba34b7b71d102737ba102332b232b930ba37b960391b60448201526064016104b7565b61082f81611491565b6040516bffffffffffffffffffffffff1960608b811b821660208401528a811b8216603484015289901b166048820152605c8101879052607c8101869052609c81018590526001600160e01b031960e085901b1660bc82015260009060c00160405160208183030381529060405280519060200120905060006108b98b8b8b8b8b8b8b8b8b610c20565b90506108c58282610bbb565b156108d1575050610a00565b6108db8282610443565b156108e7575050610a00565b6000818152603860205260408120600191336001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558086336001600160a01b03167fa7be469662a3e5b2343dce0cefce9d3e114875d7334d8d724d3838cf629c5b108e8e8e8e8e8d8d8d60405161096a989796959493929190611cee565b60405180910390a461097c82826114e0565b156109fd576000818152603960205260409020805460ff191660011790556109ab8b8b8b8b8b8b8b8b8b611600565b8086336001600160a01b03167f0fe3e5a751f4df1a701ea5d318482623b6a6b59ece98cb64169279b44219355e8e8e8e8e8e8d8d8d6040516109f4989796959493929190611cee565b60405180910390a45b50505b505050505050505050565b60358181548110610a1b57600080fd5b6000918252602090912001546001600160a01b0316905081565b6033546001600160a01b03163314610a5f5760405162461bcd60e51b81526004016104b790611c45565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b3360009081526037602052604090205460ff16610b045760405162461bcd60e51b81526020600482015260196024820152782332b232b930ba34b7b71d102737ba102332b232b930ba37b960391b60448201526064016104b7565b8483148015610b1257508481145b610b5e5760405162461bcd60e51b815260206004820152601c60248201527f46656465726174696f6e3a204c656e677468206d6973736d617463680000000060448201526064016104b7565b336001600160a01b03167f909659508bf1f4c0ad9b406809f943832e107af28b0b436d9b7d56d3993c77f146438b8b8b8b8b8b8b8b604051610ba99a99989796959493929190611d9a565b60405180910390a25050505050505050565b60008181526039602052604081205460ff16806104845750505060009081526039602052604090205460ff1690565b6033546001600160a01b03163314610c145760405162461bcd60e51b81526004016104b790611c45565b610c1d816116ab565b50565b604080516bffffffffffffffffffffffff1960609b8c1b81166020808401919091529a8c1b8116603483015298909a1b90971660488a0152605c890195909552607c880193909352609c8701919091526001600160e01b031960e091821b1660bc87015260c086019190915280850191909152815180850390910181526101009093019052815191012090565b60606035805480602002602001604051908101604052809291908181526020018280548015610d0557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ce7575b5050505050905090565b600080805b603554811015610d905760008481526038602052604081206035805491929184908110610d4357610d43611ca7565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610d7e57610d7b600183611e87565b91505b80610d8881611cbd565b915050610d14565b5092915050565b6033546001600160a01b03163314610dc15760405162461bcd60e51b81526004016104b790611c45565b60355481818111801590610dd457508015155b8015610ddf57508115155b610e2b5760405162461bcd60e51b815260206004820181905260248201527f46656465726174696f6e3a20496e76616c696420726571756972656d656e747360448201526064016104b7565b6002831015610e7c5760405162461bcd60e51b815260206004820152601f60248201527f46656465726174696f6e3a205265717569726573206174206c6561737420320060448201526064016104b7565b60368390556040518381527fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9060200160405180910390a1505050565b8383818111801590610eca57508015155b8015610ed557508115155b610f215760405162461bcd60e51b815260206004820181905260248201527f46656465726174696f6e3a20496e76616c696420726571756972656d656e747360448201526064016104b7565b600054610100900460ff1680610f3a575060005460ff16155b610f565760405162461bcd60e51b81526004016104b790611e9f565b600054610100900460ff16158015610f78576000805461ffff19166101011790555b610f81846111dc565b6032871115610fd25760405162461bcd60e51b815260206004820152601c60248201527f46656465726174696f6e3a20546f6f206d616e79206d656d626572730000000060448201526064016104b7565b610fde60358989611834565b5060005b8781101561117e57603760008a8a8481811061100057611000611ca7565b905060200201602081019061101591906118e3565b6001600160a01b0316815260208101919091526040016000205460ff1615801561106f5750600089898381811061104e5761104e611ca7565b905060200201602081019061106391906118e3565b6001600160a01b031614155b6110bb5760405162461bcd60e51b815260206004820152601b60248201527f46656465726174696f6e3a20496e76616c6964206d656d62657273000000000060448201526064016104b7565b6001603760008b8b858181106110d3576110d3611ca7565b90506020020160208101906110e891906118e3565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905588888281811061112257611122611ca7565b905060200201602081019061113791906118e3565b6001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a28061117681611cbd565b915050610fe2565b5060368690556040518681527fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9060200160405180910390a16111c0856116ab565b80156111d2576000805461ff00191690555b5050505050505050565b600054610100900460ff16806111f5575060005460ff16155b6112115760405162461bcd60e51b81526004016104b790611e9f565b600054610100900460ff16158015611233576000805461ffff19166101011790555b603380546001600160a01b0319166001600160a01b0384169081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3801561128e576000805461ff00191690555b5050565b6033546001600160a01b031633146112bc5760405162461bcd60e51b81526004016104b790611c45565b6001600160a01b03811661130d5760405162461bcd60e51b81526020600482015260186024820152772332b232b930ba34b7b71d1022b6b83a3c9036b2b6b132b960411b60448201526064016104b7565b6001600160a01b03811660009081526037602052604090205460ff16156113805760405162461bcd60e51b815260206004820152602160248201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746044820152607360f81b60648201526084016104b7565b6035546032116113d25760405162461bcd60e51b815260206004820152601f60248201527f46656465726174696f6e3a204d6178206d656d6265727320726561636865640060448201526064016104b7565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b6033546001600160a01b031633146114885760405162461bcd60e51b81526004016104b790611c45565b610c1d81611755565b468114610c1d5760405162461bcd60e51b815260206004820152601d60248201527f46656465726174696f6e3a204e6f7420626c6f636b2e636861696e696400000060448201526064016104b7565b6000806114eb611812565b90506000805b6035548110156115f4576000858152603860205260408120603580549192918490811061152057611520611ca7565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff161561155f57611558600183611e87565b91506115bf565b6000868152603860205260408120603580549192918490811061158457611584611ca7565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156115bf576115bc600183611e87565b91505b8282101580156115d157506036548210155b156115e25760019350505050610487565b806115ec81611cbd565b9150506114f1565b50600095945050505050565b60345460405163048aa97560e21b81526001600160a01b038b811660048301528a811660248301528981166044830152606482018990526084820188905260a4820187905263ffffffff861660c483015260e4820185905261010482018490529091169063122aa5d49061012401600060405180830381600087803b15801561168857600080fd5b505af115801561169c573d6000803e3d6000fd5b50505050505050505050505050565b6001600160a01b0381166117015760405162461bcd60e51b815260206004820152601860248201527f46656465726174696f6e3a20456d70747920627269646765000000000000000060448201526064016104b7565b603480546001600160a01b0319166001600160a01b0383169081179091556040519081527f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b925517827944979060200160405180910390a150565b6001600160a01b0381166117b65760405162461bcd60e51b815260206004820152602260248201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604482015261737360f01b60648201526084016104b7565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b60355460009061182490600290611ee7565b61182f906001611e87565b905090565b828054828255906000526020600020908101928215611887579160200282015b828111156118875781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190611854565b50611893929150611897565b5090565b5b808211156118935760008155600101611898565b600080604083850312156118bf57600080fd5b50508035926020909101359150565b6001600160a01b0381168114610c1d57600080fd5b6000602082840312156118f557600080fd5b8135611900816118ce565b9392505050565b60006020828403121561191957600080fd5b5035919050565b803563ffffffff8116811461193457600080fd5b919050565b60008060008060008060008060006101208a8c03121561195857600080fd5b8935611963816118ce565b985060208a0135611973816118ce565b975060408a0135611983816118ce565b965060608a0135955060808a0135945060a08a013593506119a660c08b01611920565b925060e08a013591506101008a013590509295985092959850929598565b600060208083528351808285015260005b818110156119f1578581018301518582016040015282016119d5565b81811115611a03576000604083870101525b50601f01601f1916929092016040019392505050565b60008083601f840112611a2b57600080fd5b50813567ffffffffffffffff811115611a4357600080fd5b6020830191508360208260051b8501011115611a5e57600080fd5b9250929050565b6000806000806000806000806080898b031215611a8157600080fd5b883567ffffffffffffffff80821115611a9957600080fd5b818b0191508b601f830112611aad57600080fd5b813581811115611abc57600080fd5b8c6020828501011115611ace57600080fd5b60209283019a509850908a01359080821115611ae957600080fd5b611af58c838d01611a19565b909850965060408b0135915080821115611b0e57600080fd5b611b1a8c838d01611a19565b909650945060608b0135915080821115611b3357600080fd5b50611b408b828c01611a19565b999c989b5096995094979396929594505050565b60008060408385031215611b6757600080fd5b823591506020830135611b79816118ce565b809150509250929050565b6020808252825182820181905260009190848201906040850190845b81811015611bc55783516001600160a01b031683529284019291840191600101611ba0565b50909695505050505050565b600080600080600060808688031215611be957600080fd5b853567ffffffffffffffff811115611c0057600080fd5b611c0c88828901611a19565b909650945050602086013592506040860135611c27816118ce565b91506060860135611c37816118ce565b809150509295509295909350565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082821015611ca257611ca2611c7a565b500390565b634e487b7160e01b600052603260045260246000fd5b6000600019821415611cd157611cd1611c7a565b5060010190565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b03988916815296881660208801529490961660408601526060850192909252608084015263ffffffff1660a083015260c082019290925260e08101919091526101000190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b81835260006001600160fb1b03831115611d7d57600080fd5b8260051b8083602087013760009401602001938452509192915050565b8a8152600060208b8184015260c06040840152611dbb60c084018b8d611d3b565b8381036060850152611dce818a8c611d64565b90508381036080850152611de381888a611d64565b84810360a08601528581529050818101600586901b820183018760005b88811015611e6f57848303601f190184528135368b9003601e19018112611e2657600080fd5b8a01803567ffffffffffffffff811115611e3f57600080fd5b8036038c1315611e4e57600080fd5b611e5b85828a8501611d3b565b958801959450505090850190600101611e00565b5050809450505050509b9a5050505050505050505050565b60008219821115611e9a57611e9a611c7a565b500190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b600082611f0457634e487b7160e01b600052601260045260246000fd5b50049056fea264697066735822122080da2d173e8a3678490d1bba1778aecda04e4b4a98d863e10c49639aad6d265d64736f6c63430008090033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a95760003560e01c80639386775a116100f9578063c1b4a1e311610097578063ca6d56dc11610071578063ca6d56dc14610401578063dc8452cd14610414578063e78cea921461041d578063f2fde38b1461043057600080fd5b8063c1b4a1e3146103b8578063c1f0808a146103cb578063c4d66de8146103ee57600080fd5b8063a1fb4acb116100d3578063a1fb4acb1461034c578063a230c5241461035f578063a93585f014610382578063ba51a6df146103a557600080fd5b80639386775a146102f65780639dc8f9c8146103245780639eab52531461033757600080fd5b8063681fc921116101665780637b6d343a116101405780637b6d343a146102ac5780638da5cb5b146102bf5780638dd14802146102d05780638f32d59b146102e357600080fd5b8063681fc9211461027b578063715018a61461029157806379d9ee721461029957600080fd5b806309c69cfa146101ae5780630b1ca49a146101d65780631b4613cb146101eb5780633f78f0691461021957806354fd4d501461022c5780635daf08ca14610250575b600080fd5b6101c16101bc3660046118ac565b610443565b60405190151581526020015b60405180910390f35b6101e96101e43660046118e3565b61048d565b005b6101c16101f9366004611907565b600090815260386020908152604080832033845290915290205460ff1690565b6101e9610227366004611939565b6107cb565b6040805180820182526002815261763360f01b602082015290516101cd91906119c4565b61026361025e366004611907565b610a0b565b6040516001600160a01b0390911681526020016101cd565b610283603281565b6040519081526020016101cd565b6101e9610a35565b6101e96102a7366004611a65565b610aa9565b6101c16102ba3660046118ac565b610bbb565b6033546001600160a01b0316610263565b6101e96102de3660046118e3565b610bea565b6033546001600160a01b031633146101c1565b6101c1610304366004611b54565b603860209081526000928352604080842090915290825290205460ff1681565b610283610332366004611939565b610c20565b61033f610cad565b6040516101cd9190611b84565b61028361035a366004611907565b610d0f565b6101c161036d3660046118e3565b60376020526000908152604090205460ff1681565b6101c1610390366004611907565b60009081526039602052604090205460ff1690565b6101e96103b3366004611907565b610d97565b6101e96103c6366004611bd1565b610eb9565b6101c16103d9366004611907565b60396020526000908152604090205460ff1681565b6101e96103fc3660046118e3565b6111dc565b6101e961040f3660046118e3565b611292565b61028360365481565b603454610263906001600160a01b031681565b6101e961043e3660046118e3565b61145e565b600081815260386020908152604080832033845290915281205460ff16806104845750600083815260386020908152604080832033845290915290205460ff165b90505b92915050565b6033546001600160a01b031633146104c05760405162461bcd60e51b81526004016104b790611c45565b60405180910390fd5b6001600160a01b0381166105115760405162461bcd60e51b81526020600482015260186024820152772332b232b930ba34b7b71d1022b6b83a3c9036b2b6b132b960411b60448201526064016104b7565b6001600160a01b03811660009081526037602052604090205460ff166105835760405162461bcd60e51b815260206004820152602160248201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746044820152607360f81b60648201526084016104b7565b6035546001106105e65760405162461bcd60e51b815260206004820152602860248201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604482015267206d656d6265727360c01b60648201526084016104b7565b6036546035546105f890600190611c90565b10156106605760405162461bcd60e51b815260206004820152603160248201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604482015270207265717569726564206d656d6265727360781b60648201526084016104b7565b6001600160a01b0381166000908152603760205260408120805460ff191690555b60355461069090600190611c90565b81101561076057816001600160a01b0316603582815481106106b4576106b4611ca7565b6000918252602090912001546001600160a01b0316141561074e57603580546106df90600190611c90565b815481106106ef576106ef611ca7565b600091825260209091200154603580546001600160a01b03909216918390811061071b5761071b611ca7565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610760565b8061075881611cbd565b915050610681565b50603580548061077257610772611cd8565b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b3360009081526037602052604090205460ff166108265760405162461bcd60e51b81526020600482015260196024820152782332b232b930ba34b7b71d102737ba102332b232b930ba37b960391b60448201526064016104b7565b61082f81611491565b6040516bffffffffffffffffffffffff1960608b811b821660208401528a811b8216603484015289901b166048820152605c8101879052607c8101869052609c81018590526001600160e01b031960e085901b1660bc82015260009060c00160405160208183030381529060405280519060200120905060006108b98b8b8b8b8b8b8b8b8b610c20565b90506108c58282610bbb565b156108d1575050610a00565b6108db8282610443565b156108e7575050610a00565b6000818152603860205260408120600191336001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558086336001600160a01b03167fa7be469662a3e5b2343dce0cefce9d3e114875d7334d8d724d3838cf629c5b108e8e8e8e8e8d8d8d60405161096a989796959493929190611cee565b60405180910390a461097c82826114e0565b156109fd576000818152603960205260409020805460ff191660011790556109ab8b8b8b8b8b8b8b8b8b611600565b8086336001600160a01b03167f0fe3e5a751f4df1a701ea5d318482623b6a6b59ece98cb64169279b44219355e8e8e8e8e8e8d8d8d6040516109f4989796959493929190611cee565b60405180910390a45b50505b505050505050505050565b60358181548110610a1b57600080fd5b6000918252602090912001546001600160a01b0316905081565b6033546001600160a01b03163314610a5f5760405162461bcd60e51b81526004016104b790611c45565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b3360009081526037602052604090205460ff16610b045760405162461bcd60e51b81526020600482015260196024820152782332b232b930ba34b7b71d102737ba102332b232b930ba37b960391b60448201526064016104b7565b8483148015610b1257508481145b610b5e5760405162461bcd60e51b815260206004820152601c60248201527f46656465726174696f6e3a204c656e677468206d6973736d617463680000000060448201526064016104b7565b336001600160a01b03167f909659508bf1f4c0ad9b406809f943832e107af28b0b436d9b7d56d3993c77f146438b8b8b8b8b8b8b8b604051610ba99a99989796959493929190611d9a565b60405180910390a25050505050505050565b60008181526039602052604081205460ff16806104845750505060009081526039602052604090205460ff1690565b6033546001600160a01b03163314610c145760405162461bcd60e51b81526004016104b790611c45565b610c1d816116ab565b50565b604080516bffffffffffffffffffffffff1960609b8c1b81166020808401919091529a8c1b8116603483015298909a1b90971660488a0152605c890195909552607c880193909352609c8701919091526001600160e01b031960e091821b1660bc87015260c086019190915280850191909152815180850390910181526101009093019052815191012090565b60606035805480602002602001604051908101604052809291908181526020018280548015610d0557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ce7575b5050505050905090565b600080805b603554811015610d905760008481526038602052604081206035805491929184908110610d4357610d43611ca7565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610d7e57610d7b600183611e87565b91505b80610d8881611cbd565b915050610d14565b5092915050565b6033546001600160a01b03163314610dc15760405162461bcd60e51b81526004016104b790611c45565b60355481818111801590610dd457508015155b8015610ddf57508115155b610e2b5760405162461bcd60e51b815260206004820181905260248201527f46656465726174696f6e3a20496e76616c696420726571756972656d656e747360448201526064016104b7565b6002831015610e7c5760405162461bcd60e51b815260206004820152601f60248201527f46656465726174696f6e3a205265717569726573206174206c6561737420320060448201526064016104b7565b60368390556040518381527fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9060200160405180910390a1505050565b8383818111801590610eca57508015155b8015610ed557508115155b610f215760405162461bcd60e51b815260206004820181905260248201527f46656465726174696f6e3a20496e76616c696420726571756972656d656e747360448201526064016104b7565b600054610100900460ff1680610f3a575060005460ff16155b610f565760405162461bcd60e51b81526004016104b790611e9f565b600054610100900460ff16158015610f78576000805461ffff19166101011790555b610f81846111dc565b6032871115610fd25760405162461bcd60e51b815260206004820152601c60248201527f46656465726174696f6e3a20546f6f206d616e79206d656d626572730000000060448201526064016104b7565b610fde60358989611834565b5060005b8781101561117e57603760008a8a8481811061100057611000611ca7565b905060200201602081019061101591906118e3565b6001600160a01b0316815260208101919091526040016000205460ff1615801561106f5750600089898381811061104e5761104e611ca7565b905060200201602081019061106391906118e3565b6001600160a01b031614155b6110bb5760405162461bcd60e51b815260206004820152601b60248201527f46656465726174696f6e3a20496e76616c6964206d656d62657273000000000060448201526064016104b7565b6001603760008b8b858181106110d3576110d3611ca7565b90506020020160208101906110e891906118e3565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905588888281811061112257611122611ca7565b905060200201602081019061113791906118e3565b6001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a28061117681611cbd565b915050610fe2565b5060368690556040518681527fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9060200160405180910390a16111c0856116ab565b80156111d2576000805461ff00191690555b5050505050505050565b600054610100900460ff16806111f5575060005460ff16155b6112115760405162461bcd60e51b81526004016104b790611e9f565b600054610100900460ff16158015611233576000805461ffff19166101011790555b603380546001600160a01b0319166001600160a01b0384169081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3801561128e576000805461ff00191690555b5050565b6033546001600160a01b031633146112bc5760405162461bcd60e51b81526004016104b790611c45565b6001600160a01b03811661130d5760405162461bcd60e51b81526020600482015260186024820152772332b232b930ba34b7b71d1022b6b83a3c9036b2b6b132b960411b60448201526064016104b7565b6001600160a01b03811660009081526037602052604090205460ff16156113805760405162461bcd60e51b815260206004820152602160248201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746044820152607360f81b60648201526084016104b7565b6035546032116113d25760405162461bcd60e51b815260206004820152601f60248201527f46656465726174696f6e3a204d6178206d656d6265727320726561636865640060448201526064016104b7565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b6033546001600160a01b031633146114885760405162461bcd60e51b81526004016104b790611c45565b610c1d81611755565b468114610c1d5760405162461bcd60e51b815260206004820152601d60248201527f46656465726174696f6e3a204e6f7420626c6f636b2e636861696e696400000060448201526064016104b7565b6000806114eb611812565b90506000805b6035548110156115f4576000858152603860205260408120603580549192918490811061152057611520611ca7565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff161561155f57611558600183611e87565b91506115bf565b6000868152603860205260408120603580549192918490811061158457611584611ca7565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156115bf576115bc600183611e87565b91505b8282101580156115d157506036548210155b156115e25760019350505050610487565b806115ec81611cbd565b9150506114f1565b50600095945050505050565b60345460405163048aa97560e21b81526001600160a01b038b811660048301528a811660248301528981166044830152606482018990526084820188905260a4820187905263ffffffff861660c483015260e4820185905261010482018490529091169063122aa5d49061012401600060405180830381600087803b15801561168857600080fd5b505af115801561169c573d6000803e3d6000fd5b50505050505050505050505050565b6001600160a01b0381166117015760405162461bcd60e51b815260206004820152601860248201527f46656465726174696f6e3a20456d70747920627269646765000000000000000060448201526064016104b7565b603480546001600160a01b0319166001600160a01b0383169081179091556040519081527f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b925517827944979060200160405180910390a150565b6001600160a01b0381166117b65760405162461bcd60e51b815260206004820152602260248201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604482015261737360f01b60648201526084016104b7565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b60355460009061182490600290611ee7565b61182f906001611e87565b905090565b828054828255906000526020600020908101928215611887579160200282015b828111156118875781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190611854565b50611893929150611897565b5090565b5b808211156118935760008155600101611898565b600080604083850312156118bf57600080fd5b50508035926020909101359150565b6001600160a01b0381168114610c1d57600080fd5b6000602082840312156118f557600080fd5b8135611900816118ce565b9392505050565b60006020828403121561191957600080fd5b5035919050565b803563ffffffff8116811461193457600080fd5b919050565b60008060008060008060008060006101208a8c03121561195857600080fd5b8935611963816118ce565b985060208a0135611973816118ce565b975060408a0135611983816118ce565b965060608a0135955060808a0135945060a08a013593506119a660c08b01611920565b925060e08a013591506101008a013590509295985092959850929598565b600060208083528351808285015260005b818110156119f1578581018301518582016040015282016119d5565b81811115611a03576000604083870101525b50601f01601f1916929092016040019392505050565b60008083601f840112611a2b57600080fd5b50813567ffffffffffffffff811115611a4357600080fd5b6020830191508360208260051b8501011115611a5e57600080fd5b9250929050565b6000806000806000806000806080898b031215611a8157600080fd5b883567ffffffffffffffff80821115611a9957600080fd5b818b0191508b601f830112611aad57600080fd5b813581811115611abc57600080fd5b8c6020828501011115611ace57600080fd5b60209283019a509850908a01359080821115611ae957600080fd5b611af58c838d01611a19565b909850965060408b0135915080821115611b0e57600080fd5b611b1a8c838d01611a19565b909650945060608b0135915080821115611b3357600080fd5b50611b408b828c01611a19565b999c989b5096995094979396929594505050565b60008060408385031215611b6757600080fd5b823591506020830135611b79816118ce565b809150509250929050565b6020808252825182820181905260009190848201906040850190845b81811015611bc55783516001600160a01b031683529284019291840191600101611ba0565b50909695505050505050565b600080600080600060808688031215611be957600080fd5b853567ffffffffffffffff811115611c0057600080fd5b611c0c88828901611a19565b909650945050602086013592506040860135611c27816118ce565b91506060860135611c37816118ce565b809150509295509295909350565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082821015611ca257611ca2611c7a565b500390565b634e487b7160e01b600052603260045260246000fd5b6000600019821415611cd157611cd1611c7a565b5060010190565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b03988916815296881660208801529490961660408601526060850192909252608084015263ffffffff1660a083015260c082019290925260e08101919091526101000190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b81835260006001600160fb1b03831115611d7d57600080fd5b8260051b8083602087013760009401602001938452509192915050565b8a8152600060208b8184015260c06040840152611dbb60c084018b8d611d3b565b8381036060850152611dce818a8c611d64565b90508381036080850152611de381888a611d64565b84810360a08601528581529050818101600586901b820183018760005b88811015611e6f57848303601f190184528135368b9003601e19018112611e2657600080fd5b8a01803567ffffffffffffffff811115611e3f57600080fd5b8036038c1315611e4e57600080fd5b611e5b85828a8501611d3b565b958801959450505090850190600101611e00565b5050809450505050509b9a5050505050505050505050565b60008219821115611e9a57611e9a611c7a565b500190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b600082611f0457634e487b7160e01b600052601260045260246000fd5b50049056fea264697066735822122080da2d173e8a3678490d1bba1778aecda04e4b4a98d863e10c49639aad6d265d64736f6c63430008090033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "addMember(address)": {
+ "params": {
+ "_newMember": "address of the new member"
+ }
+ },
+ "changeRequirement(uint256)": {
+ "details": "Emits the RequirementChange event",
+ "params": {
+ "_required": "the number of minimum members to approve an transaction, it has to be bigger than 1"
+ }
+ },
+ "emitHeartbeat(string,uint256[],uint256[],string[])": {
+ "details": "Emits HeartBeat event"
+ },
+ "getMembers()": {
+ "returns": {
+ "_0": "Current members"
+ }
+ },
+ "getTransactionCount(bytes32)": {
+ "params": {
+ "transactionId": "The transaction hashed from getTransactionId function"
+ }
+ },
+ "getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)": {
+ "details": "It encodes and applies keccak256 to the parameters received in the same order",
+ "params": {
+ "amount": "Could be the amount or the tokenId",
+ "blockHash": "The block hash in which the transaction with the cross event occurred",
+ "destinationChainId": "Is chainId of the destination chain",
+ "logIndex": "Index of the event in the logs",
+ "originChainId": "Is chainId of the original chain",
+ "originalTokenAddress": "The address of the token in the origin (main) chain",
+ "receiver": "Who is going to receive the token in the opposite chain",
+ "sender": "The address who solicited the cross token",
+ "transactionHash": "The transaction in which the cross event occurred"
+ },
+ "returns": {
+ "_0": "The hash generated by the parameters."
+ }
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "removeMember(address)": {
+ "params": {
+ "_oldMember": "address of the member to be removed from federation"
+ }
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "setBridge(address)": {
+ "details": "Emits BridgeChanged event",
+ "params": {
+ "_bridge": "the new bridge contract address that should implement the IBridge interface"
+ }
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "version()": {
+ "returns": {
+ "_0": "version in v{Number}"
+ }
+ },
+ "voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)": {
+ "params": {
+ "blockHash": "The block hash in which the transaction with the cross event occurred",
+ "destinationChainId": "Is chainId of the destination chain",
+ "logIndex": "Index of the event in the logs",
+ "originChainId": "Is chainId of the original chain",
+ "originalTokenAddress": "The address of the token in the origin (main) chain",
+ "receiver": "Who is going to receive the token in the opposite chain",
+ "sender": "The address who solicited the cross token",
+ "transactionHash": "The transaction in which the cross event occurred",
+ "value": "Amount"
+ }
+ }
+ },
+ "stateVariables": {
+ "isMember": {
+ "details": "The address should be a member to vote in transactions"
+ },
+ "required": {
+ "details": "It should have at least the required amount of members"
+ },
+ "votes": {
+ "details": "the members should approve the transaction by 50% + 1"
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "addMember(address)": {
+ "notice": "Add a new member to the federation"
+ },
+ "changeRequirement(uint256)": {
+ "notice": "Changes the number of required members to vote and approve an transaction"
+ },
+ "emitHeartbeat(string,uint256[],uint256[],string[])": {
+ "notice": "It emits an HeartBeat like an health check"
+ },
+ "getMembers()": {
+ "notice": "Return all the current members of the federation"
+ },
+ "getTransactionCount(bytes32)": {
+ "notice": "Get the amount of approved votes for that transactionId"
+ },
+ "getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)": {
+ "notice": "Gets the hash of transaction from the following parameters encoded and keccaked"
+ },
+ "isMember(address)": {
+ "notice": "All the addresses that are members of the federation"
+ },
+ "processed(bytes32)": {
+ "notice": "(bytes32) transactionId => (bool) votedCheck if that transaction was already processed"
+ },
+ "removeMember(address)": {
+ "notice": "Remove a member of the federation"
+ },
+ "required()": {
+ "notice": "The minimum amount of votes to approve a transaction"
+ },
+ "setBridge(address)": {
+ "notice": "Sets a new bridge contract"
+ },
+ "version()": {
+ "notice": "Current version of the contract"
+ },
+ "voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)": {
+ "notice": "Vote in a transaction, if it has enough votes it accepts the transfer"
+ },
+ "votes(bytes32,address)": {
+ "notice": "(bytes32) transactionId = keccak256( abi.encodePacked( originalTokenAddress, sender, receiver, amount, blockHash, transactionHash, logIndex ) ) => ( (address) members => (bool) voted )Votes by members by the transaction ID"
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 14589,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 14592,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 14632,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 14878,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 5025,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "bridge",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_contract(IBridge)7435"
+ },
+ {
+ "astId": 5028,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "members",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 5031,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "required",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 5036,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "isMember",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 5043,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "votes",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_mapping(t_bytes32,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 5048,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "processed",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IBridge)7435": {
+ "encoding": "inplace",
+ "label": "contract IBridge",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/FederationProxy.json b/bridge/deployments/kovan/FederationProxy.json
new file mode 100644
index 000000000..c80570aed
--- /dev/null
+++ b/bridge/deployments/kovan/FederationProxy.json
@@ -0,0 +1,257 @@
+{
+ "address": "0xa347438BC288f56Cb6083A79133e70DD2d1f6c2d",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "transactionIndex": 0,
+ "gasUsed": "895606",
+ "logsBloom": "0x00000000000000000001000000008000000100000000000000800000000000000000000000000000000000000000000000000000000000000080000000000000000000800000000000000000000000100001000000000000000000000000000000000000020000000000000000040800000000000000000000000000000000400000000000000000000020008000000000000000000000000000000000000000000000000000000000000000000000000000008000008000000010800000000000000040000000000000000000000100000000000000000000000000000020000010000000000000000000000000000100000000000000000800000000000000",
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4",
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152252,
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "address": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x00000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152252,
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "address": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "topics": [
+ "0x72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c7",
+ "0x0000000000000000000000008f397ff074ff190fc650e5cab4da039a8163e12a"
+ ],
+ "data": "0x",
+ "logIndex": 1,
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152252,
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "address": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "topics": [
+ "0xa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "logIndex": 2,
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152252,
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "address": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "topics": [
+ "0x9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b92551782794497"
+ ],
+ "data": "0x0000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf63",
+ "logIndex": 3,
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4"
+ }
+ ],
+ "blockNumber": 2152252,
+ "cumulativeGasUsed": "895606",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0x9c36A1E78D68417396FE6c715A5515d659973cF6",
+ "0x8c35e166d2dea7a8a28aaea11ad7933cdae4b0ab",
+ "0xc1b4a1e3000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf6300000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000008f397ff074ff190fc650e5cab4da039a8163e12a"
+ ],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"stateVariables\":{\"_ADMIN_SLOT\":{\"details\":\"Storage slot with the admin of the contract. This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0x590a4d952d39a99972cbcb691b472c5d58af9ae8fd142355ad26200affdd2a51\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x0d5202a38732881d576fe3831605fe2633e1bc9f981ebea9c3a368af027e0b71\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x53b00bc48bd4eac1e100195c494267c0ca082bd91ac3018e2ee6155fbcbbb14f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000c9f38038062000c9f83398101604081905262000026916200022e565b8281620000338262000071565b8051156200005457620000528282620000d360201b620002ca1760201c565b505b506200005d9050565b620000688262000102565b5050506200041d565b62000087816200012660201b620002f61760201c565b620000af5760405162461bcd60e51b8152600401620000a69062000347565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6060620000fb838360405180606001604052806027815260200162000c786027913962000130565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b60606200013d8462000126565b6200015c5760405162461bcd60e51b8152600401620000a690620003a4565b600080856001600160a01b031685604051620001799190620002f4565b600060405180830381855af49150503d8060008114620001b6576040519150601f19603f3d011682016040523d82523d6000602084013e620001bb565b606091505b509092509050620001ce828286620001d8565b9695505050505050565b60608315620001e9575081620000fb565b825115620001fa5782518084602001fd5b8160405162461bcd60e51b8152600401620000a6919062000312565b80516001600160a01b03811681146200012b57600080fd5b60008060006060848603121562000243578283fd5b6200024e8462000216565b92506200025e6020850162000216565b60408501519092506001600160401b03808211156200027b578283fd5b818601915086601f8301126200028f578283fd5b8151818111156200029c57fe5b604051601f8201601f191681016020018381118282101715620002bb57fe5b604052818152838201602001891015620002d3578485fd5b620002e6826020830160208701620003ea565b809450505050509250925092565b6000825162000308818460208701620003ea565b9190910192915050565b600060208252825180602084015262000333816040850160208701620003ea565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b8381101562000407578181015183820152602001620003ed565b8381111562000417576000848401525b50505050565b61084b806200042d6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fabbc30a04f636413f38ca4eda3e460473659576ddb6aaf9066d31235c793fc064736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fabbc30a04f636413f38ca4eda3e460473659576ddb6aaf9066d31235c793fc064736f6c63430007060033",
+ "devdoc": {
+ "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.",
+ "events": {
+ "AdminChanged(address,address)": {
+ "details": "Emitted when the admin account has changed."
+ }
+ },
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "constructor": {
+ "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "stateVariables": {
+ "_ADMIN_SLOT": {
+ "details": "Storage slot with the admin of the contract. This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/FederationV2.json b/bridge/deployments/kovan/FederationV2.json
new file mode 100644
index 000000000..00b7cb798
--- /dev/null
+++ b/bridge/deployments/kovan/FederationV2.json
@@ -0,0 +1,905 @@
+{
+ "address": "0xb861A1B6690c0252E6fDb707A06B4aCA46bc9900",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridge",
+ "type": "address"
+ }
+ ],
+ "name": "BridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Executed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "HeartBeat",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Voted",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_MEMBER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_newMember",
+ "type": "address"
+ }
+ ],
+ "name": "addMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridge",
+ "outputs": [
+ {
+ "internalType": "contract IBridge",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "emitHeartbeat",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getMembers",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "getTransactionId",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_members",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isMember",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "members",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "processed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_oldMember",
+ "type": "address"
+ }
+ ],
+ "name": "removeMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ }
+ ],
+ "name": "setBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionWasProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "voteTransaction",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "votes",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x19d064fe48152b878f3d9335a6bce717230a681f843f53eb17cbea04811f51cd",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x9c36A1E78D68417396FE6c715A5515d659973cF6",
+ "transactionIndex": 0,
+ "gasUsed": "1897118",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x8342e7f56adeebb21f7cf5af57f5fc1054b18f7c52c89d995cab2c19280d17e0",
+ "transactionHash": "0x19d064fe48152b878f3d9335a6bce717230a681f843f53eb17cbea04811f51cd",
+ "logs": [],
+ "blockNumber": 2152180,
+ "cumulativeGasUsed": "1897118",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"bridge\",\"type\":\"address\"}],\"name\":\"BridgeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"Executed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fedRskBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fedEthBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"federatorVersion\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"nodeRskInfo\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"nodeEthInfo\",\"type\":\"string\"}],\"name\":\"HeartBeat\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"Voted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MEMBER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newMember\",\"type\":\"address\"}],\"name\":\"addMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contract IBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fedRskBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fedEthBlock\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"federatorVersion\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nodeRskInfo\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nodeEthInfo\",\"type\":\"string\"}],\"name\":\"emitHeartbeat\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMembers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"getTransactionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"hasVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_members\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMember\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"members\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"processed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_oldMember\",\"type\":\"address\"}],\"name\":\"removeMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"name\":\"setBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"transactionWasProcessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"voteTransaction\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"votes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Federation/FederationV2.sol\":\"FederationV2\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Federation/FederationV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n// Upgradables\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\n\\nimport \\\"../interface/IBridge.sol\\\";\\n\\ncontract FederationV2 is Initializable, UpgradableOwnable {\\n uint constant public MAX_MEMBER_COUNT = 50;\\n address constant private NULL_ADDRESS = address(0);\\n\\n IBridge public bridge;\\n address[] public members;\\n uint public required;\\n\\n mapping (address => bool) public isMember;\\n mapping (bytes32 => mapping (address => bool)) public votes;\\n mapping(bytes32 => bool) public processed;\\n\\n event Executed(\\n address indexed federator,\\n bytes32 indexed transactionHash,\\n bytes32 indexed transactionId,\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n uint32 logIndex\\n );\\n event MemberAddition(address indexed member);\\n event MemberRemoval(address indexed member);\\n event RequirementChange(uint required);\\n event BridgeChanged(address bridge);\\n event Voted(\\n address indexed federator,\\n bytes32 indexed transactionHash,\\n bytes32 indexed transactionId,\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n uint32 logIndex\\n );\\n event HeartBeat(\\n address indexed sender,\\n uint256 fedRskBlock,\\n uint256 fedEthBlock,\\n string federatorVersion,\\n string nodeRskInfo,\\n string nodeEthInfo\\n );\\n\\n modifier onlyMember() {\\n require(isMember[_msgSender()], \\\"Federation: Not Federator\\\");\\n _;\\n }\\n\\n modifier validRequirement(uint membersCount, uint _required) {\\n // solium-disable-next-line max-len\\n require(_required <= membersCount && _required != 0 && membersCount != 0, \\\"Federation: Invalid requirements\\\");\\n _;\\n }\\n\\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\\n public validRequirement(_members.length, _required) initializer {\\n UpgradableOwnable.initialize(owner);\\n require(_members.length <= MAX_MEMBER_COUNT, \\\"Federation: Too many members\\\");\\n members = _members;\\n for (uint i = 0; i < _members.length; i++) {\\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \\\"Federation: Invalid members\\\");\\n isMember[_members[i]] = true;\\n emit MemberAddition(_members[i]);\\n }\\n required = _required;\\n emit RequirementChange(required);\\n _setBridge(_bridge);\\n }\\n\\n function version() external pure returns (string memory) {\\n return \\\"v2\\\";\\n }\\n\\n function setBridge(address _bridge) external onlyOwner {\\n _setBridge(_bridge);\\n }\\n\\n function _setBridge(address _bridge) internal {\\n require(_bridge != NULL_ADDRESS, \\\"Federation: Empty bridge\\\");\\n bridge = IBridge(_bridge);\\n emit BridgeChanged(_bridge);\\n }\\n\\n function voteTransaction(\\n address originalTokenAddress,\\n address payable sender,\\n address payable receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n bytes32 transactionHash,\\n uint32 logIndex\\n )\\n public onlyMember returns(bool)\\n {\\n bytes32 transactionId = getTransactionId(\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n transactionHash,\\n logIndex\\n );\\n if (processed[transactionId])\\n return true;\\n\\n if (votes[transactionId][_msgSender()])\\n return true;\\n\\n votes[transactionId][_msgSender()] = true;\\n emit Voted(\\n _msgSender(),\\n transactionHash,\\n transactionId,\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n logIndex\\n );\\n\\n uint transactionCount = getTransactionCount(transactionId);\\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\\n processed[transactionId] = true;\\n bridge.acceptTransfer(\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n transactionHash,\\n logIndex\\n );\\n emit Executed(\\n _msgSender(),\\n transactionHash,\\n transactionId,\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n logIndex\\n );\\n return true;\\n }\\n\\n return true;\\n }\\n\\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\\n uint count = 0;\\n for (uint i = 0; i < members.length; i++) {\\n if (votes[transactionId][members[i]])\\n count += 1;\\n }\\n return count;\\n }\\n\\n function hasVoted(bytes32 transactionId) external view returns(bool)\\n {\\n return votes[transactionId][_msgSender()];\\n }\\n\\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\\n {\\n return processed[transactionId];\\n }\\n\\n function getTransactionId(\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n bytes32 transactionHash,\\n uint32 logIndex\\n ) public pure returns(bytes32)\\n {\\n return keccak256(\\n abi.encodePacked(\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n transactionHash,\\n logIndex\\n )\\n );\\n }\\n\\n function addMember(address _newMember) external onlyOwner\\n {\\n require(_newMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\n require(!isMember[_newMember], \\\"Federation: Member already exists\\\");\\n require(members.length < MAX_MEMBER_COUNT, \\\"Federation: Max members reached\\\");\\n\\n isMember[_newMember] = true;\\n members.push(_newMember);\\n emit MemberAddition(_newMember);\\n }\\n\\n function removeMember(address _oldMember) external onlyOwner\\n {\\n require(_oldMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\n require(isMember[_oldMember], \\\"Federation: Member doesn't exists\\\");\\n require(members.length > 1, \\\"Federation: Can't remove all the members\\\");\\n require(members.length - 1 >= required, \\\"Federation: Can't have less than required members\\\");\\n\\n isMember[_oldMember] = false;\\n for (uint i = 0; i < members.length - 1; i++) {\\n if (members[i] == _oldMember) {\\n members[i] = members[members.length - 1];\\n break;\\n }\\n }\\n members.pop(); // remove an element from the end of the array.\\n emit MemberRemoval(_oldMember);\\n }\\n\\n function getMembers() external view returns (address[] memory)\\n {\\n return members;\\n }\\n\\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\\n {\\n require(_required >= 2, \\\"Federation: Requires at least 2\\\");\\n required = _required;\\n emit RequirementChange(_required);\\n }\\n\\n function emitHeartbeat(\\n uint256 fedRskBlock,\\n uint256 fedEthBlock,\\n string calldata federatorVersion,\\n string calldata nodeRskInfo,\\n string calldata nodeEthInfo\\n ) external onlyMember {\\n emit HeartBeat(\\n _msgSender(),\\n fedRskBlock,\\n fedEthBlock,\\n federatorVersion,\\n nodeRskInfo,\\n nodeEthInfo\\n );\\n }\\n}\",\"keccak256\":\"0x6f9f6a650c694e2a400fa8ea64871fb3aa19eb5610d6a3ea726318c3491c866b\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\ninterface IBridge {\\n\\n struct ClaimData {\\n address payable to;\\n uint256 amount;\\n bytes32 blockHash;\\n bytes32 transactionHash;\\n uint32 logIndex;\\n }\\n\\n function version() external pure returns (string memory);\\n\\n function getFeePercentage() external view returns(uint);\\n\\n /**\\n * ERC-20 tokens approve and transferFrom pattern\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\n */\\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\\n\\n /**\\n * Use network currency and cross it.\\n */\\n function depositTo(address to) external payable;\\n\\n /**\\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\n */\\n function tokensReceived (\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n\\n /**\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\n */\\n function acceptTransfer(\\n address _originalTokenAddress,\\n address payable _from,\\n address payable _to,\\n uint256 _amount,\\n bytes32 _blockHash,\\n bytes32 _transactionHash,\\n uint32 _logIndex\\n ) external;\\n\\n /**\\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\n */\\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n function claimGasless(\\n ClaimData calldata _claimData,\\n address payable _relayer,\\n uint256 _fee,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external returns (uint256 receivedAmount);\\n\\n function getTransactionDataHash(\\n address _to,\\n uint256 _amount,\\n bytes32 _blockHash,\\n bytes32 _transactionHash,\\n uint32 _logIndex\\n ) external returns(bytes32);\\n\\n event Cross(\\n address indexed _tokenAddress,\\n address indexed _from,\\n address indexed _to,\\n uint256 _amount,\\n bytes _userData\\n );\\n event NewSideToken(\\n address indexed _newSideTokenAddress,\\n address indexed _originalTokenAddress,\\n string _newSymbol,\\n uint256 _granularity\\n );\\n event AcceptedCrossTransfer(\\n bytes32 indexed _transactionHash,\\n address indexed _originalTokenAddress,\\n address indexed _to,\\n address _from,\\n uint256 _amount,\\n bytes32 _blockHash,\\n uint256 _logIndex\\n );\\n event FeePercentageChanged(uint256 _amount);\\n event Claimed(\\n bytes32 indexed _transactionHash,\\n address indexed _originalTokenAddress,\\n address indexed _to,\\n address _sender,\\n uint256 _amount,\\n bytes32 _blockHash,\\n uint256 _logIndex,\\n address _reciever,\\n address _relayer,\\n uint256 _fee\\n );\\n}\",\"keccak256\":\"0x188bdd14d3e1d1eaddd5d86a4d957a8c6a7e6c4571058b6db13a974db3ab5f39\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\",\"keccak256\":\"0x3eeeb5ea6bf7d3458bb36acebd4268b406e6a1525e009d4d8a90626c277a37d1\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract UpgradableOwnable is Initializable, Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function initialize(address sender) public initializer {\\n _owner = sender;\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * > Note: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n\\n}\\n\",\"keccak256\":\"0x2e0e58f4a3991801550e6a52512a3c1bbcaa5cb824120c177cb6ec1b4fa0ce97\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50611afa806100206000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063a1fb4acb116100de578063c1f0808a11610097578063dc8452cd11610071578063dc8452cd14610311578063e78cea9214610319578063f2fde38b14610321578063fa6297ba1461033457610173565b8063c1f0808a146102d8578063c4d66de8146102eb578063ca6d56dc146102fe57610173565b8063a1fb4acb14610266578063a230c52414610279578063a93585f01461028c578063b9a3b9dc1461029f578063ba51a6df146102b2578063c1b4a1e3146102c557610173565b8063715018a611610130578063715018a6146102135780638da5cb5b1461021b5780638dd14802146102235780638f32d59b146102365780639386775a1461023e5780639eab52531461025157610173565b80630b1ca49a146101785780631b4613cb1461018d57806335d4aa9e146101b657806354fd4d50146101c95780635daf08ca146101de578063681fc921146101fe575b600080fd5b61018b61018636600461128b565b610347565b005b6101a061019b366004611404565b610555565b6040516101ad9190611661565b60405180910390f35b6101a06101c43660046112ae565b610591565b6101d161080b565b6040516101ad9190611675565b6101f16101ec366004611404565b610827565b6040516101ad919061157c565b610206610851565b6040516101ad919061166c565b61018b610856565b6101f16108c4565b61018b61023136600461128b565b6108d3565b6101a0610903565b6101a061024c36600461141c565b610929565b610259610949565b6040516101ad9190611614565b610206610274366004611404565b6109ab565b6101a061028736600461128b565b610a1c565b6101a061029a366004611404565b610a31565b61018b6102ad36600461144b565b610a46565b61018b6102c0366004611404565b610aeb565b61018b6102d3366004611324565b610bac565b6101a06102e6366004611404565b610e1a565b61018b6102f936600461128b565b610e2f565b61018b61030c36600461128b565b610ef4565b610206611025565b6101f161102b565b61018b61032f36600461128b565b61103a565b6102066103423660046112ae565b611067565b61034f610903565b6103745760405162461bcd60e51b815260040161036b906118f4565b60405180910390fd5b6001600160a01b03811661039a5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff166103d25760405162461bcd60e51b815260040161036b9061176b565b6035546001106103f45760405162461bcd60e51b815260040161036b90611997565b60365460355460001901101561041c5760405162461bcd60e51b815260040161036b906118a3565b6001600160a01b0381166000908152603760205260408120805460ff191690555b603554600019018110156104f057816001600160a01b03166035828154811061046257fe5b6000918252602090912001546001600160a01b031614156104e85760358054600019810190811061048f57fe5b600091825260209091200154603580546001600160a01b0390921691839081106104b557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506104f0565b60010161043d565b5060358054806104fc57fe5b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b60008181526038602052604081208161056c6110a9565b6001600160a01b0316815260208101919091526040016000205460ff1690505b919050565b60006037600061059f6110a9565b6001600160a01b0316815260208101919091526040016000205460ff166105d85760405162461bcd60e51b815260040161036b90611a21565b60006105e989898989898989611067565b60008181526039602052604090205490915060ff161561060d576001915050610800565b6000818152603860205260408120906106246110a9565b6001600160a01b0316815260208101919091526040016000205460ff1615610650576001915050610800565b60008181526038602052604081206001916106696110a9565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055808461069b6110a9565b6001600160a01b03167fd22894491aaa5bb67855bcff4b9730bdf7768be1e25f66ced9a7d7ad623bf2918c8c8c8c8c8b6040516106dd969594939291906115d6565b60405180910390a460006106f0826109ab565b9050603654811015801561070d5750603554600290046001018110155b156107f95760008281526039602052604090819020805460ff191660011790556034549051636a86319160e01b81526001600160a01b0390911690636a86319190610768908d908d908d908d908d908d908d90600401611590565b600060405180830381600087803b15801561078257600080fd5b505af1158015610796573d6000803e3d6000fd5b5050505081856107a46110a9565b6001600160a01b03167fe21e4d3d66ef78424137270e65cfafe938736bb770702ab4fd630383e7820b738d8d8d8d8d8c6040516107e6969594939291906115d6565b60405180910390a4600192505050610800565b6001925050505b979650505050505050565b6040805180820190915260028152613b1960f11b602082015290565b6035818154811061083757600080fd5b6000918252602090912001546001600160a01b0316905081565b603281565b61085e610903565b61087a5760405162461bcd60e51b815260040161036b906118f4565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6108db610903565b6108f75760405162461bcd60e51b815260040161036b906118f4565b610900816110ad565b50565b6033546000906001600160a01b031661091a6110a9565b6001600160a01b031614905090565b603860209081526000928352604080842090915290825290205460ff1681565b606060358054806020026020016040519081016040528092919081815260200182805480156109a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610983575b5050505050905090565b600080805b603554811015610a1557600084815260386020526040812060358054919291849081106109d957fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0d576001820191505b6001016109b0565b5092915050565b60376020526000908152604090205460ff1681565b60009081526039602052604090205460ff1690565b60376000610a526110a9565b6001600160a01b0316815260208101919091526040016000205460ff16610a8b5760405162461bcd60e51b815260040161036b90611a21565b610a936110a9565b6001600160a01b03167fbb00e6cbdccbb5b7549e189335249187223d88583604555326aa1d7ccbcad4428989898989898989604051610ad9989796959493929190611a58565b60405180910390a25050505050505050565b610af3610903565b610b0f5760405162461bcd60e51b815260040161036b906118f4565b60355481818111801590610b2257508015155b8015610b2d57508115155b610b495760405162461bcd60e51b815260040161036b906116c8565b6002831015610b6a5760405162461bcd60e51b815260040161036b90611929565b60368390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610b9f90859061166c565b60405180910390a1505050565b835183818111158015610bbe57508015155b8015610bc957508115155b610be55760405162461bcd60e51b815260040161036b906116c8565b600054610100900460ff1680610bfe575060005460ff16155b610c1a5760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610c45576000805460ff1961ff0019909116610100171660011790555b610c4e84610e2f565b603287511115610c705760405162461bcd60e51b815260040161036b90611734565b8651610c839060359060208a01906111ab565b5060005b8751811015610db85760376000898381518110610ca057fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015610cfa575060006001600160a01b0316888281518110610ce657fe5b60200260200101516001600160a01b031614155b610d165760405162461bcd60e51b815260040161036b906117f4565b6001603760008a8481518110610d2857fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550878181518110610d7357fe5b60200260200101516001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a2600101610c87565b5060368690556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610dee90889061166c565b60405180910390a1610dff856110ad565b8015610e11576000805461ff00191690555b50505050505050565b60396020526000908152604090205460ff1681565b600054610100900460ff1680610e48575060005460ff16155b610e645760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610e8f576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610ef0576000805461ff00191690555b5050565b610efc610903565b610f185760405162461bcd60e51b815260040161036b906118f4565b6001600160a01b038116610f3e5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff1615610f775760405162461bcd60e51b815260040161036b9061182b565b603554603211610f995760405162461bcd60e51b815260040161036b906116fd565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b60365481565b6034546001600160a01b031681565b611042610903565b61105e5760405162461bcd60e51b815260040161036b906118f4565b61090081611129565b600087878787878787604051602001611086979695949392919061151e565b604051602081830303815290604052805190602001209050979650505050505050565b3390565b6001600160a01b0381166110d35760405162461bcd60e51b815260040161036b9061186c565b603480546001600160a01b0319166001600160a01b0383161790556040517f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b925517827944979061111e90839061157c565b60405180910390a150565b6001600160a01b03811661114f5760405162461bcd60e51b815260040161036b906119df565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b828054828255906000526020600020908101928215611200579160200282015b8281111561120057825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906111cb565b5061120c929150611210565b5090565b5b8082111561120c5760008155600101611211565b803561058c81611aaf565b60008083601f840112611241578182fd5b50813567ffffffffffffffff811115611258578182fd5b60208301915083602082850101111561127057600080fd5b9250929050565b803563ffffffff8116811461058c57600080fd5b60006020828403121561129c578081fd5b81356112a781611aaf565b9392505050565b600080600080600080600060e0888a0312156112c8578283fd5b87356112d381611aaf565b965060208801356112e381611aaf565b955060408801356112f381611aaf565b9450606088013593506080880135925060a0880135915061131660c08901611277565b905092959891949750929550565b60008060008060808587031215611339578384fd5b843567ffffffffffffffff80821115611350578586fd5b818701915087601f830112611363578586fd5b813560208282111561137157fe5b8082026040518282820101818110868211171561138a57fe5b604052838152828101945085830182870184018d10156113a8578a8bfd5b8a96505b848710156113d1576113bd81611225565b8652600196909601959483019483016113ac565b5098505088013595506113eb925050604087019050611225565b91506113f960608601611225565b905092959194509250565b600060208284031215611415578081fd5b5035919050565b6000806040838503121561142e578182fd5b82359150602083013561144081611aaf565b809150509250929050565b60008060008060008060008060a0898b031215611466578081fd5b8835975060208901359650604089013567ffffffffffffffff8082111561148b578283fd5b6114978c838d01611230565b909850965060608b01359150808211156114af578283fd5b6114bb8c838d01611230565b909650945060808b01359150808211156114d3578283fd5b506114e08b828c01611230565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b606097881b6bffffffffffffffffffffffff19908116825296881b871660148201529490961b9094166028840152603c830191909152605c820152607c81019190915260e09190911b6001600160e01b031916609c82015260a00190565b6001600160a01b0391909116815260200190565b6001600160a01b03978816815295871660208701529390951660408501526060840191909152608083015260a082019290925263ffffffff90911660c082015260e00190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925263ffffffff90911660a082015260c00190565b6020808252825182820181905260009190848201906040850190845b818110156116555783516001600160a01b031683529284019291840191600101611630565b50909695505050505050565b901515815260200190565b90815260200190565b6000602080835283518082850152825b818110156116a157858101830151858201604001528201611685565b818111156116b25783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f46656465726174696f6e3a20496e76616c696420726571756972656d656e7473604082015260600190565b6020808252601f908201527f46656465726174696f6e3a204d6178206d656d62657273207265616368656400604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20546f6f206d616e79206d656d6265727300000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746040820152607360f81b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252601b908201527f46656465726174696f6e3a20496e76616c6964206d656d626572730000000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746040820152607360f81b606082015260800190565b60208082526018908201527f46656465726174696f6e3a20456d707479206272696467650000000000000000604082015260600190565b60208082526031908201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604082015270207265717569726564206d656d6265727360781b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f46656465726174696f6e3a205265717569726573206174206c65617374203200604082015260600190565b60208082526018908201527f46656465726174696f6e3a20456d707479206d656d6265720000000000000000604082015260600190565b60208082526028908201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604082015267206d656d6265727360c01b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526019908201527f46656465726174696f6e3a204e6f7420466564657261746f7200000000000000604082015260600190565b600089825288602083015260a06040830152611a7860a08301888a6114f4565b8281036060840152611a8b8187896114f4565b90508281036080840152611aa08185876114f4565b9b9a5050505050505050505050565b6001600160a01b038116811461090057600080fdfea2646970667358221220128a4b4f51a83044e466d0c301c3119ae839536443710de99b33113388de820464736f6c63430007060033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101735760003560e01c8063a1fb4acb116100de578063c1f0808a11610097578063dc8452cd11610071578063dc8452cd14610311578063e78cea9214610319578063f2fde38b14610321578063fa6297ba1461033457610173565b8063c1f0808a146102d8578063c4d66de8146102eb578063ca6d56dc146102fe57610173565b8063a1fb4acb14610266578063a230c52414610279578063a93585f01461028c578063b9a3b9dc1461029f578063ba51a6df146102b2578063c1b4a1e3146102c557610173565b8063715018a611610130578063715018a6146102135780638da5cb5b1461021b5780638dd14802146102235780638f32d59b146102365780639386775a1461023e5780639eab52531461025157610173565b80630b1ca49a146101785780631b4613cb1461018d57806335d4aa9e146101b657806354fd4d50146101c95780635daf08ca146101de578063681fc921146101fe575b600080fd5b61018b61018636600461128b565b610347565b005b6101a061019b366004611404565b610555565b6040516101ad9190611661565b60405180910390f35b6101a06101c43660046112ae565b610591565b6101d161080b565b6040516101ad9190611675565b6101f16101ec366004611404565b610827565b6040516101ad919061157c565b610206610851565b6040516101ad919061166c565b61018b610856565b6101f16108c4565b61018b61023136600461128b565b6108d3565b6101a0610903565b6101a061024c36600461141c565b610929565b610259610949565b6040516101ad9190611614565b610206610274366004611404565b6109ab565b6101a061028736600461128b565b610a1c565b6101a061029a366004611404565b610a31565b61018b6102ad36600461144b565b610a46565b61018b6102c0366004611404565b610aeb565b61018b6102d3366004611324565b610bac565b6101a06102e6366004611404565b610e1a565b61018b6102f936600461128b565b610e2f565b61018b61030c36600461128b565b610ef4565b610206611025565b6101f161102b565b61018b61032f36600461128b565b61103a565b6102066103423660046112ae565b611067565b61034f610903565b6103745760405162461bcd60e51b815260040161036b906118f4565b60405180910390fd5b6001600160a01b03811661039a5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff166103d25760405162461bcd60e51b815260040161036b9061176b565b6035546001106103f45760405162461bcd60e51b815260040161036b90611997565b60365460355460001901101561041c5760405162461bcd60e51b815260040161036b906118a3565b6001600160a01b0381166000908152603760205260408120805460ff191690555b603554600019018110156104f057816001600160a01b03166035828154811061046257fe5b6000918252602090912001546001600160a01b031614156104e85760358054600019810190811061048f57fe5b600091825260209091200154603580546001600160a01b0390921691839081106104b557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506104f0565b60010161043d565b5060358054806104fc57fe5b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b60008181526038602052604081208161056c6110a9565b6001600160a01b0316815260208101919091526040016000205460ff1690505b919050565b60006037600061059f6110a9565b6001600160a01b0316815260208101919091526040016000205460ff166105d85760405162461bcd60e51b815260040161036b90611a21565b60006105e989898989898989611067565b60008181526039602052604090205490915060ff161561060d576001915050610800565b6000818152603860205260408120906106246110a9565b6001600160a01b0316815260208101919091526040016000205460ff1615610650576001915050610800565b60008181526038602052604081206001916106696110a9565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055808461069b6110a9565b6001600160a01b03167fd22894491aaa5bb67855bcff4b9730bdf7768be1e25f66ced9a7d7ad623bf2918c8c8c8c8c8b6040516106dd969594939291906115d6565b60405180910390a460006106f0826109ab565b9050603654811015801561070d5750603554600290046001018110155b156107f95760008281526039602052604090819020805460ff191660011790556034549051636a86319160e01b81526001600160a01b0390911690636a86319190610768908d908d908d908d908d908d908d90600401611590565b600060405180830381600087803b15801561078257600080fd5b505af1158015610796573d6000803e3d6000fd5b5050505081856107a46110a9565b6001600160a01b03167fe21e4d3d66ef78424137270e65cfafe938736bb770702ab4fd630383e7820b738d8d8d8d8d8c6040516107e6969594939291906115d6565b60405180910390a4600192505050610800565b6001925050505b979650505050505050565b6040805180820190915260028152613b1960f11b602082015290565b6035818154811061083757600080fd5b6000918252602090912001546001600160a01b0316905081565b603281565b61085e610903565b61087a5760405162461bcd60e51b815260040161036b906118f4565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6108db610903565b6108f75760405162461bcd60e51b815260040161036b906118f4565b610900816110ad565b50565b6033546000906001600160a01b031661091a6110a9565b6001600160a01b031614905090565b603860209081526000928352604080842090915290825290205460ff1681565b606060358054806020026020016040519081016040528092919081815260200182805480156109a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610983575b5050505050905090565b600080805b603554811015610a1557600084815260386020526040812060358054919291849081106109d957fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0d576001820191505b6001016109b0565b5092915050565b60376020526000908152604090205460ff1681565b60009081526039602052604090205460ff1690565b60376000610a526110a9565b6001600160a01b0316815260208101919091526040016000205460ff16610a8b5760405162461bcd60e51b815260040161036b90611a21565b610a936110a9565b6001600160a01b03167fbb00e6cbdccbb5b7549e189335249187223d88583604555326aa1d7ccbcad4428989898989898989604051610ad9989796959493929190611a58565b60405180910390a25050505050505050565b610af3610903565b610b0f5760405162461bcd60e51b815260040161036b906118f4565b60355481818111801590610b2257508015155b8015610b2d57508115155b610b495760405162461bcd60e51b815260040161036b906116c8565b6002831015610b6a5760405162461bcd60e51b815260040161036b90611929565b60368390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610b9f90859061166c565b60405180910390a1505050565b835183818111158015610bbe57508015155b8015610bc957508115155b610be55760405162461bcd60e51b815260040161036b906116c8565b600054610100900460ff1680610bfe575060005460ff16155b610c1a5760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610c45576000805460ff1961ff0019909116610100171660011790555b610c4e84610e2f565b603287511115610c705760405162461bcd60e51b815260040161036b90611734565b8651610c839060359060208a01906111ab565b5060005b8751811015610db85760376000898381518110610ca057fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015610cfa575060006001600160a01b0316888281518110610ce657fe5b60200260200101516001600160a01b031614155b610d165760405162461bcd60e51b815260040161036b906117f4565b6001603760008a8481518110610d2857fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550878181518110610d7357fe5b60200260200101516001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a2600101610c87565b5060368690556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610dee90889061166c565b60405180910390a1610dff856110ad565b8015610e11576000805461ff00191690555b50505050505050565b60396020526000908152604090205460ff1681565b600054610100900460ff1680610e48575060005460ff16155b610e645760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610e8f576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610ef0576000805461ff00191690555b5050565b610efc610903565b610f185760405162461bcd60e51b815260040161036b906118f4565b6001600160a01b038116610f3e5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff1615610f775760405162461bcd60e51b815260040161036b9061182b565b603554603211610f995760405162461bcd60e51b815260040161036b906116fd565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b60365481565b6034546001600160a01b031681565b611042610903565b61105e5760405162461bcd60e51b815260040161036b906118f4565b61090081611129565b600087878787878787604051602001611086979695949392919061151e565b604051602081830303815290604052805190602001209050979650505050505050565b3390565b6001600160a01b0381166110d35760405162461bcd60e51b815260040161036b9061186c565b603480546001600160a01b0319166001600160a01b0383161790556040517f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b925517827944979061111e90839061157c565b60405180910390a150565b6001600160a01b03811661114f5760405162461bcd60e51b815260040161036b906119df565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b828054828255906000526020600020908101928215611200579160200282015b8281111561120057825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906111cb565b5061120c929150611210565b5090565b5b8082111561120c5760008155600101611211565b803561058c81611aaf565b60008083601f840112611241578182fd5b50813567ffffffffffffffff811115611258578182fd5b60208301915083602082850101111561127057600080fd5b9250929050565b803563ffffffff8116811461058c57600080fd5b60006020828403121561129c578081fd5b81356112a781611aaf565b9392505050565b600080600080600080600060e0888a0312156112c8578283fd5b87356112d381611aaf565b965060208801356112e381611aaf565b955060408801356112f381611aaf565b9450606088013593506080880135925060a0880135915061131660c08901611277565b905092959891949750929550565b60008060008060808587031215611339578384fd5b843567ffffffffffffffff80821115611350578586fd5b818701915087601f830112611363578586fd5b813560208282111561137157fe5b8082026040518282820101818110868211171561138a57fe5b604052838152828101945085830182870184018d10156113a8578a8bfd5b8a96505b848710156113d1576113bd81611225565b8652600196909601959483019483016113ac565b5098505088013595506113eb925050604087019050611225565b91506113f960608601611225565b905092959194509250565b600060208284031215611415578081fd5b5035919050565b6000806040838503121561142e578182fd5b82359150602083013561144081611aaf565b809150509250929050565b60008060008060008060008060a0898b031215611466578081fd5b8835975060208901359650604089013567ffffffffffffffff8082111561148b578283fd5b6114978c838d01611230565b909850965060608b01359150808211156114af578283fd5b6114bb8c838d01611230565b909650945060808b01359150808211156114d3578283fd5b506114e08b828c01611230565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b606097881b6bffffffffffffffffffffffff19908116825296881b871660148201529490961b9094166028840152603c830191909152605c820152607c81019190915260e09190911b6001600160e01b031916609c82015260a00190565b6001600160a01b0391909116815260200190565b6001600160a01b03978816815295871660208701529390951660408501526060840191909152608083015260a082019290925263ffffffff90911660c082015260e00190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925263ffffffff90911660a082015260c00190565b6020808252825182820181905260009190848201906040850190845b818110156116555783516001600160a01b031683529284019291840191600101611630565b50909695505050505050565b901515815260200190565b90815260200190565b6000602080835283518082850152825b818110156116a157858101830151858201604001528201611685565b818111156116b25783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f46656465726174696f6e3a20496e76616c696420726571756972656d656e7473604082015260600190565b6020808252601f908201527f46656465726174696f6e3a204d6178206d656d62657273207265616368656400604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20546f6f206d616e79206d656d6265727300000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746040820152607360f81b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252601b908201527f46656465726174696f6e3a20496e76616c6964206d656d626572730000000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746040820152607360f81b606082015260800190565b60208082526018908201527f46656465726174696f6e3a20456d707479206272696467650000000000000000604082015260600190565b60208082526031908201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604082015270207265717569726564206d656d6265727360781b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f46656465726174696f6e3a205265717569726573206174206c65617374203200604082015260600190565b60208082526018908201527f46656465726174696f6e3a20456d707479206d656d6265720000000000000000604082015260600190565b60208082526028908201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604082015267206d656d6265727360c01b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526019908201527f46656465726174696f6e3a204e6f7420466564657261746f7200000000000000604082015260600190565b600089825288602083015260a06040830152611a7860a08301888a6114f4565b8281036060840152611a8b8187896114f4565b90508281036080840152611aa08185876114f4565b9b9a5050505050505050505050565b6001600160a01b038116811461090057600080fdfea2646970667358221220128a4b4f51a83044e466d0c301c3119ae839536443710de99b33113388de820464736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15785,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15788,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15828,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16072,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 5414,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "bridge",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_contract(IBridge)7398"
+ },
+ {
+ "astId": 5417,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "members",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 5419,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "required",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 5423,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "isMember",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 5429,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "votes",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_mapping(t_bytes32,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 5433,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "processed",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IBridge)7398": {
+ "encoding": "inplace",
+ "label": "contract IBridge",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/MultiSigWallet.json b/bridge/deployments/kovan/MultiSigWallet.json
new file mode 100644
index 000000000..aac62bd70
--- /dev/null
+++ b/bridge/deployments/kovan/MultiSigWallet.json
@@ -0,0 +1,843 @@
+{
+ "address": "0x040007b1804ad78a97f541bebed377dcb60e4138",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_owners",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Confirmation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposit",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Execution",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "ExecutionFailure",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnerAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnerRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Revocation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Submission",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_OWNER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "addOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "confirmTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "confirmations",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "executeTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getConfirmationCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "count",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getConfirmations",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "_confirmations",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getOwners",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "pending",
+ "type": "bool"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "count",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "from",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "to",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "pending",
+ "type": "bool"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "name": "getTransactionIds",
+ "outputs": [
+ {
+ "internalType": "uint256[]",
+ "name": "_transactionIds",
+ "type": "uint256[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "isConfirmed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "owners",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "removeOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "replaceOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "revokeConfirmation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "destination",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "submitTransaction",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "transactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "transactions",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "destination",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x3220b2ff54a523efde76537b235936e6dd8382bf5482db2c8433f6bdd558e172",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x6fd64b716Ef38Cbcdc966bfF1517F5B34CaA43F1",
+ "transactionIndex": 0,
+ "gasUsed": "2019878",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x879ccf214b2f36d116c885abe787bd0b2590a85bb773539465443a9750bf9284",
+ "transactionHash": "0x3220b2ff54a523efde76537b235936e6dd8382bf5482db2c8433f6bdd558e172",
+ "logs": [],
+ "blockNumber": 2152170,
+ "cumulativeGasUsed": "2019878",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ [
+ "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8"
+ ],
+ 1
+ ],
+ "solcInputHash": "3b83f9cb61a99eec06a616e65f41d75c",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_owners\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Confirmation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Execution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"ExecutionFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnerAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnerRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Revocation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Submission\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_OWNER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"addOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"confirmTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"confirmations\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"executeTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"getConfirmationCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"getConfirmations\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_confirmations\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pending\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"from\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"to\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"pending\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"name\":\"getTransactionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_transactionIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"isConfirmed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"owners\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"removeOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"replaceOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"revokeConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"submitTransaction\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"transactions\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"author\":\"Stefan George - \",\"kind\":\"dev\",\"methods\":{\"addOwner(address)\":{\"details\":\"Allows to add a new owner. Transaction has to be sent by wallet.\",\"params\":{\"owner\":\"Address of new owner.\"}},\"changeRequirement(uint256)\":{\"details\":\"Allows to change the number of required confirmations. Transaction has to be sent by wallet.\",\"params\":{\"_required\":\"Number of required confirmations.\"}},\"confirmTransaction(uint256)\":{\"details\":\"Allows an owner to confirm a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"constructor\":{\"details\":\"Contract constructor sets initial owners and required number of confirmations.\",\"params\":{\"_owners\":\"List of initial owners.\",\"_required\":\"Number of required confirmations.\"}},\"executeTransaction(uint256)\":{\"details\":\"Allows anyone to execute a confirmed transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"getConfirmationCount(uint256)\":{\"details\":\"Returns number of confirmations of a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"count\":\"Number of confirmations.\"}},\"getConfirmations(uint256)\":{\"details\":\"Returns array with owner addresses, which confirmed transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"_confirmations\":\"Returns array of owner addresses.\"}},\"getOwners()\":{\"details\":\"Returns list of owners.\",\"returns\":{\"_0\":\"List of owner addresses.\"}},\"getTransactionCount(bool,bool)\":{\"details\":\"Returns total number of transactions after filers are applied.\",\"params\":{\"executed\":\"Include executed transactions.\",\"pending\":\"Include pending transactions.\"},\"returns\":{\"count\":\"Total number of transactions after filters are applied.\"}},\"getTransactionIds(uint256,uint256,bool,bool)\":{\"details\":\"Returns list of transaction IDs in defined range.\",\"params\":{\"executed\":\"Include executed transactions.\",\"from\":\"Index start position of transaction array.\",\"pending\":\"Include pending transactions.\",\"to\":\"Index end position of transaction array.\"},\"returns\":{\"_transactionIds\":\"Returns array of transaction IDs.\"}},\"isConfirmed(uint256)\":{\"details\":\"Returns the confirmation status of a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"_0\":\"Confirmation status.\"}},\"removeOwner(address)\":{\"details\":\"Allows to remove an owner. Transaction has to be sent by wallet.\",\"params\":{\"owner\":\"Address of owner.\"}},\"replaceOwner(address,address)\":{\"details\":\"Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\",\"params\":{\"newOwner\":\"Address of new owner.\",\"owner\":\"Address of owner to be replaced.\"}},\"revokeConfirmation(uint256)\":{\"details\":\"Allows an owner to revoke a confirmation for a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"submitTransaction(address,uint256,bytes)\":{\"details\":\"Allows an owner to submit and confirm a transaction.\",\"params\":{\"data\":\"Transaction data payload.\",\"destination\":\"Transaction target address.\",\"value\":\"Transaction ether value.\"},\"returns\":{\"transactionId\":\"Returns transaction ID.\"}}},\"title\":\"Multisignature wallet - Allows multiple parties to agree on transactions before execution.\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/MultiSigWallet.sol\":\"MultiSigWallet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/MultiSigWallet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.\\n/// @author Stefan George - \\ncontract MultiSigWallet {\\n\\n /*\\n * Events\\n */\\n event Confirmation(address indexed sender, uint indexed transactionId);\\n event Revocation(address indexed sender, uint indexed transactionId);\\n event Submission(uint indexed transactionId);\\n event Execution(uint indexed transactionId);\\n event ExecutionFailure(uint indexed transactionId);\\n event Deposit(address indexed sender, uint value);\\n event OwnerAddition(address indexed owner);\\n event OwnerRemoval(address indexed owner);\\n event RequirementChange(uint required);\\n\\n /*\\n * views\\n */\\n uint constant public MAX_OWNER_COUNT = 50;\\n\\n /*\\n * Storage\\n */\\n mapping (uint => Transaction) public transactions;\\n mapping (uint => mapping (address => bool)) public confirmations;\\n mapping (address => bool) public isOwner;\\n address[] public owners;\\n uint public required;\\n uint public transactionCount;\\n\\n struct Transaction {\\n address destination;\\n uint value;\\n bytes data;\\n bool executed;\\n }\\n\\n /*\\n * Modifiers\\n */\\n modifier onlyWallet() {\\n require(msg.sender == address(this), \\\"Only wallet allowed\\\");\\n _;\\n }\\n\\n modifier ownerDoesNotExist(address owner) {\\n require(!isOwner[owner], \\\"The owner already exists\\\");\\n _;\\n }\\n\\n modifier ownerExists(address owner) {\\n require(isOwner[owner], \\\"The owner does not exist\\\");\\n _;\\n }\\n\\n modifier transactionExists(uint transactionId) {\\n require(transactions[transactionId].destination != address(0), \\\"Transaction does not exist\\\");\\n _;\\n }\\n\\n modifier confirmed(uint transactionId, address owner) {\\n require(confirmations[transactionId][owner], \\\"Transaction is not confirmed by owner\\\");\\n _;\\n }\\n\\n modifier notConfirmed(uint transactionId, address owner) {\\n require(!confirmations[transactionId][owner], \\\"Transaction is already confirmed by owner\\\");\\n _;\\n }\\n\\n modifier notExecuted(uint transactionId) {\\n require(!transactions[transactionId].executed, \\\"Transaction was already executed\\\");\\n _;\\n }\\n\\n modifier notNull(address _address) {\\n require(_address != address(0), \\\"Address cannot be empty\\\");\\n _;\\n }\\n\\n modifier validRequirement(uint ownerCount, uint _required) {\\n // solium-disable-next-line max-len\\n require(ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && _required != 0 && ownerCount != 0, \\\"Required value is invalid for the current owners count\\\");\\n _;\\n }\\n\\n /// @dev Fallback function allows to deposit ether.\\n receive ()\\n external\\n payable\\n {\\n if (msg.value > 0)\\n emit Deposit(msg.sender, msg.value);\\n }\\n\\n /*\\n * Public functions\\n */\\n /// @dev Contract constructor sets initial owners and required number of confirmations.\\n /// @param _owners List of initial owners.\\n /// @param _required Number of required confirmations.\\n constructor(address[] memory _owners, uint _required)\\n validRequirement(_owners.length, _required)\\n {\\n for (uint i = 0; i < _owners.length; i++) {\\n require(!isOwner[_owners[i]] && _owners[i] != address(0), \\\"Owners addresses are invalid\\\");\\n isOwner[_owners[i]] = true;\\n }\\n owners = _owners;\\n required = _required;\\n }\\n\\n /// @dev Allows to add a new owner. Transaction has to be sent by wallet.\\n /// @param owner Address of new owner.\\n function addOwner(address owner)\\n public\\n onlyWallet\\n ownerDoesNotExist(owner)\\n notNull(owner)\\n validRequirement(owners.length + 1, required)\\n {\\n isOwner[owner] = true;\\n owners.push(owner);\\n emit OwnerAddition(owner);\\n }\\n\\n /// @dev Allows to remove an owner. Transaction has to be sent by wallet.\\n /// @param owner Address of owner.\\n function removeOwner(address owner)\\n public\\n onlyWallet\\n ownerExists(owner)\\n {\\n isOwner[owner] = false;\\n for (uint i = 0; i < owners.length - 1; i++)\\n if (owners[i] == owner) {\\n owners[i] = owners[owners.length - 1];\\n break;\\n }\\n owners.pop(); // remove an element from the end of the array.\\n if (required > owners.length)\\n changeRequirement(owners.length);\\n emit OwnerRemoval(owner);\\n }\\n\\n /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\\n /// @param owner Address of owner to be replaced.\\n /// @param newOwner Address of new owner.\\n function replaceOwner(address owner, address newOwner)\\n public\\n onlyWallet\\n ownerExists(owner)\\n ownerDoesNotExist(newOwner)\\n {\\n for (uint i = 0; i < owners.length; i++)\\n if (owners[i] == owner) {\\n owners[i] = newOwner;\\n break;\\n }\\n isOwner[owner] = false;\\n isOwner[newOwner] = true;\\n emit OwnerRemoval(owner);\\n emit OwnerAddition(newOwner);\\n }\\n\\n /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.\\n /// @param _required Number of required confirmations.\\n function changeRequirement(uint _required)\\n public\\n onlyWallet\\n validRequirement(owners.length, _required)\\n {\\n required = _required;\\n emit RequirementChange(_required);\\n }\\n\\n /// @dev Allows an owner to submit and confirm a transaction.\\n /// @param destination Transaction target address.\\n /// @param value Transaction ether value.\\n /// @param data Transaction data payload.\\n /// @return transactionId Returns transaction ID.\\n function submitTransaction(address destination, uint value, bytes memory data)\\n public\\n returns (uint transactionId)\\n {\\n transactionId = addTransaction(destination, value, data);\\n confirmTransaction(transactionId);\\n }\\n\\n /// @dev Allows an owner to confirm a transaction.\\n /// @param transactionId Transaction ID.\\n function confirmTransaction(uint transactionId)\\n public\\n ownerExists(msg.sender)\\n transactionExists(transactionId)\\n notConfirmed(transactionId, msg.sender)\\n {\\n confirmations[transactionId][msg.sender] = true;\\n emit Confirmation(msg.sender, transactionId);\\n executeTransaction(transactionId);\\n }\\n\\n /// @dev Allows an owner to revoke a confirmation for a transaction.\\n /// @param transactionId Transaction ID.\\n function revokeConfirmation(uint transactionId)\\n public\\n ownerExists(msg.sender)\\n confirmed(transactionId, msg.sender)\\n notExecuted(transactionId)\\n {\\n confirmations[transactionId][msg.sender] = false;\\n emit Revocation(msg.sender, transactionId);\\n }\\n\\n /// @dev Allows anyone to execute a confirmed transaction.\\n /// @param transactionId Transaction ID.\\n function executeTransaction(uint transactionId)\\n public\\n ownerExists(msg.sender)\\n confirmed(transactionId, msg.sender)\\n notExecuted(transactionId)\\n {\\n if (isConfirmed(transactionId)) {\\n Transaction storage txn = transactions[transactionId];\\n txn.executed = true;\\n if (external_call(txn.destination, txn.value, txn.data.length, txn.data))\\n emit Execution(transactionId);\\n else {\\n emit ExecutionFailure(transactionId);\\n txn.executed = false;\\n }\\n }\\n }\\n\\n // call has been separated into its own function in order to take advantage\\n // of the Solidity's code generator to produce a loop that copies tx.data into memory.\\n function external_call(address destination, uint value, uint dataLength, bytes memory data) internal returns (bool) {\\n bool result;\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n let x := mload(0x40) // \\\"Allocate\\\" memory for output (0x40 is where \\\"free memory\\\" pointer is stored by convention)\\n let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that\\n result := call(\\n sub(gas(), 34710), // 34710 is the value that solidity is currently emitting\\n // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +\\n // callNewAccountGas (25000, in case the destination address does not exist and needs creating)\\n destination,\\n value,\\n d,\\n dataLength, // Size of the input (in bytes) - this is what fixes the padding problem\\n x,\\n 0 // Output is ignored, therefore the output size is zero\\n )\\n }\\n return result;\\n }\\n\\n /// @dev Returns the confirmation status of a transaction.\\n /// @param transactionId Transaction ID.\\n /// @return Confirmation status.\\n function isConfirmed(uint transactionId)\\n public\\n view\\n returns (bool)\\n {\\n uint count = 0;\\n for (uint i = 0; i < owners.length; i++) {\\n if (confirmations[transactionId][owners[i]])\\n count += 1;\\n if (count == required)\\n return true;\\n }\\n return false;\\n }\\n\\n /*\\n * Internal functions\\n */\\n /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.\\n /// @param destination Transaction target address.\\n /// @param value Transaction ether value.\\n /// @param data Transaction data payload.\\n /// @return transactionId Returns transaction ID.\\n function addTransaction(address destination, uint value, bytes memory data)\\n internal\\n notNull(destination)\\n returns (uint transactionId)\\n {\\n transactionId = transactionCount;\\n transactions[transactionId] = Transaction({\\n destination: destination,\\n value: value,\\n data: data,\\n executed: false\\n });\\n transactionCount += 1;\\n emit Submission(transactionId);\\n }\\n\\n /*\\n * Web3 call functions\\n */\\n /// @dev Returns number of confirmations of a transaction.\\n /// @param transactionId Transaction ID.\\n /// @return count Number of confirmations.\\n function getConfirmationCount(uint transactionId)\\n public\\n view\\n returns (uint count)\\n {\\n for (uint i = 0; i < owners.length; i++) {\\n if (confirmations[transactionId][owners[i]]) {\\n count += 1;\\n }\\n }\\n }\\n\\n /// @dev Returns total number of transactions after filers are applied.\\n /// @param pending Include pending transactions.\\n /// @param executed Include executed transactions.\\n /// @return count Total number of transactions after filters are applied.\\n function getTransactionCount(bool pending, bool executed)\\n public\\n view\\n returns (uint count)\\n {\\n for (uint i = 0; i < transactionCount; i++) {\\n if ( pending && !transactions[i].executed || executed && transactions[i].executed) {\\n count += 1;\\n }\\n }\\n }\\n\\n /// @dev Returns list of owners.\\n /// @return List of owner addresses.\\n function getOwners()\\n public\\n view\\n returns (address[] memory)\\n {\\n return owners;\\n }\\n\\n /// @dev Returns array with owner addresses, which confirmed transaction.\\n /// @param transactionId Transaction ID.\\n /// @return _confirmations Returns array of owner addresses.\\n function getConfirmations(uint transactionId)\\n public\\n view\\n returns (address[] memory _confirmations)\\n {\\n address[] memory confirmationsTemp = new address[](owners.length);\\n uint count = 0;\\n uint i;\\n for (i = 0; i < owners.length; i++)\\n if (confirmations[transactionId][owners[i]]) {\\n confirmationsTemp[count] = owners[i];\\n count += 1;\\n }\\n _confirmations = new address[](count);\\n for (i = 0; i < count; i++)\\n _confirmations[i] = confirmationsTemp[i];\\n }\\n\\n /// @dev Returns list of transaction IDs in defined range.\\n /// @param from Index start position of transaction array.\\n /// @param to Index end position of transaction array.\\n /// @param pending Include pending transactions.\\n /// @param executed Include executed transactions.\\n /// @return _transactionIds Returns array of transaction IDs.\\n function getTransactionIds(uint from, uint to, bool pending, bool executed)\\n public\\n view\\n returns (uint[] memory _transactionIds)\\n {\\n uint[] memory transactionIdsTemp = new uint[](transactionCount);\\n uint count = 0;\\n uint i;\\n for (i = 0; i < transactionCount; i++)\\n if ( pending && !transactions[i].executed || executed && transactions[i].executed)\\n {\\n transactionIdsTemp[count] = i;\\n count += 1;\\n }\\n _transactionIds = new uint[](to - from);\\n for (i = from; i < to; i++)\\n _transactionIds[i - from] = transactionIdsTemp[i];\\n }\\n}\",\"keccak256\":\"0x48128d95302f2405b2ca70996b8f12f7d9c52224aadf3b381139246bf2baa31b\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x60806040523480156200001157600080fd5b5060405162001e5838038062001e58833981016040819052620000349162000231565b81518160328211158015620000495750818111155b80156200005557508015155b80156200006157508115155b620000895760405162461bcd60e51b81526004016200008090620002f7565b60405180910390fd5b60005b8451811015620001705760026000868381518110620000a757fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1615801562000103575060006001600160a01b0316858281518110620000ef57fe5b60200260200101516001600160a01b031614155b620001225760405162461bcd60e51b8152600401620000809062000354565b6001600260008784815181106200013557fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff19169115159190911790556001016200008c565b5083516200018690600390602087019062000193565b505050600455506200038b565b828054828255906000526020600020908101928215620001eb579160200282015b82811115620001eb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620001b4565b50620001f9929150620001fd565b5090565b5b80821115620001f95760008155600101620001fe565b80516001600160a01b03811681146200022c57600080fd5b919050565b6000806040838503121562000244578182fd5b82516001600160401b03808211156200025b578384fd5b818501915085601f8301126200026f578384fd5b81516020828211156200027e57fe5b808202604051828282010181811086821117156200029857fe5b604052838152828101945085830182870184018b1015620002b7578889fd5b8896505b84871015620002e457620002cf8162000214565b865260019690960195948301948301620002bb565b5097909101519698969750505050505050565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f7220746860408201527f652063757272656e74206f776e65727320636f756e7400000000000000000000606082015260800190565b6020808252601c908201527f4f776e657273206164647265737365732061726520696e76616c696400000000604082015260600190565b611abd806200039b6000396000f3fe60806040526004361061012e5760003560e01c8063a0e67e2b116100ab578063c01a8c841161006f578063c01a8c84146103a6578063c6427474146103c6578063d74f8edd146103e6578063dc8452cd146103fb578063e20056e614610410578063ee22610b146104305761017d565b8063a0e67e2b14610302578063a8abe69a14610324578063b5dc40c314610351578063b77bf60014610371578063ba51a6df146103865761017d565b806354741525116100f257806354741525146102455780637065cb4814610272578063784547a7146102925780638b51d13f146102b25780639ace38c2146102d25761017d565b8063025e7c2714610182578063173825d9146101b857806320ea8d86146101d85780632f54bf6e146101f85780633411c81c146102255761017d565b3661017d57341561017b57336001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040516101729190611a7e565b60405180910390a25b005b600080fd5b34801561018e57600080fd5b506101a261019d3660046116ba565b610450565b6040516101af919061173f565b60405180910390f35b3480156101c457600080fd5b5061017b6101d3366004611594565b61047a565b3480156101e457600080fd5b5061017b6101f33660046116ba565b61062e565b34801561020457600080fd5b50610218610213366004611594565b61071d565b6040516101af9190611851565b34801561023157600080fd5b506102186102403660046116d2565b610732565b34801561025157600080fd5b50610265610260366004611691565b610752565b6040516101af9190611a7e565b34801561027e57600080fd5b5061017b61028d366004611594565b6107be565b34801561029e57600080fd5b506102186102ad3660046116ba565b61091e565b3480156102be57600080fd5b506102656102cd3660046116ba565b6109a9565b3480156102de57600080fd5b506102f26102ed3660046116ba565b610a18565b6040516101af9493929190611753565b34801561030e57600080fd5b50610317610ad6565b6040516101af91906117cc565b34801561033057600080fd5b5061034461033f3660046116f4565b610b38565b6040516101af9190611819565b34801561035d57600080fd5b5061031761036c3660046116ba565b610c92565b34801561037d57600080fd5b50610265610e37565b34801561039257600080fd5b5061017b6103a13660046116ba565b610e3d565b3480156103b257600080fd5b5061017b6103c13660046116ba565b610ee5565b3480156103d257600080fd5b506102656103e13660046115e0565b610fe5565b3480156103f257600080fd5b50610265611004565b34801561040757600080fd5b50610265611009565b34801561041c57600080fd5b5061017b61042b3660046115ae565b61100f565b34801561043c57600080fd5b5061017b61044b3660046116ba565b6111c5565b6003818154811061046057600080fd5b6000918252602090912001546001600160a01b0316905081565b3330146104a25760405162461bcd60e51b815260040161049990611977565b60405180910390fd5b6001600160a01b038116600090815260026020526040902054819060ff166104dc5760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b0382166000908152600260205260408120805460ff191690555b600354600019018110156105b057826001600160a01b03166003828154811061052257fe5b6000918252602090912001546001600160a01b031614156105a85760038054600019810190811061054f57fe5b600091825260209091200154600380546001600160a01b03909216918390811061057557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506105b0565b6001016104fd565b5060038054806105bc57fe5b600082815260209020810160001990810180546001600160a01b031916905501905560035460045411156105f6576003546105f690610e3d565b6040516001600160a01b038316907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a25050565b3360008181526002602052604090205460ff1661065d5760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff1661069a5760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156106ce5760405162461bcd60e51b815260040161049990611a49565b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b6005548110156107b75783801561077f575060008181526020819052604090206003015460ff16155b806107a357508280156107a3575060008181526020819052604090206003015460ff165b156107af576001820191505b600101610756565b5092915050565b3330146107dd5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038116600090815260026020526040902054819060ff16156108185760405162461bcd60e51b815260040161049990611a12565b816001600160a01b03811661083f5760405162461bcd60e51b815260040161049990611940565b6003805490506001016004546032821115801561085c5750818111155b801561086757508015155b801561087257508115155b61088e5760405162461bcd60e51b8152600401610499906118a5565b6001600160a01b038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b60035481101561099d576000848152600160205260408120600380549192918490811061094c57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610980576001820191505b600454821415610995576001925050506109a4565b600101610923565b5060009150505b919050565b6000805b600354811015610a1257600083815260016020526040812060038054919291849081106109d657fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0a576001820191505b6001016109ad565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f81018890048802840188019096528583526001600160a01b0390931695909491929190830182828015610ac35780601f10610a9857610100808354040283529160200191610ac3565b820191906000526020600020905b815481529060010190602001808311610aa657829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610b2e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b10575b5050505050905090565b6060600060055467ffffffffffffffff81118015610b5557600080fd5b50604051908082528060200260200182016040528015610b7f578160200160208202803683370190505b5090506000805b600554811015610c0057858015610baf575060008181526020819052604090206003015460ff16155b80610bd35750848015610bd3575060008181526020819052604090206003015460ff165b15610bf85780838381518110610be557fe5b6020026020010181815250506001820191505b600101610b86565b87870367ffffffffffffffff81118015610c1957600080fd5b50604051908082528060200260200182016040528015610c43578160200160208202803683370190505b5093508790505b86811015610c8757828181518110610c5e57fe5b60200260200101518489830381518110610c7457fe5b6020908102919091010152600101610c4a565b505050949350505050565b60035460609060009067ffffffffffffffff81118015610cb157600080fd5b50604051908082528060200260200182016040528015610cdb578160200160208202803683370190505b5090506000805b600354811015610d9e5760008581526001602052604081206003805491929184908110610d0b57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610d965760038181548110610d4557fe5b9060005260206000200160009054906101000a90046001600160a01b0316838381518110610d6f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001820191505b600101610ce2565b8167ffffffffffffffff81118015610db557600080fd5b50604051908082528060200260200182016040528015610ddf578160200160208202803683370190505b509350600090505b81811015610e2f57828181518110610dfb57fe5b6020026020010151848281518110610e0f57fe5b6001600160a01b0390921660209283029190910190910152600101610de7565b505050919050565b60055481565b333014610e5c5760405162461bcd60e51b815260040161049990611977565b6003548160328211801590610e715750818111155b8015610e7c57508015155b8015610e8757508115155b610ea35760405162461bcd60e51b8152600401610499906118a5565b60048390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610ed8908590611a7e565b60405180910390a1505050565b3360008181526002602052604090205460ff16610f145760405162461bcd60e51b8152600401610499906119a4565b60008281526020819052604090205482906001600160a01b0316610f4a5760405162461bcd60e51b8152600401610499906119db565b60008381526001602090815260408083203380855292529091205484919060ff1615610f885760405162461bcd60e51b81526004016104999061185c565b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3610fde856111c5565b5050505050565b6000610ff28484846113b5565b9050610ffd81610ee5565b9392505050565b603281565b60045481565b33301461102e5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038216600090815260026020526040902054829060ff166110685760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b038216600090815260026020526040902054829060ff16156110a35760405162461bcd60e51b815260040161049990611a12565b60005b60035481101561112b57846001600160a01b0316600382815481106110c757fe5b6000918252602090912001546001600160a01b031614156111235783600382815481106110f057fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061112b565b6001016110a6565b506001600160a01b03808516600081815260026020526040808220805460ff1990811690915593871682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a26040516001600160a01b038416907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a250505050565b3360008181526002602052604090205460ff166111f45760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff166112315760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156112655760405162461bcd60e51b815260040161049990611a49565b61126e8561091e565b15610fde576000858152602081815260409182902060038101805460ff19166001908117909155815481830154600280850180548851601f600019978316156101000297909701909116929092049485018790048702820187019097528381529395611340956001600160a01b039093169491939283908301828280156113365780601f1061130b57610100808354040283529160200191611336565b820191906000526020600020905b81548152906001019060200180831161131957829003601f168201915b50505050506114a9565b156113755760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26113ad565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038101805460ff191690555b505050505050565b6000836001600160a01b0381166113de5760405162461bcd60e51b815260040161049990611940565b600554604080516080810182526001600160a01b038881168252602080830189815283850189815260006060860181905287815280845295909520845181546001600160a01b031916941693909317835551600183015592518051949650919390926114519260028501929101906114cc565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b6000806040516020840160008287838a8c6187965a03f198975050505050505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826115025760008555611548565b82601f1061151b57805160ff1916838001178555611548565b82800160010185558215611548579182015b8281111561154857825182559160200191906001019061152d565b50611554929150611558565b5090565b5b808211156115545760008155600101611559565b80356001600160a01b03811681146109a457600080fd5b803580151581146109a457600080fd5b6000602082840312156115a5578081fd5b610ffd8261156d565b600080604083850312156115c0578081fd5b6115c98361156d565b91506115d76020840161156d565b90509250929050565b6000806000606084860312156115f4578081fd5b6115fd8461156d565b92506020808501359250604085013567ffffffffffffffff80821115611621578384fd5b818701915087601f830112611634578384fd5b81358181111561164057fe5b604051601f8201601f191681018501838111828210171561165d57fe5b60405281815283820185018a1015611673578586fd5b81858501868301378585838301015280955050505050509250925092565b600080604083850312156116a3578182fd5b6116ac83611584565b91506115d760208401611584565b6000602082840312156116cb578081fd5b5035919050565b600080604083850312156116e4578182fd5b823591506115d76020840161156d565b60008060008060808587031215611709578081fd5b843593506020850135925061172060408601611584565b915061172e60608601611584565b905092959194509250565b15159052565b6001600160a01b0391909116815260200190565b600060018060a01b038616825260208581840152608060408401528451806080850152825b818110156117945786810183015185820160a001528201611778565b818111156117a5578360a083870101525b50601f01601f1916830160a00191506117c390506060830184611739565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d5783516001600160a01b0316835292840192918401916001016117e8565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d57835183529284019291840191600101611835565b901515815260200190565b60208082526029908201527f5472616e73616374696f6e20697320616c726561647920636f6e6669726d656460408201526810313c9037bbb732b960b91b606082015260800190565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f72207468604082015275194818dd5c9c995b9d081bdddb995c9cc818dbdd5b9d60521b606082015260800190565b60208082526025908201527f5472616e73616374696f6e206973206e6f7420636f6e6669726d65642062792060408201526437bbb732b960d91b606082015260800190565b60208082526017908201527f416464726573732063616e6e6f7420626520656d707479000000000000000000604082015260600190565b60208082526013908201527213db9b1e481dd85b1b195d08185b1b1bddd959606a1b604082015260600190565b60208082526018908201527f546865206f776e657220646f6573206e6f742065786973740000000000000000604082015260600190565b6020808252601a908201527f5472616e73616374696f6e20646f6573206e6f74206578697374000000000000604082015260600190565b60208082526018908201527f546865206f776e657220616c7265616479206578697374730000000000000000604082015260600190565b6020808252818101527f5472616e73616374696f6e2077617320616c7265616479206578656375746564604082015260600190565b9081526020019056fea264697066735822122062c2739111652d12775c1bfdbf576765e75e1ef9880050cc336a31164f199d6c64736f6c63430007060033",
+ "deployedBytecode": "0x60806040526004361061012e5760003560e01c8063a0e67e2b116100ab578063c01a8c841161006f578063c01a8c84146103a6578063c6427474146103c6578063d74f8edd146103e6578063dc8452cd146103fb578063e20056e614610410578063ee22610b146104305761017d565b8063a0e67e2b14610302578063a8abe69a14610324578063b5dc40c314610351578063b77bf60014610371578063ba51a6df146103865761017d565b806354741525116100f257806354741525146102455780637065cb4814610272578063784547a7146102925780638b51d13f146102b25780639ace38c2146102d25761017d565b8063025e7c2714610182578063173825d9146101b857806320ea8d86146101d85780632f54bf6e146101f85780633411c81c146102255761017d565b3661017d57341561017b57336001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040516101729190611a7e565b60405180910390a25b005b600080fd5b34801561018e57600080fd5b506101a261019d3660046116ba565b610450565b6040516101af919061173f565b60405180910390f35b3480156101c457600080fd5b5061017b6101d3366004611594565b61047a565b3480156101e457600080fd5b5061017b6101f33660046116ba565b61062e565b34801561020457600080fd5b50610218610213366004611594565b61071d565b6040516101af9190611851565b34801561023157600080fd5b506102186102403660046116d2565b610732565b34801561025157600080fd5b50610265610260366004611691565b610752565b6040516101af9190611a7e565b34801561027e57600080fd5b5061017b61028d366004611594565b6107be565b34801561029e57600080fd5b506102186102ad3660046116ba565b61091e565b3480156102be57600080fd5b506102656102cd3660046116ba565b6109a9565b3480156102de57600080fd5b506102f26102ed3660046116ba565b610a18565b6040516101af9493929190611753565b34801561030e57600080fd5b50610317610ad6565b6040516101af91906117cc565b34801561033057600080fd5b5061034461033f3660046116f4565b610b38565b6040516101af9190611819565b34801561035d57600080fd5b5061031761036c3660046116ba565b610c92565b34801561037d57600080fd5b50610265610e37565b34801561039257600080fd5b5061017b6103a13660046116ba565b610e3d565b3480156103b257600080fd5b5061017b6103c13660046116ba565b610ee5565b3480156103d257600080fd5b506102656103e13660046115e0565b610fe5565b3480156103f257600080fd5b50610265611004565b34801561040757600080fd5b50610265611009565b34801561041c57600080fd5b5061017b61042b3660046115ae565b61100f565b34801561043c57600080fd5b5061017b61044b3660046116ba565b6111c5565b6003818154811061046057600080fd5b6000918252602090912001546001600160a01b0316905081565b3330146104a25760405162461bcd60e51b815260040161049990611977565b60405180910390fd5b6001600160a01b038116600090815260026020526040902054819060ff166104dc5760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b0382166000908152600260205260408120805460ff191690555b600354600019018110156105b057826001600160a01b03166003828154811061052257fe5b6000918252602090912001546001600160a01b031614156105a85760038054600019810190811061054f57fe5b600091825260209091200154600380546001600160a01b03909216918390811061057557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506105b0565b6001016104fd565b5060038054806105bc57fe5b600082815260209020810160001990810180546001600160a01b031916905501905560035460045411156105f6576003546105f690610e3d565b6040516001600160a01b038316907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a25050565b3360008181526002602052604090205460ff1661065d5760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff1661069a5760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156106ce5760405162461bcd60e51b815260040161049990611a49565b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b6005548110156107b75783801561077f575060008181526020819052604090206003015460ff16155b806107a357508280156107a3575060008181526020819052604090206003015460ff165b156107af576001820191505b600101610756565b5092915050565b3330146107dd5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038116600090815260026020526040902054819060ff16156108185760405162461bcd60e51b815260040161049990611a12565b816001600160a01b03811661083f5760405162461bcd60e51b815260040161049990611940565b6003805490506001016004546032821115801561085c5750818111155b801561086757508015155b801561087257508115155b61088e5760405162461bcd60e51b8152600401610499906118a5565b6001600160a01b038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b60035481101561099d576000848152600160205260408120600380549192918490811061094c57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610980576001820191505b600454821415610995576001925050506109a4565b600101610923565b5060009150505b919050565b6000805b600354811015610a1257600083815260016020526040812060038054919291849081106109d657fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0a576001820191505b6001016109ad565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f81018890048802840188019096528583526001600160a01b0390931695909491929190830182828015610ac35780601f10610a9857610100808354040283529160200191610ac3565b820191906000526020600020905b815481529060010190602001808311610aa657829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610b2e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b10575b5050505050905090565b6060600060055467ffffffffffffffff81118015610b5557600080fd5b50604051908082528060200260200182016040528015610b7f578160200160208202803683370190505b5090506000805b600554811015610c0057858015610baf575060008181526020819052604090206003015460ff16155b80610bd35750848015610bd3575060008181526020819052604090206003015460ff165b15610bf85780838381518110610be557fe5b6020026020010181815250506001820191505b600101610b86565b87870367ffffffffffffffff81118015610c1957600080fd5b50604051908082528060200260200182016040528015610c43578160200160208202803683370190505b5093508790505b86811015610c8757828181518110610c5e57fe5b60200260200101518489830381518110610c7457fe5b6020908102919091010152600101610c4a565b505050949350505050565b60035460609060009067ffffffffffffffff81118015610cb157600080fd5b50604051908082528060200260200182016040528015610cdb578160200160208202803683370190505b5090506000805b600354811015610d9e5760008581526001602052604081206003805491929184908110610d0b57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610d965760038181548110610d4557fe5b9060005260206000200160009054906101000a90046001600160a01b0316838381518110610d6f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001820191505b600101610ce2565b8167ffffffffffffffff81118015610db557600080fd5b50604051908082528060200260200182016040528015610ddf578160200160208202803683370190505b509350600090505b81811015610e2f57828181518110610dfb57fe5b6020026020010151848281518110610e0f57fe5b6001600160a01b0390921660209283029190910190910152600101610de7565b505050919050565b60055481565b333014610e5c5760405162461bcd60e51b815260040161049990611977565b6003548160328211801590610e715750818111155b8015610e7c57508015155b8015610e8757508115155b610ea35760405162461bcd60e51b8152600401610499906118a5565b60048390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610ed8908590611a7e565b60405180910390a1505050565b3360008181526002602052604090205460ff16610f145760405162461bcd60e51b8152600401610499906119a4565b60008281526020819052604090205482906001600160a01b0316610f4a5760405162461bcd60e51b8152600401610499906119db565b60008381526001602090815260408083203380855292529091205484919060ff1615610f885760405162461bcd60e51b81526004016104999061185c565b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3610fde856111c5565b5050505050565b6000610ff28484846113b5565b9050610ffd81610ee5565b9392505050565b603281565b60045481565b33301461102e5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038216600090815260026020526040902054829060ff166110685760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b038216600090815260026020526040902054829060ff16156110a35760405162461bcd60e51b815260040161049990611a12565b60005b60035481101561112b57846001600160a01b0316600382815481106110c757fe5b6000918252602090912001546001600160a01b031614156111235783600382815481106110f057fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061112b565b6001016110a6565b506001600160a01b03808516600081815260026020526040808220805460ff1990811690915593871682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a26040516001600160a01b038416907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a250505050565b3360008181526002602052604090205460ff166111f45760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff166112315760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156112655760405162461bcd60e51b815260040161049990611a49565b61126e8561091e565b15610fde576000858152602081815260409182902060038101805460ff19166001908117909155815481830154600280850180548851601f600019978316156101000297909701909116929092049485018790048702820187019097528381529395611340956001600160a01b039093169491939283908301828280156113365780601f1061130b57610100808354040283529160200191611336565b820191906000526020600020905b81548152906001019060200180831161131957829003601f168201915b50505050506114a9565b156113755760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26113ad565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038101805460ff191690555b505050505050565b6000836001600160a01b0381166113de5760405162461bcd60e51b815260040161049990611940565b600554604080516080810182526001600160a01b038881168252602080830189815283850189815260006060860181905287815280845295909520845181546001600160a01b031916941693909317835551600183015592518051949650919390926114519260028501929101906114cc565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b6000806040516020840160008287838a8c6187965a03f198975050505050505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826115025760008555611548565b82601f1061151b57805160ff1916838001178555611548565b82800160010185558215611548579182015b8281111561154857825182559160200191906001019061152d565b50611554929150611558565b5090565b5b808211156115545760008155600101611559565b80356001600160a01b03811681146109a457600080fd5b803580151581146109a457600080fd5b6000602082840312156115a5578081fd5b610ffd8261156d565b600080604083850312156115c0578081fd5b6115c98361156d565b91506115d76020840161156d565b90509250929050565b6000806000606084860312156115f4578081fd5b6115fd8461156d565b92506020808501359250604085013567ffffffffffffffff80821115611621578384fd5b818701915087601f830112611634578384fd5b81358181111561164057fe5b604051601f8201601f191681018501838111828210171561165d57fe5b60405281815283820185018a1015611673578586fd5b81858501868301378585838301015280955050505050509250925092565b600080604083850312156116a3578182fd5b6116ac83611584565b91506115d760208401611584565b6000602082840312156116cb578081fd5b5035919050565b600080604083850312156116e4578182fd5b823591506115d76020840161156d565b60008060008060808587031215611709578081fd5b843593506020850135925061172060408601611584565b915061172e60608601611584565b905092959194509250565b15159052565b6001600160a01b0391909116815260200190565b600060018060a01b038616825260208581840152608060408401528451806080850152825b818110156117945786810183015185820160a001528201611778565b818111156117a5578360a083870101525b50601f01601f1916830160a00191506117c390506060830184611739565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d5783516001600160a01b0316835292840192918401916001016117e8565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d57835183529284019291840191600101611835565b901515815260200190565b60208082526029908201527f5472616e73616374696f6e20697320616c726561647920636f6e6669726d656460408201526810313c9037bbb732b960b91b606082015260800190565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f72207468604082015275194818dd5c9c995b9d081bdddb995c9cc818dbdd5b9d60521b606082015260800190565b60208082526025908201527f5472616e73616374696f6e206973206e6f7420636f6e6669726d65642062792060408201526437bbb732b960d91b606082015260800190565b60208082526017908201527f416464726573732063616e6e6f7420626520656d707479000000000000000000604082015260600190565b60208082526013908201527213db9b1e481dd85b1b195d08185b1b1bddd959606a1b604082015260600190565b60208082526018908201527f546865206f776e657220646f6573206e6f742065786973740000000000000000604082015260600190565b6020808252601a908201527f5472616e73616374696f6e20646f6573206e6f74206578697374000000000000604082015260600190565b60208082526018908201527f546865206f776e657220616c7265616479206578697374730000000000000000604082015260600190565b6020808252818101527f5472616e73616374696f6e2077617320616c7265616479206578656375746564604082015260600190565b9081526020019056fea264697066735822122062c2739111652d12775c1bfdbf576765e75e1ef9880050cc336a31164f199d6c64736f6c63430007060033",
+ "devdoc": {
+ "author": "Stefan George - ",
+ "kind": "dev",
+ "methods": {
+ "addOwner(address)": {
+ "details": "Allows to add a new owner. Transaction has to be sent by wallet.",
+ "params": {
+ "owner": "Address of new owner."
+ }
+ },
+ "changeRequirement(uint256)": {
+ "details": "Allows to change the number of required confirmations. Transaction has to be sent by wallet.",
+ "params": {
+ "_required": "Number of required confirmations."
+ }
+ },
+ "confirmTransaction(uint256)": {
+ "details": "Allows an owner to confirm a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "constructor": {
+ "details": "Contract constructor sets initial owners and required number of confirmations.",
+ "params": {
+ "_owners": "List of initial owners.",
+ "_required": "Number of required confirmations."
+ }
+ },
+ "executeTransaction(uint256)": {
+ "details": "Allows anyone to execute a confirmed transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "getConfirmationCount(uint256)": {
+ "details": "Returns number of confirmations of a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "count": "Number of confirmations."
+ }
+ },
+ "getConfirmations(uint256)": {
+ "details": "Returns array with owner addresses, which confirmed transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "_confirmations": "Returns array of owner addresses."
+ }
+ },
+ "getOwners()": {
+ "details": "Returns list of owners.",
+ "returns": {
+ "_0": "List of owner addresses."
+ }
+ },
+ "getTransactionCount(bool,bool)": {
+ "details": "Returns total number of transactions after filers are applied.",
+ "params": {
+ "executed": "Include executed transactions.",
+ "pending": "Include pending transactions."
+ },
+ "returns": {
+ "count": "Total number of transactions after filters are applied."
+ }
+ },
+ "getTransactionIds(uint256,uint256,bool,bool)": {
+ "details": "Returns list of transaction IDs in defined range.",
+ "params": {
+ "executed": "Include executed transactions.",
+ "from": "Index start position of transaction array.",
+ "pending": "Include pending transactions.",
+ "to": "Index end position of transaction array."
+ },
+ "returns": {
+ "_transactionIds": "Returns array of transaction IDs."
+ }
+ },
+ "isConfirmed(uint256)": {
+ "details": "Returns the confirmation status of a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "_0": "Confirmation status."
+ }
+ },
+ "removeOwner(address)": {
+ "details": "Allows to remove an owner. Transaction has to be sent by wallet.",
+ "params": {
+ "owner": "Address of owner."
+ }
+ },
+ "replaceOwner(address,address)": {
+ "details": "Allows to replace an owner with a new owner. Transaction has to be sent by wallet.",
+ "params": {
+ "newOwner": "Address of new owner.",
+ "owner": "Address of owner to be replaced."
+ }
+ },
+ "revokeConfirmation(uint256)": {
+ "details": "Allows an owner to revoke a confirmation for a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "submitTransaction(address,uint256,bytes)": {
+ "details": "Allows an owner to submit and confirm a transaction.",
+ "params": {
+ "data": "Transaction data payload.",
+ "destination": "Transaction target address.",
+ "value": "Transaction ether value."
+ },
+ "returns": {
+ "transactionId": "Returns transaction ID."
+ }
+ }
+ },
+ "title": "Multisignature wallet - Allows multiple parties to agree on transactions before execution.",
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 52,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "transactions",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_uint256,t_struct(Transaction)78_storage)"
+ },
+ {
+ "astId": 58,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "confirmations",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_mapping(t_uint256,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 62,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "isOwner",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 65,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "owners",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 67,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "required",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 69,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "transactionCount",
+ "offset": 0,
+ "slot": "5",
+ "type": "t_uint256"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes_storage": {
+ "encoding": "bytes",
+ "label": "bytes",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_uint256,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_mapping(t_uint256,t_struct(Transaction)78_storage)": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => struct MultiSigWallet.Transaction)",
+ "numberOfBytes": "32",
+ "value": "t_struct(Transaction)78_storage"
+ },
+ "t_struct(Transaction)78_storage": {
+ "encoding": "inplace",
+ "label": "struct MultiSigWallet.Transaction",
+ "members": [
+ {
+ "astId": 71,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "destination",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ },
+ {
+ "astId": 73,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "value",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 75,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "data",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_bytes_storage"
+ },
+ {
+ "astId": 77,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "executed",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_bool"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/ProxyAdmin.json b/bridge/deployments/kovan/ProxyAdmin.json
new file mode 100644
index 000000000..d781b0e59
--- /dev/null
+++ b/bridge/deployments/kovan/ProxyAdmin.json
@@ -0,0 +1,261 @@
+{
+ "address": "0xe4d351911a6d599f91a3db1843e2ecb0f851e7e6",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeProxyAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ }
+ ],
+ "name": "getProxyAdmin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ }
+ ],
+ "name": "getProxyImplementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgrade",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xccb5efec2a755bdacf9df4f51f512e23701a31e89a59c11fc6bb0f6134c34a2d",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x826e131ADF0fFc77308540966d757B466fa72FFd",
+ "transactionIndex": 0,
+ "gasUsed": "601344",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000100000000000000020000020000000000000800000000000000000000000000000000400000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000020000000000000200000000000000000000000000000000000040000000000000000",
+ "blockHash": "0x23d2689ca13007d1c676dd0836055c3198c867cd10fc217c7808e956e6004304",
+ "transactionHash": "0xccb5efec2a755bdacf9df4f51f512e23701a31e89a59c11fc6bb0f6134c34a2d",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152171,
+ "transactionHash": "0xccb5efec2a755bdacf9df4f51f512e23701a31e89a59c11fc6bb0f6134c34a2d",
+ "address": "0x826e131ADF0fFc77308540966d757B466fa72FFd",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x23d2689ca13007d1c676dd0836055c3198c867cd10fc217c7808e956e6004304"
+ }
+ ],
+ "blockNumber": 2152171,
+ "cumulativeGasUsed": "601344",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\",\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"details\":\"Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`.\"},\"getProxyAdmin(address)\":{\"details\":\"Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"getProxyImplementation(address)\":{\"details\":\"Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"details\":\"Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`.\"},\"upgradeAndCall(address,address,bytes)\":{\"details\":\"Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol\":\"ProxyAdmin\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../GSN/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () {\\n _owner = _msgSender();\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x82fe89d36187df48c5e24e6ca1cf0566f4b0c0a3bd8da835ab64100e28d21b62\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0x590a4d952d39a99972cbcb691b472c5d58af9ae8fd142355ad26200affdd2a51\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../../ownership/Ownable.sol\\\";\\nimport \\\"./TransparentUpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\\n */\\ncontract ProxyAdmin is Ownable {\\n\\n /**\\n * @dev Returns the current implementation of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"implementation()\\\")) == 0x5c60da1b\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"5c60da1b\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Returns the current admin of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"admin()\\\")) == 0xf851a440\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"f851a440\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Changes the admin of `proxy` to `newAdmin`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the current admin of `proxy`.\\n */\\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\\n proxy.changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\\n proxy.upgradeTo(implementation);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\\n }\\n}\\n\",\"keccak256\":\"0x808ad1c30093ccfc011509c642615a9bad84d0e1eced5327fe50d3ec145a9899\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x0d5202a38732881d576fe3831605fe2633e1bc9f981ebea9c3a368af027e0b71\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x53b00bc48bd4eac1e100195c494267c0ca082bd91ac3018e2ee6155fbcbbb14f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50610019610066565b600080546001600160a01b0319166001600160a01b03928316178082556040519216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a361006a565b3390565b61079e806100796000396000f3fe6080604052600436106100865760003560e01c80638f32d59b116100595780638f32d59b1461010d5780639623609d1461012f57806399a88ec414610142578063f2fde38b14610162578063f3b7dead1461018257610086565b8063204e1c7a1461008b578063715018a6146100c15780637eff275e146100d85780638da5cb5b146100f8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610503565b6101a2565b6040516100b89190610656565b60405180910390f35b3480156100cd57600080fd5b506100d6610228565b005b3480156100e457600080fd5b506100d66100f3366004610542565b61029f565b34801561010457600080fd5b506100ab610325565b34801561011957600080fd5b50610122610334565b6040516100b891906106cd565b6100d661013d36600461057a565b610358565b34801561014e57600080fd5b506100d661015d366004610542565b6103e3565b34801561016e57600080fd5b506100d661017d366004610503565b610433565b34801561018e57600080fd5b506100ab61019d366004610503565b610463565b6000806000836001600160a01b03166040516101bd90610636565b600060405180830381855afa9150503d80600081146101f8576040519150601f19603f3d011682016040523d82523d6000602084013e6101fd565b606091505b50915091508161020c57600080fd5b808060200190518101906102209190610526565b949350505050565b610230610334565b6102555760405162461bcd60e51b815260040161024c9061071e565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6102a7610334565b6102c35760405162461bcd60e51b815260040161024c9061071e565b6040516308f2839760e41b81526001600160a01b03831690638f283970906102ef908490600401610656565b600060405180830381600087803b15801561030957600080fd5b505af115801561031d573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031690565b600080546001600160a01b031661034961047e565b6001600160a01b031614905090565b610360610334565b61037c5760405162461bcd60e51b815260040161024c9061071e565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906103ac908690869060040161066a565b6000604051808303818588803b1580156103c557600080fd5b505af11580156103d9573d6000803e3d6000fd5b5050505050505050565b6103eb610334565b6104075760405162461bcd60e51b815260040161024c9061071e565b604051631b2ce7f360e11b81526001600160a01b03831690633659cfe6906102ef908490600401610656565b61043b610334565b6104575760405162461bcd60e51b815260040161024c9061071e565b61046081610482565b50565b6000806000836001600160a01b03166040516101bd90610646565b3390565b6001600160a01b0381166104a85760405162461bcd60e51b815260040161024c906106d8565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600060208284031215610514578081fd5b813561051f81610753565b9392505050565b600060208284031215610537578081fd5b815161051f81610753565b60008060408385031215610554578081fd5b823561055f81610753565b9150602083013561056f81610753565b809150509250929050565b60008060006060848603121561058e578081fd5b833561059981610753565b92506020848101356105aa81610753565b9250604085013567ffffffffffffffff808211156105c6578384fd5b818701915087601f8301126105d9578384fd5b8135818111156105e557fe5b604051601f8201601f191681018501838111828210171561060257fe5b60405281815283820185018a1015610618578586fd5b81858501868301378585838301015280955050505050509250925092565b635c60da1b60e01b815260040190565b6303e1469160e61b815260040190565b6001600160a01b0391909116815260200190565b600060018060a01b038416825260206040818401528351806040850152825b818110156106a557858101830151858201606001528201610689565b818111156106b65783606083870101525b50601f01601f191692909201606001949350505050565b901515815260200190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6001600160a01b038116811461046057600080fdfea2646970667358221220142b10fc4fdd881bdff70408546e1b1005f22944adc6b0a0da6becaf7c2b47a164736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106100865760003560e01c80638f32d59b116100595780638f32d59b1461010d5780639623609d1461012f57806399a88ec414610142578063f2fde38b14610162578063f3b7dead1461018257610086565b8063204e1c7a1461008b578063715018a6146100c15780637eff275e146100d85780638da5cb5b146100f8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610503565b6101a2565b6040516100b89190610656565b60405180910390f35b3480156100cd57600080fd5b506100d6610228565b005b3480156100e457600080fd5b506100d66100f3366004610542565b61029f565b34801561010457600080fd5b506100ab610325565b34801561011957600080fd5b50610122610334565b6040516100b891906106cd565b6100d661013d36600461057a565b610358565b34801561014e57600080fd5b506100d661015d366004610542565b6103e3565b34801561016e57600080fd5b506100d661017d366004610503565b610433565b34801561018e57600080fd5b506100ab61019d366004610503565b610463565b6000806000836001600160a01b03166040516101bd90610636565b600060405180830381855afa9150503d80600081146101f8576040519150601f19603f3d011682016040523d82523d6000602084013e6101fd565b606091505b50915091508161020c57600080fd5b808060200190518101906102209190610526565b949350505050565b610230610334565b6102555760405162461bcd60e51b815260040161024c9061071e565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6102a7610334565b6102c35760405162461bcd60e51b815260040161024c9061071e565b6040516308f2839760e41b81526001600160a01b03831690638f283970906102ef908490600401610656565b600060405180830381600087803b15801561030957600080fd5b505af115801561031d573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031690565b600080546001600160a01b031661034961047e565b6001600160a01b031614905090565b610360610334565b61037c5760405162461bcd60e51b815260040161024c9061071e565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906103ac908690869060040161066a565b6000604051808303818588803b1580156103c557600080fd5b505af11580156103d9573d6000803e3d6000fd5b5050505050505050565b6103eb610334565b6104075760405162461bcd60e51b815260040161024c9061071e565b604051631b2ce7f360e11b81526001600160a01b03831690633659cfe6906102ef908490600401610656565b61043b610334565b6104575760405162461bcd60e51b815260040161024c9061071e565b61046081610482565b50565b6000806000836001600160a01b03166040516101bd90610646565b3390565b6001600160a01b0381166104a85760405162461bcd60e51b815260040161024c906106d8565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600060208284031215610514578081fd5b813561051f81610753565b9392505050565b600060208284031215610537578081fd5b815161051f81610753565b60008060408385031215610554578081fd5b823561055f81610753565b9150602083013561056f81610753565b809150509250929050565b60008060006060848603121561058e578081fd5b833561059981610753565b92506020848101356105aa81610753565b9250604085013567ffffffffffffffff808211156105c6578384fd5b818701915087601f8301126105d9578384fd5b8135818111156105e557fe5b604051601f8201601f191681018501838111828210171561060257fe5b60405281815283820185018a1015610618578586fd5b81858501868301378585838301015280955050505050509250925092565b635c60da1b60e01b815260040190565b6303e1469160e61b815260040190565b6001600160a01b0391909116815260200190565b600060018060a01b038416825260206040818401528351806040850152825b818110156106a557858101830151858201606001528201610689565b818111156106b65783606083870101525b50601f01601f191692909201606001949350505050565b901515815260200190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6001600160a01b038116811461046057600080fdfea2646970667358221220142b10fc4fdd881bdff70408546e1b1005f22944adc6b0a0da6becaf7c2b47a164736f6c63430007060033",
+ "devdoc": {
+ "details": "This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.",
+ "kind": "dev",
+ "methods": {
+ "changeProxyAdmin(address,address)": {
+ "details": "Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`."
+ },
+ "getProxyAdmin(address)": {
+ "details": "Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "getProxyImplementation(address)": {
+ "details": "Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "upgrade(address,address)": {
+ "details": "Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "upgradeAndCall(address,address,bytes)": {
+ "details": "Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 10887,
+ "contract": "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol:ProxyAdmin",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/SideTokenFactory.json b/bridge/deployments/kovan/SideTokenFactory.json
new file mode 100644
index 000000000..0ff859834
--- /dev/null
+++ b/bridge/deployments/kovan/SideTokenFactory.json
@@ -0,0 +1,173 @@
+{
+ "address": "0x984192ad76A8FFF2edf39C260324d32d8A80512b",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "SideTokenCreated",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xf071cbcee4df45bf0ae491286231caef0506950be07a1abcbc958b9fd4f2a393",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0xbB74098e1F6F95198209bA30BA92725a6CCd5eab",
+ "transactionIndex": 0,
+ "gasUsed": "3175216",
+ "logsBloom": "0x08000400000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000100000",
+ "blockHash": "0x79b80ecb04e871e6dfecafd5fe3a5df3b027a87a2268ac97a843fcdea8e78280",
+ "transactionHash": "0xf071cbcee4df45bf0ae491286231caef0506950be07a1abcbc958b9fd4f2a393",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152177,
+ "transactionHash": "0xf071cbcee4df45bf0ae491286231caef0506950be07a1abcbc958b9fd4f2a393",
+ "address": "0xbB74098e1F6F95198209bA30BA92725a6CCd5eab",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ],
+ "data": "0x000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8",
+ "logIndex": 0,
+ "blockHash": "0x79b80ecb04e871e6dfecafd5fe3a5df3b027a87a2268ac97a843fcdea8e78280"
+ }
+ ],
+ "blockNumber": 2152177,
+ "cumulativeGasUsed": "3175216",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"granularity\",\"type\":\"uint256\"}],\"name\":\"SideTokenCreated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"granularity\",\"type\":\"uint256\"}],\"name\":\"createSideToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/SideTokenFactory/SideTokenFactory.sol\":\"SideTokenFactory\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/SideToken/SideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../zeppelin/token/ERC777/ERC777.sol\\\";\\nimport \\\"../interface/IERC677Receiver.sol\\\";\\nimport \\\"../interface/ISideToken.sol\\\";\\nimport \\\"../lib/LibEIP712.sol\\\";\\n\\ncontract SideToken is ISideToken, ERC777 {\\n using Address for address;\\n using SafeMath for uint256;\\n\\n address public minter;\\n uint256 private _granularity;\\n\\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\\n bytes32 public domainSeparator;\\n // keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\\n mapping(address => uint) public nonces;\\n\\n // ERC677 Transfer Event\\n event Transfer(address,address,uint256,bytes);\\n\\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\\n require(_minterAddr != address(0), \\\"SideToken: Empty Minter\\\");\\n require(_newGranularity >= 1, \\\"SideToken: Granularity < 1\\\");\\n minter = _minterAddr;\\n _granularity = _newGranularity;\\n\\n uint chainId;\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n chainId := chainid()\\n }\\n domainSeparator = LibEIP712.hashEIP712Domain(\\n name(),\\n \\\"1\\\",\\n chainId,\\n address(this)\\n );\\n }\\n\\n modifier onlyMinter() {\\n require(_msgSender() == minter, \\\"SideToken: Caller is not the minter\\\");\\n _;\\n }\\n\\n function mint(\\n address account,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n )\\n external onlyMinter override\\n {\\n _mint(_msgSender(), account, amount, userData, operatorData);\\n }\\n\\n /**\\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\\n * @param recipient The address to transfer to.\\n * @param amount The amount to be transferred.\\n * @param data The extra data to be passed to the receiving contract.\\n */\\n function transferAndCall(address recipient, uint amount, bytes calldata data)\\n external returns (bool success)\\n {\\n address from = _msgSender();\\n\\n _send(from, from, recipient, amount, data, \\\"\\\", false);\\n emit Transfer(from, recipient, amount, data);\\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\\n return true;\\n }\\n\\n function granularity() public view override returns (uint256) {\\n return _granularity;\\n }\\n\\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\\n require(deadline >= block.timestamp, \\\"SideToken: EXPIRED\\\"); // solhint-disable-line not-rely-on-time\\n bytes32 digest = LibEIP712.hashEIP712Message(\\n domainSeparator,\\n keccak256(\\n abi.encode(\\n PERMIT_TYPEHASH,\\n owner,\\n spender,\\n value,\\n nonces[owner]++,\\n deadline\\n )\\n )\\n );\\n address recoveredAddress = ecrecover(digest, v, r, s);\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"SideToken: INVALID_SIGNATURE\\\");\\n _approve(owner, spender, value);\\n }\\n\\n}\",\"keccak256\":\"0x4f6915fef50725cfde92986c2e2c83c80758b7de6d863d125974c1e1b5c47c82\",\"license\":\"MIT\"},\"contracts/SideTokenFactory/SideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../zeppelin/ownership/Secondary.sol\\\";\\nimport \\\"../interface/ISideTokenFactory.sol\\\";\\nimport \\\"../SideToken/SideToken.sol\\\";\\n\\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\\n\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\\n external onlyPrimary override returns(address) {\\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\\n emit SideTokenCreated(sideToken, symbol, granularity);\\n return sideToken;\\n }\\n}\",\"keccak256\":\"0xd777e928d953e0bc0f31cbcaa50b9e10eb501fd580fe7b32da279833824def44\",\"license\":\"MIT\"},\"contracts/interface/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\\n}\",\"keccak256\":\"0xea0204863235cba5119f6c54b594ea1eefa84e4741ee607ed7ee05f62cb2d9e0\",\"license\":\"MIT\"},\"contracts/interface/ISideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\ninterface ISideToken {\\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\\n}\",\"keccak256\":\"0xf01477bc820f57970d7d8384417ac0aead22bd336077e371c48da917270013b4\",\"license\":\"MIT\"},\"contracts/interface/ISideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\ninterface ISideTokenFactory {\\n\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\\n\\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\\n}\",\"keccak256\":\"0x550c1af5fa52739ac28f58c36f04ba634213c5307ae95b412e41f3ee1d2e7217\",\"license\":\"MIT\"},\"contracts/lib/LibEIP712.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\\nlibrary LibEIP712 {\\n\\n // Hash of the EIP712 Domain Separator Schema\\n // keccak256(abi.encodePacked(\\n // \\\"EIP712Domain(\\\",\\n // \\\"string name,\\\",\\n // \\\"string version,\\\",\\n // \\\"uint256 chainId,\\\",\\n // \\\"address verifyingContract\\\",\\n // \\\")\\\"\\n // ))\\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\\n\\n /// @dev Calculates a EIP712 domain separator.\\n /// @param name The EIP712 domain name.\\n /// @param version The EIP712 domain version.\\n /// @param verifyingContract The EIP712 verifying contract.\\n /// @return result EIP712 domain separator.\\n function hashEIP712Domain(\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract\\n )\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\\n\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\\n // keccak256(bytes(name)),\\n // keccak256(bytes(version)),\\n // chainId,\\n // uint256(verifyingContract)\\n // ))\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Calculate hashes of dynamic data\\n let nameHash := keccak256(add(name, 32), mload(name))\\n let versionHash := keccak256(add(version, 32), mload(version))\\n\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n // Store params in memory\\n mstore(memPtr, schemaHash)\\n mstore(add(memPtr, 32), nameHash)\\n mstore(add(memPtr, 64), versionHash)\\n mstore(add(memPtr, 96), chainId)\\n mstore(add(memPtr, 128), verifyingContract)\\n\\n // Compute hash\\n result := keccak256(memPtr, 160)\\n }\\n return result;\\n }\\n\\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\\n /// with getDomainHash().\\n /// @param hashStruct The EIP712 hash struct.\\n /// @return result EIP712 hash applied to the given EIP712 Domain.\\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // EIP191_HEADER,\\n // EIP712_DOMAIN_HASH,\\n // hashStruct\\n // ));\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\\n\\n // Compute hash\\n result := keccak256(memPtr, 66)\\n }\\n return result;\\n }\\n}\",\"keccak256\":\"0x6116e22c413fc65e87bf7db958d5c1f301b493494813f76dce512f8254c3b012\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC1820Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\n * implementers for interfaces in this registry, as well as query support.\\n *\\n * Implementers may be shared by multiple accounts, and can also implement more\\n * than a single interface for each account. Contracts can implement interfaces\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\n * contract.\\n *\\n * {IERC165} interfaces can also be queried via the registry.\\n *\\n * For an in-depth explanation and source code analysis, see the EIP text.\\n */\\ninterface IERC1820Registry {\\n /**\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\n * account is able to set interface implementers for it.\\n *\\n * By default, each account is its own manager. Passing a value of `0x0` in\\n * `newManager` will reset the manager to this initial state.\\n *\\n * Emits a {ManagerChanged} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `account`.\\n */\\n function setManager(address account, address newManager) external;\\n\\n /**\\n * @dev Returns the manager for `account`.\\n *\\n * See {setManager}.\\n */\\n function getManager(address account) external view returns (address);\\n\\n /**\\n * @dev Sets the `implementer` contract as `account`'s implementer for\\n * `interfaceHash`.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n * The zero address can also be used in `implementer` to remove an old one.\\n *\\n * See {interfaceHash} to learn how these are created.\\n *\\n * Emits an {InterfaceImplementerSet} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `_account`.\\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\n * end in 28 zeroes).\\n * - `_implementer` must implement {IERC1820Implementer} and return true when\\n * queried for support, unless `implementer` is the caller. See\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\n */\\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\\n\\n /**\\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\\n * implementer is registered, returns the zero address.\\n *\\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\n * zeroes), `_account` will be queried for support of it.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n */\\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\\n\\n /**\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\n * corresponding\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\n */\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\n\\n /**\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\n * @param account Address of the contract for which to update the cache.\\n * @param interfaceId ERC165 interface for which to update the cache.\\n */\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\n * If the result is not cached a direct lookup on the contract address is performed.\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\n * {updateERC165Cache} with the contract address.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\n\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\n\\n event ManagerChanged(address indexed account, address indexed newManager);\\n}\\n\",\"keccak256\":\"0x1b44f619ae588fd201e93b126b80576e1244ef468e8b4e54e62fbad6a805cc87\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x09ca2716452528a6e69ac9f83f874292a1e547630473f3133038314a2f16029e\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Secondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../GSN/Context.sol\\\";\\n/**\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\n */\\nabstract contract Secondary is Context {\\n address private _primary;\\n\\n /**\\n * @dev Emitted when the primary contract changes.\\n */\\n event PrimaryTransferred(\\n address recipient\\n );\\n\\n /**\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\n */\\n constructor () {\\n _primary = _msgSender();\\n emit PrimaryTransferred(_primary);\\n }\\n\\n /**\\n * @dev Reverts if called from any account other than the primary.\\n */\\n modifier onlyPrimary() {\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\n _;\\n }\\n\\n /**\\n * @return the address of the primary.\\n */\\n function primary() public view returns (address) {\\n return _primary;\\n }\\n\\n /**\\n * @dev Transfers contract to a new primary.\\n * @param recipient The address of new primary.\\n */\\n function transferPrimary(address recipient) public onlyPrimary {\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\n _primary = recipient;\\n emit PrimaryTransferred(_primary);\\n }\\n}\\n\",\"keccak256\":\"0x79b3afb98ca1e12e33c63da57ca460fc217f2110a4fa1c18c67a7d84e048d285\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {ERC20Detailed}.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x1bc9527655c4be58541c2fb90c0a05952938961c289f505c70160f87e08aef33\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/ERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"./IERC777.sol\\\";\\nimport \\\"./IERC777Recipient.sol\\\";\\nimport \\\"./IERC777Sender.sol\\\";\\nimport \\\"../../token/ERC20/IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../introspection/IERC1820Registry.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC777} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n *\\n * Support for ERC20 is included in this contract, as specified by the EIP: both\\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\\n * movements.\\n *\\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\\n * are no special restrictions in the amount of tokens that created, moved, or\\n * destroyed. This makes integration with ERC20 applications seamless.\\n */\\ncontract ERC777 is Context, IERC777, IERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\n\\n mapping(address => uint256) private _balances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\\n // See https://github.com/ethereum/solidity/issues/4024.\\n\\n // keccak256(\\\"ERC777TokensSender\\\")\\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\\n\\n // keccak256(\\\"ERC777TokensRecipient\\\")\\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\\n\\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\\n address[] private _defaultOperatorsArray;\\n\\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\\n mapping(address => bool) private _defaultOperators;\\n\\n // For each account, a mapping of its operators and revoked default operators.\\n mapping(address => mapping(address => bool)) private _operators;\\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\\n\\n // ERC20-allowances\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n /**\\n * @dev `defaultOperators` may be an empty array.\\n */\\n constructor(\\n string memory aName,\\n string memory aSymbol,\\n address[] memory theDefaultOperators\\n ) {\\n _name = aName;\\n _symbol = aSymbol;\\n\\n _defaultOperatorsArray = theDefaultOperators;\\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\\n _defaultOperators[_defaultOperatorsArray[i]] = true;\\n }\\n\\n // register interfaces\\n _erc1820.setInterfaceImplementer(address(this), keccak256(\\\"ERC777Token\\\"), address(this));\\n _erc1820.setInterfaceImplementer(address(this), keccak256(\\\"ERC20Token\\\"), address(this));\\n }\\n\\n /**\\n * @dev See {IERC777-name}.\\n */\\n function name() public view override(IERC777) returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC777-symbol}.\\n */\\n function symbol() public view override(IERC777) returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {ERC20Detailed-decimals}.\\n *\\n * Always returns 18, as per the\\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\\n */\\n function decimals() public pure override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC777-granularity}.\\n *\\n * This implementation always returns `1`.\\n */\\n function granularity() public view virtual override(IERC777) returns (uint256) {\\n return 1;\\n }\\n\\n /**\\n * @dev See {IERC777-totalSupply}.\\n */\\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\\n */\\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\\n return _balances[tokenHolder];\\n }\\n\\n /**\\n * @dev See {IERC777-send}.\\n *\\n * Also emits a {Transfer} event for ERC20 compatibility.\\n */\\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\\n _send(_msgSender(), _msgSender(), recipient, amount, data, \\\"\\\", true);\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\\n * interface if it is a contract.\\n *\\n * Also emits a {Sent} event.\\n */\\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\\n require(recipient != address(0), \\\"ERC777: transfer to zero address\\\");\\n\\n address from = _msgSender();\\n\\n _callTokensToSend(from, from, recipient, amount, \\\"\\\", \\\"\\\");\\n\\n _move(from, from, recipient, amount, \\\"\\\", \\\"\\\");\\n\\n _callTokensReceived(from, from, recipient, amount, \\\"\\\", \\\"\\\", false);\\n\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC777-burn}.\\n *\\n * Also emits a {Transfer} event for ERC20 compatibility.\\n */\\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\\n _burn(_msgSender(), _msgSender(), amount, data, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC777-isOperatorFor}.\\n */\\n function isOperatorFor(\\n address operator,\\n address tokenHolder\\n ) public view override(IERC777) returns (bool) {\\n return operator == tokenHolder ||\\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\\n _operators[tokenHolder][operator];\\n }\\n\\n /**\\n * @dev See {IERC777-authorizeOperator}.\\n */\\n function authorizeOperator(address operator) external override(IERC777) {\\n require(_msgSender() != operator, \\\"ERC777: authorizing self as operator\\\");\\n\\n if (_defaultOperators[operator]) {\\n delete _revokedDefaultOperators[_msgSender()][operator];\\n } else {\\n _operators[_msgSender()][operator] = true;\\n }\\n\\n emit AuthorizedOperator(operator, _msgSender());\\n }\\n\\n /**\\n * @dev See {IERC777-revokeOperator}.\\n */\\n function revokeOperator(address operator) external override(IERC777) {\\n require(operator != _msgSender(), \\\"ERC777: revoking self as operator\\\");\\n\\n if (_defaultOperators[operator]) {\\n _revokedDefaultOperators[_msgSender()][operator] = true;\\n } else {\\n delete _operators[_msgSender()][operator];\\n }\\n\\n emit RevokedOperator(operator, _msgSender());\\n }\\n\\n /**\\n * @dev See {IERC777-defaultOperators}.\\n */\\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\\n return _defaultOperatorsArray;\\n }\\n\\n /**\\n * @dev See {IERC777-operatorSend}.\\n *\\n * Emits {Sent} and {Transfer} events.\\n */\\n function operatorSend(\\n address sender,\\n address recipient,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n )\\n external override(IERC777)\\n {\\n require(isOperatorFor(_msgSender(), sender), \\\"ERC777: caller is not an operator\\\");\\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\\n }\\n\\n /**\\n * @dev See {IERC777-operatorBurn}.\\n *\\n * Emits {Burned} and {Transfer} events.\\n */\\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\\n external override(IERC777) {\\n require(isOperatorFor(_msgSender(), account), \\\"ERC777: caller is not an operator\\\");\\n _burn(_msgSender(), account, amount, data, operatorData);\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n *\\n * Note that operator and allowance concepts are orthogonal: operators may\\n * not have allowance, and accounts with allowance may not be operators\\n * themselves.\\n */\\n function allowance(address holder, address spender)\\n public view override(IERC20) returns (uint256) {\\n return _allowances[holder][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Note that accounts cannot have allowance issued by their operators.\\n */\\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\\n address holder = _msgSender();\\n _approve(holder, spender, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Note that operator and allowance concepts are orthogonal: operators cannot\\n * call `transferFrom` (unless they have allowance), and accounts with\\n * allowance cannot call `operatorSend` (unless they are operators).\\n *\\n * Emits {Sent}, {Transfer} and {Approval} events.\\n */\\n function transferFrom(address holder, address recipient, uint256 amount)\\n external override(IERC20) returns (bool) {\\n require(recipient != address(0), \\\"ERC777: transfer to zero address\\\");\\n require(holder != address(0), \\\"ERC777: transfer from zero address\\\");\\n\\n address spender = _msgSender();\\n\\n _callTokensToSend(spender, holder, recipient, amount, \\\"\\\", \\\"\\\");\\n\\n _move(spender, holder, recipient, amount, \\\"\\\", \\\"\\\");\\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \\\"ERC777: transfer amount exceeds allowance\\\"));\\n\\n _callTokensReceived(spender, holder, recipient, amount, \\\"\\\", \\\"\\\", false);\\n\\n return true;\\n }\\n\\n /**\\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * If a send hook is registered for `account`, the corresponding function\\n * will be called with `operator`, `data` and `operatorData`.\\n *\\n * See {IERC777Sender} and {IERC777Recipient}.\\n *\\n * Emits {Minted} and {Transfer} events.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - if `account` is a contract, it must implement the {IERC777Recipient}\\n * interface.\\n */\\n function _mint(\\n address operator,\\n address account,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData\\n )\\n internal\\n {\\n require(account != address(0), \\\"ERC777: mint to zero address\\\");\\n\\n // Update state variables\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n\\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\\n\\n emit Minted(operator, account, amount, userData, operatorData);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Send tokens\\n * @param operator address operator requesting the transfer\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\\n */\\n function _send(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData,\\n bool requireReceptionAck\\n )\\n internal\\n {\\n require(from != address(0), \\\"ERC777: send from zero address\\\");\\n require(to != address(0), \\\"ERC777: send to zero address\\\");\\n\\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\\n\\n _move(operator, from, to, amount, userData, operatorData);\\n\\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\\n }\\n\\n /**\\n * @dev Burn tokens\\n * @param operator address operator requesting the operation\\n * @param from address token holder address\\n * @param amount uint256 amount of tokens to burn\\n * @param data bytes extra information provided by the token holder\\n * @param operatorData bytes extra information provided by the operator (if any)\\n */\\n function _burn(\\n address operator,\\n address from,\\n uint256 amount,\\n bytes memory data,\\n bytes memory operatorData\\n )\\n internal\\n {\\n require(from != address(0), \\\"ERC777: burn from zero address\\\");\\n\\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\\n\\n // Update state variables\\n _balances[from] = _balances[from].sub(amount, \\\"ERC777: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n\\n emit Burned(operator, from, amount, data, operatorData);\\n emit Transfer(from, address(0), amount);\\n }\\n\\n function _move(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData\\n )\\n internal\\n {\\n _balances[from] = _balances[from].sub(amount, \\\"ERC777: transfer amount exceeds balance\\\");\\n _balances[to] = _balances[to].add(amount);\\n\\n emit Sent(operator, from, to, amount, userData, operatorData);\\n emit Transfer(from, to, amount);\\n }\\n\\n function _approve(address holder, address spender, uint256 value) internal {\\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\\n // currently unnecessary.\\n //require(holder != address(0), \\\"ERC777: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC777: approve to zero address\\\");\\n\\n _allowances[holder][spender] = value;\\n emit Approval(holder, spender, value);\\n }\\n\\n /**\\n * @dev Call from.tokensToSend() if the interface is registered\\n * @param operator address operator requesting the transfer\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n */\\n function _callTokensToSend(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData\\n )\\n internal\\n {\\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\\n if (implementer != address(0)) {\\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\\n }\\n }\\n\\n /**\\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\\n * tokensReceived() was not registered for the recipient\\n * @param operator address operator requesting the transfer\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\\n */\\n function _callTokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData,\\n bool requireReceptionAck\\n )\\n private\\n {\\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\\n if (implementer != address(0)) {\\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\\n } else if (requireReceptionAck) {\\n require(!to.isContract(), \\\"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xcde4544ee18969a20b184e0acccecfa116a5abbfd9c2a1ebd4dcafc7b65cfc86\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777Token standard as defined in the EIP.\\n *\\n * This contract uses the\\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\\n * token holders and recipients react to token movements by using setting implementers\\n * for the associated interfaces in said registry. See `IERC1820Registry` and\\n * `ERC1820Implementer`.\\n */\\ninterface IERC777 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the smallest part of the token that is not divisible. This\\n * means all token operations (creation, movement and destruction) must have\\n * amounts that are a multiple of this number.\\n *\\n * For most token contracts, this value will equal 1.\\n */\\n function granularity() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by an account (`owner`).\\n */\\n function balanceOf(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * If send or receive hooks are registered for the caller and `recipient`,\\n * the corresponding functions will be called with `data` and empty\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function send(address recipient, uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Destroys `amount` tokens from the caller's account, reducing the\\n * total supply.\\n *\\n * If a send hook is registered for the caller, the corresponding function\\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n */\\n function burn(uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Returns true if an account is an operator of `tokenHolder`.\\n * Operators can send and burn tokens on behalf of their owners. All\\n * accounts are their own operator.\\n *\\n * See `operatorSend` and `operatorBurn`.\\n */\\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor`.\\n *\\n * Emits an `AuthorizedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function authorizeOperator(address operator) external;\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor` and `defaultOperators`.\\n *\\n * Emits a `RevokedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function revokeOperator(address operator) external;\\n\\n /**\\n * @dev Returns the list of default operators. These accounts are operators\\n * for all token holders, even if `authorizeOperator` was never called on\\n * them.\\n *\\n * This list is immutable, but individual holders may revoke these via\\n * `revokeOperator`, in which case `isOperatorFor` will return false.\\n */\\n function defaultOperators() external view returns (address[] memory);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\\n * be an operator of `sender`.\\n *\\n * If send or receive hooks are registered for `sender` and `recipient`,\\n * the corresponding functions will be called with `data` and\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - `sender` cannot be the zero address.\\n * - `sender` must have at least `amount` tokens.\\n * - the caller must be an operator for `sender`.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function operatorSend(\\n address sender,\\n address recipient,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n /**\\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\\n * The caller must be an operator of `account`.\\n *\\n * If a send hook is registered for `account`, the corresponding function\\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n * - the caller must be an operator for `account`.\\n */\\n function operatorBurn(\\n address account,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n event Sent(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256 amount,\\n bytes data,\\n bytes operatorData\\n );\\n\\n function decimals() external returns (uint8);\\n\\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\\n\\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\\n\\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\\n\\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\\n}\\n\",\"keccak256\":\"0x9ace3cf83443ae90a995a8e33652238fa2b5afb258897757f85467d5fb437c1a\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\n *\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an `IERC777` token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0xc8dae3544a459d13f23ba0c7737f6e279e06d83ef86b8f7a0318d83bcf4147e3\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Sender.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\\n *\\n * `IERC777` Token holders can be notified of operations performed on their\\n * tokens by having a contract implement this interface (contract holders can be\\n * their own implementer) and registering it on the\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\n *\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\n */\\ninterface IERC777Sender {\\n /**\\n * @dev Called by an `IERC777` token contract whenever a registered holder's\\n * (`from`) tokens are about to be moved or destroyed. The type of operation\\n * is conveyed by `to` being the zero address or not.\\n *\\n * This call occurs _before_ the token contract's state is updated, so\\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensToSend(\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x222036566a212defc97ef08e8f41f08dbc4880c69839f0e8d76f4d4d2406c862\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50610019610074565b600080546001600160a01b0319166001600160a01b0392831617908190556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610067921690610078565b60405180910390a161008c565b3390565b6001600160a01b0391909116815260200190565b612d628061009b6000396000f3fe60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b57806326d9e9631462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002b8565b6200009d565b005b6200007b62000075366004620002e8565b6200016c565b6040516200008a91906200038a565b60405180910390f35b6200007b6200024d565b6000546001600160a01b0316620000b36200025c565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000458565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc906200040e565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992620001619216906200038a565b60405180910390a150565b600080546001600160a01b0316620001836200025c565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000458565b600086868686620001bc6200024d565b87604051620001cb9062000260565b620001dc969594939291906200039e565b604051809103906000f080158015620001f9573d6000803e3d6000fd5b509050806001600160a01b03167ff57d2ded8330a4affd2fa52378069be534fe22288536537d1a1cfc06151845078686866040516200023b93929190620003e8565b60405180910390a29695505050505050565b6000546001600160a01b031690565b3390565b61288880620004a583390190565b60008083601f84011262000280578182fd5b50813567ffffffffffffffff81111562000298578182fd5b602083019150836020828501011115620002b157600080fd5b9250929050565b600060208284031215620002ca578081fd5b81356001600160a01b0381168114620002e1578182fd5b9392505050565b60008060008060006060868803121562000300578081fd5b853567ffffffffffffffff8082111562000318578283fd5b6200032689838a016200026e565b909750955060208801359150808211156200033f578283fd5b506200034e888289016200026e565b96999598509660400135949350505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060808252620003b460808301888a62000360565b8281036020840152620003c981878962000360565b6001600160a01b03959095166040840152505060600152949350505050565b600060408252620003fe60408301858762000360565b9050826020830152949350505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b506040516200288838038062002888833981016040819052620000349162000561565b60408051600081526020808201909252855186928692916200005d9160029190860190620003c2565b50815162000073906003906020850190620003c2565b5080516200008990600490602084019062000457565b5060005b600454811015620000e95760016005600060048481548110620000ac57fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff19169115159190911790556001016200008d565b506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90620001479030907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054908290600401620005f0565b600060405180830381600087803b1580156200016257600080fd5b505af115801562000177573d6000803e3d6000fd5b50506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad2492506329965a1d9150620001d89030907faea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a908290600401620005f0565b600060405180830381600087803b158015620001f357600080fd5b505af115801562000208573d6000803e3d6000fd5b50505050506001600160a01b038416151591506200024590505760405162461bcd60e51b81526004016200023c9062000613565b60405180910390fd5b6001811015620002695760405162461bcd60e51b81526004016200023c906200064a565b600980546001600160a01b0319166001600160a01b038416179055600a81905546620002c562000298620002d4565b604051806040016040528060018152602001603160f81b81525083306200036b60201b62000fa41760201c565b600b5550620006819350505050565b60028054604080516020601f6000196101006001871615020190941685900493840181900481028201810190925282815260609390929091830182828015620003615780601f10620003355761010080835404028352916020019162000361565b820191906000526020600020905b8154815290600101906020018083116200034357829003601f168201915b5050505050905090565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620003fa576000855562000445565b82601f106200041557805160ff191683800117855562000445565b8280016001018555821562000445579182015b828111156200044557825182559160200191906001019062000428565b5062000453929150620004af565b5090565b82805482825590600052602060002090810192821562000445579160200282015b828111156200044557825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000478565b5b80821115620004535760008155600101620004b0565b600082601f830112620004d7578081fd5b81516001600160401b0380821115620004ec57fe5b6040516020601f8401601f19168201810183811183821017156200050c57fe5b604052838252858401810187101562000523578485fd5b8492505b8383101562000546578583018101518284018201529182019162000527565b838311156200055757848185840101525b5095945050505050565b6000806000806080858703121562000577578384fd5b84516001600160401b03808211156200058e578586fd5b6200059c88838901620004c6565b95506020870151915080821115620005b2578485fd5b50620005c187828801620004c6565b604087015190945090506001600160a01b0381168114620005e0578283fd5b6060959095015193969295505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b6020808252601a908201527f53696465546f6b656e3a204772616e756c6172697479203c2031000000000000604082015260600190565b6121f780620006916000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80637ecebe00116100de578063d95b637111610097578063f698da2511610071578063f698da2514610308578063fad8b32a14610310578063fc673c4f14610323578063fe9d93031461033657610173565b8063d95b6371146102cf578063dcdc7dd0146102e2578063dd62ed3e146102f557610173565b80637ecebe0014610268578063959b8c3f1461027b57806395d89b411461028e5780639bd9bbc614610296578063a9059cbb146102a9578063d505accf146102bc57610173565b806330adf81f1161013057806330adf81f14610208578063313ce567146102105780634000aea014610225578063556f0dc71461023857806362ad1b831461024057806370a082311461025557610173565b806306e485381461017857806306fdde031461019657806307546172146101ab578063095ea7b3146101c057806318160ddd146101e057806323b872dd146101f5575b600080fd5b610180610349565b60405161018d9190611c97565b60405180910390f35b61019e6103ab565b60405161018d9190611d4a565b6101b3610435565b60405161018d9190611b9f565b6101d36101ce3660046119d2565b610444565b60405161018d9190611ce4565b6101e8610466565b60405161018d9190611cef565b6101d3610203366004611881565b61046c565b6101e86105b4565b6102186105d8565b60405161018d9190612128565b6101d36102333660046119fd565b6105dd565b6101e86106eb565b61025361024e3660046118c1565b6106f1565b005b6101e8610263366004611811565b6107a8565b6101e8610276366004611811565b6107c3565b610253610289366004611811565b6107d5565b61019e610902565b6102536102a43660046119fd565b610963565b6101d36102b73660046119d2565b6109cb565b6102536102ca36600461195d565b610a85565b6101d36102dd366004611849565b610bd8565b6102536102f0366004611a57565b610c7a565b6101e8610303366004611849565b610d39565b6101e8610d64565b61025361031e366004611811565b610d6a565b610253610331366004611a57565b610e97565b610253610344366004611ae0565b610f41565b606060048054806020026020016040519081016040528092919081815260200182805480156103a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610383575b5050505050905090565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b820191906000526020600020905b81548152906001019060200180831161041757509395945050505050565b6009546001600160a01b031681565b60008061044f610ffb565b905061045c818585610fff565b5060019392505050565b60015490565b60006001600160a01b03831661049d5760405162461bcd60e51b815260040161049490611e50565b60405180910390fd5b6001600160a01b0384166104c35760405162461bcd60e51b815260040161049490612043565b60006104cd610ffb565b90506104fb81868686604051806020016040528060008152506040518060200160405280600081525061108d565b6105278186868660405180602001604052806000815250604051806020016040528060008152506111bb565b61057b858261057686604051806060016040528060298152602001612176602991396001600160a01b03808c166000908152600860209081526040808320938b168352929052205491906112db565b610fff565b6105a98186868660405180602001604052806000815250604051806020016040528060008152506000611307565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601290565b6000806105e8610ffb565b905061063c8182888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060408051602081019091528181529350915061146e9050565b7fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c168187878787604051610673959493929190611c0d565b60405180910390a1604051635260769b60e11b81526001600160a01b0387169063a4c0ed36906106ad908490899089908990600401611c65565b600060405180830381600087803b1580156106c757600080fd5b505af11580156106db573d6000803e3d6000fd5b5060019998505050505050505050565b600a5490565b6107026106fc610ffb565b88610bd8565b61071e5760405162461bcd60e51b815260040161049490612085565b61079f610729610ffb565b88888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a91508990819084018382808284376000920191909152506001925061146e915050565b50505050505050565b6001600160a01b031660009081526020819052604090205490565b600c6020526000908152604090205481565b806001600160a01b03166107e7610ffb565b6001600160a01b0316141561080e5760405162461bcd60e51b815260040161049490611dcb565b6001600160a01b03811660009081526005602052604090205460ff1615610871576007600061083b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690556108b8565b60016006600061087f610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b6108c0610ffb565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b6109c561096e610ffb565b610976610ffb565b868686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604080516020810190915290815292506001915061146e9050565b50505050565b60006001600160a01b0383166109f35760405162461bcd60e51b815260040161049490611e50565b60006109fd610ffb565b9050610a2b81828686604051806020016040528060008152506040518060200160405280600081525061108d565b610a578182868660405180602001604052806000815250604051806020016040528060008152506111bb565b61045c8182868660405180602001604052806000815250604051806020016040528060008152506000611307565b42841015610aa55760405162461bcd60e51b815260040161049490611fa9565b600b546001600160a01b0388166000908152600c6020908152604080832080546001810190915590519293610b27939092610b0c927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928e928e928e9290918e9101611cf8565b604051602081830303815290604052805190602001206114e5565b9050600060018286868660405160008152602001604052604051610b4e9493929190611d2c565b6020604051602081039080840390855afa158015610b70573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610ba65750886001600160a01b0316816001600160a01b0316145b610bc25760405162461bcd60e51b815260040161049490611f2f565b610bcd898989610fff565b505050505050505050565b6000816001600160a01b0316836001600160a01b03161480610c4357506001600160a01b03831660009081526005602052604090205460ff168015610c4357506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b80610c7357506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b6009546001600160a01b0316610c8e610ffb565b6001600160a01b031614610cb45760405162461bcd60e51b815260040161049490611f66565b610d31610cbf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061150492505050565b505050505050565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b600b5481565b610d72610ffb565b6001600160a01b0316816001600160a01b03161415610da35760405162461bcd60e51b815260040161049490611e0f565b6001600160a01b03811660009081526005602052604090205460ff1615610e0f57600160076000610dd2610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055610e4d565b60066000610e1b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b610e55610ffb565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b610ea8610ea2610ffb565b87610bd8565b610ec45760405162461bcd60e51b815260040161049490612085565b610d31610ecf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061162c92505050565b610f9f610f4c610ffb565b610f54610ffb565b8585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805160208101909152908152925061162c915050565b505050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b3390565b6001600160a01b0382166110255760405162461bcd60e51b8152600401610494906120c6565b6001600160a01b0380841660008181526008602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611080908590611cef565b60405180910390a3505050565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906110e99089907f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89590600401611c4c565b60206040518083038186803b15801561110157600080fd5b505afa158015611115573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611139919061182d565b90506001600160a01b0381161561079f57604051633ad5cbc160e11b81526001600160a01b038216906375ab978290611180908a908a908a908a908a908a90600401611bb3565b600060405180830381600087803b15801561119a57600080fd5b505af11580156111ae573d6000803e3d6000fd5b5050505050505050505050565b6111f88360405180606001604052806027815260200161214f602791396001600160a01b03881660009081526020819052604090205491906112db565b6001600160a01b038087166000908152602081905260408082209390935590861681522054611227908461175d565b6001600160a01b0380861660008181526020819052604090819020939093559151878216918916907f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc8261467798790611280908890889088906120fd565b60405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516112cb9190611cef565b60405180910390a3505050505050565b600081848411156112ff5760405162461bcd60e51b81526004016104949190611d4a565b505050900390565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906113639089907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b90600401611c4c565b60206040518083038186803b15801561137b57600080fd5b505afa15801561138f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b3919061182d565b90506001600160a01b0381161561142f576040516223de2960e01b81526001600160a01b038216906223de29906113f8908b908b908b908b908b908b90600401611bb3565b600060405180830381600087803b15801561141257600080fd5b505af1158015611426573d6000803e3d6000fd5b50505050611464565b811561146457611447866001600160a01b0316611782565b156114645760405162461bcd60e51b815260040161049490611ebc565b5050505050505050565b6001600160a01b0386166114945760405162461bcd60e51b815260040161049490611fd5565b6001600160a01b0385166114ba5760405162461bcd60e51b81526004016104949061200c565b6114c887878787878761108d565b6114d68787878787876111bb565b61079f87878787878787611307565b60405161190160f01b8152600281019290925260228201526042902090565b6001600160a01b03841661152a5760405162461bcd60e51b815260040161049490611e85565b600154611537908461175d565b6001556001600160a01b03841660009081526020819052604090205461155d908461175d565b6001600160a01b03851660009081526020819052604081209190915561158a908690868686866001611307565b836001600160a01b0316856001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d8585856040516115d1939291906120fd565b60405180910390a3836001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b60405180910390a35050505050565b6001600160a01b0384166116525760405162461bcd60e51b815260040161049490611d94565b6116618585600086868661108d565b61169e8360405180606001604052806023815260200161219f602391396001600160a01b03871660009081526020819052604090205491906112db565b6001600160a01b0385166000908152602081905260409020556001546116c49084611788565b600181905550836001600160a01b0316856001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098858585604051611711939291906120fd565b60405180910390a360006001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b600082820183811015610c735760405162461bcd60e51b815260040161049490611d5d565b3b151590565b6000610c7383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506112db565b60008083601f8401126117db578182fd5b50813567ffffffffffffffff8111156117f2578182fd5b60208301915083602082850101111561180a57600080fd5b9250929050565b600060208284031215611822578081fd5b8135610c7381612136565b60006020828403121561183e578081fd5b8151610c7381612136565b6000806040838503121561185b578081fd5b823561186681612136565b9150602083013561187681612136565b809150509250929050565b600080600060608486031215611895578081fd5b83356118a081612136565b925060208401356118b081612136565b929592945050506040919091013590565b600080600080600080600060a0888a0312156118db578283fd5b87356118e681612136565b965060208801356118f681612136565b955060408801359450606088013567ffffffffffffffff80821115611919578485fd5b6119258b838c016117ca565b909650945060808a013591508082111561193d578384fd5b5061194a8a828b016117ca565b989b979a50959850939692959293505050565b600080600080600080600060e0888a031215611977578283fd5b873561198281612136565b9650602088013561199281612136565b95506040880135945060608801359350608088013560ff811681146119b5578384fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156119e4578182fd5b82356119ef81612136565b946020939093013593505050565b60008060008060608587031215611a12578384fd5b8435611a1d81612136565b935060208501359250604085013567ffffffffffffffff811115611a3f578283fd5b611a4b878288016117ca565b95989497509550505050565b60008060008060008060808789031215611a6f578182fd5b8635611a7a81612136565b955060208701359450604087013567ffffffffffffffff80821115611a9d578384fd5b611aa98a838b016117ca565b90965094506060890135915080821115611ac1578384fd5b50611ace89828a016117ca565b979a9699509497509295939492505050565b600080600060408486031215611af4578283fd5b83359250602084013567ffffffffffffffff811115611b11578283fd5b611b1d868287016117ca565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b81811015611b7957602081850181015186830182015201611b5d565b81811115611b8a5782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0387811682528681166020830152851660408201526060810184905260c060808201819052600090611bee90830185611b54565b82810360a0840152611c008185611b54565b9998505050505050505050565b6001600160a01b0386811682528516602082015260408101849052608060608201819052600090611c419083018486611b2a565b979650505050505050565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038616825284602083015260606040830152611c8d606083018486611b2a565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611cd85783516001600160a01b031683529284019291840191600101611cb3565b50909695505050505050565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610c736020830184611b54565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f4552433737373a206275726e2066726f6d207a65726f20616464726573730000604082015260600190565b60208082526024908201527f4552433737373a20617574686f72697a696e672073656c66206173206f70657260408201526330ba37b960e11b606082015260800190565b60208082526021908201527f4552433737373a207265766f6b696e672073656c66206173206f70657261746f6040820152603960f91b606082015260800190565b6020808252818101527f4552433737373a207472616e7366657220746f207a65726f2061646472657373604082015260600190565b6020808252601c908201527f4552433737373a206d696e7420746f207a65726f206164647265737300000000604082015260600190565b6020808252604d908201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460408201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60608201526c1ad95b9cd49958da5c1a595b9d609a1b608082015260a00190565b6020808252601c908201527f53696465546f6b656e3a20494e56414c49445f5349474e415455524500000000604082015260600190565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b60208082526012908201527114da5919551bdad95b8e881156141254915160721b604082015260600190565b6020808252601e908201527f4552433737373a2073656e642066726f6d207a65726f20616464726573730000604082015260600190565b6020808252601c908201527f4552433737373a2073656e6420746f207a65726f206164647265737300000000604082015260600190565b60208082526022908201527f4552433737373a207472616e736665722066726f6d207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526021908201527f4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f6040820152603960f91b606082015260800190565b6020808252601f908201527f4552433737373a20617070726f766520746f207a65726f206164647265737300604082015260600190565b6000848252606060208301526121166060830185611b54565b8281036040840152611c8d8185611b54565b60ff91909116815260200190565b6001600160a01b038116811461214b57600080fd5b5056fe4552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a206275726e20616d6f756e7420657863656564732062616c616e6365a2646970667358221220e96305596548c1ccf5a73d7bede36fbfaeee3f672cbf14157179325f27c57bf764736f6c63430007060033a26469706673582212204cc330cf5079dbaee9f34fb1607540a3d5891d5eeb955ff8beaa47811a8c189964736f6c63430007060033",
+ "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b57806326d9e9631462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002b8565b6200009d565b005b6200007b62000075366004620002e8565b6200016c565b6040516200008a91906200038a565b60405180910390f35b6200007b6200024d565b6000546001600160a01b0316620000b36200025c565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000458565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc906200040e565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992620001619216906200038a565b60405180910390a150565b600080546001600160a01b0316620001836200025c565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000458565b600086868686620001bc6200024d565b87604051620001cb9062000260565b620001dc969594939291906200039e565b604051809103906000f080158015620001f9573d6000803e3d6000fd5b509050806001600160a01b03167ff57d2ded8330a4affd2fa52378069be534fe22288536537d1a1cfc06151845078686866040516200023b93929190620003e8565b60405180910390a29695505050505050565b6000546001600160a01b031690565b3390565b61288880620004a583390190565b60008083601f84011262000280578182fd5b50813567ffffffffffffffff81111562000298578182fd5b602083019150836020828501011115620002b157600080fd5b9250929050565b600060208284031215620002ca578081fd5b81356001600160a01b0381168114620002e1578182fd5b9392505050565b60008060008060006060868803121562000300578081fd5b853567ffffffffffffffff8082111562000318578283fd5b6200032689838a016200026e565b909750955060208801359150808211156200033f578283fd5b506200034e888289016200026e565b96999598509660400135949350505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060808252620003b460808301888a62000360565b8281036020840152620003c981878962000360565b6001600160a01b03959095166040840152505060600152949350505050565b600060408252620003fe60408301858762000360565b9050826020830152949350505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b506040516200288838038062002888833981016040819052620000349162000561565b60408051600081526020808201909252855186928692916200005d9160029190860190620003c2565b50815162000073906003906020850190620003c2565b5080516200008990600490602084019062000457565b5060005b600454811015620000e95760016005600060048481548110620000ac57fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff19169115159190911790556001016200008d565b506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90620001479030907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054908290600401620005f0565b600060405180830381600087803b1580156200016257600080fd5b505af115801562000177573d6000803e3d6000fd5b50506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad2492506329965a1d9150620001d89030907faea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a908290600401620005f0565b600060405180830381600087803b158015620001f357600080fd5b505af115801562000208573d6000803e3d6000fd5b50505050506001600160a01b038416151591506200024590505760405162461bcd60e51b81526004016200023c9062000613565b60405180910390fd5b6001811015620002695760405162461bcd60e51b81526004016200023c906200064a565b600980546001600160a01b0319166001600160a01b038416179055600a81905546620002c562000298620002d4565b604051806040016040528060018152602001603160f81b81525083306200036b60201b62000fa41760201c565b600b5550620006819350505050565b60028054604080516020601f6000196101006001871615020190941685900493840181900481028201810190925282815260609390929091830182828015620003615780601f10620003355761010080835404028352916020019162000361565b820191906000526020600020905b8154815290600101906020018083116200034357829003601f168201915b5050505050905090565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620003fa576000855562000445565b82601f106200041557805160ff191683800117855562000445565b8280016001018555821562000445579182015b828111156200044557825182559160200191906001019062000428565b5062000453929150620004af565b5090565b82805482825590600052602060002090810192821562000445579160200282015b828111156200044557825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000478565b5b80821115620004535760008155600101620004b0565b600082601f830112620004d7578081fd5b81516001600160401b0380821115620004ec57fe5b6040516020601f8401601f19168201810183811183821017156200050c57fe5b604052838252858401810187101562000523578485fd5b8492505b8383101562000546578583018101518284018201529182019162000527565b838311156200055757848185840101525b5095945050505050565b6000806000806080858703121562000577578384fd5b84516001600160401b03808211156200058e578586fd5b6200059c88838901620004c6565b95506020870151915080821115620005b2578485fd5b50620005c187828801620004c6565b604087015190945090506001600160a01b0381168114620005e0578283fd5b6060959095015193969295505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b6020808252601a908201527f53696465546f6b656e3a204772616e756c6172697479203c2031000000000000604082015260600190565b6121f780620006916000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80637ecebe00116100de578063d95b637111610097578063f698da2511610071578063f698da2514610308578063fad8b32a14610310578063fc673c4f14610323578063fe9d93031461033657610173565b8063d95b6371146102cf578063dcdc7dd0146102e2578063dd62ed3e146102f557610173565b80637ecebe0014610268578063959b8c3f1461027b57806395d89b411461028e5780639bd9bbc614610296578063a9059cbb146102a9578063d505accf146102bc57610173565b806330adf81f1161013057806330adf81f14610208578063313ce567146102105780634000aea014610225578063556f0dc71461023857806362ad1b831461024057806370a082311461025557610173565b806306e485381461017857806306fdde031461019657806307546172146101ab578063095ea7b3146101c057806318160ddd146101e057806323b872dd146101f5575b600080fd5b610180610349565b60405161018d9190611c97565b60405180910390f35b61019e6103ab565b60405161018d9190611d4a565b6101b3610435565b60405161018d9190611b9f565b6101d36101ce3660046119d2565b610444565b60405161018d9190611ce4565b6101e8610466565b60405161018d9190611cef565b6101d3610203366004611881565b61046c565b6101e86105b4565b6102186105d8565b60405161018d9190612128565b6101d36102333660046119fd565b6105dd565b6101e86106eb565b61025361024e3660046118c1565b6106f1565b005b6101e8610263366004611811565b6107a8565b6101e8610276366004611811565b6107c3565b610253610289366004611811565b6107d5565b61019e610902565b6102536102a43660046119fd565b610963565b6101d36102b73660046119d2565b6109cb565b6102536102ca36600461195d565b610a85565b6101d36102dd366004611849565b610bd8565b6102536102f0366004611a57565b610c7a565b6101e8610303366004611849565b610d39565b6101e8610d64565b61025361031e366004611811565b610d6a565b610253610331366004611a57565b610e97565b610253610344366004611ae0565b610f41565b606060048054806020026020016040519081016040528092919081815260200182805480156103a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610383575b5050505050905090565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b820191906000526020600020905b81548152906001019060200180831161041757509395945050505050565b6009546001600160a01b031681565b60008061044f610ffb565b905061045c818585610fff565b5060019392505050565b60015490565b60006001600160a01b03831661049d5760405162461bcd60e51b815260040161049490611e50565b60405180910390fd5b6001600160a01b0384166104c35760405162461bcd60e51b815260040161049490612043565b60006104cd610ffb565b90506104fb81868686604051806020016040528060008152506040518060200160405280600081525061108d565b6105278186868660405180602001604052806000815250604051806020016040528060008152506111bb565b61057b858261057686604051806060016040528060298152602001612176602991396001600160a01b03808c166000908152600860209081526040808320938b168352929052205491906112db565b610fff565b6105a98186868660405180602001604052806000815250604051806020016040528060008152506000611307565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601290565b6000806105e8610ffb565b905061063c8182888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060408051602081019091528181529350915061146e9050565b7fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c168187878787604051610673959493929190611c0d565b60405180910390a1604051635260769b60e11b81526001600160a01b0387169063a4c0ed36906106ad908490899089908990600401611c65565b600060405180830381600087803b1580156106c757600080fd5b505af11580156106db573d6000803e3d6000fd5b5060019998505050505050505050565b600a5490565b6107026106fc610ffb565b88610bd8565b61071e5760405162461bcd60e51b815260040161049490612085565b61079f610729610ffb565b88888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a91508990819084018382808284376000920191909152506001925061146e915050565b50505050505050565b6001600160a01b031660009081526020819052604090205490565b600c6020526000908152604090205481565b806001600160a01b03166107e7610ffb565b6001600160a01b0316141561080e5760405162461bcd60e51b815260040161049490611dcb565b6001600160a01b03811660009081526005602052604090205460ff1615610871576007600061083b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690556108b8565b60016006600061087f610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b6108c0610ffb565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b6109c561096e610ffb565b610976610ffb565b868686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604080516020810190915290815292506001915061146e9050565b50505050565b60006001600160a01b0383166109f35760405162461bcd60e51b815260040161049490611e50565b60006109fd610ffb565b9050610a2b81828686604051806020016040528060008152506040518060200160405280600081525061108d565b610a578182868660405180602001604052806000815250604051806020016040528060008152506111bb565b61045c8182868660405180602001604052806000815250604051806020016040528060008152506000611307565b42841015610aa55760405162461bcd60e51b815260040161049490611fa9565b600b546001600160a01b0388166000908152600c6020908152604080832080546001810190915590519293610b27939092610b0c927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928e928e928e9290918e9101611cf8565b604051602081830303815290604052805190602001206114e5565b9050600060018286868660405160008152602001604052604051610b4e9493929190611d2c565b6020604051602081039080840390855afa158015610b70573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610ba65750886001600160a01b0316816001600160a01b0316145b610bc25760405162461bcd60e51b815260040161049490611f2f565b610bcd898989610fff565b505050505050505050565b6000816001600160a01b0316836001600160a01b03161480610c4357506001600160a01b03831660009081526005602052604090205460ff168015610c4357506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b80610c7357506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b6009546001600160a01b0316610c8e610ffb565b6001600160a01b031614610cb45760405162461bcd60e51b815260040161049490611f66565b610d31610cbf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061150492505050565b505050505050565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b600b5481565b610d72610ffb565b6001600160a01b0316816001600160a01b03161415610da35760405162461bcd60e51b815260040161049490611e0f565b6001600160a01b03811660009081526005602052604090205460ff1615610e0f57600160076000610dd2610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055610e4d565b60066000610e1b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b610e55610ffb565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b610ea8610ea2610ffb565b87610bd8565b610ec45760405162461bcd60e51b815260040161049490612085565b610d31610ecf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061162c92505050565b610f9f610f4c610ffb565b610f54610ffb565b8585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805160208101909152908152925061162c915050565b505050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b3390565b6001600160a01b0382166110255760405162461bcd60e51b8152600401610494906120c6565b6001600160a01b0380841660008181526008602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611080908590611cef565b60405180910390a3505050565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906110e99089907f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89590600401611c4c565b60206040518083038186803b15801561110157600080fd5b505afa158015611115573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611139919061182d565b90506001600160a01b0381161561079f57604051633ad5cbc160e11b81526001600160a01b038216906375ab978290611180908a908a908a908a908a908a90600401611bb3565b600060405180830381600087803b15801561119a57600080fd5b505af11580156111ae573d6000803e3d6000fd5b5050505050505050505050565b6111f88360405180606001604052806027815260200161214f602791396001600160a01b03881660009081526020819052604090205491906112db565b6001600160a01b038087166000908152602081905260408082209390935590861681522054611227908461175d565b6001600160a01b0380861660008181526020819052604090819020939093559151878216918916907f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc8261467798790611280908890889088906120fd565b60405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516112cb9190611cef565b60405180910390a3505050505050565b600081848411156112ff5760405162461bcd60e51b81526004016104949190611d4a565b505050900390565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906113639089907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b90600401611c4c565b60206040518083038186803b15801561137b57600080fd5b505afa15801561138f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b3919061182d565b90506001600160a01b0381161561142f576040516223de2960e01b81526001600160a01b038216906223de29906113f8908b908b908b908b908b908b90600401611bb3565b600060405180830381600087803b15801561141257600080fd5b505af1158015611426573d6000803e3d6000fd5b50505050611464565b811561146457611447866001600160a01b0316611782565b156114645760405162461bcd60e51b815260040161049490611ebc565b5050505050505050565b6001600160a01b0386166114945760405162461bcd60e51b815260040161049490611fd5565b6001600160a01b0385166114ba5760405162461bcd60e51b81526004016104949061200c565b6114c887878787878761108d565b6114d68787878787876111bb565b61079f87878787878787611307565b60405161190160f01b8152600281019290925260228201526042902090565b6001600160a01b03841661152a5760405162461bcd60e51b815260040161049490611e85565b600154611537908461175d565b6001556001600160a01b03841660009081526020819052604090205461155d908461175d565b6001600160a01b03851660009081526020819052604081209190915561158a908690868686866001611307565b836001600160a01b0316856001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d8585856040516115d1939291906120fd565b60405180910390a3836001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b60405180910390a35050505050565b6001600160a01b0384166116525760405162461bcd60e51b815260040161049490611d94565b6116618585600086868661108d565b61169e8360405180606001604052806023815260200161219f602391396001600160a01b03871660009081526020819052604090205491906112db565b6001600160a01b0385166000908152602081905260409020556001546116c49084611788565b600181905550836001600160a01b0316856001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098858585604051611711939291906120fd565b60405180910390a360006001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b600082820183811015610c735760405162461bcd60e51b815260040161049490611d5d565b3b151590565b6000610c7383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506112db565b60008083601f8401126117db578182fd5b50813567ffffffffffffffff8111156117f2578182fd5b60208301915083602082850101111561180a57600080fd5b9250929050565b600060208284031215611822578081fd5b8135610c7381612136565b60006020828403121561183e578081fd5b8151610c7381612136565b6000806040838503121561185b578081fd5b823561186681612136565b9150602083013561187681612136565b809150509250929050565b600080600060608486031215611895578081fd5b83356118a081612136565b925060208401356118b081612136565b929592945050506040919091013590565b600080600080600080600060a0888a0312156118db578283fd5b87356118e681612136565b965060208801356118f681612136565b955060408801359450606088013567ffffffffffffffff80821115611919578485fd5b6119258b838c016117ca565b909650945060808a013591508082111561193d578384fd5b5061194a8a828b016117ca565b989b979a50959850939692959293505050565b600080600080600080600060e0888a031215611977578283fd5b873561198281612136565b9650602088013561199281612136565b95506040880135945060608801359350608088013560ff811681146119b5578384fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156119e4578182fd5b82356119ef81612136565b946020939093013593505050565b60008060008060608587031215611a12578384fd5b8435611a1d81612136565b935060208501359250604085013567ffffffffffffffff811115611a3f578283fd5b611a4b878288016117ca565b95989497509550505050565b60008060008060008060808789031215611a6f578182fd5b8635611a7a81612136565b955060208701359450604087013567ffffffffffffffff80821115611a9d578384fd5b611aa98a838b016117ca565b90965094506060890135915080821115611ac1578384fd5b50611ace89828a016117ca565b979a9699509497509295939492505050565b600080600060408486031215611af4578283fd5b83359250602084013567ffffffffffffffff811115611b11578283fd5b611b1d868287016117ca565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b81811015611b7957602081850181015186830182015201611b5d565b81811115611b8a5782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0387811682528681166020830152851660408201526060810184905260c060808201819052600090611bee90830185611b54565b82810360a0840152611c008185611b54565b9998505050505050505050565b6001600160a01b0386811682528516602082015260408101849052608060608201819052600090611c419083018486611b2a565b979650505050505050565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038616825284602083015260606040830152611c8d606083018486611b2a565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611cd85783516001600160a01b031683529284019291840191600101611cb3565b50909695505050505050565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610c736020830184611b54565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f4552433737373a206275726e2066726f6d207a65726f20616464726573730000604082015260600190565b60208082526024908201527f4552433737373a20617574686f72697a696e672073656c66206173206f70657260408201526330ba37b960e11b606082015260800190565b60208082526021908201527f4552433737373a207265766f6b696e672073656c66206173206f70657261746f6040820152603960f91b606082015260800190565b6020808252818101527f4552433737373a207472616e7366657220746f207a65726f2061646472657373604082015260600190565b6020808252601c908201527f4552433737373a206d696e7420746f207a65726f206164647265737300000000604082015260600190565b6020808252604d908201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460408201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60608201526c1ad95b9cd49958da5c1a595b9d609a1b608082015260a00190565b6020808252601c908201527f53696465546f6b656e3a20494e56414c49445f5349474e415455524500000000604082015260600190565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b60208082526012908201527114da5919551bdad95b8e881156141254915160721b604082015260600190565b6020808252601e908201527f4552433737373a2073656e642066726f6d207a65726f20616464726573730000604082015260600190565b6020808252601c908201527f4552433737373a2073656e6420746f207a65726f206164647265737300000000604082015260600190565b60208082526022908201527f4552433737373a207472616e736665722066726f6d207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526021908201527f4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f6040820152603960f91b606082015260800190565b6020808252601f908201527f4552433737373a20617070726f766520746f207a65726f206164647265737300604082015260600190565b6000848252606060208301526121166060830185611b54565b8281036040840152611c8d8185611b54565b60ff91909116815260200190565b6001600160a01b038116811461214b57600080fd5b5056fe4552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a206275726e20616d6f756e7420657863656564732062616c616e6365a2646970667358221220e96305596548c1ccf5a73d7bede36fbfaeee3f672cbf14157179325f27c57bf764736f6c63430007060033a26469706673582212204cc330cf5079dbaee9f34fb1607540a3d5891d5eeb955ff8beaa47811a8c189964736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 11014,
+ "contract": "contracts/SideTokenFactory/SideTokenFactory.sol:SideTokenFactory",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/WRBTC.json b/bridge/deployments/kovan/WRBTC.json
new file mode 100644
index 000000000..3dc367aac
--- /dev/null
+++ b/bridge/deployments/kovan/WRBTC.json
@@ -0,0 +1,400 @@
+{
+ "address": "0xd0A1E359811322d97991E03f863a0C30C2cF029C",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "guy",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposit",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Withdrawal",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "guy",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "deposit",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdraw",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xa55afc0a86fae3e78c22da4d796f54929788ac921ad83ef5ebf35902982c73ca",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0xcAB50DA63928519b4dD58e3766D90B8E860982D9",
+ "transactionIndex": 0,
+ "gasUsed": "665718",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xdb8404801fc937df8ffbc62579c7ec91193ef9ac5d47401cb5a264ab3ce8090c",
+ "transactionHash": "0xa55afc0a86fae3e78c22da4d796f54929788ac921ad83ef5ebf35902982c73ca",
+ "logs": [],
+ "blockNumber": 2152326,
+ "cumulativeGasUsed": "665718",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/test/WRBTC.sol\":\"WRBTC\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interface/IWrapped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\ninterface IWrapped {\\n function balanceOf(address) external returns(uint);\\n\\n function deposit() external payable;\\n\\n function withdraw(uint wad) external;\\n\\n function totalSupply() external view returns (uint);\\n\\n function approve(address guy, uint wad) external returns (bool);\\n\\n function transfer(address dst, uint wad) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint wad)\\n external\\n returns (bool);\\n}\",\"keccak256\":\"0x2d8a99b6a030e37f01dba86db80e3bd29d1d01e592e399c8635df3fb636ec0d1\",\"license\":\"MIT\"},\"contracts/test/WRBTC.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../interface/IWrapped.sol\\\";\\n\\ncontract WRBTC is IWrapped {\\n string public name = \\\"Wrapped RBTC\\\";\\n string public symbol = \\\"WRBTC\\\";\\n uint8 public decimals = 18;\\n\\n event Approval(address indexed src, address indexed guy, uint wad);\\n event Transfer(address indexed src, address indexed dst, uint wad);\\n event Deposit(address indexed dst, uint wad);\\n event Withdrawal(address indexed src, uint wad);\\n\\n mapping (address => uint) override public balanceOf;\\n mapping (address => mapping (address => uint)) public allowance;\\n\\n receive () external payable {\\n deposit();\\n }\\n function deposit() override public payable {\\n balanceOf[msg.sender] += msg.value;\\n emit Deposit(msg.sender, msg.value);\\n }\\n function withdraw(uint wad) override public {\\n require(balanceOf[msg.sender] >= wad, \\\"WRBTC: Balance less than wad\\\");\\n balanceOf[msg.sender] -= wad;\\n msg.sender.transfer(wad);\\n emit Withdrawal(msg.sender, wad);\\n }\\n\\n function totalSupply() override public view returns (uint) {\\n return address(this).balance;\\n }\\n\\n function approve(address guy, uint wad) override public returns (bool) {\\n allowance[msg.sender][guy] = wad;\\n emit Approval(msg.sender, guy, wad);\\n return true;\\n }\\n\\n function transfer(address dst, uint wad) override public returns (bool) {\\n return transferFrom(msg.sender, dst, wad);\\n }\\n\\n function transferFrom(address src, address dst, uint wad)\\n override public\\n returns (bool)\\n {\\n require(balanceOf[src] >= wad, \\\"WRBTC: Balance less than wad\\\");\\n\\n if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\\n require(allowance[src][msg.sender] >= wad, \\\"WRBTC: Allowance less than wad\\\");\\n allowance[src][msg.sender] -= wad;\\n }\\n\\n balanceOf[src] -= wad;\\n balanceOf[dst] += wad;\\n\\n emit Transfer(src, dst, wad);\\n\\n return true;\\n }\\n}\",\"keccak256\":\"0xf664c159f6302a78c9e6393c00de0c2630dc3e830215dc467a03f17a533b6807\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x60c0604052600c60808190526b57726170706564205242544360a01b60a090815261002d916000919061007a565b5060408051808201909152600580825264575242544360d81b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b5061011b565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826100b057600085556100f6565b82601f106100c957805160ff19168380011785556100f6565b828001600101855582156100f6579182015b828111156100f65782518255916020019190600101906100db565b50610102929150610106565b5090565b5b808211156101025760008155600101610107565b6107d28061012a6000396000f3fe6080604052600436106100a05760003560e01c8063313ce56711610064578063313ce5671461021f57806370a082311461024a57806395d89b411461027d578063a9059cbb14610292578063d0e30db0146102cb578063dd62ed3e146102d3576100af565b806306fdde03146100b4578063095ea7b31461013e57806318160ddd1461018b57806323b872dd146101b25780632e1a7d4d146101f5576100af565b366100af576100ad61030e565b005b600080fd5b3480156100c057600080fd5b506100c961035d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101035781810151838201526020016100eb565b50505050905090810190601f1680156101305780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014a57600080fd5b506101776004803603604081101561016157600080fd5b506001600160a01b0381351690602001356103eb565b604080519115158252519081900360200190f35b34801561019757600080fd5b506101a0610451565b60408051918252519081900360200190f35b3480156101be57600080fd5b50610177600480360360608110156101d557600080fd5b506001600160a01b03813581169160208101359091169060400135610455565b34801561020157600080fd5b506100ad6004803603602081101561021857600080fd5b5035610619565b34801561022b57600080fd5b506102346106f6565b6040805160ff9092168252519081900360200190f35b34801561025657600080fd5b506101a06004803603602081101561026d57600080fd5b50356001600160a01b03166106ff565b34801561028957600080fd5b506100c9610711565b34801561029e57600080fd5b50610177600480360360408110156102b557600080fd5b506001600160a01b03813516906020013561076b565b6100ad61030e565b3480156102df57600080fd5b506101a0600480360360408110156102f657600080fd5b506001600160a01b038135811691602001351661077f565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b820191906000526020600020905b8154815290600101906020018083116103c657829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b6001600160a01b0383166000908152600360205260408120548211156104c2576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b6001600160a01b038416331480159061050057506001600160a01b038416600090815260046020908152604080832033845290915290205460001914155b156105a8576001600160a01b038416600090815260046020908152604080832033845290915290205482111561057d576040805162461bcd60e51b815260206004820152601e60248201527f57524254433a20416c6c6f77616e6365206c657373207468616e207761640000604482015290519081900360640190fd5b6001600160a01b03841660009081526004602090815260408083203384529091529020805483900390555b6001600160a01b03808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561067d576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106bc573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b6000610778338484610455565b9392505050565b60046020908152600092835260408084209091529082529020548156fea26469706673582212202d01111733e2aa80d67d08b8b3a53d89aabe0e468d80eba287b4a34d46db4ab564736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106100a05760003560e01c8063313ce56711610064578063313ce5671461021f57806370a082311461024a57806395d89b411461027d578063a9059cbb14610292578063d0e30db0146102cb578063dd62ed3e146102d3576100af565b806306fdde03146100b4578063095ea7b31461013e57806318160ddd1461018b57806323b872dd146101b25780632e1a7d4d146101f5576100af565b366100af576100ad61030e565b005b600080fd5b3480156100c057600080fd5b506100c961035d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101035781810151838201526020016100eb565b50505050905090810190601f1680156101305780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014a57600080fd5b506101776004803603604081101561016157600080fd5b506001600160a01b0381351690602001356103eb565b604080519115158252519081900360200190f35b34801561019757600080fd5b506101a0610451565b60408051918252519081900360200190f35b3480156101be57600080fd5b50610177600480360360608110156101d557600080fd5b506001600160a01b03813581169160208101359091169060400135610455565b34801561020157600080fd5b506100ad6004803603602081101561021857600080fd5b5035610619565b34801561022b57600080fd5b506102346106f6565b6040805160ff9092168252519081900360200190f35b34801561025657600080fd5b506101a06004803603602081101561026d57600080fd5b50356001600160a01b03166106ff565b34801561028957600080fd5b506100c9610711565b34801561029e57600080fd5b50610177600480360360408110156102b557600080fd5b506001600160a01b03813516906020013561076b565b6100ad61030e565b3480156102df57600080fd5b506101a0600480360360408110156102f657600080fd5b506001600160a01b038135811691602001351661077f565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b820191906000526020600020905b8154815290600101906020018083116103c657829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b6001600160a01b0383166000908152600360205260408120548211156104c2576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b6001600160a01b038416331480159061050057506001600160a01b038416600090815260046020908152604080832033845290915290205460001914155b156105a8576001600160a01b038416600090815260046020908152604080832033845290915290205482111561057d576040805162461bcd60e51b815260206004820152601e60248201527f57524254433a20416c6c6f77616e6365206c657373207468616e207761640000604482015290519081900360640190fd5b6001600160a01b03841660009081526004602090815260408083203384529091529020805483900390555b6001600160a01b03808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561067d576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106bc573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b6000610778338484610455565b9392505050565b60046020908152600092835260408084209091529082529020548156fea26469706673582212202d01111733e2aa80d67d08b8b3a53d89aabe0e468d80eba287b4a34d46db4ab564736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {},
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 9308,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "name",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 9311,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "symbol",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 9314,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "decimals",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint8"
+ },
+ {
+ "astId": 9347,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "balanceOf",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_mapping(t_address,t_uint256)"
+ },
+ {
+ "astId": 9353,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "allowance",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_uint256))": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_uint256)"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "encoding": "inplace",
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/WTBTC.json b/bridge/deployments/kovan/WTBTC.json
new file mode 100644
index 000000000..06e3bd937
--- /dev/null
+++ b/bridge/deployments/kovan/WTBTC.json
@@ -0,0 +1,460 @@
+{
+ "address": "0x4CCc35c8f2e780203C5DC4b605F495ACEa9255bc",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "initialSupply",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "subtractedValue",
+ "type": "uint256"
+ }
+ ],
+ "name": "decreaseAllowance",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "addedValue",
+ "type": "uint256"
+ }
+ ],
+ "name": "increaseAllowance",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "supply",
+ "type": "uint256"
+ }
+ ],
+ "name": "mint",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x8174f2bd3512e25f33d2edbb9a2a9ac162823b6217b7cb38ae8aec8afc82e349",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x4CCc35c8f2e780203C5DC4b605F495ACEa9255bc",
+ "transactionIndex": 0,
+ "gasUsed": "780825",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000004000000000000000000000000000000000000008000000000000000000000000000000000100000000002000020000000000000000000800000000000000000000000010000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000020000000000000200000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xe5b11677e85b255bcd96bb1044c1fca60e63075abbb456fd465f0ec340ebcab8",
+ "transactionHash": "0x8174f2bd3512e25f33d2edbb9a2a9ac162823b6217b7cb38ae8aec8afc82e349",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 28555001,
+ "transactionHash": "0x8174f2bd3512e25f33d2edbb9a2a9ac162823b6217b7cb38ae8aec8afc82e349",
+ "address": "0x4CCc35c8f2e780203C5DC4b605F495ACEa9255bc",
+ "topics": [
+ "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8"
+ ],
+ "data": "0x0000000000000000000000000000002c14beeaa50af71f8196f0118000000000",
+ "logIndex": 0,
+ "blockHash": "0xe5b11677e85b255bcd96bb1044c1fca60e63075abbb456fd465f0ec340ebcab8"
+ }
+ ],
+ "blockNumber": 28555001,
+ "cumulativeGasUsed": "780825",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "15000000000000000000000000000000000000000"
+ ],
+ "solcInputHash": "7a48ec801ec0f5d1e7af76fbc81bb365",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.0+commit.c7dfd78e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"initialSupply\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"supply\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}; Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for `sender`'s tokens of at least `amount`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/test/WTBTC.sol\":\"WTBTC\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/test/WTBTC.sol\":{\"content\":\"// Sources flattened with hardhat v2.6.1 https://hardhat.org\\n\\n// SPDX-License-Identifier: MIT\\nimport \\\"../zeppelin/token/ERC20/ERC20.sol\\\";\\n\\npragma solidity ^0.8.0;\\n\\ncontract WTBTC is ERC20 {\\n string public name = \\\"Ethereum Test BTC\\\";\\n string public symbol = \\\"WTBTC\\\";\\n uint8 public decimals = 18;\\n\\n constructor(uint256 initialSupply) {\\n _mint(msg.sender, initialSupply);\\n }\\n\\n function mint(uint256 supply) external {\\n _mint(msg.sender, supply);\\n }\\n\\n}\",\"keccak256\":\"0x1bc77c27fd7d35d0fdf48603adb3f079d815a5a05b9016b707801c4546b9e5e2\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return payable(msg.sender);\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x6f3f274a2270bfe073339370edfa2485e2d515a2656039937f6b972fae96d297\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x8038a6eca31e013b0c7f248c7a4eb5846ab0d52bb3f7636fafcf00b075643afe\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20Mintable}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() override public view returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) override public view returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) override public returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) override public view returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) override public returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20};\\n *\\n * Requirements:\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for `sender`'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal {\\n require(sender != address(0), \\\"ERC20: transfer from zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to zero address\\\");\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal {\\n require(account != address(0), \\\"ERC20: mint to zero address\\\");\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal {\\n require(account != address(0), \\\"ERC20: burn from zero address\\\");\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\\n *\\n * This is internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal {\\n require(owner != address(0), \\\"ERC20: approve from zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\\n * from the caller's allowance.\\n *\\n * See {_burn} and {_approve}.\\n */\\n function _burnFrom(address account, uint256 amount) internal {\\n _burn(account, amount);\\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \\\"ERC20: burn amount exceeds allowance\\\"));\\n }\\n}\\n\",\"keccak256\":\"0x3d82d998d70e0566ebab88b6ca3d508cbf792ecb2e5e24e05673ae904e1a7bd8\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {ERC20Detailed}.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xdb194e173849ac56dbc15eaf0c01848361748ff8e4679985c3d11013ee4fa4b6\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x60c06040526011608081905270457468657265756d20546573742042544360781b60a0908152620000349160039190620001cd565b5060408051808201909152600580825264575442544360d81b60209092019182526200006391600491620001cd565b506005805460ff191660121790553480156200007e57600080fd5b5060405162000e5238038062000e52833981016040819052620000a19162000273565b620000ad3382620000b4565b5062000365565b6001600160a01b038216620000e65760405162461bcd60e51b8152600401620000dd90620002c3565b60405180910390fd5b62000102816002546200019260201b6200041f1790919060201c565b6002556001600160a01b03821660009081526020818152604090912054620001359183906200041f62000192821b17901c565b6001600160a01b0383166000818152602081905260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9062000186908590620002fa565b60405180910390a35050565b600080620001a1838562000303565b905083811015620001c65760405162461bcd60e51b8152600401620000dd906200028c565b9392505050565b828054620001db9062000328565b90600052602060002090601f016020900481019282620001ff57600085556200024a565b82601f106200021a57805160ff19168380011785556200024a565b828001600101855582156200024a579182015b828111156200024a5782518255916020019190600101906200022d565b50620002589291506200025c565b5090565b5b808211156200025857600081556001016200025d565b60006020828403121562000285578081fd5b5051919050565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601b908201527f45524332303a206d696e7420746f207a65726f20616464726573730000000000604082015260600190565b90815260200190565b600082198211156200032357634e487b7160e01b81526011600452602481fd5b500190565b6002810460018216806200033d57607f821691505b602082108114156200035f57634e487b7160e01b600052602260045260246000fd5b50919050565b610add80620003756000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c806370a082311161007157806370a082311461014757806395d89b411461015a578063a0712d6814610162578063a457c2d714610177578063a9059cbb1461018a578063dd62ed3e1461019d576100b4565b806306fdde03146100b9578063095ea7b3146100d757806318160ddd146100f757806323b872dd1461010c578063313ce5671461011f5780633950935114610134575b600080fd5b6100c16101b0565b6040516100ce91906107f8565b60405180910390f35b6100ea6100e53660046107ac565b61023e565b6040516100ce91906107ed565b6100ff61025b565b6040516100ce919061099d565b6100ea61011a366004610771565b610261565b6101276102e8565b6040516100ce91906109a6565b6100ea6101423660046107ac565b6102f1565b6100ff610155366004610725565b61033f565b6100c161035e565b6101756101703660046107d5565b61036b565b005b6100ea6101853660046107ac565b610378565b6100ea6101983660046107ac565b6103e0565b6100ff6101ab36600461073f565b6103f4565b600380546101bd906109e3565b80601f01602080910402602001604051908101604052809291908181526020018280546101e9906109e3565b80156102365780601f1061020b57610100808354040283529160200191610236565b820191906000526020600020905b81548152906001019060200180831161021957829003601f168201915b505050505081565b600061025261024b61045e565b8484610462565b50600192915050565b60025490565b600061026e848484610516565b6102de8461027a61045e565b6102d985604051806060016040528060288152602001610a5b602891396001600160a01b038a166000908152600160205260408120906102b861045e565b6001600160a01b031681526020810191909152604001600020549190610620565b610462565b5060019392505050565b60055460ff1681565b60006102526102fe61045e565b846102d9856001600061030f61045e565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549061041f565b6001600160a01b0381166000908152602081905260409020545b919050565b600480546101bd906109e3565b610375338261065a565b50565b600061025261038561045e565b846102d985604051806060016040528060258152602001610a8360259139600160006103af61045e565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610620565b60006102526103ed61045e565b8484610516565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60008061042c83856109b4565b9050838110156104575760405162461bcd60e51b815260040161044e90610882565b60405180910390fd5b9392505050565b3390565b6001600160a01b0383166104885760405162461bcd60e51b815260040161044e90610968565b6001600160a01b0382166104ae5760405162461bcd60e51b815260040161044e9061084b565b6001600160a01b0380841660008181526001602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061050990859061099d565b60405180910390a3505050565b6001600160a01b03831661053c5760405162461bcd60e51b815260040161044e906108b9565b6001600160a01b0382166105625760405162461bcd60e51b815260040161044e906108fa565b61059f81604051806060016040528060268152602001610a35602691396001600160a01b0386166000908152602081905260409020549190610620565b6001600160a01b0380851660009081526020819052604080822093909355908416815220546105ce908261041f565b6001600160a01b0380841660008181526020819052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061050990859061099d565b600081848411156106445760405162461bcd60e51b815260040161044e91906107f8565b50600061065184866109cc565b95945050505050565b6001600160a01b0382166106805760405162461bcd60e51b815260040161044e90610931565b60025461068d908261041f565b6002556001600160a01b0382166000908152602081905260409020546106b3908261041f565b6001600160a01b0383166000818152602081905260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061070290859061099d565b60405180910390a35050565b80356001600160a01b038116811461035957600080fd5b600060208284031215610736578081fd5b6104578261070e565b60008060408385031215610751578081fd5b61075a8361070e565b91506107686020840161070e565b90509250929050565b600080600060608486031215610785578081fd5b61078e8461070e565b925061079c6020850161070e565b9150604084013590509250925092565b600080604083850312156107be578182fd5b6107c78361070e565b946020939093013593505050565b6000602082840312156107e6578081fd5b5035919050565b901515815260200190565b6000602080835283518082850152825b8181101561082457858101830151858201604001528201610808565b818111156108355783604083870101525b50601f01601f1916929092016040019392505050565b6020808252601e908201527f45524332303a20617070726f766520746f207a65726f20616464726573730000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526021908201527f45524332303a207472616e736665722066726f6d207a65726f206164647265736040820152607360f81b606082015260800190565b6020808252601f908201527f45524332303a207472616e7366657220746f207a65726f206164647265737300604082015260600190565b6020808252601b908201527f45524332303a206d696e7420746f207a65726f20616464726573730000000000604082015260600190565b6020808252818101527f45524332303a20617070726f76652066726f6d207a65726f2061646472657373604082015260600190565b90815260200190565b60ff91909116815260200190565b600082198211156109c7576109c7610a1e565b500190565b6000828210156109de576109de610a1e565b500390565b6002810460018216806109f757607f821691505b60208210811415610a1857634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fdfe45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220ffdf1e8acdd112d323e90b33448577205883596d7e94ee827d263fcca9ebc15e64736f6c63430008000033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100b45760003560e01c806370a082311161007157806370a082311461014757806395d89b411461015a578063a0712d6814610162578063a457c2d714610177578063a9059cbb1461018a578063dd62ed3e1461019d576100b4565b806306fdde03146100b9578063095ea7b3146100d757806318160ddd146100f757806323b872dd1461010c578063313ce5671461011f5780633950935114610134575b600080fd5b6100c16101b0565b6040516100ce91906107f8565b60405180910390f35b6100ea6100e53660046107ac565b61023e565b6040516100ce91906107ed565b6100ff61025b565b6040516100ce919061099d565b6100ea61011a366004610771565b610261565b6101276102e8565b6040516100ce91906109a6565b6100ea6101423660046107ac565b6102f1565b6100ff610155366004610725565b61033f565b6100c161035e565b6101756101703660046107d5565b61036b565b005b6100ea6101853660046107ac565b610378565b6100ea6101983660046107ac565b6103e0565b6100ff6101ab36600461073f565b6103f4565b600380546101bd906109e3565b80601f01602080910402602001604051908101604052809291908181526020018280546101e9906109e3565b80156102365780601f1061020b57610100808354040283529160200191610236565b820191906000526020600020905b81548152906001019060200180831161021957829003601f168201915b505050505081565b600061025261024b61045e565b8484610462565b50600192915050565b60025490565b600061026e848484610516565b6102de8461027a61045e565b6102d985604051806060016040528060288152602001610a5b602891396001600160a01b038a166000908152600160205260408120906102b861045e565b6001600160a01b031681526020810191909152604001600020549190610620565b610462565b5060019392505050565b60055460ff1681565b60006102526102fe61045e565b846102d9856001600061030f61045e565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549061041f565b6001600160a01b0381166000908152602081905260409020545b919050565b600480546101bd906109e3565b610375338261065a565b50565b600061025261038561045e565b846102d985604051806060016040528060258152602001610a8360259139600160006103af61045e565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610620565b60006102526103ed61045e565b8484610516565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60008061042c83856109b4565b9050838110156104575760405162461bcd60e51b815260040161044e90610882565b60405180910390fd5b9392505050565b3390565b6001600160a01b0383166104885760405162461bcd60e51b815260040161044e90610968565b6001600160a01b0382166104ae5760405162461bcd60e51b815260040161044e9061084b565b6001600160a01b0380841660008181526001602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061050990859061099d565b60405180910390a3505050565b6001600160a01b03831661053c5760405162461bcd60e51b815260040161044e906108b9565b6001600160a01b0382166105625760405162461bcd60e51b815260040161044e906108fa565b61059f81604051806060016040528060268152602001610a35602691396001600160a01b0386166000908152602081905260409020549190610620565b6001600160a01b0380851660009081526020819052604080822093909355908416815220546105ce908261041f565b6001600160a01b0380841660008181526020819052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061050990859061099d565b600081848411156106445760405162461bcd60e51b815260040161044e91906107f8565b50600061065184866109cc565b95945050505050565b6001600160a01b0382166106805760405162461bcd60e51b815260040161044e90610931565b60025461068d908261041f565b6002556001600160a01b0382166000908152602081905260409020546106b3908261041f565b6001600160a01b0383166000818152602081905260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061070290859061099d565b60405180910390a35050565b80356001600160a01b038116811461035957600080fd5b600060208284031215610736578081fd5b6104578261070e565b60008060408385031215610751578081fd5b61075a8361070e565b91506107686020840161070e565b90509250929050565b600080600060608486031215610785578081fd5b61078e8461070e565b925061079c6020850161070e565b9150604084013590509250925092565b600080604083850312156107be578182fd5b6107c78361070e565b946020939093013593505050565b6000602082840312156107e6578081fd5b5035919050565b901515815260200190565b6000602080835283518082850152825b8181101561082457858101830151858201604001528201610808565b818111156108355783604083870101525b50601f01601f1916929092016040019392505050565b6020808252601e908201527f45524332303a20617070726f766520746f207a65726f20616464726573730000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526021908201527f45524332303a207472616e736665722066726f6d207a65726f206164647265736040820152607360f81b606082015260800190565b6020808252601f908201527f45524332303a207472616e7366657220746f207a65726f206164647265737300604082015260600190565b6020808252601b908201527f45524332303a206d696e7420746f207a65726f20616464726573730000000000604082015260600190565b6020808252818101527f45524332303a20617070726f76652066726f6d207a65726f2061646472657373604082015260600190565b90815260200190565b60ff91909116815260200190565b600082198211156109c7576109c7610a1e565b500190565b6000828210156109de576109de610a1e565b500390565b6002810460018216806109f757607f821691505b60208210811415610a1857634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fdfe45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220ffdf1e8acdd112d323e90b33448577205883596d7e94ee827d263fcca9ebc15e64736f6c63430008000033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "allowance(address,address)": {
+ "details": "See {IERC20-allowance}."
+ },
+ "approve(address,uint256)": {
+ "details": "See {IERC20-approve}. Requirements: - `spender` cannot be the zero address."
+ },
+ "balanceOf(address)": {
+ "details": "See {IERC20-balanceOf}."
+ },
+ "decreaseAllowance(address,uint256)": {
+ "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`."
+ },
+ "increaseAllowance(address,uint256)": {
+ "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address."
+ },
+ "totalSupply()": {
+ "details": "See {IERC20-totalSupply}."
+ },
+ "transfer(address,uint256)": {
+ "details": "See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`."
+ },
+ "transferFrom(address,address,uint256)": {
+ "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}; Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for `sender`'s tokens of at least `amount`."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 13920,
+ "contract": "contracts/test/WTBTC.sol:WTBTC",
+ "label": "_balances",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_address,t_uint256)"
+ },
+ {
+ "astId": 13926,
+ "contract": "contracts/test/WTBTC.sol:WTBTC",
+ "label": "_allowances",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))"
+ },
+ {
+ "astId": 13928,
+ "contract": "contracts/test/WTBTC.sol:WTBTC",
+ "label": "_totalSupply",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 10955,
+ "contract": "contracts/test/WTBTC.sol:WTBTC",
+ "label": "name",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 10958,
+ "contract": "contracts/test/WTBTC.sol:WTBTC",
+ "label": "symbol",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 10961,
+ "contract": "contracts/test/WTBTC.sol:WTBTC",
+ "label": "decimals",
+ "offset": 0,
+ "slot": "5",
+ "type": "t_uint8"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_uint256))": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_uint256)"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "encoding": "inplace",
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/solcInputs/257bf35cfef475bad06cad6d9dd245f2.json b/bridge/deployments/kovan/solcInputs/257bf35cfef475bad06cad6d9dd245f2.json
new file mode 100644
index 000000000..fc67aa92f
--- /dev/null
+++ b/bridge/deployments/kovan/solcInputs/257bf35cfef475bad06cad6d9dd245f2.json
@@ -0,0 +1,270 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/math/SafeMath.sol\";\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\n\nimport \"../interface/IAllowTokens.sol\";\n\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\n\tusing SafeMath for uint256;\n\n\taddress constant private NULL_ADDRESS = address(0);\n\tuint256 constant public MAX_TYPES = 250;\n\tmapping (address => TokenInfo) public allowedTokens;\n\tmapping (uint256 => Limits) public typeLimits;\n\tuint256 public smallAmountConfirmations;\n\tuint256 public mediumAmountConfirmations;\n\tuint256 public largeAmountConfirmations;\n\tstring[] public typeDescriptions;\n\n\tevent SetToken(address indexed _tokenAddress, uint256 _typeId);\n\tevent AllowedTokenRemoved(address indexed _tokenAddress);\n\tevent TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\n\tevent TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\n\tevent UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\n\tevent ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\n\n\tmodifier notNull(address _address) {\n\t\trequire(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\n\t\t_;\n\t}\n\n\tfunction initialize(\n\t\taddress _manager,\n\t\taddress _primary,\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations,\n\t\tTypeInfo[] memory typesInfo) public initializer {\n\t\tUpgradableOwnable.initialize(_manager);\n\t\tUpgradableSecondary.__Secondary_init(_primary);\n\t\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t\tfor(uint i = 0; i < typesInfo.length; i = i + 1) {\n\t\t\t_addTokenType(typesInfo[i].description, typesInfo[i].limits);\n\t\t}\n\t}\n\n\tfunction version() override external pure returns (string memory) {\n\t\treturn \"v1\";\n\t}\n\n\tfunction tokenInfo(address tokenAddress) public view returns(TokenInfo memory) {\n\t\treturn allowedTokens[tokenAddress];\n\t}\n\n\tfunction setTokenInfoByTokenAddress(address tokenAddress, TokenInfo memory info) internal {\n\t\trequire(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n\t\tallowedTokens[tokenAddress] = info;\n\t}\n\n\tfunction getInfoAndLimits(\n\t\taddress tokenAddress\n\t) public view override returns (\n\t\tTokenInfo memory info,\n\t\tLimits memory limit\n\t) {\n\t\tinfo = tokenInfo(tokenAddress);\n\t\tlimit = typeLimits[info.typeId];\n\t\treturn (info, limit);\n\t}\n\n\tfunction calcMaxWithdraw(address token) public view override returns (uint256 maxWithdraw) {\n\t\t(TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\n\t\treturn _calcMaxWithdraw(info, limits);\n\t}\n\n\tfunction _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\n\t\t// solium-disable-next-line security/no-block-members\n\t\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n\t\t\tinfo.spentToday = 0;\n\t\t}\n\t\tif (limits.daily <= info.spentToday) {\n\t\t\treturn 0;\n\t\t}\n\t\tmaxWithdraw = limits.daily - info.spentToday;\n\t\tif (maxWithdraw > limits.max) {\n\t\t\tmaxWithdraw = limits.max;\n\t\t}\n\t\treturn maxWithdraw;\n\t}\n\n\tfunction updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\n\t\t(TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\n\t\trequire(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\n\t\trequire(amount >= limit.min, \"AllowTokens: Lower than limit\");\n\n\t\t// solium-disable-next-line security/no-block-members\n\t\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n\t\t\t// solium-disable-next-line security/no-block-members\n\t\t\tinfo.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n\t\t\tinfo.spentToday = 0;\n\t\t}\n\t\tuint maxWithdraw = _calcMaxWithdraw(info, limit);\n\t\trequire(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\n\t\tinfo.spentToday = info.spentToday.add(amount);\n\t\tsetTokenInfoByTokenAddress(token, info);\n\n\t\temit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\n\t}\n\n\tfunction _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\n\t\trequire(bytes(description).length > 0, \"AllowTokens: Empty description\");\n\t\tlen = typeDescriptions.length;\n\t\trequire(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\n\t\ttypeDescriptions.push(description);\n\t\t_setTypeLimits(len, limits);\n\t\temit TokenTypeAdded(len, description);\n\t\treturn len;\n\t}\n\n\tfunction addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\n\t\treturn _addTokenType(description, limits);\n\t}\n\n\tfunction _setTypeLimits(uint256 typeId, Limits memory limits) private {\n\t\trequire(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\n\t\trequire(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\n\t\trequire(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\n\t\trequire(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\n\t\trequire(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\n\t\ttypeLimits[typeId] = limits;\n\t\temit TypeLimitsChanged(typeId, limits);\n\t}\n\n\tfunction setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\n\t\t_setTypeLimits(typeId, limits);\n\t}\n\n\tfunction getTypesLimits() external view override returns(Limits[] memory limits) {\n\t\tlimits = new Limits[](typeDescriptions.length);\n\t\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\n\t\t\tlimits[i] = typeLimits[i];\n\t\t}\n\t\treturn limits;\n\t}\n\n\tfunction getTypeDescriptionsLength() external view override returns(uint256) {\n\t\treturn typeDescriptions.length;\n\t}\n\n\tfunction getTypeDescriptions() external view override returns(string[] memory descriptions) {\n\t\tdescriptions = new string[](typeDescriptions.length);\n\t\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\n\t\t\tdescriptions[i] = typeDescriptions[i];\n\t\t}\n\t\treturn descriptions;\n\t}\n\n\tfunction isTokenAllowed(address token) public view notNull(token) override returns (bool) {\n\t\treturn tokenInfo(token).allowed;\n\t}\n\n\tfunction setToken(address token, uint256 typeId) override public notNull(token) {\n\t\trequire(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n\t\trequire(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\n\t\tTokenInfo memory info = tokenInfo(token);\n\t\tinfo.allowed = true;\n\t\tinfo.typeId = typeId;\n\t\tsetTokenInfoByTokenAddress(token, info);\n\t\temit SetToken(token, typeId);\n\t}\n\n\tfunction setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\n\t\trequire(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\n\t\tfor(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\n\t\t\tsetToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\n\t\t}\n\t}\n\n\tfunction removeAllowedToken(address token) external notNull(token) onlyOwner {\n\t\tTokenInfo memory info = tokenInfo(token);\n\t\trequire(info.allowed, \"AllowTokens: Not Allowed\");\n\t\tinfo.allowed = false;\n\t\tsetTokenInfoByTokenAddress(token, info);\n\t\temit AllowedTokenRemoved(token);\n\t}\n\n\tfunction setConfirmations(\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations) external onlyOwner {\n\t\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t}\n\n\tfunction _setConfirmations(\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations) private {\n\t\trequire(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\n\t\trequire(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\n\t\tsmallAmountConfirmations = _smallAmountConfirmations;\n\t\tmediumAmountConfirmations = _mediumAmountConfirmations;\n\t\tlargeAmountConfirmations = _largeAmountConfirmations;\n\t\temit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t}\n\n\tfunction getConfirmations() external view override\n\t\treturns (\n\t\tuint256 smallAmount,\n\t\tuint256 mediumAmount,\n\t\tuint256 largeAmount\n\t) {\n\t\treturn (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\n\t}\n\n}\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @title Initializable\n *\n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(initializing || !initialized, \"Contract instance is already initialized\");\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\n * the owner.\n */\ncontract UpgradableOwnable is Initializable, Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function initialize(address sender) public initializer {\n _owner = sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * > Note: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\ncontract UpgradableSecondary is Initializable, Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n function __Secondary_init(address sender) public initializer {\n _primary = sender;\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(recipient);\n }\n\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IAllowTokens {\n\n\tstruct Limits {\n\t\tuint256 min;\n\t\tuint256 max;\n\t\tuint256 daily;\n\t\tuint256 mediumAmount;\n\t\tuint256 largeAmount;\n\t}\n\n\tstruct TokenInfo {\n\t\tbool allowed;\n\t\tuint256 typeId;\n\t\tuint256 spentToday;\n\t\tuint256 lastDay;\n\t}\n\n\tstruct TypeInfo {\n\t\tstring description;\n\t\tLimits limits;\n\t}\n\n\tstruct TokensAndType {\n\t\taddress token;\n\t\tuint256 typeId;\n\t}\n\n\tfunction version() external pure returns (string memory);\n\n\tfunction getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\n\n\tfunction calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\n\n\tfunction getTypesLimits() external view returns(Limits[] memory limits);\n\n\tfunction getTypeDescriptionsLength() external view returns(uint256);\n\n\tfunction getTypeDescriptions() external view returns(string[] memory descriptions);\n\n\tfunction setToken(address token, uint256 typeId) external;\n\n\tfunction getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\n\n\tfunction isTokenAllowed(address token) external view returns (bool);\n\n\tfunction updateTokenTransfer(address token, uint256 amount) external;\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n\n function _msgSender() internal view returns (address payable) {\n return payable(msg.sender);\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
+ },
+ "contracts/Bridge/BridgeV3.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// import \"hardhat/console.sol\";\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./IBridgeV3.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n\ncontract BridgeV3 is Initializable, IBridgeV3, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant internal NULL_ADDRESS = address(0);\n bytes32 constant internal NULL_HASH = bytes32(0);\n IERC1820Registry constant internal erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address internal federation;\n uint256 internal feePercentage;\n string public symbolPrefix;\n bytes32 public DOMAIN_SEPARATOR; // replaces uint256 internal _depprecatedLastDay;\n uint256 internal _deprecatedSpentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n uint256 constant public feePercentageDivider = 10000; // Porcentage with up to 2 decimals\n //Bridge_v3 variables\n bytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\");\n IWrapped public wrappedCurrency;\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n // keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\n mapping(address => uint) public nonces;\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool _isUpgrading);\n event WrappedCurrencyChanged(address _wrappedCurrency);\n\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n federation = _federation;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n initDomainSeparator();\n }\n\n receive () external payable {\n // The fallback function is needed to use WRBTC\n require(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n }\n\n function version() override external pure returns (string memory) {\n return \"v3\";\n }\n\n function initDomainSeparator() public {\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n DOMAIN_SEPARATOR = LibEIP712.hashEIP712Domain(\n \"RSK Token Bridge\",\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"Bridge: Not Federation\");\n require(knownTokens[_originalTokenAddress] ||\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\n \"Bridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"Bridge: Null To\");\n require(_amount > 0, \"Bridge: Amount 0\");\n require(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _amount,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed also has the previously processed using the older bridge version\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n require(!claimed[_transactionDataHash], \"Bridge: Already claimed\");\n\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\n senderAddresses[_transactionHash] = _from;\n\n emit AcceptedCrossTransfer(\n _transactionHash,\n _originalTokenAddress,\n _to,\n _from,\n _amount,\n _blockHash,\n _logIndex\n );\n }\n\n\n function createSideToken(\n uint256 _typeId,\n address _originalTokenAddress,\n uint8 _originalTokenDecimals,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n address sideToken = mappedTokens[_originalTokenAddress];\n require(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\n\n mappedTokens[_originalTokenAddress] = sideToken;\n originalTokens[sideToken] = _originalTokenAddress;\n allowTokens.setToken(sideToken, _typeId);\n\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\n }\n\n function claim(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function claimFallback(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n receivedAmount = _claim(\n _claimData,\n _msgSender(),\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function getDigest(\n ClaimData memory _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline\n ) internal returns (bytes32) {\n return LibEIP712.hashEIP712Message(\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n CLAIM_TYPEHASH,\n _claimData.to,\n _claimData.amount,\n _claimData.transactionHash,\n _relayer,\n _fee,\n nonces[_claimData.to]++,\n _deadline\n )\n )\n );\n }\n\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external override returns (uint256 receivedAmount) {\n require(_deadline >= block.timestamp, \"Bridge: EXPIRED\");\n\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claim(\n ClaimData calldata _claimData,\n address payable _reciever,\n address payable _relayer,\n uint256 _fee\n ) internal nonReentrant returns (uint256 receivedAmount) {\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n require(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.amount,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n require(!claimed[transactionDataHash], \"Bridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (knownTokens[originalTokenAddress]) {\n receivedAmount =_claimCrossBackToToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n } else {\n receivedAmount =_claimCrossToSideToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n }\n emit Claimed(\n _claimData.transactionHash,\n originalTokenAddress,\n _claimData.to,\n senderAddresses[_claimData.transactionHash],\n _claimData.amount,\n _claimData.blockHash,\n _claimData.logIndex,\n _reciever,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claimCrossToSideToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n address sideToken = mappedTokens[_originalTokenAddress];\n uint256 granularity = IERC777(sideToken).granularity();\n uint256 formattedAmount = _amount.mul(granularity);\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n ISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n if(_fee > 0) {\n ISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n }\n return receivedAmount;\n }\n\n function _claimCrossBackToToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n //As side tokens are ERC777 they will always have 18 decimals\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n if(address(wrappedCurrency) == _originalTokenAddress) {\n wrappedCurrency.withdraw(formattedAmount);\n _receiver.transfer(receivedAmount);\n if(_fee > 0) {\n _relayer.transfer(_fee);\n }\n } else {\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n if(_fee > 0) {\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n }\n }\n return receivedAmount;\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\n address sender = _msgSender();\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, to, amount, \"\");\n }\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) override external payable {\n address sender = _msgSender();\n require(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n wrappedCurrency.deposit{ value: msg.value }();\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \"\");\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external override(IBridgeV3, IERC777Recipient){\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to this address\");\n address tokenToUse = _msgSender();\n require(erc1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n require(userData.length != 0 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\n crossTokens(tokenToUse, from, receiver, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\n internal whenNotUpgrading whenNotPaused nonReentrant {\n knownTokens[tokenToUse] = true;\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n uint256 amountMinusFees = amount.sub(fee);\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n // We consider the amount before fees converted to 18 decimals to check the limits\n // updateTokenTransfer revert if token not allowed\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n address originalTokenAddress = tokenToUse;\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\n //Side Token Crossing\n originalTokenAddress = originalTokens[tokenToUse];\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\n uint256 modulo = amountMinusFees.mod(granularity);\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n }\n\n emit Cross(\n originalTokenAddress,\n from,\n to,\n amountMinusFees,\n userData\n );\n\n if (fee > 0) {\n //Send the payment to the MultiSig of the Federation\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n }\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n )\n public pure override returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n }\n\n function setFeePercentage(uint amount) external onlyOwner {\n require(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() external view override returns(uint) {\n return feePercentage;\n }\n\n function changeFederation(address newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n require(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n wrappedCurrency = IWrapped(_wrappedCurrency);\n emit WrappedCurrencyChanged(_wrappedCurrency);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionsDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionsDataHashes[transactionHash]];\n }\n\n}"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\n/**\n * @title Helps contracts guard against reentrancy attacks.\n * @author Remco Bloemen , Eenae \n * @dev If you mark a function `nonReentrant`, you should also\n * mark it `external`.\n */\ncontract ReentrancyGuard is Initializable {\n /// @dev counter to allow mutex lock with only one SSTORE operation\n uint256 private _guardCounter;\n\n function initialize() public initializer {\n // The counter starts at one to prevent changing it from zero to a non-zero\n // value, which is a more expensive operation.\n _guardCounter = 1;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _guardCounter += 1;\n uint256 localCounter = _guardCounter;\n _;\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\n }\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\nimport \"../access/roles/UpgradablePauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n function __Pausable_init(address sender) public initializer {\n UpgradablePauserRole.__PauserRol_init(sender);\n\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as `account`'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `_account`.\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `_implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\n\n /**\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `_account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an `IERC777` token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {ERC20Detailed}.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeERC20: low-level call failed\");\n\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See `IERC1820Registry` and\n * `ERC1820Implementer`.\n */\ninterface IERC777 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See `operatorSend` and `operatorBurn`.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor`.\n *\n * Emits an `AuthorizedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor` and `defaultOperators`.\n *\n * Emits a `RevokedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if `authorizeOperator` was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * `revokeOperator`, in which case `isOperatorFor` will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n\n function decimals() external returns (uint8);\n\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n}\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\nlibrary LibEIP712 {\n\n // Hash of the EIP712 Domain Separator Schema\n // keccak256(abi.encodePacked(\n // \"EIP712Domain(\",\n // \"string name,\",\n // \"string version,\",\n // \"uint256 chainId,\",\n // \"address verifyingContract\",\n // \")\"\n // ))\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n /// @dev Calculates a EIP712 domain separator.\n /// @param name The EIP712 domain name.\n /// @param version The EIP712 domain version.\n /// @param verifyingContract The EIP712 verifying contract.\n /// @return result EIP712 domain separator.\n function hashEIP712Domain(\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n // keccak256(bytes(name)),\n // keccak256(bytes(version)),\n // chainId,\n // uint256(verifyingContract)\n // ))\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Calculate hashes of dynamic data\n let nameHash := keccak256(add(name, 32), mload(name))\n let versionHash := keccak256(add(version, 32), mload(version))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n // Store params in memory\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), nameHash)\n mstore(add(memPtr, 64), versionHash)\n mstore(add(memPtr, 96), chainId)\n mstore(add(memPtr, 128), verifyingContract)\n\n // Compute hash\n result := keccak256(memPtr, 160)\n }\n return result;\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\n /// with getDomainHash().\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to the given EIP712 Domain.\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n internal\n pure\n returns (bytes32 result)\n {\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct\n // ));\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nlibrary LibUtils {\n\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\n return uint256(10)**(18-decimals);\n }\n\n function getDecimals(address tokenToUse) internal view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"LibUtils: No decimals\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n return uint8(abi.decode(data, (uint256)));\n }\n\n function getGranularity(address tokenToUse) internal view returns (uint256) {\n //support granularity if ERC777\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\n require(success, \"LibUtils: No granularity\");\n\n return abi.decode(data, (uint256));\n }\n\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n addr := mload(add(bys,20))\n }\n }\n\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\n require(_bytes.length >= _start + 20, \"LibUtils: toAddress_outOfBounds\");\n address tempAddress;\n\n assembly {\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n }\n\n return tempAddress;\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\n require(_bytes.length >= _start + 16, \"LibUtils: toUint128_outOfBounds\");\n uint128 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x10), _start))\n }\n\n return tempUint;\n }\n\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\n\t\trequire(_bytes.length >= _start + 32, \"LibUtils: toUint256_outOfBounds\");\n\t\tuint256 tempUint;\n\n // solium-disable-next-line security/no-inline-assembly\n\t\tassembly {\n\t\t\ttempUint := mload(add(add(_bytes, 0x20), _start))\n\t\t}\n\n\t\treturn tempUint;\n\t}\n}\n"
+ },
+ "contracts/Bridge/IBridgeV3.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IBridgeV3 {\n\n struct ClaimData {\n address payable to;\n uint256 amount;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) external payable;\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n */\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external returns (uint256 receivedAmount);\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns(bytes32);\n\n event Cross(\n address indexed _tokenAddress,\n address indexed _from,\n address indexed _to,\n uint256 _amount,\n bytes _userData\n );\n event NewSideToken(\n address indexed _newSideTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 _granularity\n );\n event AcceptedCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FeePercentageChanged(uint256 _amount);\n event Claimed(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _reciever,\n address _relayer,\n uint256 _fee\n );\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideToken {\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideTokenFactory {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\n\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IWrapped {\n function balanceOf(address) external returns(uint);\n\n function deposit() external payable;\n\n function withdraw(uint wad) external;\n\n function totalSupply() external view returns (uint);\n\n function approve(address guy, uint wad) external returns (bool);\n\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad)\n external\n returns (bool);\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../Initializable.sol\";\n\nimport \"../../../GSN/Context.sol\";\nimport \"../../../access/Roles.sol\";\n\ncontract UpgradablePauserRole is Initializable, Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n function __PauserRol_init(address sender) public initializer {\n if (!isPauser(sender)) {\n _addPauser(sender);\n }\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @title Roles\n * @dev Library for managing addresses assigned to a Role.\n */\nlibrary Roles {\n struct Role {\n mapping (address => bool) bearer;\n }\n\n /**\n * @dev Give an account access to this role.\n */\n function add(Role storage role, address account) internal {\n require(!has(role, account), \"Roles: account already has role\");\n role.bearer[account] = true;\n }\n\n /**\n * @dev Remove an account's access to this role.\n */\n function remove(Role storage role, address account) internal {\n require(has(role, account), \"Roles: account doesn't have role\");\n role.bearer[account] = false;\n }\n\n /**\n * @dev Check if an account has this role.\n * @return bool\n */\n function has(Role storage role, address account) internal view returns (bool) {\n require(account != address(0), \"Roles: account is the zero address\");\n return role.bearer[account];\n }\n}\n"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract WRBTC is IWrapped {\n string public name = \"Wrapped RBTC\";\n string public symbol = \"WRBTC\";\n uint8 public decimals = 18;\n\n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n event Deposit(address indexed dst, uint wad);\n event Withdrawal(address indexed src, uint wad);\n\n mapping (address => uint) override public balanceOf;\n mapping (address => mapping (address => uint)) public allowance;\n\n receive () external payable {\n deposit();\n }\n function deposit() override public payable {\n balanceOf[msg.sender] += msg.value;\n emit Deposit(msg.sender, msg.value);\n }\n function withdraw(uint wad) override public {\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\n balanceOf[msg.sender] -= wad;\n (bool success, ) = msg.sender.call{value:wad, gas:23000}(\"\");\n require(success, \"WRBTC: transfer fail\");\n emit Withdrawal(msg.sender, wad);\n }\n\n function totalSupply() override public view returns (uint) {\n return address(this).balance;\n }\n\n function approve(address guy, uint wad) override public returns (bool) {\n allowance[msg.sender][guy] = wad;\n emit Approval(msg.sender, guy, wad);\n return true;\n }\n\n function transfer(address dst, uint wad) override public returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad)\n override public\n returns (bool)\n {\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\n\n if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\n allowance[src][msg.sender] -= wad;\n }\n\n balanceOf[src] -= wad;\n balanceOf[dst] += wad;\n\n emit Transfer(src, dst, wad);\n\n return true;\n }\n}"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// import \"hardhat/console.sol\";\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n\tusing SafeMath for uint256;\n\tusing SafeERC20 for IERC20;\n\tusing Address for address;\n\n\taddress constant internal NULL_ADDRESS = address(0);\n\tbytes32 constant internal NULL_HASH = bytes32(0);\n\tIERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n\taddress internal federation;\n\tuint256 internal feePercentage;\n\tstring public deprecatedSymbolPrefix;\n\t// domainSeparator replaces uint256 internal _depprecatedLastDay;\n\tbytes32 public domainSeparator;\n\tuint256 internal _deprecatedSpentToday;\n\n\tmapping (address => address) public deprecatedMappedTokens; // OriginalToken => SideToken\n\tmapping (address => address) public deprecatedOriginalTokens; // SideToken => OriginalToken\n\tmapping (address => bool) public deprecatedKnownTokens; // OriginalToken => true\n\n\t// claimed can use the same of bytes32\n\tmapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n\n\tIAllowTokens public allowTokens;\n\tISideTokenFactory public sideTokenFactory;\n\t//Bridge_v1 variables\n\tbool public isUpgrading;\n\t// Percentage with up to 2 decimals\n\tuint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\n\t//Bridge_v2 variables\n\tbytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\n\tIWrapped public wrappedCurrency;\n\tmapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n\tmapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n\tmapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n\t// keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,uint256 originChainId,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n\tbytes32 public constant CLAIM_TYPEHASH = 0xaf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c;\n\tmapping(address => uint) public nonces;\n\n\t//Bridge_v3 variables multichain\n\tmapping (uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain; // chainId => OriginalToken Address => SideToken Address\n\tmapping (address => OriginalToken) public originalTokenBySideToken; // SideTokenAddress => struct {}\n\tmapping (uint256 => mapping(address => bool)) public knownTokenByChain; // chainId => OriginalToken Address => Know\n\n\tevent AllowTokensChanged(address _newAllowTokens);\n\tevent FederationChanged(address _newFederation);\n\tevent SideTokenFactoryChanged(address _newSideTokenFactory);\n\tevent Upgrading(bool _isUpgrading);\n\tevent WrappedCurrencyChanged(address _wrappedCurrency);\n\n\tfunction initialize(\n\t\taddress _manager,\n\t\taddress _federation,\n\t\taddress _allowTokens,\n\t\taddress _sideTokenFactory\n\t) public initializer {\n\t\tUpgradableOwnable.initialize(_manager);\n\t\tUpgradablePausable.__Pausable_init(_manager);\n\t\tallowTokens = IAllowTokens(_allowTokens);\n\t\tsideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n\t\tfederation = _federation;\n\t\t//keccak256(\"ERC777TokensRecipient\")\n\t\tERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n\t\tinitDomainSeparator();\n\t}\n\n\treceive () external payable {\n\t\t// The fallback function is needed to use WRBTC\n\t\trequire(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n\t}\n\n\tfunction version() override external pure returns (string memory) {\n\t\treturn \"v4\";\n\t}\n\n\tfunction initDomainSeparator() public {\n\t\tdomainSeparator = LibEIP712.hashEIP712Domain(\n\t\t\t\"RSK Token Bridge\",\n\t\t\t\"1\",\n\t\t\tblock.chainid,\n\t\t\taddress(this)\n\t\t);\n\t}\n\n\tmodifier whenNotUpgrading() {\n\t\trequire(!isUpgrading, \"Bridge: Upgrading\");\n\t\t_;\n\t}\n\n\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\n\t\trequire(chainId == block.chainid, \"Bridge: Not block.chainid\");\n\t}\n\n\tfunction sideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\n\t\taddress sideTokenAddr = sideTokenByOriginalTokenByChain[chainId][originalToken];\n\n\t\tif (sideTokenAddr != NULL_ADDRESS) {\n\t\t\treturn sideTokenAddr;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\treturn deprecatedMappedTokens[originalToken];\n\t}\n\n\tfunction setSideTokenByOriginalAddressByChain(uint256 chainId, address originalToken, address sideToken) public onlyOwner {\n\t\tsideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\n\t}\n\n\tfunction getOriginalTokenBySideToken(address sideToken) public view returns(OriginalToken memory originalToken) {\n\t\toriginalToken = originalTokenBySideToken[sideToken];\n\t\tif (originalToken.tokenAddress != NULL_ADDRESS) {\n\t\t\treturn originalToken;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\toriginalToken.originChainId = 1; // ethereum main chain id\n\t\toriginalToken.tokenAddress = deprecatedOriginalTokens[sideToken];\n\t\treturn originalToken;\n\t}\n\n\tfunction setOriginalTokenBySideTokenByChain(address sideToken, OriginalToken memory originalToken) public onlyOwner {\n\t\toriginalTokenBySideToken[sideToken] = originalToken;\n\t}\n\n\tfunction knownToken(uint256 chainId, address originalToken) public view returns(bool) {\n\t\tbool knowToken = knownTokenByChain[chainId][originalToken];\n\t\tif (knowToken) {\n\t\t\treturn knowToken;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\treturn deprecatedKnownTokens[originalToken];\n\t}\n\n\tfunction _setKnownTokenByChain(uint256 chainId, address originalToken, bool knownTokenValue) internal {\n\t\tknownTokenByChain[chainId][originalToken] = knownTokenValue;\n\t}\n\n\tfunction acceptTransfer(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _from,\n\t\taddress payable _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) external whenNotPaused nonReentrant override {\n\t\trequire(_msgSender() == federation, \"Bridge: Not Federation\");\n\t\tcheckChainId(_originChainId);\n\t\tshouldBeCurrentChainId(_destinationChainId);\n\t\trequire(knownToken(_originChainId, _originalTokenAddress) ||\n\t\t\tsideTokenByOriginalToken(_originChainId, _originalTokenAddress) != NULL_ADDRESS,\n\t\t\t\"Bridge: Unknown token\"\n\t\t);\n\t\trequire(_to != NULL_ADDRESS, \"Bridge: Null To\");\n\t\trequire(_amount > 0, \"Bridge: Amount 0\");\n\t\trequire(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n\t\trequire(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n\t\trequire(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n\t\tbytes32 _transactionDataHash = getTransactionDataHash(\n\t\t\t_to,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_transactionHash,\n\t\t\t_logIndex\n\t\t);\n\n\t\tbytes32 _transactionDataHashMultichain = getTransactionDataHash(\n\t\t\t_to,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_transactionHash,\n\t\t\t_logIndex,\n\t\t\t_originChainId,\n\t\t\t_destinationChainId\n\t\t);\n\t\t// Do not remove, claimed also has the previously processed using the older bridge version\n\t\t// https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n\t\trequire(!isClaimed(_transactionDataHash, _transactionDataHashMultichain), \"Bridge: Already claimed\");\n\n\t\ttransactionsDataHashes[_transactionHash] = _transactionDataHashMultichain;\n\t\toriginalTokenAddresses[_transactionHash] = _originalTokenAddress;\n\t\tsenderAddresses[_transactionHash] = _from;\n\n\t\temit AcceptedCrossTransfer(\n\t\t\t_transactionHash,\n\t\t\t_originalTokenAddress,\n\t\t\t_to,\n\t\t\t_from,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_logIndex,\n\t\t\t_originChainId,\n\t\t\t_destinationChainId\n\t\t);\n\t}\n\n\tfunction checkChainId(uint256 chainId) internal pure {\n\t\trequire(chainId > 0, \"Bridge: ChainId is 0\");\n\t}\n\n\tfunction _createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _tokenSymbol,\n\t\tstring calldata _tokenName,\n\t\tuint256 _originChainId\n\t) internal {\n\t\trequire(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n\t\tcheckChainId(_originChainId);\n\t\taddress sideToken = sideTokenByOriginalToken(_originChainId, _originalTokenAddress);\n\t\trequire(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n\n\t\tuint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n\n\t\t// Create side token\n\t\tsideToken = sideTokenFactory.createSideToken(_tokenName, _tokenSymbol, granularity);\n\n\t\tsetSideTokenByOriginalAddressByChain(_originChainId, _originalTokenAddress, sideToken);\n\n\t\tOriginalToken memory originalToken;\n\t\toriginalToken.originChainId = _originChainId;\n\t\toriginalToken.tokenAddress = _originalTokenAddress;\n\t\tsetOriginalTokenBySideTokenByChain(sideToken, originalToken);\n\t\tallowTokens.setToken(sideToken, _typeId);\n\n\t\temit NewSideToken(sideToken, _originalTokenAddress, _tokenSymbol, granularity, _originChainId);\n\t}\n\n\tfunction createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _tokenSymbol,\n\t\tstring calldata _tokenName,\n\t\tuint256 _originChainId\n\t) external onlyOwner override {\n\t\t_createSideToken(\n\t\t\t_typeId,\n\t\t\t_originalTokenAddress,\n\t\t\t_originalTokenDecimals,\n\t\t\t_tokenSymbol,\n\t\t\t_tokenName,\n\t\t\t_originChainId\n\t\t);\n\t}\n\n\tfunction createMultipleSideTokens(\n\t\tCreateSideTokenStruct[] calldata createSideTokenStruct\n\t) external onlyOwner {\n\t\tfor(uint256 i = 0; i < createSideTokenStruct.length; i++) {\n\t\t\t_createSideToken(\n\t\t\t\tcreateSideTokenStruct[i]._typeId,\n\t\t\t\tcreateSideTokenStruct[i]._originalTokenAddress,\n\t\t\t\tcreateSideTokenStruct[i]._originalTokenDecimals,\n\t\t\t\tcreateSideTokenStruct[i]._originalTokenSymbol,\n\t\t\t\tcreateSideTokenStruct[i]._originalTokenName,\n\t\t\t\tcreateSideTokenStruct[i]._originChainId\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction claim(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\n\t\treceivedAmount = _claim(\n\t\t\t_claimData,\n\t\t\t_claimData.to,\n\t\t\tpayable(address(0)),\n\t\t\t0\n\t\t);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction claimFallback(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\n\t\trequire(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n\t\treceivedAmount = _claim(\n\t\t\t_claimData,\n\t\t\t_msgSender(),\n\t\t\tpayable(address(0)),\n\t\t\t0\n\t\t);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction getDigest(\n\t\tClaimData memory _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline\n\t) internal returns (bytes32) {\n\t\treturn LibEIP712.hashEIP712Message(\n\t\t\tdomainSeparator,\n\t\t\tkeccak256(\n\t\t\t\tabi.encode(\n\t\t\t\t\tCLAIM_TYPEHASH,\n\t\t\t\t\t_claimData.to,\n\t\t\t\t\t_claimData.amount,\n\t\t\t\t\t_claimData.transactionHash,\n\t\t\t\t\t_claimData.originChainId,\n\t\t\t\t\t_relayer,\n\t\t\t\t\t_fee,\n\t\t\t\t\tnonces[_claimData.to]++,\n\t\t\t\t\t_deadline\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t}\n\n\t// Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n\tfunction claimGasless(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline,\n\t\tuint8 _v,\n\t\tbytes32 _r,\n\t\tbytes32 _s\n\t) external override returns (uint256 receivedAmount) {\n\t\trequire(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\n\n\t\tbytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n\t\taddress recoveredAddress = ecrecover(digest, _v, _r, _s);\n\t\trequire(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n\t\treturn _claim(\n\t\t\t_claimData,\n\t\t\t_claimData.to,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\t}\n\n\tfunction isClaimed(bytes32 transactionDataHash, bytes32 transactionDataHashMultichain) public view returns(bool) {\n\t\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\n\t}\n\n\tfunction isClaimed(ClaimData calldata _claimData, bytes32 transactionDataHashMultichain) public view returns(bool) {\n\t\tbytes32 transactionDataHash = getTransactionDataHash(\n\t\t\t_claimData.to,\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.transactionHash,\n\t\t\t_claimData.logIndex\n\t\t);\n\n\t\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\n\t}\n\n\tfunction _claim(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _reciever,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal nonReentrant returns (uint256 receivedAmount) {\n\t\taddress originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n\t\trequire(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n\t\tbytes32 transactionDataHash = getTransactionDataHash(\n\t\t\t_claimData.to,\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.transactionHash,\n\t\t\t_claimData.logIndex,\n\t\t\t_claimData.originChainId,\n\t\t\tblock.chainid\n\t\t);\n\n\t\trequire(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n\t\trequire(!isClaimed(_claimData, transactionDataHash), \"Bridge: Already claimed\");\n\t\tclaimed[transactionDataHash] = true;\n\n\t\treceivedAmount = _claimCross(\n\t\t\t_claimData.originChainId,\n\t\t\toriginalTokenAddress,\n\t\t\t_reciever,\n\t\t\t_claimData.amount,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\n\t\temitClaimed(_claimData, originalTokenAddress, _reciever, _relayer, _fee);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction emitClaimed(\n\t\tClaimData calldata _claimData,\n\t\taddress _originalTokenAddress,\n\t\taddress payable _reciever,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal {\n\t\temit Claimed(\n\t\t\t_claimData.transactionHash,\n\t\t\t_originalTokenAddress,\n\t\t\t_claimData.to,\n\t\t\tsenderAddresses[_claimData.transactionHash],\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.logIndex,\n\t\t\t_reciever,\n\t\t\t_relayer,\n\t\t\t_fee,\n\t\t\t_claimData.originChainId,\n\t\t\tblock.chainid\n\t\t);\n\t}\n\n\tfunction _claimCross(\n\t\tuint256 _originalChainId,\n\t\taddress _originalTokenAddress,\n\t\taddress payable _reciever,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256) {\n\t\tcheckChainId(_originalChainId);\n\t\tif (knownToken(_originalChainId, _originalTokenAddress)) {\n\t\t\treturn _claimCrossBackToToken(\n\t\t\t\t_originalTokenAddress,\n\t\t\t\t_reciever,\n\t\t\t\t_amount,\n\t\t\t\t_relayer,\n\t\t\t\t_fee\n\t\t\t);\n\t\t}\n\n\t\treturn _claimCrossToSideToken(\n\t\t\tsideTokenByOriginalToken(_originalChainId, _originalTokenAddress),\n\t\t\t_reciever,\n\t\t\t_amount,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\t}\n\n\tfunction _claimCrossToSideToken(\n\t\taddress _sideToken,\n\t\taddress payable _receiver,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256 receivedAmount) {\n\t\trequire(_sideToken != NULL_ADDRESS, \"Bridge: side token is null\");\n\t\tuint256 granularity = IERC777(_sideToken).granularity();\n\t\tuint256 formattedAmount = _amount.mul(granularity);\n\t\trequire(_fee <= formattedAmount, \"Bridge: fee too high\");\n\t\treceivedAmount = formattedAmount.sub(_fee);\n\t\tISideToken(_sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n\t\tif (_fee > 0) {\n\t\t\tISideToken(_sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n\t\t}\n\t\treturn receivedAmount;\n\t}\n\n\tfunction _claimCrossBackToToken(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _receiver,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256 receivedAmount) {\n\t\tuint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n\t\t//As side tokens are ERC777 they will always have 18 decimals\n\t\tuint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n\t\trequire(_fee <= formattedAmount, \"Bridge: fee too high\");\n\t\treceivedAmount = formattedAmount.sub(_fee);\n\t\tif (address(wrappedCurrency) == _originalTokenAddress) {\n\t\t\twrappedCurrency.withdraw(formattedAmount);\n\t\t\t_receiver.transfer(receivedAmount);\n\t\t\tif(_fee > 0) {\n\t\t\t\t_relayer.transfer(_fee);\n\t\t\t}\n\t\t} else {\n\t\t\tIERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n\t\t\tif(_fee > 0) {\n\t\t\t\tIERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n\t\t\t}\n\t\t}\n\t\treturn receivedAmount;\n\t}\n\n\t/**\n\t\t* ERC-20 tokens approve and transferFrom pattern\n\t\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n\t\t*/\n\tfunction receiveTokensTo(uint256 destinationChainId, address tokenToUse, address to, uint256 amount) external override {\n\t\taddress sender = _msgSender();\n\t\t//Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n\t\tIERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n\t\tcrossTokens(tokenToUse, sender, to, amount, \"\", destinationChainId);\n\t}\n\n\t/**\n\t\t* Use network currency and cross it.\n\t\t*/\n\tfunction depositTo(uint256 chainId, address to) external payable override {\n\t\taddress sender = _msgSender();\n\t\trequire(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n\t\twrappedCurrency.deposit{ value: msg.value }();\n\t\tcrossTokens(address(wrappedCurrency), sender, to, msg.value, \"\", chainId);\n\t}\n\n\t/**\n\t\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n\t\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n\t\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\n\t\t* const userData = web3.eth.abi.encodeParameters(\n * [\"address\", \"uint256\"],\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\n * );\n\t\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\n\t\t* const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\n\t\t*/\n\tfunction tokensReceived(\n\t\taddress operator,\n\t\taddress from,\n\t\taddress to,\n\t\tuint amount,\n\t\tbytes calldata userData, // [address,uint256] user addrest receiver, destinationChainId || [uint256] same as from, destinationChainId\n\t\tbytes calldata\n\t) external override(IBridge, IERC777Recipient) {\n\t\t//Hook from ERC777address\n\t\tif(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n\t\trequire(to == address(this), \"Bridge: Not to this address\");\n\t\taddress tokenToUse = _msgSender();\n\t\trequire(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n\t\trequire(userData.length >= 32, \"Bridge: user data with at least the destinationChainId\");\n\t\trequire(userData.length == 64 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n\t\taddress receiver = userData.length == 32 ? from : LibUtils.toAddress(userData, 12);\n\t\tuint256 destinationChainId = LibUtils.toUint256(userData, userData.length - 32);\n\t\tcrossTokens(tokenToUse, from, receiver, amount, userData, destinationChainId);\n\t}\n\n\tfunction crossTokens(\n\t\taddress tokenToUse,\n\t\taddress from,\n\t\taddress to,\n\t\tuint256 amount,\n\t\tbytes memory userData,\n\t\tuint256 destinationChainId\n\t) internal whenNotUpgrading whenNotPaused nonReentrant {\n\t\trequire(block.chainid != destinationChainId, \"Bridge: destination chain id equal current chain id\");\n\t\tcheckChainId(destinationChainId);\n\t\t_setKnownTokenByChain(destinationChainId, tokenToUse, true);\n\t\tuint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n\t\tuint256 amountMinusFees = amount.sub(fee);\n\t\tuint8 decimals = LibUtils.getDecimals(tokenToUse);\n\t\tuint formattedAmount = amount;\n\t\tif (decimals != 18) {\n\t\t\tformattedAmount = amount.mul(uint256(10)**(18-decimals));\n\t\t}\n\t\t// We consider the amount before fees converted to 18 decimals to check the limits\n\t\t// updateTokenTransfer revert if token not allowed\n\t\tallowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n\n\t\tOriginalToken memory sideToken = getOriginalTokenBySideToken(tokenToUse);\n\t\tif (sideToken.tokenAddress != NULL_ADDRESS) {\n\t\t\t// Side Token Crossing back\n\t\t\t{ // Created scope to avoid stack too deep\n\t\t\t\tuint256 granularity = LibUtils.getGranularity(tokenToUse);\n\t\t\t\tuint256 modulo = amountMinusFees.mod(granularity);\n\t\t\t\tfee = fee.add(modulo);\n\t\t\t\tamountMinusFees = amountMinusFees.sub(modulo);\n\t\t\t\tIERC777(tokenToUse).burn(amountMinusFees, userData);\n\t\t\t}\n\t\t\temit Cross(\n\t\t\t\tsideToken.tokenAddress,\n\t\t\t\tto,\n\t\t\t\tdestinationChainId,\n\t\t\t\tfrom,\n\t\t\t\tblock.chainid,\n\t\t\t\tamountMinusFees,\n\t\t\t\tuserData\n\t\t\t);\n\t\t} else {\n\t\t\temit Cross(\n\t\t\t\ttokenToUse,\n\t\t\t\tto,\n\t\t\t\tdestinationChainId,\n\t\t\t\tfrom,\n\t\t\t\tblock.chainid,\n\t\t\t\tamountMinusFees,\n\t\t\t\tuserData\n\t\t\t);\n\t\t}\n\n\t\tif (fee > 0) {\n\t\t\t//Send the payment to the MultiSig of the Federation\n\t\t\tIERC20(tokenToUse).safeTransfer(owner(), fee);\n\t\t}\n\t}\n\n\t// function for retrocompatibility\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex\n\t) internal pure returns(bytes32) {\n\t\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n\t}\n\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) public pure override returns(bytes32) {\n\t\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex, _originChainId, _destinationChainId));\n\t}\n\n\tfunction setFeePercentage(uint amount) external onlyOwner {\n\t\trequire(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n\t\tfeePercentage = amount;\n\t\temit FeePercentageChanged(feePercentage);\n\t}\n\n\tfunction getFeePercentage() external view override returns(uint) {\n\t\treturn feePercentage;\n\t}\n\n\tfunction changeFederation(address newFederation) external onlyOwner {\n\t\trequire(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n\t\tfederation = newFederation;\n\t\temit FederationChanged(federation);\n\t}\n\n\tfunction changeAllowTokens(address newAllowTokens) external onlyOwner {\n\t\trequire(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n\t\tallowTokens = IAllowTokens(newAllowTokens);\n\t\temit AllowTokensChanged(newAllowTokens);\n\t}\n\n\tfunction getFederation() external view returns(address) {\n\t\treturn federation;\n\t}\n\n\tfunction changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n\t\trequire(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n\t\tsideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n\t\temit SideTokenFactoryChanged(newSideTokenFactory);\n\t}\n\n\tfunction setUpgrading(bool _isUpgrading) external onlyOwner {\n\t\tisUpgrading = _isUpgrading;\n\t\temit Upgrading(isUpgrading);\n\t}\n\n\tfunction setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n\t\trequire(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n\t\twrappedCurrency = IWrapped(_wrappedCurrency);\n\t\temit WrappedCurrencyChanged(_wrappedCurrency);\n\t}\n\n\tfunction hasCrossed(bytes32 transactionHash) public view returns (bool) {\n\t\treturn transactionsDataHashes[transactionHash] != bytes32(0);\n\t}\n\n\tfunction hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n\t\treturn claimed[transactionsDataHashes[transactionHash]];\n\t}\n\n}\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IBridge {\n\n\tstruct ClaimData {\n\t\taddress payable to;\n\t\tuint256 amount;\n\t\tbytes32 blockHash;\n\t\tbytes32 transactionHash;\n\t\tuint32 logIndex;\n\t\tuint256 originChainId;\n\t}\n\n\tstruct OriginalToken {\n\t\taddress tokenAddress;\n\t\tuint256 originChainId;\n\t}\n\t\n\tstruct CreateSideTokenStruct {\n\t\tuint256 _typeId;\n\t\taddress _originalTokenAddress;\n\t\tuint8 _originalTokenDecimals;\n\t\tstring _originalTokenSymbol;\n\t\tstring _originalTokenName;\n\t\tuint256 _originChainId;\n\t}\n\n\tfunction version() external pure returns (string memory);\n\n\tfunction getFeePercentage() external view returns(uint);\n\n\t/**\n\t\t* ERC-20 tokens approve and transferFrom pattern\n\t\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n\t\t*/\n\tfunction receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;\n\n\t/**\n\t\t* Use network currency and cross it.\n\t\t*/\n\tfunction depositTo(uint256 chainId, address to) external payable;\n\n\t/**\n\t\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n\t\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n\t\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\n\t\t* const userData = web3.eth.abi.encodeParameters(\n * [\"address\", \"uint256\"],\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\n * );\n\t\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\n\t\t* const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\n\t\t*/\n\tfunction tokensReceived (\n\t\taddress operator,\n\t\taddress from,\n\t\taddress to,\n\t\tuint amount,\n\t\tbytes calldata userData,\n\t\tbytes calldata operatorData\n\t) external;\n\n\t/**\n\t\t* Accepts the transaction from the other chain that was voted and sent by the Federation contract\n\t\t*/\n\tfunction acceptTransfer(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _from,\n\t\taddress payable _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) external;\n\n\t/**\n\t\t* Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n\t\t*/\n\tfunction claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n\tfunction claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n\tfunction claimGasless(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline,\n\t\tuint8 _v,\n\t\tbytes32 _r,\n\t\tbytes32 _s\n\t) external returns (uint256 receivedAmount);\n\n\tfunction createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _originalTokenSymbol,\n\t\tstring calldata _originalTokenName,\n\t\tuint256 _chainId\n\t) external;\n\n\tfunction createMultipleSideTokens(\n\t\tCreateSideTokenStruct[] calldata createSideTokenStruct\n\t) external;\n\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256 _destinationChainId\n\t) external returns(bytes32);\n\n\tevent Cross(\n\t\taddress indexed _tokenAddress,\n\t\taddress indexed _to,\n\t\tuint256 indexed _destinationChainId,\n\t\taddress _from,\n\t\tuint256 _originChainId,\n\t\tuint256 _amount,\n\t\tbytes _userData\n\t);\n\n\tevent NewSideToken(\n\t\taddress indexed _newSideTokenAddress,\n\t\taddress indexed _originalTokenAddress,\n\t\tstring _newSymbol,\n\t\tuint256 _granularity,\n\t\tuint256 _chainId\n\t);\n\tevent AcceptedCrossTransfer(\n\t\tbytes32 indexed _transactionHash,\n\t\taddress indexed _originalTokenAddress,\n\t\taddress indexed _to,\n\t\taddress _from,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tuint256 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t);\n\tevent FeePercentageChanged(uint256 _amount);\n\tevent Claimed(\n\t\tbytes32 indexed _transactionHash,\n\t\taddress indexed _originalTokenAddress,\n\t\taddress indexed _to,\n\t\taddress _sender,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tuint256 _logIndex,\n\t\taddress _reciever,\n\t\taddress _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _destinationChainId,\n\t\tuint256 _originChainId\n\t);\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../SideToken/SideToken.sol\";\n\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\n external onlyPrimary override returns(address) {\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\n emit SideTokenCreated(sideToken, symbol, granularity);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\nabstract contract Secondary is Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n constructor () {\n _primary = _msgSender();\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(_primary);\n }\n}\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\nimport \"../interface/IERC677Receiver.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../lib/LibEIP712.sol\";\n\ncontract SideToken is ISideToken, ERC777 {\n using SafeMath for uint256;\n\n address public minter;\n uint256 private _granularity;\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n bytes32 public domainSeparator;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n // ERC677 Transfer Event\n event Transfer(address,address,uint256,bytes);\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\n minter = _minterAddr;\n _granularity = _newGranularity;\n\n domainSeparator = LibEIP712.hashEIP712Domain(\n name(),\n \"1\",\n block.chainid,\n address(this)\n );\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter override\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n /**\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\n * @param recipient The address to transfer to.\n * @param amount The amount to be transferred.\n * @param data The extra data to be passed to the receiving contract.\n */\n function transferAndCall(address recipient, uint amount, bytes calldata data)\n external returns (bool success)\n {\n address from = _msgSender();\n\n _send(from, from, recipient, amount, data, \"\", false);\n emit Transfer(from, recipient, amount, data);\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\n return true;\n }\n\n function granularity() public view override returns (uint256) {\n return _granularity;\n }\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\n bytes32 digest = LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../../token/ERC20/IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\n // See https://github.com/ethereum/solidity/issues/4024.\n\n // keccak256(\"ERC777TokensSender\")\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\n\n // keccak256(\"ERC777TokensRecipient\")\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping (address => mapping (address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(\n string memory aName,\n string memory aSymbol,\n address[] memory theDefaultOperators\n ) {\n _name = aName;\n _symbol = aSymbol;\n\n _defaultOperatorsArray = theDefaultOperators;\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\n _defaultOperators[_defaultOperatorsArray[i]] = true;\n }\n\n // register interfaces\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view override(IERC777) returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view override(IERC777) returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20Detailed-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override(IERC777) returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n\n address from = _msgSender();\n\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\n\n _move(from, from, recipient, amount, \"\", \"\");\n\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(\n address operator,\n address tokenHolder\n ) public view override(IERC777) returns (bool) {\n return operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) external override(IERC777) {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) external override(IERC777) {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n )\n external override(IERC777)\n {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {Transfer} events.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\n external override(IERC777) {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\n _burn(_msgSender(), account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender)\n public view override(IERC20) returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {Transfer} and {Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount)\n external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n require(holder != address(0), \"ERC777: transfer from zero address\");\n\n address spender = _msgSender();\n\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\n\n _move(spender, holder, recipient, amount, \"\", \"\");\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\n\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address operator,\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n require(account != address(0), \"ERC777: mint to zero address\");\n\n // Update state variables\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n internal\n {\n require(from != address(0), \"ERC777: send from zero address\");\n require(to != address(0), \"ERC777: send to zero address\");\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param operator address operator requesting the operation\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(\n address operator,\n address from,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n )\n internal\n {\n require(from != address(0), \"ERC777: burn from zero address\");\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n // Update state variables\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\n _balances[to] = _balances[to].add(amount);\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n function _approve(address holder, address spender, uint256 value) internal {\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\n // currently unnecessary.\n //require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n private\n {\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n}\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * `IERC777` Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an `IERC777` token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\nimport \"../interface/IERC677Receiver.sol\";\n\ncontract mockERC677Receiver is IERC677Receiver {\n event Success(address _sender, uint _value, bytes _data);\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\n emit Success(_sender, _value, _data);\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Optional functions from the ERC20 standard.\n */\nabstract contract ERC20Detailed is IERC20 {\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\n * these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\n _name = aName;\n _symbol = aSymbol;\n _decimals = theDecimals;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20Mintable}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() override public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) override public view returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) override public returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) override public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) override public returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal {\n require(sender != address(0), \"ERC20: transfer from zero address\");\n require(recipient != address(0), \"ERC20: transfer to zero address\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: mint to zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: burn from zero address\");\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n *\n * This is internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal {\n require(owner != address(0), \"ERC20: approve from zero address\");\n require(spender != address(0), \"ERC20: approve to zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\n * from the caller's allowance.\n *\n * See {_burn} and {_approve}.\n */\n function _burnFrom(address account, uint256 amount) internal {\n _burn(account, amount);\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\n }\n}\n"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract MainToken is ERC20Detailed, ERC20 {\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\n ERC20Detailed(name, symbol, decimals)\n {\n _mint(msg.sender, totalSupply);\n }\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\n bool result = transfer(_to, _value);\n if (!result) return false;\n\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\n receiver.tokenFallback(msg.sender, _value, _data);\n\n // IMPORTANT: the ERC-677 specification does not say\n // anything about the use of the receiver contract's\n // tokenFallback method return value. Given\n // its return type matches with this method's return\n // type, returning it could be a possibility.\n // We here take the more conservative approach and\n // ignore the return value, returning true\n // to signal a succesful transfer despite tokenFallback's\n // return value -- fact being tokens are transferred\n // in any case.\n return true;\n }\n}\n\ninterface ERC677TransferReceiver {\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\n}"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IBridge.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockReceiveTokensCall is IERC777Recipient {\n address public bridge;\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor(address _bridge) {\n bridge = _bridge;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount, uint256 destinationChainId) external {\n IERC20(tokenToUse).approve(bridge, amount);\n IBridge(bridge).receiveTokensTo(destinationChainId, tokenToUse, receiver, amount);\n }\n\n function callDepositTo(address receiver, uint256 destinationChainId) external payable {\n IBridge(bridge).depositTo{ value: msg.value }(destinationChainId, receiver);\n }\n\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\n IERC777(tokenToUse).send(bridge, amount, data);\n }\n\n // Mandatory for IERC777Recipient\n function tokensReceived(\n address,\n address,\n address,\n uint,\n bytes calldata,\n bytes calldata\n ) override external view {\n this;\n }\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockERC777Recipient is IERC777Recipient {\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor() {\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\n }\n\n event Success(\n address operator,\n address from,\n address to,\n uint amount,\n bytes userData,\n bytes operatorData);\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) override external {\n emit Success(operator, from, to, amount, userData, operatorData);\n }\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\n\ncontract SideTokenV1 is ERC777 {\n address public minter;\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\n minter = _minterAddr;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../SideToken/SideTokenV1.sol\";\n\ncontract SideTokenFactoryV1 is Secondary {\n event CreatedSideToken(address sideToken, string symbol);\n\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\n emit CreatedSideToken(address(sideToken), symbol);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./ERC721.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721Burnable is Context, ERC721 {\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n _burn(tokenId);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _tokenOwners.contains(tokenId);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(tokenId);\n\n emit Transfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n */\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC721.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC721 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC721Pausable is ERC721, Pausable {\n /**\n * @dev See {ERC721-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\nimport \"../access/roles/PauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context, PauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n constructor () {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract PauserRole is Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n constructor () {\n _addPauser(_msgSender());\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC1155 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Pausable is ERC1155, Pausable {\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using SafeMath for uint256;\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping (uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /*\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri_) {\n _setURI(uri_);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) external view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: balance query for the zero address\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(amount);\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, address(0), id, amount);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\n /**\n @dev Handles the receipt of a single ERC1155 token type. This function is\n called at the end of a `safeTransferFrom` after the balance has been updated.\n To accept the transfer, this must return\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n (i.e. 0xf23a6e61, or its own function selector).\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n )\n external\n returns(bytes4);\n\n /**\n @dev Handles the receipt of a multiple ERC1155 token types. This function\n is called at the end of a `safeBatchTransferFrom` after the balances have\n been updated. To accept the transfer(s), this must return\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n (i.e. 0xbc197c81, or its own function selector).\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match values array)\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n )\n external\n returns(bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Burnable is ERC1155 {\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./Proxy.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n *\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\n * {TransparentUpgradeableProxy}.\n */\ncontract UpgradeableProxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _setImplementation(_logic);\n if(_data.length > 0) {\n Address.functionDelegateCall(_logic, _data);\n }\n }\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n bytes32 slot = _IMPLEMENTATION_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n impl := sload(slot)\n }\n }\n\n /**\n * @dev Upgrades the proxy to a new implementation.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal virtual {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\n\n bytes32 slot = _IMPLEMENTATION_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newImplementation)\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./UpgradeableProxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _setAdmin(admin_);\n }\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _admin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _admin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\n emit AdminChanged(_admin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external virtual ifAdmin {\n _upgradeTo(newImplementation);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\n _upgradeTo(newImplementation);\n Address.functionDelegateCall(newImplementation, data);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address adm) {\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n adm := sload(slot)\n }\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n bytes32 slot = _ADMIN_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newAdmin)\n }\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../ownership/Ownable.sol\";\nimport \"./TransparentUpgradeableProxy.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () {\n _owner = _msgSender();\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../../zeppelin/ownership/Ownable.sol\";\nimport \"../../zeppelin/math/SafeMath.sol\";\nimport \"../../zeppelin/utils/Strings.sol\";\nimport \"./OpenSeaEIP712Base.sol\";\n\n\n/**\n * @title OpenSea721\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\n */\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\n using SafeMath for uint256;\n\n uint256 private _currentTokenId = 0;\n\n constructor(\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n _initializeEIP712(_name);\n }\n\n function baseTokenURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/api/creature/\";\n }\n\n function contractURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\n }\n\n /**\n * @dev Mints a token to an address with a tokenURI.\n * @param _to address of the future owner of the token\n */\n function mintTo(address _to) public onlyOwner {\n uint256 newTokenId = _getNextTokenId();\n _mint(_to, newTokenId);\n _incrementTokenId();\n }\n\n /**\n * @dev calculates the next token ID based on value of _currentTokenId\n * @return uint256 for the next token ID\n */\n function _getNextTokenId() private view returns (uint256) {\n return _currentTokenId.add(1);\n }\n\n /**\n * @dev increments the value of _currentTokenId\n */\n function _incrementTokenId() private {\n _currentTokenId++;\n }\n\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\n }\n\n}"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../zeppelin/upgradable/Initializable.sol\";\n\ncontract OpenSeaEIP712Base is Initializable {\n struct EIP712Domain {\n string name;\n string version;\n address verifyingContract;\n bytes32 salt;\n }\n\n string constant public ERC712_VERSION = \"1\";\n\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\n bytes(\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\n )\n );\n bytes32 internal domainSeperator;\n\n // supposed to be called once while initializing.\n // one of the contracts that inherits this contract follows proxy pattern\n // so it is not possible to do this in a constructor\n function _initializeEIP712(\n string memory name\n )\n internal\n initializer\n {\n _setDomainSeperator(name);\n }\n\n function _setDomainSeperator(string memory name) internal {\n domainSeperator = keccak256(\n abi.encode(\n EIP712_DOMAIN_TYPEHASH,\n keccak256(bytes(name)),\n keccak256(bytes(ERC712_VERSION)),\n address(this),\n bytes32(block.chainid)\n )\n );\n }\n\n function getDomainSeperator() public view returns (bytes32) {\n return domainSeperator;\n }\n\n /**\n * Accept message hash and returns hash message in EIP712 compatible form\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\n * https://eips.ethereum.org/EIPS/eip-712\n * \"\\\\x19\" makes the encoding deterministic\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\n */\n function toTypedMessageHash(bytes32 messageHash)\n internal\n view\n returns (bytes32)\n {\n return\n keccak256(\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\n );\n }\n}\n"
+ },
+ "contracts/Federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../Bridge/IBridgeV3.sol\";\n\ncontract FederationV2 is Initializable, UpgradableOwnable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridgeV3 public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\n validRequirement(_members.length, _required) public initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n }\n\n function version() external pure returns (string memory) {\n return \"v2\";\n }\n\n function setBridge(address _bridge) external onlyOwner {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridgeV3(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n )\n public onlyMember returns(bool)\n {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32)\n {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}"
+ },
+ "contracts/Federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/IFederation.sol\";\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\n\tuint constant public MAX_MEMBER_COUNT = 50;\n\taddress constant private NULL_ADDRESS = address(0);\n\n\tIBridge public bridge;\n\taddress[] public members;\n\n\t/**\n\t\t@notice The minimum amount of votes to approve a transaction\n\t\t@dev It should have at least the required amount of members\n\t\t*/\n\tuint public required;\n\n\t/**\n\t\t@notice All the addresses that are members of the federation\n\t\t@dev The address should be a member to vote in transactions\n\t\t*/\n\tmapping (address => bool) public isMember;\n\n\t/**\n\t\t(bytes32) transactionId = keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tamount,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex\n\t\t\t)\n\t\t) => (\n\t\t\t(address) members => (bool) voted\n\t\t)\n\t\t@notice Votes by members by the transaction ID\n\t\t@dev the members should approve the transaction by 50% + 1\n\t\t*/\n\tmapping (bytes32 => mapping (address => bool)) public votes;\n\n\t/**\n\t\t(bytes32) transactionId => (bool) voted\n\t\t@notice Check if that transaction was already processed\n\t*/\n\tmapping(bytes32 => bool) public processed;\n\n\tmodifier onlyMember() {\n\t\trequire(isMember[_msgSender()], \"Federation: Not Federator\");\n\t\t_;\n\t}\n\n\tmodifier validRequirement(uint membersCount, uint _required) {\n\t\trequire(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n\t\t_;\n\t}\n\n\tfunction initialize(\n\t\taddress[] calldata _members,\n\t\tuint _required,\n\t\taddress _bridge,\n\t\taddress owner\n\t) public validRequirement(_members.length, _required) initializer {\n\t\tUpgradableOwnable.initialize(owner);\n\t\trequire(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n\t\tmembers = _members;\n\t\tfor (uint i = 0; i < _members.length; i++) {\n\t\t\trequire(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n\t\t\tisMember[_members[i]] = true;\n\t\t\temit MemberAddition(_members[i]);\n\t\t}\n\t\trequired = _required;\n\t\temit RequirementChange(required);\n\t\t_setBridge(_bridge);\n\t}\n\n\t/**\n\t\t@notice Current version of the contract\n\t\t@return version in v{Number}\n\t\t*/\n\tfunction version() external pure override returns (string memory) {\n\t\treturn \"v3\";\n\t}\n\n\t/**\n\t\t@notice Sets a new bridge contract\n\t\t@dev Emits BridgeChanged event\n\t\t@param _bridge the new bridge contract address that should implement the IBridge interface\n\t\t*/\n\tfunction setBridge(address _bridge) external onlyOwner override {\n\t\t_setBridge(_bridge);\n\t}\n\n\tfunction _setBridge(address _bridge) internal {\n\t\trequire(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n\t\tbridge = IBridge(_bridge);\n\t\temit BridgeChanged(_bridge);\n\t}\n\n\tfunction validateTransaction(bytes32 transactionId, bytes32 transactionIdMultichain) internal view returns(bool) {\n\t\tuint256 minimumVotes = getMinimalNumberOfVotes();\n\t\tuint256 amountVotes = 0;\n\n for (uint256 i = 0; i < members.length; i++) {\n if (votes[transactionIdMultichain][members[i]]) {\n amountVotes += 1;\n\t\t\t} else if (votes[transactionId][members[i]]) {\n amountVotes += 1;\n\t\t\t}\n\n\t\t\tif (amountVotes >= minimumVotes && amountVotes >= required) {\n\t\t\t\treturn true;\n\t\t\t}\n }\n\n\t\treturn false;\n\t}\n\n\tfunction getMinimalNumberOfVotes() internal view returns(uint256) {\n\t\treturn members.length / 2 + 1;\n\t}\n\n\tfunction isProcessed(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\n\t\treturn processed[transactionIdMultichain] || processed[transactionId];\n\t}\n\n\tfunction isVoted(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\n\t\treturn votes[transactionIdMultichain][_msgSender()] || votes[transactionId][_msgSender()];\n\t}\n\n\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\n\t\trequire(chainId == block.chainid, \"Federation: Not block.chainid\");\n\t}\n\n\t/**\n\t\t@notice Vote in a transaction, if it has enough votes it accepts the transfer\n\t\t@param originalTokenAddress The address of the token in the origin (main) chain\n\t\t@param sender The address who solicited the cross token\n\t\t@param receiver Who is going to receive the token in the opposite chain\n\t\t@param value Amount\n\t\t@param blockHash The block hash in which the transaction with the cross event occurred\n\t\t@param transactionHash The transaction in which the cross event occurred\n\t\t@param logIndex Index of the event in the logs\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n\t\t*/\n\tfunction voteTransaction(\n\t\taddress originalTokenAddress,\n\t\taddress payable sender,\n\t\taddress payable receiver,\n\t\tuint256 value,\n\t\tbytes32 blockHash,\n\t\tbytes32 transactionHash,\n\t\tuint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n\t) external onlyMember override {\n\t\tshouldBeCurrentChainId(destinationChainId);\n\t\tbytes32 transactionId = keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex\n\t\t\t)\n\t\t);\n\n\t\tbytes32 transactionIdMultichain = getTransactionId(\n\t\t\toriginalTokenAddress,\n\t\t\tsender,\n\t\t\treceiver,\n\t\t\tvalue,\n\t\t\tblockHash,\n\t\t\ttransactionHash,\n\t\t\tlogIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n\t\t);\n\n\t\tif (isProcessed(transactionId, transactionIdMultichain))\n\t\t\treturn;\n\n\t\tif (isVoted(transactionId, transactionIdMultichain))\n\t\t\treturn;\n\n\t\tvotes[transactionIdMultichain][_msgSender()] = true;\n\t\temit Voted(\n\t\t\t_msgSender(),\n\t\t\ttransactionHash,\n\t\t\ttransactionIdMultichain,\n\t\t\toriginalTokenAddress,\n\t\t\tsender,\n\t\t\treceiver,\n\t\t\tvalue,\n\t\t\tblockHash,\n\t\t\tlogIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n\t\t);\n\n\t\tif (validateTransaction(transactionId, transactionIdMultichain)) {\n\t\t\tprocessed[transactionIdMultichain] = true;\n\n\t\t\tacceptTransfer(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex,\n\t\t\t\t\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\n\t\t\temit Executed(\n\t\t\t\t_msgSender(),\n\t\t\t\ttransactionHash,\n\t\t\t\ttransactionIdMultichain,\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\tlogIndex,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\t\t}\n\t}\n\n function acceptTransfer(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n\tuint256 originChainId,\n\tuint256\tdestinationChainId\n ) internal {\n\t bridge.acceptTransfer(\n\t\toriginalTokenAddress,\n\t\tsender,\n\t\treceiver,\n\t\tvalue,\n\t\tblockHash,\n\t\ttransactionHash,\n\t\tlogIndex,\n\t\toriginChainId,\n\t\tdestinationChainId\n\t );\n }\n\n /**\n @notice Get the amount of approved votes for that transactionId\n @param transactionId The transaction hashed from getTransactionId function\n */\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n\tfunction hasVoted(bytes32 transactionId) external view returns(bool) {\n\t\treturn votes[transactionId][_msgSender()];\n\t}\n\n\tfunction transactionWasProcessed(bytes32 transactionId) external view returns(bool) {\n\t\treturn processed[transactionId];\n\t}\n\n\t/**\n\t\t@notice Gets the hash of transaction from the following parameters encoded and keccaked\n\t\t@dev It encodes and applies keccak256 to the parameters received in the same order\n\t\t@param originalTokenAddress The address of the token in the origin (main) chain\n\t\t@param sender The address who solicited the cross token\n\t\t@param receiver Who is going to receive the token in the opposite chain\n\t\t@param amount Could be the amount or the tokenId\n\t\t@param blockHash The block hash in which the transaction with the cross event occurred\n\t\t@param transactionHash The transaction in which the cross event occurred\n\t\t@param logIndex Index of the event in the logs\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n\t\t@return The hash generated by the parameters.\n\t*/\n\tfunction getTransactionId(\n\t\taddress originalTokenAddress,\n\t\taddress sender,\n\t\taddress receiver,\n\t\tuint256 amount,\n\t\tbytes32 blockHash,\n\t\tbytes32 transactionHash,\n\t\tuint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n\t) public pure returns(bytes32) {\n\t\treturn keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tamount,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t)\n\t\t);\n\t}\n\n\tfunction addMember(address _newMember) external onlyOwner override {\n\t\trequire(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n\t\trequire(!isMember[_newMember], \"Federation: Member already exists\");\n\t\trequire(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n\t\tisMember[_newMember] = true;\n\t\tmembers.push(_newMember);\n\t\temit MemberAddition(_newMember);\n\t}\n\n\tfunction removeMember(address _oldMember) external onlyOwner override {\n\t\trequire(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n\t\trequire(isMember[_oldMember], \"Federation: Member doesn't exists\");\n\t\trequire(members.length > 1, \"Federation: Can't remove all the members\");\n\t\trequire(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n\t\tisMember[_oldMember] = false;\n\t\tfor (uint i = 0; i < members.length - 1; i++) {\n\t\t\tif (members[i] == _oldMember) {\n\t\t\t\tmembers[i] = members[members.length - 1];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tmembers.pop(); // remove an element from the end of the array.\n\t\temit MemberRemoval(_oldMember);\n\t}\n\n\t/**\n\t\t@notice Return all the current members of the federation\n\t\t@return Current members\n\t\t*/\n\tfunction getMembers() external view override returns (address[] memory) {\n\t\treturn members;\n\t}\n\n\t/**\n\t\t@notice Changes the number of required members to vote and approve an transaction\n\t\t@dev Emits the RequirementChange event\n\t\t@param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n\t\t*/\n\tfunction changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\n\t\trequire(_required >= 2, \"Federation: Requires at least 2\");\n\t\trequired = _required;\n\t\temit RequirementChange(_required);\n\t}\n\n\t/**\n\t\t@notice It emits an HeartBeat like an health check\n\t\t@dev Emits HeartBeat event\n\t\t*/\n\tfunction emitHeartbeat(\n\t\tstring calldata fedVersion,\n\t\tuint256[] calldata fedChainsIds,\n\t\tuint256[] calldata fedChainsBlocks,\n\t\tstring[] calldata fedChainsInfo\n\t) external onlyMember override {\n\t\trequire(fedChainsIds.length == fedChainsBlocks.length &&\n\t\t\tfedChainsIds.length == fedChainsInfo.length, \"Federation: Length missmatch\");\n\t\temit HeartBeat(\n\t\t\t_msgSender(),\n\t\t\tblock.chainid,\n\t\t\tblock.number,\n\t\t\tfedVersion,\n\t\t\tfedChainsIds,\n\t\t\tfedChainsBlocks,\n\t\t\tfedChainsInfo\n\t\t);\n\t}\n}\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface IFederation {\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure returns (string memory);\n\n /**\n @notice Sets a new bridge contract\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external;\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Amount\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n\t uint256 originChainId,\n\t uint256\tdestinationChainId\n ) external;\n\n /**\n @notice Add a new member to the federation\n @param _newMember address of the new member\n */\n function addMember(address _newMember) external;\n\n /**\n @notice Remove a member of the federation\n @param _oldMember address of the member to be removed from federation\n */\n function removeMember(address _oldMember) external;\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view returns (address[] memory);\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external;\n\n /**\n @notice It emmits an HeartBeat like an healthy check\n */\n function emitHeartbeat(\n string calldata federatorVersion,\n\t\tuint256[] calldata fedChainsIds,\n\t\tuint256[] calldata fedChainsBlocks,\n\t\tstring[] calldata fedChainsInfo\n ) external;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex,\n uint256 originChainId,\n\t\tuint256\tdestinationChainId\n );\n event HeartBeat(\n address indexed sender,\n uint256 currentChainId,\n uint256 currentBlock,\n string fedVersion,\n uint256[] fedChainsIds,\n\t\tuint256[] fedChainsBlocks,\n\t\tstring[] fedChainsInfo\n );\n\n}\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract MinterRole is Context {\n using Roles for Roles.Role;\n\n event MinterAdded(address indexed account);\n event MinterRemoved(address indexed account);\n\n Roles.Role private _minters;\n\n constructor () {\n _addMinter(_msgSender());\n }\n\n modifier onlyMinter() {\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\n _;\n }\n\n function isMinter(address account) public view returns (bool) {\n return _minters.has(account);\n }\n\n function addMinter(address account) public onlyMinter {\n _addMinter(account);\n }\n\n function renounceMinter() public {\n _removeMinter(_msgSender());\n }\n\n function _addMinter(address account) internal {\n _minters.add(account);\n emit MinterAdded(account);\n }\n\n function _removeMinter(address account) internal {\n _minters.remove(account);\n emit MinterRemoved(account);\n }\n}\n"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract AllowTokensV0 is Ownable {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n\n mapping (address => bool) public allowedTokens;\n bool private validateAllowedTokens;\n uint256 private maxTokensAllowed;\n uint256 private minTokensAllowed;\n uint256 public dailyLimit;\n\n event AllowedTokenAdded(address indexed _tokenAddress);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event AllowedTokenValidation(bool _enabled);\n event MaxTokensAllowedChanged(uint256 _maxTokens);\n event MinTokensAllowedChanged(uint256 _minTokens);\n event DailyLimitChanged(uint256 dailyLimit);\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\n _;\n }\n\n constructor(address _manager) {\n transferOwnership(_manager);\n validateAllowedTokens = true;\n maxTokensAllowed = 10000 ether;\n minTokensAllowed = 1 ether;\n dailyLimit = 100000 ether;\n }\n\n function isValidatingAllowedTokens() external view returns(bool) {\n return validateAllowedTokens;\n }\n\n function getMaxTokensAllowed() external view returns(uint256) {\n return maxTokensAllowed;\n }\n\n function getMinTokensAllowed() external view returns(uint256) {\n return minTokensAllowed;\n }\n\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\n return allowedTokens[token];\n }\n\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\n if (validateAllowedTokens) {\n return allowedTokenExist(token);\n }\n return true;\n }\n\n function addAllowedToken(address token) external onlyOwner {\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\n allowedTokens[token] = true;\n emit AllowedTokenAdded(token);\n }\n\n function removeAllowedToken(address token) external onlyOwner {\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\n allowedTokens[token] = false;\n emit AllowedTokenRemoved(token);\n }\n\n function enableAllowedTokensValidation() external onlyOwner {\n validateAllowedTokens = true;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function disableAllowedTokensValidation() external onlyOwner {\n // Before disabling Allowed Tokens Validations some kind of contract validation system\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\n validateAllowedTokens = false;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\n maxTokensAllowed = maxTokens;\n emit MaxTokensAllowedChanged(maxTokensAllowed);\n }\n\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\n minTokensAllowed = minTokens;\n emit MinTokensAllowedChanged(minTokensAllowed);\n }\n\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\n dailyLimit = _dailyLimit;\n emit DailyLimitChanged(_dailyLimit);\n }\n\n // solium-disable-next-line max-len\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\n if(amount > maxTokensAllowed)\n return false;\n if(amount < minTokensAllowed)\n return false;\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\n return false;\n if(!isSideToken && !isTokenAllowed(tokenToUse))\n return false;\n return true;\n }\n\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\n uint maxWithrow = dailyLimit - spentToday;\n if (dailyLimit < spentToday)\n return 0;\n if(maxWithrow > maxTokensAllowed)\n maxWithrow = maxTokensAllowed;\n return maxWithrow;\n }\n\n}\n"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\n\ncontract BridgeProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract FederationProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() {\n _registerInterface(\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\n );\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Receiver.sol\";\n\n /**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers. \n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract AlternativeERC20Detailed is ERC20 {\n string private _name;\n bytes32 private _symbol;\n uint256 private _decimals;\n\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\n {\n _name = aName;\n _symbol = aSymbol;\n _decimals = someDecimals;\n _mint(msg.sender, aTotalSupply);\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (bytes32) {\n return _symbol;\n }\n\n function decimals() public view returns (uint256) {\n return _decimals;\n }\n}"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../lib/LibUtils.sol\";\n\ncontract LibUtilsHarness {\n\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\n return LibUtils.decimalsToGranularity(decimals);\n }\n\n function getDecimals(address tokenToUse) external view returns (uint8) {\n return LibUtils.getDecimals(tokenToUse);\n }\n\n function getGranularity(address tokenToUse) external view returns (uint256) {\n return LibUtils.getGranularity(tokenToUse);\n }\n\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\n return LibUtils.bytesToAddress(bys);\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) external pure returns (uint128) {\n return LibUtils.toUint128(_bytes, _start);\n }\n\n}\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/solcInputs/3b83f9cb61a99eec06a616e65f41d75c.json b/bridge/deployments/kovan/solcInputs/3b83f9cb61a99eec06a616e65f41d75c.json
new file mode 100644
index 000000000..e68d5ccb0
--- /dev/null
+++ b/bridge/deployments/kovan/solcInputs/3b83f9cb61a99eec06a616e65f41d75c.json
@@ -0,0 +1,36 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/MultiSigWallet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.\n/// @author Stefan George - \ncontract MultiSigWallet {\n\n /*\n * Events\n */\n event Confirmation(address indexed sender, uint indexed transactionId);\n event Revocation(address indexed sender, uint indexed transactionId);\n event Submission(uint indexed transactionId);\n event Execution(uint indexed transactionId);\n event ExecutionFailure(uint indexed transactionId);\n event Deposit(address indexed sender, uint value);\n event OwnerAddition(address indexed owner);\n event OwnerRemoval(address indexed owner);\n event RequirementChange(uint required);\n\n /*\n * views\n */\n uint constant public MAX_OWNER_COUNT = 50;\n\n /*\n * Storage\n */\n mapping (uint => Transaction) public transactions;\n mapping (uint => mapping (address => bool)) public confirmations;\n mapping (address => bool) public isOwner;\n address[] public owners;\n uint public required;\n uint public transactionCount;\n\n struct Transaction {\n address destination;\n uint value;\n bytes data;\n bool executed;\n }\n\n /*\n * Modifiers\n */\n modifier onlyWallet() {\n require(msg.sender == address(this), \"Only wallet allowed\");\n _;\n }\n\n modifier ownerDoesNotExist(address owner) {\n require(!isOwner[owner], \"The owner already exists\");\n _;\n }\n\n modifier ownerExists(address owner) {\n require(isOwner[owner], \"The owner does not exist\");\n _;\n }\n\n modifier transactionExists(uint transactionId) {\n require(transactions[transactionId].destination != address(0), \"Transaction does not exist\");\n _;\n }\n\n modifier confirmed(uint transactionId, address owner) {\n require(confirmations[transactionId][owner], \"Transaction is not confirmed by owner\");\n _;\n }\n\n modifier notConfirmed(uint transactionId, address owner) {\n require(!confirmations[transactionId][owner], \"Transaction is already confirmed by owner\");\n _;\n }\n\n modifier notExecuted(uint transactionId) {\n require(!transactions[transactionId].executed, \"Transaction was already executed\");\n _;\n }\n\n modifier notNull(address _address) {\n require(_address != address(0), \"Address cannot be empty\");\n _;\n }\n\n modifier validRequirement(uint ownerCount, uint _required) {\n // solium-disable-next-line max-len\n require(ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && _required != 0 && ownerCount != 0, \"Required value is invalid for the current owners count\");\n _;\n }\n\n /// @dev Fallback function allows to deposit ether.\n receive ()\n external\n payable\n {\n if (msg.value > 0)\n emit Deposit(msg.sender, msg.value);\n }\n\n /*\n * Public functions\n */\n /// @dev Contract constructor sets initial owners and required number of confirmations.\n /// @param _owners List of initial owners.\n /// @param _required Number of required confirmations.\n constructor(address[] memory _owners, uint _required)\n validRequirement(_owners.length, _required)\n {\n for (uint i = 0; i < _owners.length; i++) {\n require(!isOwner[_owners[i]] && _owners[i] != address(0), \"Owners addresses are invalid\");\n isOwner[_owners[i]] = true;\n }\n owners = _owners;\n required = _required;\n }\n\n /// @dev Allows to add a new owner. Transaction has to be sent by wallet.\n /// @param owner Address of new owner.\n function addOwner(address owner)\n public\n onlyWallet\n ownerDoesNotExist(owner)\n notNull(owner)\n validRequirement(owners.length + 1, required)\n {\n isOwner[owner] = true;\n owners.push(owner);\n emit OwnerAddition(owner);\n }\n\n /// @dev Allows to remove an owner. Transaction has to be sent by wallet.\n /// @param owner Address of owner.\n function removeOwner(address owner)\n public\n onlyWallet\n ownerExists(owner)\n {\n isOwner[owner] = false;\n for (uint i = 0; i < owners.length - 1; i++)\n if (owners[i] == owner) {\n owners[i] = owners[owners.length - 1];\n break;\n }\n owners.pop(); // remove an element from the end of the array.\n if (required > owners.length)\n changeRequirement(owners.length);\n emit OwnerRemoval(owner);\n }\n\n /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\n /// @param owner Address of owner to be replaced.\n /// @param newOwner Address of new owner.\n function replaceOwner(address owner, address newOwner)\n public\n onlyWallet\n ownerExists(owner)\n ownerDoesNotExist(newOwner)\n {\n for (uint i = 0; i < owners.length; i++)\n if (owners[i] == owner) {\n owners[i] = newOwner;\n break;\n }\n isOwner[owner] = false;\n isOwner[newOwner] = true;\n emit OwnerRemoval(owner);\n emit OwnerAddition(newOwner);\n }\n\n /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.\n /// @param _required Number of required confirmations.\n function changeRequirement(uint _required)\n public\n onlyWallet\n validRequirement(owners.length, _required)\n {\n required = _required;\n emit RequirementChange(_required);\n }\n\n /// @dev Allows an owner to submit and confirm a transaction.\n /// @param destination Transaction target address.\n /// @param value Transaction ether value.\n /// @param data Transaction data payload.\n /// @return transactionId Returns transaction ID.\n function submitTransaction(address destination, uint value, bytes memory data)\n public\n returns (uint transactionId)\n {\n transactionId = addTransaction(destination, value, data);\n confirmTransaction(transactionId);\n }\n\n /// @dev Allows an owner to confirm a transaction.\n /// @param transactionId Transaction ID.\n function confirmTransaction(uint transactionId)\n public\n ownerExists(msg.sender)\n transactionExists(transactionId)\n notConfirmed(transactionId, msg.sender)\n {\n confirmations[transactionId][msg.sender] = true;\n emit Confirmation(msg.sender, transactionId);\n executeTransaction(transactionId);\n }\n\n /// @dev Allows an owner to revoke a confirmation for a transaction.\n /// @param transactionId Transaction ID.\n function revokeConfirmation(uint transactionId)\n public\n ownerExists(msg.sender)\n confirmed(transactionId, msg.sender)\n notExecuted(transactionId)\n {\n confirmations[transactionId][msg.sender] = false;\n emit Revocation(msg.sender, transactionId);\n }\n\n /// @dev Allows anyone to execute a confirmed transaction.\n /// @param transactionId Transaction ID.\n function executeTransaction(uint transactionId)\n public\n ownerExists(msg.sender)\n confirmed(transactionId, msg.sender)\n notExecuted(transactionId)\n {\n if (isConfirmed(transactionId)) {\n Transaction storage txn = transactions[transactionId];\n txn.executed = true;\n if (external_call(txn.destination, txn.value, txn.data.length, txn.data))\n emit Execution(transactionId);\n else {\n emit ExecutionFailure(transactionId);\n txn.executed = false;\n }\n }\n }\n\n // call has been separated into its own function in order to take advantage\n // of the Solidity's code generator to produce a loop that copies tx.data into memory.\n function external_call(address destination, uint value, uint dataLength, bytes memory data) internal returns (bool) {\n bool result;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let x := mload(0x40) // \"Allocate\" memory for output (0x40 is where \"free memory\" pointer is stored by convention)\n let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that\n result := call(\n sub(gas(), 34710), // 34710 is the value that solidity is currently emitting\n // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +\n // callNewAccountGas (25000, in case the destination address does not exist and needs creating)\n destination,\n value,\n d,\n dataLength, // Size of the input (in bytes) - this is what fixes the padding problem\n x,\n 0 // Output is ignored, therefore the output size is zero\n )\n }\n return result;\n }\n\n /// @dev Returns the confirmation status of a transaction.\n /// @param transactionId Transaction ID.\n /// @return Confirmation status.\n function isConfirmed(uint transactionId)\n public\n view\n returns (bool)\n {\n uint count = 0;\n for (uint i = 0; i < owners.length; i++) {\n if (confirmations[transactionId][owners[i]])\n count += 1;\n if (count == required)\n return true;\n }\n return false;\n }\n\n /*\n * Internal functions\n */\n /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.\n /// @param destination Transaction target address.\n /// @param value Transaction ether value.\n /// @param data Transaction data payload.\n /// @return transactionId Returns transaction ID.\n function addTransaction(address destination, uint value, bytes memory data)\n internal\n notNull(destination)\n returns (uint transactionId)\n {\n transactionId = transactionCount;\n transactions[transactionId] = Transaction({\n destination: destination,\n value: value,\n data: data,\n executed: false\n });\n transactionCount += 1;\n emit Submission(transactionId);\n }\n\n /*\n * Web3 call functions\n */\n /// @dev Returns number of confirmations of a transaction.\n /// @param transactionId Transaction ID.\n /// @return count Number of confirmations.\n function getConfirmationCount(uint transactionId)\n public\n view\n returns (uint count)\n {\n for (uint i = 0; i < owners.length; i++) {\n if (confirmations[transactionId][owners[i]]) {\n count += 1;\n }\n }\n }\n\n /// @dev Returns total number of transactions after filers are applied.\n /// @param pending Include pending transactions.\n /// @param executed Include executed transactions.\n /// @return count Total number of transactions after filters are applied.\n function getTransactionCount(bool pending, bool executed)\n public\n view\n returns (uint count)\n {\n for (uint i = 0; i < transactionCount; i++) {\n if ( pending && !transactions[i].executed || executed && transactions[i].executed) {\n count += 1;\n }\n }\n }\n\n /// @dev Returns list of owners.\n /// @return List of owner addresses.\n function getOwners()\n public\n view\n returns (address[] memory)\n {\n return owners;\n }\n\n /// @dev Returns array with owner addresses, which confirmed transaction.\n /// @param transactionId Transaction ID.\n /// @return _confirmations Returns array of owner addresses.\n function getConfirmations(uint transactionId)\n public\n view\n returns (address[] memory _confirmations)\n {\n address[] memory confirmationsTemp = new address[](owners.length);\n uint count = 0;\n uint i;\n for (i = 0; i < owners.length; i++)\n if (confirmations[transactionId][owners[i]]) {\n confirmationsTemp[count] = owners[i];\n count += 1;\n }\n _confirmations = new address[](count);\n for (i = 0; i < count; i++)\n _confirmations[i] = confirmationsTemp[i];\n }\n\n /// @dev Returns list of transaction IDs in defined range.\n /// @param from Index start position of transaction array.\n /// @param to Index end position of transaction array.\n /// @param pending Include pending transactions.\n /// @param executed Include executed transactions.\n /// @return _transactionIds Returns array of transaction IDs.\n function getTransactionIds(uint from, uint to, bool pending, bool executed)\n public\n view\n returns (uint[] memory _transactionIds)\n {\n uint[] memory transactionIdsTemp = new uint[](transactionCount);\n uint count = 0;\n uint i;\n for (i = 0; i < transactionCount; i++)\n if ( pending && !transactions[i].executed || executed && transactions[i].executed)\n {\n transactionIdsTemp[count] = i;\n count += 1;\n }\n _transactionIds = new uint[](to - from);\n for (i = from; i < to; i++)\n _transactionIds[i - from] = transactionIdsTemp[i];\n }\n}"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/solcInputs/7a48ec801ec0f5d1e7af76fbc81bb365.json b/bridge/deployments/kovan/solcInputs/7a48ec801ec0f5d1e7af76fbc81bb365.json
new file mode 100644
index 000000000..79562d6a4
--- /dev/null
+++ b/bridge/deployments/kovan/solcInputs/7a48ec801ec0f5d1e7af76fbc81bb365.json
@@ -0,0 +1,306 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/math/SafeMath.sol\";\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\n\nimport \"../interface/IAllowTokens.sol\";\n\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\n\tusing SafeMath for uint256;\n\n\taddress constant private NULL_ADDRESS = address(0);\n\tuint256 constant public MAX_TYPES = 250;\n\tmapping (address => TokenInfo) public allowedTokens;\n\tmapping (uint256 => Limits) public typeLimits;\n\tuint256 public smallAmountConfirmations;\n\tuint256 public mediumAmountConfirmations;\n\tuint256 public largeAmountConfirmations;\n\tstring[] public typeDescriptions;\n\n\tevent SetToken(address indexed _tokenAddress, uint256 _typeId);\n\tevent AllowedTokenRemoved(address indexed _tokenAddress);\n\tevent TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\n\tevent TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\n\tevent UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\n\tevent ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\n\n\tmodifier notNull(address _address) {\n\t\trequire(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\n\t\t_;\n\t}\n\n\tfunction initialize(\n\t\taddress _manager,\n\t\taddress _primary,\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations,\n\t\tTypeInfo[] memory typesInfo) public initializer {\n\t\tUpgradableOwnable.initialize(_manager);\n\t\tUpgradableSecondary.__Secondary_init(_primary);\n\t\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t\tfor(uint i = 0; i < typesInfo.length; i = i + 1) {\n\t\t\t_addTokenType(typesInfo[i].description, typesInfo[i].limits);\n\t\t}\n\t}\n\n\tfunction version() override external pure returns (string memory) {\n\t\treturn \"v1\";\n\t}\n\n\tfunction tokenInfo(address tokenAddress) public view returns(TokenInfo memory) {\n\t\treturn allowedTokens[tokenAddress];\n\t}\n\n\tfunction setTokenInfoByTokenAddress(address tokenAddress, TokenInfo memory info) public {\n\t\trequire(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n\t\tallowedTokens[tokenAddress] = info;\n\t}\n\n\tfunction getInfoAndLimits(\n\t\taddress tokenAddress\n\t) public view override returns (\n\t\tTokenInfo memory info,\n\t\tLimits memory limit\n\t) {\n\t\tinfo = tokenInfo(tokenAddress);\n\t\tlimit = typeLimits[info.typeId];\n\t\treturn (info, limit);\n\t}\n\n\tfunction calcMaxWithdraw(address token) public view override returns (uint256 maxWithdraw) {\n\t\t(TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\n\t\treturn _calcMaxWithdraw(info, limits);\n\t}\n\n\tfunction _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\n\t\t// solium-disable-next-line security/no-block-members\n\t\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n\t\t\tinfo.spentToday = 0;\n\t\t}\n\t\tif (limits.daily <= info.spentToday) {\n\t\t\treturn 0;\n\t\t}\n\t\tmaxWithdraw = limits.daily - info.spentToday;\n\t\tif (maxWithdraw > limits.max) {\n\t\t\tmaxWithdraw = limits.max;\n\t\t}\n\t\treturn maxWithdraw;\n\t}\n\n\tfunction updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\n\t\t(TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\n\t\trequire(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\n\t\trequire(amount >= limit.min, \"AllowTokens: Lower than limit\");\n\n\t\t// solium-disable-next-line security/no-block-members\n\t\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n\t\t\t// solium-disable-next-line security/no-block-members\n\t\t\tinfo.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n\t\t\tinfo.spentToday = 0;\n\t\t}\n\t\tuint maxWithdraw = _calcMaxWithdraw(info, limit);\n\t\trequire(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\n\t\tinfo.spentToday = info.spentToday.add(amount);\n\t\tsetTokenInfoByTokenAddress(token, info);\n\n\t\temit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\n\t}\n\n\tfunction _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\n\t\trequire(bytes(description).length > 0, \"AllowTokens: Empty description\");\n\t\tlen = typeDescriptions.length;\n\t\trequire(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\n\t\ttypeDescriptions.push(description);\n\t\t_setTypeLimits(len, limits);\n\t\temit TokenTypeAdded(len, description);\n\t\treturn len;\n\t}\n\n\tfunction addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\n\t\treturn _addTokenType(description, limits);\n\t}\n\n\tfunction _setTypeLimits(uint256 typeId, Limits memory limits) private {\n\t\trequire(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\n\t\trequire(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\n\t\trequire(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\n\t\trequire(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\n\t\trequire(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\n\t\ttypeLimits[typeId] = limits;\n\t\temit TypeLimitsChanged(typeId, limits);\n\t}\n\n\tfunction setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\n\t\t_setTypeLimits(typeId, limits);\n\t}\n\n\tfunction getTypesLimits() external view override returns(Limits[] memory limits) {\n\t\tlimits = new Limits[](typeDescriptions.length);\n\t\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\n\t\t\tlimits[i] = typeLimits[i];\n\t\t}\n\t\treturn limits;\n\t}\n\n\tfunction getTypeDescriptionsLength() external view override returns(uint256) {\n\t\treturn typeDescriptions.length;\n\t}\n\n\tfunction getTypeDescriptions() external view override returns(string[] memory descriptions) {\n\t\tdescriptions = new string[](typeDescriptions.length);\n\t\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\n\t\t\tdescriptions[i] = typeDescriptions[i];\n\t\t}\n\t\treturn descriptions;\n\t}\n\n\tfunction isTokenAllowed(address token) public view notNull(token) override returns (bool) {\n\t\treturn tokenInfo(token).allowed;\n\t}\n\n\tfunction setToken(address token, uint256 typeId) override public notNull(token) {\n\t\trequire(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n\t\trequire(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\n\t\tTokenInfo memory info = tokenInfo(token);\n\t\tinfo.allowed = true;\n\t\tinfo.typeId = typeId;\n\t\tsetTokenInfoByTokenAddress(token, info);\n\t\temit SetToken(token, typeId);\n\t}\n\n\tfunction setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\n\t\trequire(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\n\t\tfor(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\n\t\t\tsetToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\n\t\t}\n\t}\n\n\tfunction removeAllowedToken(address token) external notNull(token) onlyOwner {\n\t\tTokenInfo memory info = tokenInfo(token);\n\t\trequire(info.allowed, \"AllowTokens: Not Allowed\");\n\t\tinfo.allowed = false;\n\t\tsetTokenInfoByTokenAddress(token, info);\n\t\temit AllowedTokenRemoved(token);\n\t}\n\n\tfunction setConfirmations(\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations) external onlyOwner {\n\t\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t}\n\n\tfunction _setConfirmations(\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations) private {\n\t\trequire(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\n\t\trequire(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\n\t\tsmallAmountConfirmations = _smallAmountConfirmations;\n\t\tmediumAmountConfirmations = _mediumAmountConfirmations;\n\t\tlargeAmountConfirmations = _largeAmountConfirmations;\n\t\temit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t}\n\n\tfunction getConfirmations() external view override\n\t\treturns (\n\t\tuint256 smallAmount,\n\t\tuint256 mediumAmount,\n\t\tuint256 largeAmount\n\t) {\n\t\treturn (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\n\t}\n\n}\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @title Initializable\n *\n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(initializing || !initialized, \"Contract instance is already initialized\");\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\n * the owner.\n */\ncontract UpgradableOwnable is Initializable, Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function initialize(address sender) public initializer {\n _owner = sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * > Note: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\ncontract UpgradableSecondary is Initializable, Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n function __Secondary_init(address sender) public initializer {\n _primary = sender;\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(recipient);\n }\n\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IAllowTokens {\n\n\tstruct Limits {\n\t\tuint256 min;\n\t\tuint256 max;\n\t\tuint256 daily;\n\t\tuint256 mediumAmount;\n\t\tuint256 largeAmount;\n\t}\n\n\tstruct TokenInfo {\n\t\tbool allowed;\n\t\tuint256 typeId;\n\t\tuint256 spentToday;\n\t\tuint256 lastDay;\n\t}\n\n\tstruct TypeInfo {\n\t\tstring description;\n\t\tLimits limits;\n\t}\n\n\tstruct TokensAndType {\n\t\taddress token;\n\t\tuint256 typeId;\n\t}\n\n\tfunction version() external pure returns (string memory);\n\n\tfunction getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\n\n\tfunction calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\n\n\tfunction getTypesLimits() external view returns(Limits[] memory limits);\n\n\tfunction getTypeDescriptionsLength() external view returns(uint256);\n\n\tfunction getTypeDescriptions() external view returns(string[] memory descriptions);\n\n\tfunction setToken(address token, uint256 typeId) external;\n\n\tfunction getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\n\n\tfunction isTokenAllowed(address token) external view returns (bool);\n\n\tfunction updateTokenTransfer(address token, uint256 amount) external;\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n\n function _msgSender() internal view returns (address payable) {\n return payable(msg.sender);\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
+ },
+ "contracts/nftbridge/NFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC721/IERC721.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Metadata.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Enumerable.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Receiver.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./INFTBridge.sol\";\nimport \"./ISideNFTToken.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract NFTBridge is\n Initializable,\n INFTBridge,\n UpgradablePausable,\n UpgradableOwnable,\n ReentrancyGuard,\n IERC721Receiver {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address internal constant NULL_ADDRESS = address(0);\n bytes32 internal constant NULL_HASH = bytes32(0);\n IERC1820Registry internal constant ERC1820 =\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address payable internal federation;\n uint256 internal fixedFee;\n string public symbolPrefix;\n\n mapping(uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain;\n mapping(address => OriginalNft) public originalTokenBySideToken;\n mapping(uint256 => mapping(address => bool)) public isAddressFromCrossedOriginalTokenByChain; // uint256 => address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n\n IAllowTokens public allowTokens;\n ISideNFTTokenFactory public sideTokenFactory;\n bool public isUpgrading;\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\n event Upgrading(bool _isUpgrading);\n\n function initialize(\n address _manager,\n address payable _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\n federation = _federation;\n ERC1820.setInterfaceImplementer(\n address(this),\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\n address(this)\n );\n }\n\n function version() external pure override returns (string memory) {\n return \"v1\";\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _tokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\tuint256\t_destinationChainId\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"NFTBridge: Not Federation\");\n require(\n isAddressFromCrossedOriginalToken(_originChainId, _tokenAddress) ||\n getSideTokenByOriginalToken(_originChainId, _tokenAddress) != NULL_ADDRESS,\n \"NFTBridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"NFTBridge: Null To\");\n require(_from != NULL_ADDRESS, \"NFTBridge: Null From\");\n require(_blockHash != NULL_HASH, \"NFTBridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"NFTBridge: Null TxHash\");\n require(\n transactionDataHashes[_transactionHash] == bytes32(0),\n \"NFTBridge: Already accepted\"\n );\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _blockHash,\n _transactionHash,\n _logIndex,\n _originChainId,\n\t_destinationChainId\n );\n\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\n require(!claimed[_transactionDataHash], \"NFTBridge: Already claimed\");\n transactionDataHashes[_transactionHash] = _transactionDataHash;\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\n// senderAddresses[_transactionHash] = _from;\n\n emit AcceptedNFTCrossTransfer(\n _transactionHash,\n _tokenAddress,\n _to,\n _from,\n _tokenId,\n _blockHash,\n _logIndex,\n _originChainId,\n\t_destinationChainId\n );\n }\n\n function getSideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\n return sideTokenByOriginalTokenByChain[chainId][originalToken];\n }\n\n function setSideTokenByOriginalToken(uint256 chainId, address originalToken, address sideToken) public {\n sideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\n }\n\n function getOriginalTokenBySideToken(address sideToken) public view returns(OriginalNft memory) {\n return originalTokenBySideToken[sideToken];\n }\n\n function setOriginalTokenBySideToken(address sideToken, OriginalNft memory originalToken) public {\n originalTokenBySideToken[sideToken] = originalToken;\n }\n\n function isAddressFromCrossedOriginalToken(uint256 chainId, address originalToken) public view returns(bool addressHasCrossed) {\n return isAddressFromCrossedOriginalTokenByChain[chainId][originalToken];\n }\n\n function setAddressFromCrossedOriginalToken(uint256 chainId, address originalToken, bool addressHasCrossed) public {\n isAddressFromCrossedOriginalTokenByChain[chainId][originalToken] = addressHasCrossed;\n }\n\n function createSideNFTToken(\n address _originalTokenAddress,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName,\n string calldata _baseURI,\n string calldata _contractURI,\n uint256 originChainId\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"NFTBridge: Null original token address\");\n\n require(getSideTokenByOriginalToken(originChainId, _originalTokenAddress) == NULL_ADDRESS, \"NFTBridge: Side token already exists\");\n string memory sideTokenSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n address sideTokenAddress = sideTokenFactory.createSideNFTToken(_originalTokenName, sideTokenSymbol, _baseURI, _contractURI);\n\n setSideTokenByOriginalToken(originChainId, _originalTokenAddress, sideTokenAddress);\n\n OriginalNft memory originalNft;\n originalNft.originChainId = originChainId;\n originalNft.nftAddress = _originalTokenAddress;\n setOriginalTokenBySideToken(sideTokenAddress, originalNft);\n\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, sideTokenSymbol, originChainId);\n }\n\n function claim(NFTClaimData calldata _claimData) external override {\n _claim(_claimData, _claimData.to);\n }\n\n function claimFallback(NFTClaimData calldata _claimData) external override {\n require(_msgSender() == _claimData.from, \"NFTBridge: invalid sender\");\n _claim(_claimData, _msgSender());\n }\n\n function _claim(\n NFTClaimData calldata _claimData,\n address payable _receiver\n ) internal {\n address tokenAddress = _claimData.tokenAddress;\n uint256 tokenId = _claimData.tokenId;\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.from,\n tokenId,\n tokenAddress,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex,\n _claimData.originChainId,\n block.chainid\n );\n\n\n require(\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\n \"NFTBridge: Wrong txDataHash\"\n );\n require(!claimed[transactionDataHash], \"NFTBridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (isAddressFromCrossedOriginalToken(_claimData.originChainId, tokenAddress)) {\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\n } else {\n address sideTokenAddress = getSideTokenByOriginalToken(_claimData.originChainId, tokenAddress);\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\n }\n\n emit ClaimedNFTToken(\n _claimData.transactionHash,\n tokenAddress,\n _claimData.to,\n _claimData.from,\n _claimData.tokenId,\n _claimData.blockHash,\n _claimData.logIndex,\n _receiver,\n _claimData.originChainId,\n block.chainid\n );\n }\n\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\"creator()\"));\n if (success) {\n return abi.decode(data, (address));\n }\n\n return IERC721(tokenAddress).ownerOf(tokenId);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId,\n uint256 destinationChainId\n ) public payable override {\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\n address payable sender = _msgSender();\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\n\n crossTokens(tokenAddress, to, tokenCreator, \"\", tokenId, destinationChainId);\n\n if (fixedFee == 0) {\n return;\n }\n uint256 msgValue = msg.value;\n require(msgValue >= fixedFee, \"NFTBridge: value is smaller than fixed fee\");\n\n // Send the payment to the MultiSig of the Federation\n federation.transfer(fixedFee);\n\n if (msgValue > fixedFee) { // refund of unused value\n sender.transfer(msgValue.sub(fixedFee));\n }\n }\n\n function crossTokens(\n address tokenAddress,\n address to,\n address tokenCreator,\n bytes memory userData,\n uint256 tokenId,\n uint256 destinationChainId\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\n require(block.chainid != destinationChainId, \"NFTBridge: destination chain id equal current chain id\");\n setAddressFromCrossedOriginalToken(destinationChainId, tokenAddress, true);\n\n IERC721Enumerable enumerable = IERC721Enumerable(tokenAddress);\n IERC721Metadata metadataIERC = IERC721Metadata(tokenAddress);\n string memory tokenURI = metadataIERC.tokenURI(tokenId);\n\n OriginalNft memory originalToken = getOriginalTokenBySideToken(tokenAddress);\n if (originalToken.nftAddress != NULL_ADDRESS) {\n ERC721Burnable(tokenAddress).burn(tokenId);\n emit Cross(\n originalToken.nftAddress,\n _msgSender(),\n to,\n tokenCreator,\n userData,\n enumerable.totalSupply(),\n tokenId,\n tokenURI,\n block.chainid,\n\t\t\t\tdestinationChainId\n );\n return;\n }\n\n emit Cross(\n tokenAddress,\n _msgSender(),\n to,\n tokenCreator,\n userData,\n enumerable.totalSupply(),\n tokenId,\n tokenURI,\n block.chainid,\n destinationChainId\n );\n }\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\tuint256\t_destinationChainId\n ) public pure override returns (bytes32) {\n return keccak256(\n abi.encodePacked(\n _blockHash,\n _transactionHash,\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _logIndex,\n _originChainId,\n _destinationChainId\n )\n );\n }\n\n function setFixedFee(uint256 amount) external onlyOwner {\n fixedFee = amount;\n emit FixedFeeNFTChanged(fixedFee);\n }\n\n function getFixedFee() external view override returns (uint256) {\n return fixedFee;\n }\n\n function changeFederation(address payable newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"NFTBridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"NFTBridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns (address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\n require(\n newSideNFTTokenFactory != NULL_ADDRESS,\n \"NFTBridge: empty SideTokenFactory\"\n );\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionDataHashes[transactionHash]];\n }\n\n /**\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\n/**\n * @title Helps contracts guard against reentrancy attacks.\n * @author Remco Bloemen , Eenae \n * @dev If you mark a function `nonReentrant`, you should also\n * mark it `external`.\n */\ncontract ReentrancyGuard is Initializable {\n /// @dev counter to allow mutex lock with only one SSTORE operation\n uint256 private _guardCounter;\n\n function initialize() public initializer {\n // The counter starts at one to prevent changing it from zero to a non-zero\n // value, which is a more expensive operation.\n _guardCounter = 1;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _guardCounter += 1;\n uint256 localCounter = _guardCounter;\n _;\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\n }\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\nimport \"../access/roles/UpgradablePauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n function __Pausable_init(address sender) public initializer {\n UpgradablePauserRole.__PauserRol_init(sender);\n\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as `account`'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `_account`.\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `_implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\n\n /**\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `_account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {ERC20Detailed}.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeERC20: low-level call failed\");\n\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n */\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./ERC721.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721Burnable is Context, ERC721 {\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n _burn(tokenId);\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\nlibrary LibEIP712 {\n\n // Hash of the EIP712 Domain Separator Schema\n // keccak256(abi.encodePacked(\n // \"EIP712Domain(\",\n // \"string name,\",\n // \"string version,\",\n // \"uint256 chainId,\",\n // \"address verifyingContract\",\n // \")\"\n // ))\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n /// @dev Calculates a EIP712 domain separator.\n /// @param name The EIP712 domain name.\n /// @param version The EIP712 domain version.\n /// @param verifyingContract The EIP712 verifying contract.\n /// @return result EIP712 domain separator.\n function hashEIP712Domain(\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n // keccak256(bytes(name)),\n // keccak256(bytes(version)),\n // chainId,\n // uint256(verifyingContract)\n // ))\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Calculate hashes of dynamic data\n let nameHash := keccak256(add(name, 32), mload(name))\n let versionHash := keccak256(add(version, 32), mload(version))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n // Store params in memory\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), nameHash)\n mstore(add(memPtr, 64), versionHash)\n mstore(add(memPtr, 96), chainId)\n mstore(add(memPtr, 128), verifyingContract)\n\n // Compute hash\n result := keccak256(memPtr, 160)\n }\n return result;\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\n /// with getDomainHash().\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to the given EIP712 Domain.\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n internal\n pure\n returns (bytes32 result)\n {\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct\n // ));\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nlibrary LibUtils {\n\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\n return uint256(10)**(18-decimals);\n }\n\n function getDecimals(address tokenToUse) internal view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"LibUtils: No decimals\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n return uint8(abi.decode(data, (uint256)));\n }\n\n function getGranularity(address tokenToUse) internal view returns (uint256) {\n //support granularity if ERC777\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\n require(success, \"LibUtils: No granularity\");\n\n return abi.decode(data, (uint256));\n }\n\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n addr := mload(add(bys,20))\n }\n }\n\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\n require(_bytes.length >= _start + 20, \"LibUtils: toAddress_outOfBounds\");\n address tempAddress;\n\n assembly {\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n }\n\n return tempAddress;\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\n require(_bytes.length >= _start + 16, \"LibUtils: toUint128_outOfBounds\");\n uint128 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x10), _start))\n }\n\n return tempUint;\n }\n\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\n\t\trequire(_bytes.length >= _start + 32, \"LibUtils: toUint256_outOfBounds\");\n\t\tuint256 tempUint;\n\n // solium-disable-next-line security/no-inline-assembly\n\t\tassembly {\n\t\t\ttempUint := mload(add(add(_bytes, 0x20), _start))\n\t\t}\n\n\t\treturn tempUint;\n\t}\n}\n"
+ },
+ "contracts/nftbridge/INFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface INFTBridge {\n\n struct NFTClaimData {\n address payable to;\n address from;\n uint256 tokenId;\n address tokenAddress;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n uint256 originChainId;\n }\n\n\tstruct OriginalNft {\n\t\taddress nftAddress;\n\t\tuint256 originChainId;\n\t}\n\n function version() external pure returns (string memory);\n\n function getFixedFee() external view returns (uint256);\n\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId,\n uint256 destinationChainId\n ) external payable;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\tuint256\t_destinationChainId\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\n */\n function claim(NFTClaimData calldata _claimData) external;\n\n function claimFallback(NFTClaimData calldata _claimData) external;\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\t\tuint256\t_destinationChainId\n ) external returns (bytes32);\n\n event Cross(\n address indexed _originalTokenAddress,\n address indexed _from,\n address indexed _to,\n address _tokenCreator,\n bytes _userData,\n uint256 _totalSupply,\n uint256 _tokenId,\n string _tokenURI,\n uint256 _originChainId,\n\tuint256 _destinationChainId\n );\n event NewSideNFTToken(\n address indexed _newSideNFTTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 originChainId\n );\n event AcceptedNFTCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n uint256 _originChainId,\n\tuint256\t_destinationChainId\n );\n event FixedFeeNFTChanged(uint256 _amount);\n event ClaimedNFTToken(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _receiver,\n uint256 _originChainId,\n\tuint256\t_destinationChainId\n );\n}\n"
+ },
+ "contracts/nftbridge/ISideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideNFTToken {\n function mint(address account, uint256 tokenId) external;\n}"
+ },
+ "contracts/nftbridge/ISideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideNFTTokenFactory {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external returns(address);\n\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IWrapped {\n function balanceOf(address) external returns(uint);\n\n function deposit() external payable;\n\n function withdraw(uint wad) external;\n\n function totalSupply() external view returns (uint);\n\n function approve(address guy, uint wad) external returns (bool);\n\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad)\n external\n returns (bool);\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../Initializable.sol\";\n\nimport \"../../../GSN/Context.sol\";\nimport \"../../../access/Roles.sol\";\n\ncontract UpgradablePauserRole is Initializable, Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n function __PauserRol_init(address sender) public initializer {\n if (!isPauser(sender)) {\n _addPauser(sender);\n }\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @title Roles\n * @dev Library for managing addresses assigned to a Role.\n */\nlibrary Roles {\n struct Role {\n mapping (address => bool) bearer;\n }\n\n /**\n * @dev Give an account access to this role.\n */\n function add(Role storage role, address account) internal {\n require(!has(role, account), \"Roles: account already has role\");\n role.bearer[account] = true;\n }\n\n /**\n * @dev Remove an account's access to this role.\n */\n function remove(Role storage role, address account) internal {\n require(has(role, account), \"Roles: account doesn't have role\");\n role.bearer[account] = false;\n }\n\n /**\n * @dev Check if an account has this role.\n * @return bool\n */\n function has(Role storage role, address account) internal view returns (bool) {\n require(account != address(0), \"Roles: account is the zero address\");\n return role.bearer[account];\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _tokenOwners.contains(tokenId);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(tokenId);\n\n emit Transfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n}\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n}\n"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract WRBTC is IWrapped {\n string public name = \"Wrapped RBTC\";\n string public symbol = \"WRBTC\";\n uint8 public decimals = 18;\n\n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n event Deposit(address indexed dst, uint wad);\n event Withdrawal(address indexed src, uint wad);\n\n mapping (address => uint) override public balanceOf;\n mapping (address => mapping (address => uint)) public allowance;\n\n receive () external payable {\n deposit();\n }\n function deposit() override public payable {\n balanceOf[msg.sender] += msg.value;\n emit Deposit(msg.sender, msg.value);\n }\n function withdraw(uint wad) override public {\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\n balanceOf[msg.sender] -= wad;\n (bool success, ) = msg.sender.call{value:wad, gas:23000}(\"\");\n require(success, \"WRBTC: transfer fail\");\n emit Withdrawal(msg.sender, wad);\n }\n\n function totalSupply() override public view returns (uint) {\n return address(this).balance;\n }\n\n function approve(address guy, uint wad) override public returns (bool) {\n allowance[msg.sender][guy] = wad;\n emit Approval(msg.sender, guy, wad);\n return true;\n }\n\n function transfer(address dst, uint wad) override public returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad)\n override public\n returns (bool)\n {\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\n\n if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\n allowance[src][msg.sender] -= wad;\n }\n\n balanceOf[src] -= wad;\n balanceOf[dst] += wad;\n\n emit Transfer(src, dst, wad);\n\n return true;\n }\n}"
+ },
+ "contracts/test/WBNB.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract WBNB is IWrapped {\n\tstring public name = \"Wrapped BNB\";\n\tstring public symbol = \"WBNB\";\n\tuint8 public decimals = 18;\n\n\tevent Approval(address indexed src, address indexed guy, uint wad);\n\tevent Transfer(address indexed src, address indexed dst, uint wad);\n\tevent Deposit(address indexed dst, uint wad);\n\tevent Withdrawal(address indexed src, uint wad);\n\n\tmapping (address => uint) override public balanceOf;\n\tmapping (address => mapping (address => uint)) public allowance;\n\n\treceive () external payable {\n\t\tdeposit();\n\t}\n\n\tfunction deposit() override public payable {\n\t\tbalanceOf[msg.sender] += msg.value;\n\t\temit Deposit(msg.sender, msg.value);\n\t}\n\n\tfunction withdraw(uint wad) override public {\n\t\trequire(balanceOf[msg.sender] >= wad, \"WBNB: Balance less than wad\");\n\t\tbalanceOf[msg.sender] -= wad;\n\t\t(bool success, ) = msg.sender.call{value:wad, gas:23000}(\"\");\n\t\trequire(success, \"WBNB: transfer fail\");\n\t\temit Withdrawal(msg.sender, wad);\n\t}\n\n\tfunction totalSupply() override public view returns (uint) {\n\t\treturn address(this).balance;\n\t}\n\n\tfunction approve(address guy, uint wad) override public returns (bool) {\n\t\tallowance[msg.sender][guy] = wad;\n\t\temit Approval(msg.sender, guy, wad);\n\t\treturn true;\n\t}\n\n\tfunction transfer(address dst, uint wad) override public returns (bool) {\n\t\treturn transferFrom(msg.sender, dst, wad);\n\t}\n\n\tfunction transferFrom(\n\t\taddress src,\n\t\taddress dst,\n\t\tuint wad\n\t) override public returns (bool) {\n\t\trequire(balanceOf[src] >= wad, \"WBNB: Balance less than wad\");\n\n\t\tif (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {\n\t\t\trequire(allowance[src][msg.sender] >= wad, \"WBNB: Allowance less than wad\");\n\t\t\tallowance[src][msg.sender] -= wad;\n\t\t}\n\n\t\tbalanceOf[src] -= wad;\n\t\tbalanceOf[dst] += wad;\n\n\t\temit Transfer(src, dst, wad);\n\n\t\treturn true;\n\t}\n}"
+ },
+ "contracts/test/CallWrbtc.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract CallWrbtc {\n\n\tIWrapped public wrbtc;\n\n\tconstructor(address _wrbtcAddr) {\n\t\tsetWrbtc(_wrbtcAddr);\n\t}\n\n\treceive() external payable {\n\t\t// The fallback function is needed to use WRBTC\n\t\trequire(msg.sender == address(wrbtc), \"wrong WRBTC addr\");\n\t}\n\n\tfunction setWrbtc(address _wrbtcAddr) public {\n\t\twrbtc = IWrapped(_wrbtcAddr);\n\t}\n\n\tfunction deposit() public payable {\n\t\twrbtc.deposit{ value: msg.value }();\n\t}\n\n\tfunction withdraw(uint256 wad) public {\n\t\twrbtc.withdraw(wad);\n\t\taddress payable senderPayable = payable(msg.sender);\n\t\t(bool success, ) = senderPayable.call{value: wad, gas:23000}(\"\");\n\t\trequire(success, \"CallWrbtc: transfer fail\");\n\t}\n\n}"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// import \"hardhat/console.sol\";\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n\tusing SafeMath for uint256;\n\tusing SafeERC20 for IERC20;\n\tusing Address for address;\n\n\taddress constant internal NULL_ADDRESS = address(0);\n\tbytes32 constant internal NULL_HASH = bytes32(0);\n\tIERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n\taddress internal federation;\n\tuint256 internal feePercentage;\n\tstring public symbolPrefix;\n\t// domainSeparator replaces uint256 internal _depprecatedLastDay;\n\tbytes32 public domainSeparator;\n\tuint256 internal _deprecatedSpentToday;\n\n\tmapping (address => address) public deprecatedMappedTokens; // OriginalToken => SideToken\n\tmapping (address => address) public deprecatedOriginalTokens; // SideToken => OriginalToken\n\tmapping (address => bool) public deprecatedKnownTokens; // OriginalToken => true\n\n\t// claimed can use the same of bytes32\n\tmapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n\n\tIAllowTokens public allowTokens;\n\tISideTokenFactory public sideTokenFactory;\n\t//Bridge_v1 variables\n\tbool public isUpgrading;\n\t// Percentage with up to 2 decimals\n\tuint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\n\t//Bridge_v3 variables\n\tbytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\n\tIWrapped public wrappedCurrency;\n\tmapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n\tmapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n\tmapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n\t// keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,uint256 originChainId,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n\tbytes32 public constant CLAIM_TYPEHASH = 0xaf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c;\n\tmapping(address => uint) public nonces;\n\n\t//Bridge_v4 variables multichain\n\tmapping (uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain; // chainId => OriginalToken Address => SideToken Address\n\tmapping (address => OriginalToken) public originalTokenBySideToken; // SideTokenAddress => struct {}\n\tmapping (uint256 => mapping(address => bool)) public knownTokenByChain; // chainId => OriginalToken Address => Know\n\n\tevent AllowTokensChanged(address _newAllowTokens);\n\tevent FederationChanged(address _newFederation);\n\tevent SideTokenFactoryChanged(address _newSideTokenFactory);\n\tevent Upgrading(bool _isUpgrading);\n\tevent WrappedCurrencyChanged(address _wrappedCurrency);\n\n\tfunction initialize(\n\t\taddress _manager,\n\t\taddress _federation,\n\t\taddress _allowTokens,\n\t\taddress _sideTokenFactory,\n\t\tstring memory _symbolPrefix\n\t) public initializer {\n\t\tUpgradableOwnable.initialize(_manager);\n\t\tUpgradablePausable.__Pausable_init(_manager);\n\t\tsymbolPrefix = _symbolPrefix;\n\t\tallowTokens = IAllowTokens(_allowTokens);\n\t\tsideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n\t\tfederation = _federation;\n\t\t//keccak256(\"ERC777TokensRecipient\")\n\t\tERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n\t\tinitDomainSeparator();\n\t}\n\n\treceive () external payable {\n\t\t// The fallback function is needed to use WRBTC\n\t\trequire(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n\t}\n\n\tfunction version() override external pure returns (string memory) {\n\t\treturn \"v3\";\n\t}\n\n\tfunction initDomainSeparator() public {\n\t\tdomainSeparator = LibEIP712.hashEIP712Domain(\n\t\t\t\"RSK Token Bridge\",\n\t\t\t\"1\",\n\t\t\tblock.chainid,\n\t\t\taddress(this)\n\t\t);\n\t}\n\n\tmodifier whenNotUpgrading() {\n\t\trequire(!isUpgrading, \"Bridge: Upgrading\");\n\t\t_;\n\t}\n\n\tfunction isCurrentChainId(uint256 chainId) private view returns(bool) {\n\t\treturn chainId == block.chainid;\n\t}\n\n\tfunction sideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\n\t\taddress sideTokenAddr = sideTokenByOriginalTokenByChain[chainId][originalToken];\n\n\t\tif (sideTokenAddr != NULL_ADDRESS) {\n\t\t\treturn sideTokenAddr;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\treturn deprecatedMappedTokens[originalToken];\n\t}\n\n\tfunction setSideTokenByOriginalAddressByChain(uint256 chainId, address originalToken, address sideToken) public onlyOwner {\n\t\tsideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\n\t}\n\n\tfunction getOriginalTokenBySideToken(address sideToken) public view returns(OriginalToken memory originalToken) {\n\t\toriginalToken = originalTokenBySideToken[sideToken];\n\t\tif (originalToken.tokenAddress != NULL_ADDRESS) {\n\t\t\treturn originalToken;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\toriginalToken.originChainId = 1; // ethereum main chain id\n\t\toriginalToken.tokenAddress = deprecatedOriginalTokens[sideToken];\n\t\treturn originalToken;\n\t}\n\n\tfunction setOriginalTokenBySideTokenByChain(address sideToken, OriginalToken memory originalToken) public onlyOwner {\n\t\toriginalTokenBySideToken[sideToken] = originalToken;\n\t}\n\n\tfunction knownToken(uint256 chainId, address originalToken) public view returns(bool) {\n\t\tbool knowToken = knownTokenByChain[chainId][originalToken];\n\t\tif (knowToken) {\n\t\t\treturn knowToken;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\treturn deprecatedKnownTokens[originalToken];\n\t}\n\n\tfunction setKnownTokenByChain(uint256 chainId, address originalToken, bool knownTokenValue) public {\n\t\tknownTokenByChain[chainId][originalToken] = knownTokenValue;\n\t}\n\n\tfunction acceptTransfer(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _from,\n\t\taddress payable _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) external whenNotPaused nonReentrant override {\n\t\trequire(_msgSender() == federation, \"Bridge: Not Federation\");\n\t\trequire(knownToken(_originChainId, _originalTokenAddress) ||\n\t\t\tsideTokenByOriginalToken(_originChainId, _originalTokenAddress) != NULL_ADDRESS,\n\t\t\t\"Bridge: Unknown token\"\n\t\t);\n\t\trequire(_to != NULL_ADDRESS, \"Bridge: Null To\");\n\t\trequire(_amount > 0, \"Bridge: Amount 0\");\n\t\trequire(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n\t\trequire(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n\t\trequire(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n\t\tbytes32 _transactionDataHash = getTransactionDataHash(\n\t\t\t_to,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_transactionHash,\n\t\t\t_logIndex\n\t\t);\n\n\t\tbytes32 _transactionDataHashMultichain = getTransactionDataHash(\n\t\t\t_to,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_transactionHash,\n\t\t\t_logIndex,\n\t\t\t_originChainId,\n\t\t\t_destinationChainId\n\t\t);\n\t\t// Do not remove, claimed also has the previously processed using the older bridge version\n\t\t// https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n\t\trequire(!isClaimed(_transactionDataHash, _transactionDataHashMultichain), \"Bridge: Already claimed\");\n\n\t\ttransactionsDataHashes[_transactionHash] = _transactionDataHashMultichain;\n\t\toriginalTokenAddresses[_transactionHash] = _originalTokenAddress;\n\t\tsenderAddresses[_transactionHash] = _from;\n\n\t\temit AcceptedCrossTransfer(\n\t\t\t_transactionHash,\n\t\t\t_originalTokenAddress,\n\t\t\t_to,\n\t\t\t_from,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_logIndex,\n\t\t\t_originChainId,\n\t\t\t_destinationChainId\n\t\t);\n\t}\n\n\tfunction createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _originalTokenSymbol,\n\t\tstring calldata _originalTokenName,\n\t\tuint256 originChainId\n\t) external onlyOwner override {\n\t\trequire(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n\n\t\taddress sideToken = sideTokenByOriginalToken(originChainId, _originalTokenAddress);\n\t\trequire(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n\n\t\tuint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n\t\tstring memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n\t\t// Create side token\n\t\tsideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\n\n\t\tsetSideTokenByOriginalAddressByChain(originChainId, _originalTokenAddress, sideToken);\n\n\t\tOriginalToken memory originalToken;\n\t\toriginalToken.originChainId = originChainId;\n\t\toriginalToken.tokenAddress = _originalTokenAddress;\n\t\tsetOriginalTokenBySideTokenByChain(sideToken, originalToken);\n\t\tallowTokens.setToken(sideToken, _typeId);\n\n\t\temit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity, originChainId);\n\t}\n\n\tfunction claim(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\n\t\treceivedAmount = _claim(\n\t\t\t_claimData,\n\t\t\t_claimData.to,\n\t\t\tpayable(address(0)),\n\t\t\t0\n\t\t);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction claimFallback(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\n\t\trequire(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n\t\treceivedAmount = _claim(\n\t\t\t_claimData,\n\t\t\t_msgSender(),\n\t\t\tpayable(address(0)),\n\t\t\t0\n\t\t);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction getDigest(\n\t\tClaimData memory _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline\n\t) internal returns (bytes32) {\n\t\treturn LibEIP712.hashEIP712Message(\n\t\t\tdomainSeparator,\n\t\t\tkeccak256(\n\t\t\t\tabi.encode(\n\t\t\t\t\tCLAIM_TYPEHASH,\n\t\t\t\t\t_claimData.to,\n\t\t\t\t\t_claimData.amount,\n\t\t\t\t\t_claimData.transactionHash,\n\t\t\t\t\t_claimData.originChainId,\n\t\t\t\t\t_relayer,\n\t\t\t\t\t_fee,\n\t\t\t\t\tnonces[_claimData.to]++,\n\t\t\t\t\t_deadline\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t}\n\n\t// Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n\tfunction claimGasless(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline,\n\t\tuint8 _v,\n\t\tbytes32 _r,\n\t\tbytes32 _s\n\t) external override returns (uint256 receivedAmount) {\n\t\trequire(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\n\n\t\tbytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n\t\taddress recoveredAddress = ecrecover(digest, _v, _r, _s);\n\t\trequire(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n\t\treturn _claim(\n\t\t\t_claimData,\n\t\t\t_claimData.to,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\t}\n\n\tfunction isClaimed(bytes32 transactionDataHash, bytes32 transactionDataHashMultichain) public view returns(bool) {\n\t\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\n\t}\n\n\tfunction isClaimed(ClaimData calldata _claimData, bytes32 transactionDataHashMultichain) public view returns(bool) {\n\t\tbytes32 transactionDataHash = getTransactionDataHash(\n\t\t\t_claimData.to,\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.transactionHash,\n\t\t\t_claimData.logIndex\n\t\t);\n\n\t\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\n\t}\n\n\tfunction _claim(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _reciever,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal nonReentrant returns (uint256 receivedAmount) {\n\t\taddress originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n\t\trequire(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n\t\tbytes32 transactionDataHash = getTransactionDataHash(\n\t\t\t_claimData.to,\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.transactionHash,\n\t\t\t_claimData.logIndex,\n\t\t\t_claimData.originChainId,\n\t\t\tblock.chainid\n\t\t);\n\n\t\trequire(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n\t\trequire(!isClaimed(_claimData, transactionDataHash), \"Bridge: Already claimed\");\n\t\tclaimed[transactionDataHash] = true;\n\n\t\treceivedAmount = _claimCross(\n\t\t\t_claimData.originChainId,\n\t\t\toriginalTokenAddress,\n\t\t\t_reciever,\n\t\t\t_claimData.amount,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\n\t\temitClaimed(_claimData, originalTokenAddress, _reciever, _relayer, _fee);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction emitClaimed(\n\t\tClaimData calldata _claimData,\n\t\taddress originalTokenAddress,\n\t\taddress payable _reciever,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal {\n\t\temit Claimed(\n\t\t\t_claimData.transactionHash,\n\t\t\toriginalTokenAddress,\n\t\t\t_claimData.to,\n\t\t\tsenderAddresses[_claimData.transactionHash],\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.logIndex,\n\t\t\t_reciever,\n\t\t\t_relayer,\n\t\t\t_fee,\n\t\t\t_claimData.originChainId,\n\t\t\tblock.chainid\n\t\t);\n\t}\n\n\tfunction _claimCross(\n\t\tuint256 chainId,\n\t\taddress originalTokenAddress,\n\t\taddress payable _reciever,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256) {\n\t\tif (knownToken(chainId, originalTokenAddress)) {\n\t\t\treturn _claimCrossBackToToken(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\t_reciever,\n\t\t\t\t_amount,\n\t\t\t\t_relayer,\n\t\t\t\t_fee\n\t\t\t);\n\t\t}\n\n\t\treturn _claimCrossToSideToken(\n\t\t\tsideTokenByOriginalToken(chainId, originalTokenAddress),\n\t\t\t_reciever,\n\t\t\t_amount,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\t}\n\n\tfunction _claimCrossToSideToken(\n\t\taddress sideToken,\n\t\taddress payable _receiver,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256 receivedAmount) {\n\t\trequire(sideToken != NULL_ADDRESS, \"Bridge: side token is null\");\n\t\tuint256 granularity = IERC777(sideToken).granularity();\n\t\tuint256 formattedAmount = _amount.mul(granularity);\n\t\trequire(_fee <= formattedAmount, \"Bridge: fee too high\");\n\t\treceivedAmount = formattedAmount.sub(_fee);\n\t\tISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n\t\tif (_fee > 0) {\n\t\t\tISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n\t\t}\n\t\treturn receivedAmount;\n\t}\n\n\tfunction _claimCrossBackToToken(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _receiver,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256 receivedAmount) {\n\t\tuint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n\t\t//As side tokens are ERC777 they will always have 18 decimals\n\t\tuint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n\t\trequire(_fee <= formattedAmount, \"Bridge: fee too high\");\n\t\treceivedAmount = formattedAmount.sub(_fee);\n\t\tif (address(wrappedCurrency) == _originalTokenAddress) {\n\t\t\twrappedCurrency.withdraw(formattedAmount);\n\t\t\t_receiver.transfer(receivedAmount);\n\t\t\tif(_fee > 0) {\n\t\t\t\t_relayer.transfer(_fee);\n\t\t\t}\n\t\t} else {\n\t\t\tIERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n\t\t\tif(_fee > 0) {\n\t\t\t\tIERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n\t\t\t}\n\t\t}\n\t\treturn receivedAmount;\n\t}\n\n\t/**\n\t\t* ERC-20 tokens approve and transferFrom pattern\n\t\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n\t\t*/\n\tfunction receiveTokensTo(uint256 destinationChainId, address tokenToUse, address to, uint256 amount) external override {\n\t\taddress sender = _msgSender();\n\t\t//Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n\t\tIERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n\t\tcrossTokens(tokenToUse, sender, to, amount, \"\", destinationChainId);\n\t}\n\n\t/**\n\t\t* Use network currency and cross it.\n\t\t*/\n\tfunction depositTo(uint256 chainId, address to) external payable override {\n\t\taddress sender = _msgSender();\n\t\trequire(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n\t\twrappedCurrency.deposit{ value: msg.value }();\n\t\tcrossTokens(address(wrappedCurrency), sender, to, msg.value, \"\", chainId);\n\t}\n\n\t/**\n\t\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n\t\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n\t\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\n\t\t* const userData = web3.eth.abi.encodeParameters(\n * [\"address\", \"uint256\"],\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\n * );\n\t\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\n\t\t* const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\n\t\t*/\n\tfunction tokensReceived(\n\t\taddress operator,\n\t\taddress from,\n\t\taddress to,\n\t\tuint amount,\n\t\tbytes calldata userData, // [address,uint256] user addrest receiver, destinationChainId || [uint256] same as from, destinationChainId\n\t\tbytes calldata\n\t) external override(IBridge, IERC777Recipient) {\n\t\t//Hook from ERC777address\n\t\tif(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n\t\trequire(to == address(this), \"Bridge: Not to this address\");\n\t\taddress tokenToUse = _msgSender();\n\t\trequire(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n\t\trequire(userData.length >= 32, \"Bridge: user data with at least the destinationChainId\");\n\t\trequire(userData.length == 64 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n\t\taddress receiver = userData.length == 32 ? from : LibUtils.toAddress(userData, 12);\n\t\tuint256 destinationChainId = LibUtils.toUint256(userData, userData.length - 32);\n\t\tcrossTokens(tokenToUse, from, receiver, amount, userData, destinationChainId);\n\t}\n\n\tfunction crossTokens(\n\t\taddress tokenToUse,\n\t\taddress from,\n\t\taddress to,\n\t\tuint256 amount,\n\t\tbytes memory userData,\n\t\tuint256 destinationChainId\n\t) internal whenNotUpgrading whenNotPaused nonReentrant {\n\t\trequire(block.chainid != destinationChainId, \"Bridge: destination chain id equal current chain id\");\n\t\tsetKnownTokenByChain(destinationChainId, tokenToUse, true);\n\t\tuint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n\t\tuint256 amountMinusFees = amount.sub(fee);\n\t\tuint8 decimals = LibUtils.getDecimals(tokenToUse);\n\t\tuint formattedAmount = amount;\n\t\tif (decimals != 18) {\n\t\t\tformattedAmount = amount.mul(uint256(10)**(18-decimals));\n\t\t}\n\t\t// We consider the amount before fees converted to 18 decimals to check the limits\n\t\t// updateTokenTransfer revert if token not allowed\n\t\tallowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n\n\t\tOriginalToken memory sideToken = getOriginalTokenBySideToken(tokenToUse);\n\t\tif (sideToken.tokenAddress != NULL_ADDRESS) {\n\t\t\t// Side Token Crossing back\n\t\t\tuint256 granularity = LibUtils.getGranularity(tokenToUse);\n\t\t\tuint256 modulo = amountMinusFees.mod(granularity);\n\t\t\tfee = fee.add(modulo);\n\t\t\tamountMinusFees = amountMinusFees.sub(modulo);\n\t\t\tIERC777(tokenToUse).burn(amountMinusFees, userData);\n\t\t\temit Cross(\n\t\t\t\tsideToken.tokenAddress,\n\t\t\t\tfrom,\n\t\t\t\tto,\n\t\t\t\tamountMinusFees,\n\t\t\t\tuserData,\n\t\t\t\tblock.chainid,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\t\t} else {\n\t\t\temit Cross(\n\t\t\t\ttokenToUse,\n\t\t\t\tfrom,\n\t\t\t\tto,\n\t\t\t\tamountMinusFees,\n\t\t\t\tuserData,\n\t\t\t\tblock.chainid,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\t\t}\n\n\t\tif (fee > 0) {\n\t\t\t//Send the payment to the MultiSig of the Federation\n\t\t\tIERC20(tokenToUse).safeTransfer(owner(), fee);\n\t\t}\n\t}\n\n\t// function for retrocompatibility\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex\n\t) internal pure returns(bytes32) {\n\t\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n\t}\n\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) public pure override returns(bytes32) {\n\t\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex, _originChainId, _destinationChainId));\n\t}\n\n\tfunction setFeePercentage(uint amount) external onlyOwner {\n\t\trequire(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n\t\tfeePercentage = amount;\n\t\temit FeePercentageChanged(feePercentage);\n\t}\n\n\tfunction getFeePercentage() external view override returns(uint) {\n\t\treturn feePercentage;\n\t}\n\n\tfunction changeFederation(address newFederation) external onlyOwner {\n\t\trequire(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n\t\tfederation = newFederation;\n\t\temit FederationChanged(federation);\n\t}\n\n\tfunction changeAllowTokens(address newAllowTokens) external onlyOwner {\n\t\trequire(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n\t\tallowTokens = IAllowTokens(newAllowTokens);\n\t\temit AllowTokensChanged(newAllowTokens);\n\t}\n\n\tfunction getFederation() external view returns(address) {\n\t\treturn federation;\n\t}\n\n\tfunction changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n\t\trequire(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n\t\tsideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n\t\temit SideTokenFactoryChanged(newSideTokenFactory);\n\t}\n\n\tfunction setUpgrading(bool _isUpgrading) external onlyOwner {\n\t\tisUpgrading = _isUpgrading;\n\t\temit Upgrading(isUpgrading);\n\t}\n\n\tfunction setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n\t\trequire(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n\t\twrappedCurrency = IWrapped(_wrappedCurrency);\n\t\temit WrappedCurrencyChanged(_wrappedCurrency);\n\t}\n\n\tfunction hasCrossed(bytes32 transactionHash) public view returns (bool) {\n\t\treturn transactionsDataHashes[transactionHash] != bytes32(0);\n\t}\n\n\tfunction hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n\t\treturn claimed[transactionsDataHashes[transactionHash]];\n\t}\n\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an `IERC777` token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See `IERC1820Registry` and\n * `ERC1820Implementer`.\n */\ninterface IERC777 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See `operatorSend` and `operatorBurn`.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor`.\n *\n * Emits an `AuthorizedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor` and `defaultOperators`.\n *\n * Emits a `RevokedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if `authorizeOperator` was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * `revokeOperator`, in which case `isOperatorFor` will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n\n function decimals() external returns (uint8);\n\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n}\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IBridge {\n\n\tstruct ClaimData {\n\t\taddress payable to;\n\t\tuint256 amount;\n\t\tbytes32 blockHash;\n\t\tbytes32 transactionHash;\n\t\tuint32 logIndex;\n\t\tuint256 originChainId;\n\t}\n\n\tstruct OriginalToken {\n\t\taddress tokenAddress;\n\t\tuint256 originChainId;\n\t}\n\n\tfunction version() external pure returns (string memory);\n\n\tfunction getFeePercentage() external view returns(uint);\n\n\t/**\n\t\t* ERC-20 tokens approve and transferFrom pattern\n\t\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n\t\t*/\n\tfunction receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;\n\n\t/**\n\t\t* Use network currency and cross it.\n\t\t*/\n\tfunction depositTo(uint256 chainId, address to) external payable;\n\n\t/**\n\t\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n\t\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n\t\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\n\t\t* const userData = web3.eth.abi.encodeParameters(\n * [\"address\", \"uint256\"],\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\n * );\n\t\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\n\t\t* const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\n\t\t*/\n\tfunction tokensReceived (\n\t\taddress operator,\n\t\taddress from,\n\t\taddress to,\n\t\tuint amount,\n\t\tbytes calldata userData,\n\t\tbytes calldata operatorData\n\t) external;\n\n\t/**\n\t\t* Accepts the transaction from the other chain that was voted and sent by the Federation contract\n\t\t*/\n\tfunction acceptTransfer(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _from,\n\t\taddress payable _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) external;\n\n\t/**\n\t\t* Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n\t\t*/\n\tfunction claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n\tfunction claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n\tfunction claimGasless(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline,\n\t\tuint8 _v,\n\t\tbytes32 _r,\n\t\tbytes32 _s\n\t) external returns (uint256 receivedAmount);\n\n\tfunction createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _originalTokenSymbol,\n\t\tstring calldata _originalTokenName,\n\t\tuint256 chainId\n\t) external;\n\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256 _destinationChainId\n\t) external returns(bytes32);\n\n\tevent Cross(\n\t\taddress indexed _tokenAddress,\n\t\taddress indexed _from,\n\t\taddress indexed _to,\n\t\tuint256 _amount,\n\t\tbytes _userData,\n\t\tuint256 originChainId,\n\t\tuint256 destinationChainId\n\t);\n\n\tevent NewSideToken(\n\t\taddress indexed _newSideTokenAddress,\n\t\taddress indexed _originalTokenAddress,\n\t\tstring _newSymbol,\n\t\tuint256 _granularity,\n\t\tuint256 chainId\n\t);\n\tevent AcceptedCrossTransfer(\n\t\tbytes32 indexed _transactionHash,\n\t\taddress indexed _originalTokenAddress,\n\t\taddress indexed _to,\n\t\taddress _from,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tuint256 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t);\n\tevent FeePercentageChanged(uint256 _amount);\n\tevent Claimed(\n\t\tbytes32 indexed _transactionHash,\n\t\taddress indexed _originalTokenAddress,\n\t\taddress indexed _to,\n\t\taddress _sender,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tuint256 _logIndex,\n\t\taddress _reciever,\n\t\taddress _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _destinationChainId,\n\t\tuint256 _originChainId\n\t);\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideToken {\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideTokenFactory {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\n\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../SideToken/SideToken.sol\";\n\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\n external onlyPrimary override returns(address) {\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\n emit SideTokenCreated(sideToken, symbol, granularity);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\nabstract contract Secondary is Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n constructor () {\n _primary = _msgSender();\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(_primary);\n }\n}\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\nimport \"../interface/IERC677Receiver.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../lib/LibEIP712.sol\";\n\ncontract SideToken is ISideToken, ERC777 {\n using SafeMath for uint256;\n\n address public minter;\n uint256 private _granularity;\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n bytes32 public domainSeparator;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n // ERC677 Transfer Event\n event Transfer(address,address,uint256,bytes);\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\n minter = _minterAddr;\n _granularity = _newGranularity;\n\n domainSeparator = LibEIP712.hashEIP712Domain(\n name(),\n \"1\",\n block.chainid,\n address(this)\n );\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter override\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n /**\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\n * @param recipient The address to transfer to.\n * @param amount The amount to be transferred.\n * @param data The extra data to be passed to the receiving contract.\n */\n function transferAndCall(address recipient, uint amount, bytes calldata data)\n external returns (bool success)\n {\n address from = _msgSender();\n\n _send(from, from, recipient, amount, data, \"\", false);\n emit Transfer(from, recipient, amount, data);\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\n return true;\n }\n\n function granularity() public view override returns (uint256) {\n return _granularity;\n }\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\n bytes32 digest = LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../../token/ERC20/IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\n // See https://github.com/ethereum/solidity/issues/4024.\n\n // keccak256(\"ERC777TokensSender\")\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\n\n // keccak256(\"ERC777TokensRecipient\")\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping (address => mapping (address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(\n string memory aName,\n string memory aSymbol,\n address[] memory theDefaultOperators\n ) {\n _name = aName;\n _symbol = aSymbol;\n\n _defaultOperatorsArray = theDefaultOperators;\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\n _defaultOperators[_defaultOperatorsArray[i]] = true;\n }\n\n // register interfaces\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view override(IERC777) returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view override(IERC777) returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20Detailed-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override(IERC777) returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n\n address from = _msgSender();\n\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\n\n _move(from, from, recipient, amount, \"\", \"\");\n\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(\n address operator,\n address tokenHolder\n ) public view override(IERC777) returns (bool) {\n return operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) external override(IERC777) {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) external override(IERC777) {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n )\n external override(IERC777)\n {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {Transfer} events.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\n external override(IERC777) {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\n _burn(_msgSender(), account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender)\n public view override(IERC20) returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {Transfer} and {Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount)\n external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n require(holder != address(0), \"ERC777: transfer from zero address\");\n\n address spender = _msgSender();\n\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\n\n _move(spender, holder, recipient, amount, \"\", \"\");\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\n\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address operator,\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n require(account != address(0), \"ERC777: mint to zero address\");\n\n // Update state variables\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n internal\n {\n require(from != address(0), \"ERC777: send from zero address\");\n require(to != address(0), \"ERC777: send to zero address\");\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param operator address operator requesting the operation\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(\n address operator,\n address from,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n )\n internal\n {\n require(from != address(0), \"ERC777: burn from zero address\");\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n // Update state variables\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\n _balances[to] = _balances[to].add(amount);\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n function _approve(address holder, address spender, uint256 value) internal {\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\n // currently unnecessary.\n //require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n private\n {\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n}\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * `IERC777` Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an `IERC777` token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/Bridge/BridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"./IBridgeV2.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../AllowTokens/AllowTokensV0.sol\";\nimport \"../Utils/UtilsV1.sol\";\n\ncontract BridgeV2 is Initializable, IBridgeV2, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant private NULL_ADDRESS = address(0);\n bytes32 constant private NULL_HASH = bytes32(0);\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address private federation;\n uint256 private feePercentage;\n string public symbolPrefix;\n uint256 public lastDay;\n uint256 public spentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping(bytes32 => bool) public processed; // ProcessedHash => true\n AllowTokensV0 public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n uint256 constant public FEE_PERCENTAGE_DIVIDER = 10000; // Percentage with up to 2 decimals\n bool private alreadyRun;\n\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool isUpgrading);\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = AllowTokensV0(_allowTokens);\n _changeSideTokenFactory(_sideTokenFactory);\n _changeFederation(_federation);\n //keccak256(\"ERC777TokensRecipient\")\n ERC_1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function version() external pure override returns (string memory) {\n return \"v2\";\n }\n\n modifier onlyFederation() {\n require(msg.sender == federation, \"Bridge: Sender not Federation\");\n _;\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address tokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity\n ) external onlyFederation whenNotPaused nonReentrant override returns(bool) {\n require(tokenAddress != NULL_ADDRESS, \"Bridge: Token is null\");\n require(receiver != NULL_ADDRESS, \"Bridge: Receiver is null\");\n require(amount > 0, \"Bridge: Amount 0\");\n require(bytes(symbol).length > 0, \"Bridge: Empty symbol\");\n require(blockHash != NULL_HASH, \"Bridge: BlockHash is null\");\n require(transactionHash != NULL_HASH, \"Bridge: Transaction is null\");\n require(decimals <= 18, \"Bridge: Decimals bigger 18\");\n require(UtilsV1.granularityToDecimals(granularity) <= 18, \"Bridge: invalid granularity\");\n\n _processTransaction(blockHash, transactionHash, receiver, amount, logIndex);\n\n if (knownTokens[tokenAddress]) {\n _acceptCrossBackToToken(receiver, tokenAddress, decimals, granularity, amount);\n } else {\n _acceptCrossToSideToken(receiver, tokenAddress, decimals, granularity, amount, symbol);\n }\n return true;\n }\n\n function _acceptCrossToSideToken(\n address receiver,\n address tokenAddress,\n uint8 decimals,\n uint256 granularity,\n uint256 amount,\n string memory symbol\n ) private {\n\n (uint256 calculatedGranularity,uint256 formattedAmount) = UtilsV1.calculateGranularityAndAmount(decimals, granularity, amount);\n address sideToken = mappedTokens[tokenAddress];\n if (sideToken == NULL_ADDRESS) {\n sideToken = _createSideToken(tokenAddress, symbol, calculatedGranularity);\n } else {\n require(calculatedGranularity == IERC777(sideToken).granularity(), \"Bridge: Granularity differ from side token\");\n }\n ISideToken(sideToken).mint(receiver, formattedAmount, \"\", \"\");\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, 18, calculatedGranularity);\n }\n\n function _acceptCrossBackToToken(address receiver, address tokenAddress, uint8 decimals, uint256 granularity, uint256 amount) private {\n require(decimals == 18, \"Bridge: Invalid decimals cross back\");\n //As side tokens are ERC777 we need to convert granularity to decimals\n (uint8 calculatedDecimals, uint256 formattedAmount) = UtilsV1.calculateDecimalsAndAmount(tokenAddress, granularity, amount);\n IERC20(tokenAddress).safeTransfer(receiver, formattedAmount);\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, calculatedDecimals, 1);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokens(address tokenToUse, uint256 amount) override external whenNotUpgrading whenNotPaused nonReentrant returns(bool) {\n address sender = _msgSender();\n require(!sender.isContract(), \"Bridge: Sender can't be a contract\");\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, amount, \"\");\n return true;\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external whenNotPaused whenNotUpgrading override(IBridgeV2, IERC777Recipient) {\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to address\");\n address tokenToUse = _msgSender();\n //This can only be used with trusted contracts\n crossTokens(tokenToUse, from, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, uint256 amount, bytes memory userData) private {\n bool isASideToken = originalTokens[tokenToUse] != NULL_ADDRESS;\n //Send the payment to the MultiSig of the Federation\n uint256 fee = amount.mul(feePercentage).div(FEE_PERCENTAGE_DIVIDER);\n uint256 amountMinusFees = amount.sub(fee);\n if (isASideToken) {\n uint256 modulo = amountMinusFees.mod(IERC777(tokenToUse).granularity());\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n }\n if(fee > 0) {\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n if (isASideToken) {\n verifyWithAllowTokens(tokenToUse, amount, isASideToken);\n //Side Token Crossing\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n // solium-disable-next-line max-len\n emit Cross(originalTokens[tokenToUse], from, amountMinusFees, IERC777(tokenToUse).symbol(), userData, IERC777(tokenToUse).decimals(), IERC777(tokenToUse).granularity());\n } else {\n //Main Token Crossing\n knownTokens[tokenToUse] = true;\n (uint8 decimals, uint256 granularity, string memory symbol) = UtilsV1.getTokenInfo(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n //We consider the amount before fees converted to 18 decimals to check the limits\n verifyWithAllowTokens(tokenToUse, formattedAmount, isASideToken);\n emit Cross(tokenToUse, from, amountMinusFees, symbol, userData, decimals, granularity);\n }\n }\n\n function _createSideToken(address token, string memory symbol, uint256 granularity) private returns (address sideToken){\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, symbol));\n address sideTokenAddress = sideTokenFactory.createSideToken(newSymbol, newSymbol, granularity);\n sideToken = sideTokenAddress;\n mappedTokens[token] = sideToken;\n originalTokens[sideTokenAddress] = token;\n emit NewSideToken(sideTokenAddress, token, newSymbol, granularity);\n return sideToken;\n }\n\n function verifyWithAllowTokens(address tokenToUse, uint256 amount, bool isASideToken) private {\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n // solium-disable-next-line security/no-block-members\n lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n spentToday = 0;\n }\n require(allowTokens.isValidTokenTransfer(tokenToUse, amount, spentToday, isASideToken), \"Bridge: Bigger than limit\");\n spentToday = spentToday.add(amount);\n }\n\n function getTransactionId(\n bytes32 _blockHash,\n bytes32 _transactionHash,\n address _receiver,\n uint256 _amount,\n uint32 _logIndex\n )\n public pure returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _receiver, _amount, _logIndex));\n }\n\n function _processTransaction(\n bytes32 _blockHash,\n bytes32 _transactionHash,\n address _receiver,\n uint256 _amount,\n uint32 _logIndex\n )\n private\n {\n bytes32 compiledId = getTransactionId(_blockHash, _transactionHash, _receiver, _amount, _logIndex);\n require(!processed[compiledId], \"Bridge: Already processed\");\n processed[compiledId] = true;\n }\n\n function setFeePercentage(uint amount) external onlyOwner whenNotPaused {\n require(amount < (FEE_PERCENTAGE_DIVIDER/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() override external view returns(uint) {\n return feePercentage;\n }\n\n function calcMaxWithdraw() override external view returns (uint) {\n uint spent = spentToday;\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > lastDay + 24 hours) // solhint-disable-line not-rely-on-time\n spent = 0;\n return allowTokens.calcMaxWithdraw(spent);\n }\n\n function changeFederation(address newFederation) external onlyOwner returns(bool) {\n _changeFederation(newFederation);\n return true;\n }\n\n function _changeFederation(address newFederation) internal {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner returns(bool) {\n _changeSideTokenFactory(newSideTokenFactory);\n return true;\n }\n\n function _changeSideTokenFactory(address newSideTokenFactory) internal {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function startUpgrade() external onlyOwner {\n isUpgrading = true;\n emit Upgrading(isUpgrading);\n }\n\n function endUpgrade() external onlyOwner {\n isUpgrading = false;\n emit Upgrading(isUpgrading);\n }\n\n //This method is only to recreate the USDT and USDC tokens on rsk without granularity restrictions.\n function clearSideToken() external onlyOwner returns(bool) {\n require(!alreadyRun, \"already done\");\n alreadyRun = true;\n address payable[4] memory sideTokens = [\n payable(0xe506F698b31a66049BD4653ed934E7a07Cbc5549),\n payable(0x5a42221D7AaE8e185BC0054Bb036D9757eC18857),\n payable(0xcdc8ccBbFB6407c53118fE47259e8d00C81F42CD),\n payable(0x6117C9529F15c52e2d3188d5285C745B757b5825)\n ];\n for (uint i = 0; i < sideTokens.length; i++) {\n address originalToken = address(originalTokens[sideTokens[i]]);\n originalTokens[sideTokens[i]] = NULL_ADDRESS;\n mappedTokens[originalToken] = address(NULL_ADDRESS);\n }\n return true;\n }\n\n}\n"
+ },
+ "contracts/Bridge/IBridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IBridgeV2 {function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n function calcMaxWithdraw() external view returns (uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokens(address tokenToUse, uint256 amount) external returns(bool);\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the federation contract\n */\n function acceptTransfer(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity\n ) external returns(bool);\n\n event Cross(address indexed _tokenAddress, address indexed _to, uint256 _amount, string _symbol, bytes _userData,\n uint8 _decimals, uint256 _granularity);\n event NewSideToken(address indexed _newSideTokenAddress, address indexed _originalTokenAddress, string _newSymbol, uint256 _granularity);\n event AcceptedCrossTransfer(address indexed _tokenAddress, address indexed _to, uint256 _amount, uint8 _decimals, uint256 _granularity,\n uint256 _formattedAmount, uint8 _calculatedDecimals, uint256 _calculatedGranularity);\n event FeePercentageChanged(uint256 _amount);\n}"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract AllowTokensV0 is Ownable {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n\n mapping (address => bool) public allowedTokens;\n bool private validateAllowedTokens;\n uint256 private maxTokensAllowed;\n uint256 private minTokensAllowed;\n uint256 public dailyLimit;\n\n event AllowedTokenAdded(address indexed _tokenAddress);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event AllowedTokenValidation(bool _enabled);\n event MaxTokensAllowedChanged(uint256 _maxTokens);\n event MinTokensAllowedChanged(uint256 _minTokens);\n event DailyLimitChanged(uint256 dailyLimit);\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\n _;\n }\n\n constructor(address _manager) {\n transferOwnership(_manager);\n validateAllowedTokens = true;\n maxTokensAllowed = 10000 ether;\n minTokensAllowed = 1 ether;\n dailyLimit = 100000 ether;\n }\n\n function isValidatingAllowedTokens() external view returns(bool) {\n return validateAllowedTokens;\n }\n\n function getMaxTokensAllowed() external view returns(uint256) {\n return maxTokensAllowed;\n }\n\n function getMinTokensAllowed() external view returns(uint256) {\n return minTokensAllowed;\n }\n\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\n return allowedTokens[token];\n }\n\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\n if (validateAllowedTokens) {\n return allowedTokenExist(token);\n }\n return true;\n }\n\n function addAllowedToken(address token) external onlyOwner {\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\n allowedTokens[token] = true;\n emit AllowedTokenAdded(token);\n }\n\n function removeAllowedToken(address token) external onlyOwner {\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\n allowedTokens[token] = false;\n emit AllowedTokenRemoved(token);\n }\n\n function enableAllowedTokensValidation() external onlyOwner {\n validateAllowedTokens = true;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function disableAllowedTokensValidation() external onlyOwner {\n // Before disabling Allowed Tokens Validations some kind of contract validation system\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\n validateAllowedTokens = false;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\n maxTokensAllowed = maxTokens;\n emit MaxTokensAllowedChanged(maxTokensAllowed);\n }\n\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\n minTokensAllowed = minTokens;\n emit MinTokensAllowedChanged(minTokensAllowed);\n }\n\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\n dailyLimit = _dailyLimit;\n emit DailyLimitChanged(_dailyLimit);\n }\n\n // solium-disable-next-line max-len\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\n if(amount > maxTokensAllowed)\n return false;\n if(amount < minTokensAllowed)\n return false;\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\n return false;\n if(!isSideToken && !isTokenAllowed(tokenToUse))\n return false;\n return true;\n }\n\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\n uint maxWithrow = dailyLimit - spentToday;\n if (dailyLimit < spentToday)\n return 0;\n if(maxWithrow > maxTokensAllowed)\n maxWithrow = maxTokensAllowed;\n return maxWithrow;\n }\n\n}\n"
+ },
+ "contracts/Utils/UtilsV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nlibrary UtilsV1 {\n using SafeMath for uint256;\n\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n // keccak256(\"ERC777Token\")\n bytes32 constant private TOKENS_ERC777_HASH = 0xac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054;\n\n function getTokenInfo(address tokenToUse) external view returns (uint8 decimals, uint256 granularity, string memory symbol) {\n decimals = getDecimals(tokenToUse);\n granularity = getGranularity(tokenToUse);\n symbol = getSymbol(tokenToUse);\n }\n\n function getSymbol(address tokenToUse) public view returns (string memory symbol) {\n //support 32 bytes or string symbol\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"symbol()\"));\n require(success, \"Utils: Token hasn't symbol()\");\n if (data.length == 32) {\n symbol = bytes32ToString(abi.decode(data, (bytes32)));\n } else {\n symbol = abi.decode(data, (string));\n }\n require(bytes(symbol).length > 0, \"Utils: Token empty symbol\");\n return symbol;\n }\n\n function getDecimals(address tokenToUse) public view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"Utils: No decimals\");\n require(data.length == 32, \"Utils: Decimals not uint\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n uint256 decimalsDecoded = abi.decode(data, (uint256));\n require(decimalsDecoded <= 18, \"Utils: Decimals not in 0 to 18\");\n return uint8(decimalsDecoded);\n }\n\n function getGranularity(address tokenToUse) public view returns (uint256 granularity) {\n granularity = 1;\n //support granularity if ERC777\n address implementer = ERC_1820.getInterfaceImplementer(tokenToUse, TOKENS_ERC777_HASH);\n if (implementer != address(0)) {\n granularity = IERC777(implementer).granularity();\n //Verify granularity is power of 10 to keep it compatible with ERC20 decimals\n granularityToDecimals(granularity);\n }\n return granularity;\n }\n\n /* bytes32 (fixed-size array) to string (dynamically-sized array) */\n function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) {\n uint8 i = 0;\n while(i < 32 && _bytes32[i] != 0) {\n i++;\n }\n bytes memory bytesArray = new bytes(i);\n for (i = 0; i < 32 && _bytes32[i] != 0; i++) {\n bytesArray[i] = _bytes32[i];\n }\n return string(bytesArray);\n }\n\n function decimalsToGranularity(uint8 decimals) public pure returns (uint256) {\n require(decimals <= 18, \"Utils: Decimals not in 0 to 18\");\n return uint256(10)**(18-decimals);\n }\n\n function granularityToDecimals(uint256 granularity) public pure returns (uint8) {\n if(granularity == 1) return 18;\n if(granularity == 10) return 17;\n if(granularity == 100) return 16;\n if(granularity == 1000) return 15;\n if(granularity == 10000) return 14;\n if(granularity == 100000) return 13;\n if(granularity == 1000000) return 12;\n if(granularity == 10000000) return 11;\n if(granularity == 100000000) return 10;\n if(granularity == 1000000000) return 9;\n if(granularity == 10000000000) return 8;\n if(granularity == 100000000000) return 7;\n if(granularity == 1000000000000) return 6;\n if(granularity == 10000000000000) return 5;\n if(granularity == 100000000000000) return 4;\n if(granularity == 1000000000000000) return 3;\n if(granularity == 10000000000000000) return 2;\n if(granularity == 100000000000000000) return 1;\n if(granularity == 1000000000000000000) return 0;\n require(false, \"Utils: invalid granularity\");\n return 0;\n }\n\n function calculateGranularityAndAmount(uint8 decimals, uint256 granularity, uint256 amount) external pure\n returns(uint256 calculatedGranularity, uint256 formattedAmount) {\n\n if(decimals == 18) {\n //tokenAddress is a ERC20 with 18 decimals should have 1 granularity\n //tokenAddress is a ERC777 token we give the same granularity\n calculatedGranularity = granularity;\n formattedAmount = amount;\n } else {\n //tokenAddress is a ERC20 with other than 18 decimals\n calculatedGranularity = decimalsToGranularity(decimals);\n formattedAmount = amount.mul(calculatedGranularity);\n }\n }\n\n function calculateDecimalsAndAmount(address tokenAddress, uint256 granularity, uint256 amount)\n external view returns (uint8 calculatedDecimals, uint256 formattedAmount) {\n uint8 tokenDecimals = getDecimals(tokenAddress);\n //As side tokens are ERC777 we need to convert granularity to decimals\n calculatedDecimals = granularityToDecimals(granularity);\n require(tokenDecimals == calculatedDecimals, \"Utils: Token decimals differ from decimals - granularity\");\n formattedAmount = amount.div(granularity);\n }\n\n}\n"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () {\n _owner = _msgSender();\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IBridge.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockReceiveTokensCall is IERC777Recipient {\n address public bridge;\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor(address _bridge) {\n bridge = _bridge;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount, uint256 destinationChainId) external {\n IERC20(tokenToUse).approve(bridge, amount);\n IBridge(bridge).receiveTokensTo(destinationChainId, tokenToUse, receiver, amount);\n }\n\n function callDepositTo(address receiver, uint256 destinationChainId) external payable {\n IBridge(bridge).depositTo{ value: msg.value }(destinationChainId, receiver);\n }\n\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\n IERC777(tokenToUse).send(bridge, amount, data);\n }\n\n // Mandatory for IERC777Recipient\n function tokensReceived(\n address,\n address,\n address,\n uint,\n bytes calldata,\n bytes calldata\n ) override external view {\n this;\n }\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockERC777Recipient is IERC777Recipient {\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor() {\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\n }\n\n event Success(\n address operator,\n address from,\n address to,\n uint amount,\n bytes userData,\n bytes operatorData);\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) override external {\n emit Success(operator, from, to, amount, userData, operatorData);\n }\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\n\ncontract SideTokenV1 is ERC777 {\n address public minter;\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\n minter = _minterAddr;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../SideToken/SideTokenV1.sol\";\n\ncontract SideTokenFactoryV1 is Secondary {\n event CreatedSideToken(address sideToken, string symbol);\n\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\n emit CreatedSideToken(address(sideToken), symbol);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using SafeMath for uint256;\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping (uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /*\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri_) {\n _setURI(uri_);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) external view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: balance query for the zero address\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(amount);\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, address(0), id, amount);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\n /**\n @dev Handles the receipt of a single ERC1155 token type. This function is\n called at the end of a `safeTransferFrom` after the balance has been updated.\n To accept the transfer, this must return\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n (i.e. 0xf23a6e61, or its own function selector).\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n )\n external\n returns(bytes4);\n\n /**\n @dev Handles the receipt of a multiple ERC1155 token types. This function\n is called at the end of a `safeBatchTransferFrom` after the balances have\n been updated. To accept the transfer(s), this must return\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n (i.e. 0xbc197c81, or its own function selector).\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match values array)\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n )\n external\n returns(bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC1155 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Pausable is ERC1155, Pausable {\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\nimport \"../access/roles/PauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context, PauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n constructor () {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract PauserRole is Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n constructor () {\n _addPauser(_msgSender());\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC721.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC721 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC721Pausable is ERC721, Pausable {\n /**\n * @dev See {ERC721-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../../zeppelin/ownership/Ownable.sol\";\nimport \"../../zeppelin/math/SafeMath.sol\";\nimport \"../../zeppelin/utils/Strings.sol\";\nimport \"./OpenSeaEIP712Base.sol\";\n\n\n/**\n * @title OpenSea721\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\n */\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\n using SafeMath for uint256;\n\n uint256 private _currentTokenId = 0;\n\n constructor(\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n _initializeEIP712(_name);\n }\n\n function baseTokenURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/api/creature/\";\n }\n\n function contractURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\n }\n\n /**\n * @dev Mints a token to an address with a tokenURI.\n * @param _to address of the future owner of the token\n */\n function mintTo(address _to) public onlyOwner {\n uint256 newTokenId = _getNextTokenId();\n _mint(_to, newTokenId);\n _incrementTokenId();\n }\n\n /**\n * @dev calculates the next token ID based on value of _currentTokenId\n * @return uint256 for the next token ID\n */\n function _getNextTokenId() private view returns (uint256) {\n return _currentTokenId.add(1);\n }\n\n /**\n * @dev increments the value of _currentTokenId\n */\n function _incrementTokenId() private {\n _currentTokenId++;\n }\n\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\n }\n\n}"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../zeppelin/upgradable/Initializable.sol\";\n\ncontract OpenSeaEIP712Base is Initializable {\n struct EIP712Domain {\n string name;\n string version;\n address verifyingContract;\n bytes32 salt;\n }\n\n string constant public ERC712_VERSION = \"1\";\n\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\n bytes(\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\n )\n );\n bytes32 internal domainSeperator;\n\n // supposed to be called once while initializing.\n // one of the contracts that inherits this contract follows proxy pattern\n // so it is not possible to do this in a constructor\n function _initializeEIP712(\n string memory name\n )\n internal\n initializer\n {\n _setDomainSeperator(name);\n }\n\n function _setDomainSeperator(string memory name) internal {\n domainSeperator = keccak256(\n abi.encode(\n EIP712_DOMAIN_TYPEHASH,\n keccak256(bytes(name)),\n keccak256(bytes(ERC712_VERSION)),\n address(this),\n bytes32(block.chainid)\n )\n );\n }\n\n function getDomainSeperator() public view returns (bytes32) {\n return domainSeperator;\n }\n\n /**\n * Accept message hash and returns hash message in EIP712 compatible form\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\n * https://eips.ethereum.org/EIPS/eip-712\n * \"\\\\x19\" makes the encoding deterministic\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\n */\n function toTypedMessageHash(bytes32 messageHash)\n internal\n view\n returns (bytes32)\n {\n return\n keccak256(\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\n );\n }\n}\n"
+ },
+ "contracts/Federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../Bridge/IBridgeV2.sol\";\n\ncontract FederationV2 is Initializable, UpgradableOwnable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridgeV2 public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\n public validRequirement(_members.length, _required) initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n }\n\n function version() external pure returns (string memory) {\n return \"v2\";\n }\n\n function setBridge(address _bridge) external onlyOwner {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridgeV2(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n )\n public onlyMember returns(bool)\n {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bridge.acceptTransfer(\n originalTokenAddress,\n receiver,\n amount,\n \"\",\n blockHash,\n transactionHash,\n logIndex,\n 18,\n 3\n );\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32)\n {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}"
+ },
+ "contracts/Federation/FederationV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../Bridge/IBridgeV2.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract FederationV1 is Ownable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridgeV2 public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n // solium-disable-next-line max-len\n event Voted(address indexed sender, bytes32 indexed transactionId, address originalTokenAddress, address receiver, uint256 amount, string symbol, bytes32 blockHash, bytes32 indexed transactionHash, uint32 logIndex, uint8 decimals, uint256 granularity);\n event Executed(bytes32 indexed transactionId);\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Caller not a Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n constructor(address[] memory _members, uint _required) validRequirement(_members.length, _required) {\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Members larger than max allowed\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n }\n\n function setBridge(address _bridge) external onlyOwner {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridgeV2(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity)\n external onlyMember returns(bool)\n {\n // solium-disable-next-line max-len\n bytes32 transactionId = getTransactionId(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n // solium-disable-next-line max-len\n emit Voted(_msgSender(), transactionId, originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bool acceptTransfer = bridge.acceptTransfer(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n require(acceptTransfer, \"Federation: Bridge acceptTransfer error\");\n emit Executed(transactionId);\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string memory symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity)\n public pure returns(bytes32)\n {\n // solium-disable-next-line max-len\n return keccak256(abi.encodePacked(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity));\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove last element\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n}"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../ownership/Ownable.sol\";\nimport \"./TransparentUpgradeableProxy.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./UpgradeableProxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _setAdmin(admin_);\n }\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _admin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _admin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\n emit AdminChanged(_admin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external virtual ifAdmin {\n _upgradeTo(newImplementation);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\n _upgradeTo(newImplementation);\n Address.functionDelegateCall(newImplementation, data);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address adm) {\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n adm := sload(slot)\n }\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n bytes32 slot = _ADMIN_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newAdmin)\n }\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./Proxy.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n *\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\n * {TransparentUpgradeableProxy}.\n */\ncontract UpgradeableProxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _setImplementation(_logic);\n if(_data.length > 0) {\n Address.functionDelegateCall(_logic, _data);\n }\n }\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n bytes32 slot = _IMPLEMENTATION_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n impl := sload(slot)\n }\n }\n\n /**\n * @dev Upgrades the proxy to a new implementation.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal virtual {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\n\n bytes32 slot = _IMPLEMENTATION_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newImplementation)\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20Mintable}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() override public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) override public view returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) override public returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) override public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) override public returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal {\n require(sender != address(0), \"ERC20: transfer from zero address\");\n require(recipient != address(0), \"ERC20: transfer to zero address\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: mint to zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: burn from zero address\");\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n *\n * This is internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal {\n require(owner != address(0), \"ERC20: approve from zero address\");\n require(spender != address(0), \"ERC20: approve to zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\n * from the caller's allowance.\n *\n * See {_burn} and {_approve}.\n */\n function _burnFrom(address account, uint256 amount) internal {\n _burn(account, amount);\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\n }\n}\n"
+ },
+ "contracts/test/WTBTC.sol": {
+ "content": "// Sources flattened with hardhat v2.6.1 https://hardhat.org\n\n// SPDX-License-Identifier: MIT\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\npragma solidity ^0.8.0;\n\ncontract WTBTC is ERC20 {\n string public name = \"Ethereum Test BTC\";\n string public symbol = \"WTBTC\";\n uint8 public decimals = 18;\n\n constructor(uint256 initialSupply) {\n _mint(msg.sender, initialSupply);\n }\n\n function mint(uint256 supply) external {\n _mint(msg.sender, supply);\n }\n\n}"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\nimport \"../interface/IERC677Receiver.sol\";\n\ncontract mockERC677Receiver is IERC677Receiver {\n event Success(address _sender, uint _value, bytes _data);\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\n emit Success(_sender, _value, _data);\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Optional functions from the ERC20 standard.\n */\nabstract contract ERC20Detailed is IERC20 {\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\n * these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\n _name = aName;\n _symbol = aSymbol;\n _decimals = theDecimals;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n}\n"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract MainToken is ERC20Detailed, ERC20 {\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\n ERC20Detailed(name, symbol, decimals)\n {\n _mint(msg.sender, totalSupply);\n }\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\n bool result = transfer(_to, _value);\n if (!result) return false;\n\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\n receiver.tokenFallback(msg.sender, _value, _data);\n\n // IMPORTANT: the ERC-677 specification does not say\n // anything about the use of the receiver contract's\n // tokenFallback method return value. Given\n // its return type matches with this method's return\n // type, returning it could be a possibility.\n // We here take the more conservative approach and\n // ignore the return value, returning true\n // to signal a succesful transfer despite tokenFallback's\n // return value -- fact being tokens are transferred\n // in any case.\n return true;\n }\n}\n\ninterface ERC677TransferReceiver {\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\n}"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract AlternativeERC20Detailed is ERC20 {\n string private _name;\n bytes32 private _symbol;\n uint256 private _decimals;\n\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\n {\n _name = aName;\n _symbol = aSymbol;\n _decimals = someDecimals;\n _mint(msg.sender, aTotalSupply);\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (bytes32) {\n return _symbol;\n }\n\n function decimals() public view returns (uint256) {\n return _decimals;\n }\n}"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\n\ncontract BridgeProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract FederationProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}"
+ },
+ "contracts/Federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../nftbridge/INFTBridge.sol\";\nimport \"../interface/IBridge.sol\";\nimport \"../interface/IFederation.sol\";\n\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\n\tuint constant public MAX_MEMBER_COUNT = 50;\n\taddress constant private NULL_ADDRESS = address(0);\n\n\tIBridge public bridge;\n\taddress[] public members;\n\n\t/**\n\t\t@notice The minimum amount of votes to approve a transaction\n\t\t@dev It should have more members than the required amount\n\t\t*/\n\tuint public required;\n\n\t/**\n\t\t@notice All the addresses that are members of the federation\n\t\t@dev The address should be a member to vote in transactions\n\t\t*/\n\tmapping (address => bool) public isMember;\n\n\t/**\n\t\t(bytes32) transactionId = keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tamount,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex\n\t\t\t)\n\t\t) => (\n\t\t\t(address) members => (bool) voted\n\t\t)\n\t\t@notice Votes by members by the transaction ID\n\t\t@dev usually the members should approve the transaction by 50% + 1\n\t\t*/\n\tmapping (bytes32 => mapping (address => bool)) public votes;\n\n\t/**\n\t\t(bytes32) transactionId => (bool) voted\n\t\t@notice Check if that transaction was already processed\n\t\t*/\n\tmapping(bytes32 => bool) public processed;\n\n\t/** Federator v3 variables */\n\tINFTBridge public bridgeNFT;\n\n\tmodifier onlyMember() {\n\t\trequire(isMember[_msgSender()], \"Federation: Not Federator\");\n\t\t_;\n\t}\n\n\tmodifier validRequirement(uint membersCount, uint _required) {\n\t\trequire(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n\t\t_;\n\t}\n\n\tfunction initialize(\n\t\taddress[] memory _members,\n\t\tuint _required,\n\t\taddress _bridge,\n\t\taddress owner,\n\t\taddress _bridgeNFT\n\t) public validRequirement(_members.length, _required) initializer {\n\t\tUpgradableOwnable.initialize(owner);\n\t\trequire(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n\t\tmembers = _members;\n\t\tfor (uint i = 0; i < _members.length; i++) {\n\t\t\trequire(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n\t\t\tisMember[_members[i]] = true;\n\t\t\temit MemberAddition(_members[i]);\n\t\t}\n\t\trequired = _required;\n\t\temit RequirementChange(required);\n\t\t_setBridge(_bridge);\n\t\t_setNFTBridge(_bridgeNFT);\n\t}\n\n\t/**\n\t\t@notice Current version of the contract\n\t\t@return version in v{Number}\n\t\t*/\n\tfunction version() external pure override returns (string memory) {\n\t\treturn \"v3\";\n\t}\n\n\t/**\n\t\t@notice Sets a new bridge contract\n\t\t@dev Emits BridgeChanged event\n\t\t@param _bridge the new bridge contract address that should implement the IBridge interface\n\t\t*/\n\tfunction setBridge(address _bridge) external onlyOwner override {\n\t\t_setBridge(_bridge);\n\t}\n\n\tfunction _setBridge(address _bridge) internal {\n\t\trequire(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n\t\tbridge = IBridge(_bridge);\n\t\temit BridgeChanged(_bridge);\n\t}\n\n\t/**\n\t\t@notice Sets a new NFT bridge contract\n\t\t@dev Emits NFTBridgeChanged event\n\t\t@param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n\t\t*/\n\tfunction setNFTBridge(address _bridgeNFT) external onlyOwner override {\n\t\t_setNFTBridge(_bridgeNFT);\n\t}\n\n\tfunction _setNFTBridge(address _bridgeNFT) internal {\n\t\trequire(_bridgeNFT != NULL_ADDRESS, \"Federation: Empty NFT bridge\");\n\t\tbridgeNFT = INFTBridge(_bridgeNFT);\n\t\temit NFTBridgeChanged(_bridgeNFT);\n\t}\n\n\tfunction validateTransaction(bytes32 transactionId, bytes32 transactionIdMultichain) internal view returns(bool) {\n\t\tuint256 minimumVotes = getMinimalNumberOfVotes();\n\t\tuint256 amountVotes = 0;\n\n for (uint256 i = 0; i < members.length; i++) {\n if (votes[transactionIdMultichain][members[i]]) {\n amountVotes += 1;\n\t\t\t} else if (votes[transactionId][members[i]]) {\n amountVotes += 1;\n\t\t\t}\n\n\t\t\tif (amountVotes >= minimumVotes && amountVotes >= required) {\n\t\t\t\treturn true;\n\t\t\t}\n }\n\n\t\treturn false;\n\t}\n\n\tfunction getMinimalNumberOfVotes() internal view returns(uint256) {\n\t\treturn members.length / 2 + 1;\n\t}\n\n\tfunction isProcessed(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\n\t\treturn processed[transactionIdMultichain] || processed[transactionId];\n\t}\n\n\tfunction isVoted(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\n\t\treturn votes[transactionIdMultichain][_msgSender()] || votes[transactionId][_msgSender()];\n\t}\n\n\t/**\n\t\t@notice Vote in a transaction, if it has enough votes it accepts the transfer\n\t\t@param originalTokenAddress The address of the token in the origin (main) chain\n\t\t@param sender The address who solicited the cross token\n\t\t@param receiver Who is going to receive the token in the opposite chain\n\t\t@param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n\t\t@param blockHash The block hash in which the transaction with the cross event occurred\n\t\t@param transactionHash The transaction in which the cross event occurred\n\t\t@param logIndex Index of the event in the logs\n\t\t@param tokenType Is the type of bridge to be used\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n\t\t*/\n\tfunction voteTransaction(\n\t\taddress originalTokenAddress,\n\t\taddress payable sender,\n\t\taddress payable receiver,\n\t\tuint256 value,\n\t\tbytes32 blockHash,\n\t\tbytes32 transactionHash,\n\t\tuint32 logIndex,\n\t\tTokenType tokenType,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n\t) external onlyMember override {\n\t\tbytes32 transactionId = keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex\n\t\t\t)\n\t\t);\n\n\t\tbytes32 transactionIdMultichain = getTransactionId(\n\t\t\toriginalTokenAddress,\n\t\t\tsender,\n\t\t\treceiver,\n\t\t\tvalue,\n\t\t\tblockHash,\n\t\t\ttransactionHash,\n\t\t\tlogIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n\t\t);\n\n\t\tif (isProcessed(transactionId, transactionIdMultichain))\n\t\t\treturn;\n\n\t\tif (isVoted(transactionId, transactionIdMultichain))\n\t\t\treturn;\n\n\t\tvotes[transactionIdMultichain][_msgSender()] = true;\n\t\temit Voted(\n\t\t\t_msgSender(),\n\t\t\ttransactionHash,\n\t\t\ttransactionIdMultichain,\n\t\t\toriginalTokenAddress,\n\t\t\tsender,\n\t\t\treceiver,\n\t\t\tvalue,\n\t\t\tblockHash,\n\t\t\tlogIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n\t\t);\n\n\t\tif (validateTransaction(transactionId, transactionIdMultichain)) {\n\t\t\tprocessed[transactionIdMultichain] = true;\n\t\t\tacceptTransfer(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex,\n\t\t\t\ttokenType,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\n\t\t\temit Executed(\n\t\t\t\t_msgSender(),\n\t\t\t\ttransactionHash,\n\t\t\t\ttransactionIdMultichain,\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\tlogIndex,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\t\t}\n\t}\n\n function acceptTransfer(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n ) internal {\n if (tokenType == TokenType.NFT) {\n require(address(bridgeNFT) != NULL_ADDRESS, \"Federation: Empty NFTBridge\");\n bridgeNFT.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex,\n\toriginChainId,\n\tdestinationChainId\n );\n return;\n }\n\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n );\n }\n\n /**\n @notice Get the amount of approved votes for that transactionId\n @param transactionId The transaction hashed from getTransactionId function\n */\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n\tfunction hasVoted(bytes32 transactionId) external view returns(bool) {\n\t\treturn votes[transactionId][_msgSender()];\n\t}\n\n\tfunction transactionWasProcessed(bytes32 transactionId) external view returns(bool) {\n\t\treturn processed[transactionId];\n\t}\n\n\t/**\n\t\t@notice Gets the hash of transaction from the following parameters encoded and keccaked\n\t\t@dev It encodes and applies keccak256 to the parameters received in the same order\n\t\t@param originalTokenAddress The address of the token in the origin (main) chain\n\t\t@param sender The address who solicited the cross token\n\t\t@param receiver Who is going to receive the token in the opposite chain\n\t\t@param amount Could be the amount or the tokenId\n\t\t@param blockHash The block hash in which the transaction with the cross event occurred\n\t\t@param transactionHash The transaction in which the cross event occurred\n\t\t@param logIndex Index of the event in the logs\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n\t\t@return The hash generated by the parameters.\n\t*/\n\tfunction getTransactionId(\n\t\taddress originalTokenAddress,\n\t\taddress sender,\n\t\taddress receiver,\n\t\tuint256 amount,\n\t\tbytes32 blockHash,\n\t\tbytes32 transactionHash,\n\t\tuint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n\t) public pure returns(bytes32) {\n\t\treturn keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tamount,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t)\n\t\t);\n\t}\n\n\tfunction addMember(address _newMember) external onlyOwner override {\n\t\trequire(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n\t\trequire(!isMember[_newMember], \"Federation: Member already exists\");\n\t\trequire(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n\t\tisMember[_newMember] = true;\n\t\tmembers.push(_newMember);\n\t\temit MemberAddition(_newMember);\n\t}\n\n\tfunction removeMember(address _oldMember) external onlyOwner override {\n\t\trequire(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n\t\trequire(isMember[_oldMember], \"Federation: Member doesn't exists\");\n\t\trequire(members.length > 1, \"Federation: Can't remove all the members\");\n\t\trequire(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n\t\tisMember[_oldMember] = false;\n\t\tfor (uint i = 0; i < members.length - 1; i++) {\n\t\t\tif (members[i] == _oldMember) {\n\t\t\t\tmembers[i] = members[members.length - 1];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tmembers.pop(); // remove an element from the end of the array.\n\t\temit MemberRemoval(_oldMember);\n\t}\n\n\t/**\n\t\t@notice Return all the current members of the federation\n\t\t@return Current members\n\t\t*/\n\tfunction getMembers() external view override returns (address[] memory) {\n\t\treturn members;\n\t}\n\n\t/**\n\t\t@notice Changes the number of required members to vote and approve an transaction\n\t\t@dev Emits the RequirementChange event\n\t\t@param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n\t\t*/\n\tfunction changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\n\t\trequire(_required >= 2, \"Federation: Requires at least 2\");\n\t\trequired = _required;\n\t\temit RequirementChange(_required);\n\t}\n\n\t/**\n\t\t@notice It emits an HeartBeat like an health check\n\t\t@dev Emits HeartBeat event\n\t\t*/\n\tfunction emitHeartbeat(\n\t\tuint256 fedRskBlock,\n\t\tuint256 fedEthBlock,\n\t\tstring calldata federatorVersion,\n\t\tstring calldata nodeRskInfo,\n\t\tstring calldata nodeEthInfo\n\t) external onlyMember override {\n\t\temit HeartBeat(\n\t\t\t_msgSender(),\n\t\t\tfedRskBlock,\n\t\t\tfedEthBlock,\n\t\t\tfederatorVersion,\n\t\t\tnodeRskInfo,\n\t\t\tnodeEthInfo,\n\t\t\tblock.chainid\n\t\t);\n\t}\n}\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface IFederation {\n enum TokenType{ COIN, NFT }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure returns (string memory);\n\n /**\n @notice Sets a new bridge contract\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external;\n\n /**\n @notice Sets a new NFT bridge contract\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external;\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n ) external;\n\n /**\n @notice Add a new member to the federation\n @param _newMember address of the new member\n */\n function addMember(address _newMember) external;\n\n /**\n @notice Remove a member of the federation\n @param _oldMember address of the member to be removed from federation\n */\n function removeMember(address _oldMember) external;\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view returns (address[] memory);\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external;\n\n /**\n @notice It emmits an HeartBeat like an healthy check\n */\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event NFTBridgeChanged(address bridgeNFT);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex,\n uint256 originChainId,\n\t\tuint256\tdestinationChainId\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo,\n uint256 chainId\n );\n\n}\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract MinterRole is Context {\n using Roles for Roles.Role;\n\n event MinterAdded(address indexed account);\n event MinterRemoved(address indexed account);\n\n Roles.Role private _minters;\n\n constructor () {\n _addMinter(_msgSender());\n }\n\n modifier onlyMinter() {\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\n _;\n }\n\n function isMinter(address account) public view returns (bool) {\n return _minters.has(account);\n }\n\n function addMinter(address account) public onlyMinter {\n _addMinter(account);\n }\n\n function renounceMinter() public {\n _removeMinter(_msgSender());\n }\n\n function _addMinter(address account) internal {\n _minters.add(account);\n emit MinterAdded(account);\n }\n\n function _removeMinter(address account) internal {\n _minters.remove(account);\n emit MinterRemoved(account);\n }\n}\n"
+ },
+ "contracts/test/nftbridge/NFTERC721TestToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\n\ncontract NFTERC721TestToken is ERC721 {\n\n string private _contractURI;\n\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\n\n function safeMint(address to, uint256 tokenId) public {\n _safeMint(to, tokenId);\n }\n\n function setBaseURI(string memory baseURI) public {\n _setBaseURI(baseURI);\n }\n\n function setContractURI(string memory contractURI_) public {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n function setTokenURI(uint256 tokenId, string memory _tokenURI) public {\n _setTokenURI(tokenId, _tokenURI);\n }\n\n}\n"
+ },
+ "contracts/nftbridge/SideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./ISideNFTToken.sol\";\nimport \"../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\n\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\n address public minter;\n string private _contractURI;\n\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\n require(_minter != address(0), \"SideToken: Empty Minter\");\n minter = _minter;\n _setBaseURI(_baseURI);\n _setContractURI(contractURI_);\n }\n\n function _setContractURI(string memory contractURI_) internal {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(address account, uint256 tokenId) external onlyMinter override {\n _mint(account, tokenId);\n }\n}"
+ },
+ "contracts/nftbridge/SideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"./SideNFTToken.sol\";\n\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external onlyPrimary override returns(address) {\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\n return sideTokenAddress;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() {\n _registerInterface(\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\n );\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Receiver.sol\";\n\n /**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers. \n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Burnable is ERC1155 {\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n}\n"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../lib/LibUtils.sol\";\n\ncontract LibUtilsHarness {\n\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\n return LibUtils.decimalsToGranularity(decimals);\n }\n\n function getDecimals(address tokenToUse) external view returns (uint8) {\n return LibUtils.getDecimals(tokenToUse);\n }\n\n function getGranularity(address tokenToUse) external view returns (uint256) {\n return LibUtils.getGranularity(tokenToUse);\n }\n\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\n return LibUtils.bytesToAddress(bys);\n }\n\n}\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/solcInputs/bd60cbce915f67c6e3ddca09e6c29f99.json b/bridge/deployments/kovan/solcInputs/bd60cbce915f67c6e3ddca09e6c29f99.json
new file mode 100644
index 000000000..75948d241
--- /dev/null
+++ b/bridge/deployments/kovan/solcInputs/bd60cbce915f67c6e3ddca09e6c29f99.json
@@ -0,0 +1,297 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/math/SafeMath.sol\";\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\n\nimport \"../interface/IAllowTokens.sol\";\n\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n uint256 constant public MAX_TYPES = 250;\n mapping (address => TokenInfo) public allowedTokens;\n mapping (uint256 => Limits) public typeLimits;\n uint256 public smallAmountConfirmations;\n uint256 public mediumAmountConfirmations;\n uint256 public largeAmountConfirmations;\n string[] public typeDescriptions;\n\n event SetToken(address indexed _tokenAddress, uint256 _typeId);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\n event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\n event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\n event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\n\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\n _;\n }\n\n function initialize(\n address _manager,\n address _primary,\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations,\n TypeInfo[] memory typesInfo) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradableSecondary.__Secondary_init(_primary);\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n for(uint i = 0; i < typesInfo.length; i = i + 1) {\n _addTokenType(typesInfo[i].description, typesInfo[i].limits);\n }\n }\n\n function version() override external pure returns (string memory) {\n return \"v1\";\n }\n\n function getInfoAndLimits(address token) override public view\n returns (TokenInfo memory info, Limits memory limit) {\n info = allowedTokens[token];\n limit = typeLimits[info.typeId];\n return (info, limit);\n }\n function calcMaxWithdraw(address token) override public view returns (uint256 maxWithdraw) {\n (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\n return _calcMaxWithdraw(info, limits);\n }\n\n function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n info.spentToday = 0;\n }\n if (limits.daily <= info.spentToday)\n return 0;\n maxWithdraw = limits.daily - info.spentToday;\n if(maxWithdraw > limits.max)\n maxWithdraw = limits.max;\n return maxWithdraw;\n }\n\n // solium-disable-next-line max-len\n function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\n (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\n require(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\n require(amount >= limit.min, \"AllowTokens: Lower than limit\");\n\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n // solium-disable-next-line security/no-block-members\n info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n info.spentToday = 0;\n }\n uint maxWithdraw = _calcMaxWithdraw(info, limit);\n require(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\n info.spentToday = info.spentToday.add(amount);\n allowedTokens[token] = info;\n\n emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\n }\n\n function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\n require(bytes(description).length > 0, \"AllowTokens: Empty description\");\n len = typeDescriptions.length;\n require(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\n typeDescriptions.push(description);\n _setTypeLimits(len, limits);\n emit TokenTypeAdded(len, description);\n return len;\n }\n\n function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\n return _addTokenType(description, limits);\n }\n\n function _setTypeLimits(uint256 typeId, Limits memory limits) private {\n require(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\n require(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\n require(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\n require(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\n require(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\n typeLimits[typeId] = limits;\n emit TypeLimitsChanged(typeId, limits);\n }\n\n function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\n _setTypeLimits(typeId, limits);\n }\n\n function getTypesLimits() external view override returns(Limits[] memory limits) {\n limits = new Limits[](typeDescriptions.length);\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\n limits[i] = typeLimits[i];\n }\n return limits;\n }\n\n function getTypeDescriptionsLength() external view override returns(uint256) {\n return typeDescriptions.length;\n }\n\n function getTypeDescriptions() external view override returns(string[] memory descriptions) {\n descriptions = new string[](typeDescriptions.length);\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\n descriptions[i] = typeDescriptions[i];\n }\n return descriptions;\n }\n\n function isTokenAllowed(address token) public view notNull(token) override returns (bool) {\n return allowedTokens[token].allowed;\n }\n\n function setToken(address token, uint256 typeId) override public notNull(token) {\n require(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n require(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\n TokenInfo memory info = allowedTokens[token];\n info.allowed = true;\n info.typeId = typeId;\n allowedTokens[token] = info;\n emit SetToken(token, typeId);\n }\n\n function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\n require(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\n for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\n setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\n }\n }\n\n function removeAllowedToken(address token) external notNull(token) onlyOwner {\n TokenInfo memory info = allowedTokens[token];\n require(info.allowed, \"AllowTokens: Not Allowed\");\n info.allowed = false;\n allowedTokens[token] = info;\n emit AllowedTokenRemoved(token);\n }\n\n function setConfirmations(\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations) external onlyOwner {\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n }\n\n function _setConfirmations(\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations) private {\n require(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\n require(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\n smallAmountConfirmations = _smallAmountConfirmations;\n mediumAmountConfirmations = _mediumAmountConfirmations;\n largeAmountConfirmations = _largeAmountConfirmations;\n emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n }\n\n function getConfirmations() external view override\n returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount) {\n return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\n }\n\n}\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @title Initializable\n *\n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(initializing || !initialized, \"Contract instance is already initialized\");\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\n * the owner.\n */\ncontract UpgradableOwnable is Initializable, Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function initialize(address sender) public initializer {\n _owner = sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * > Note: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\ncontract UpgradableSecondary is Initializable, Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n function __Secondary_init(address sender) public initializer {\n _primary = sender;\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(recipient);\n }\n\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IAllowTokens {\n\n struct Limits {\n uint256 min;\n uint256 max;\n uint256 daily;\n uint256 mediumAmount;\n uint256 largeAmount;\n }\n\n struct TokenInfo {\n bool allowed;\n uint256 typeId;\n uint256 spentToday;\n uint256 lastDay;\n }\n\n struct TypeInfo {\n string description;\n Limits limits;\n }\n\n struct TokensAndType {\n address token;\n uint256 typeId;\n }\n\n function version() external pure returns (string memory);\n\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\n\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\n\n function getTypesLimits() external view returns(Limits[] memory limits);\n\n function getTypeDescriptionsLength() external view returns(uint256);\n\n function getTypeDescriptions() external view returns(string[] memory descriptions);\n\n function setToken(address token, uint256 typeId) external;\n\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\n\n function isTokenAllowed(address token) external view returns (bool);\n\n function updateTokenTransfer(address token, uint256 amount) external;\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n\n function _msgSender() internal view returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
+ },
+ "contracts/nftbridge/NFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC721/IERC721.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Metadata.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Enumerable.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Receiver.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./INFTBridge.sol\";\nimport \"./ISideNFTToken.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract NFTBridge is\n Initializable,\n INFTBridge,\n UpgradablePausable,\n UpgradableOwnable,\n ReentrancyGuard,\n IERC721Receiver {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address internal constant NULL_ADDRESS = address(0);\n bytes32 internal constant NULL_HASH = bytes32(0);\n IERC1820Registry internal constant ERC1820 =\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address payable internal federation;\n uint256 internal fixedFee;\n string public symbolPrefix;\n\n mapping(address => address) public sideTokenAddressByOriginalTokenAddress;\n mapping(address => address) public originalTokenAddressBySideTokenAddress;\n mapping(address => bool) public isAddressFromCrossedOriginalToken; // address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideNFTTokenFactory public sideTokenFactory;\n bool public isUpgrading;\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\n event Upgrading(bool _isUpgrading);\n\n function initialize(\n address _manager,\n address payable _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\n federation = _federation;\n ERC1820.setInterfaceImplementer(\n address(this),\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\n address(this)\n );\n }\n\n function version() external pure override returns (string memory) {\n return \"v1\";\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _tokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external override whenNotPaused nonReentrant {\n require(_msgSender() == federation, \"NFTBridge: Not Federation\");\n require(\n isAddressFromCrossedOriginalToken[_tokenAddress] ||\n sideTokenAddressByOriginalTokenAddress[_tokenAddress] != NULL_ADDRESS,\n \"NFTBridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"NFTBridge: Null To\");\n require(_from != NULL_ADDRESS, \"NFTBridge: Null From\");\n require(_blockHash != NULL_HASH, \"NFTBridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"NFTBridge: Null TxHash\");\n require(\n transactionDataHashes[_transactionHash] == bytes32(0),\n \"NFTBridge: Already accepted\"\n );\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\n require(!claimed[_transactionDataHash], \"NFTBridge: Already claimed\");\n\n transactionDataHashes[_transactionHash] = _transactionDataHash;\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\n// senderAddresses[_transactionHash] = _from;\n\n emit AcceptedNFTCrossTransfer(\n _transactionHash,\n _tokenAddress,\n _to,\n _from,\n _tokenId,\n _blockHash,\n _logIndex\n );\n }\n\n function createSideNFTToken(\n address _originalTokenAddress,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName,\n string calldata _baseURI,\n string calldata _contractURI\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"NFTBridge: Null original token address\");\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[_originalTokenAddress];\n require(sideTokenAddress == NULL_ADDRESS, \"NFTBridge: Side token already exists\");\n string memory sideTokenSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideTokenAddress = sideTokenFactory.createSideNFTToken(_originalTokenName, sideTokenSymbol, _baseURI, _contractURI);\n\n sideTokenAddressByOriginalTokenAddress[_originalTokenAddress] = sideTokenAddress;\n originalTokenAddressBySideTokenAddress[sideTokenAddress] = _originalTokenAddress;\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, sideTokenSymbol);\n }\n\n function claim(NFTClaimData calldata _claimData) external override {\n _claim(_claimData, _claimData.to);\n }\n\n function claimFallback(NFTClaimData calldata _claimData) external override {\n require(_msgSender() == _claimData.from, \"NFTBridge: invalid sender\");\n _claim(_claimData, _msgSender());\n }\n\n function _claim(\n NFTClaimData calldata _claimData,\n address payable _receiver\n ) internal {\n address tokenAddress = _claimData.tokenAddress;\n uint256 tokenId = _claimData.tokenId;\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.from,\n tokenId,\n tokenAddress,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\n \"NFTBridge: Wrong txDataHash\"\n );\n require(!claimed[transactionDataHash], \"NFTBridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n bool isClaimBeingRequestedInMainChain = isAddressFromCrossedOriginalToken[tokenAddress];\n if (isClaimBeingRequestedInMainChain) {\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\n } else {\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[tokenAddress];\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\n }\n\n emit ClaimedNFTToken(\n _claimData.transactionHash,\n tokenAddress,\n _claimData.to,\n _claimData.from,\n _claimData.tokenId,\n _claimData.blockHash,\n _claimData.logIndex,\n _receiver\n );\n }\n\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\"creator()\"));\n if (success) {\n return abi.decode(data, (address));\n }\n\n return IERC721(tokenAddress).ownerOf(tokenId);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId\n ) public payable override {\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\n\n address payable sender = _msgSender();\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\n\n crossTokens(tokenAddress, to, tokenCreator, \"\", tokenId);\n\n if (fixedFee > 0) {\n require(msg.value >= fixedFee, \"NFTBridge: value is smaller than fixed fee\");\n\n // Send the payment to the MultiSig of the Federation\n federation.transfer(fixedFee);\n if (msg.value > fixedFee) { // refund of unused value\n sender.transfer(msg.value.sub(fixedFee));\n }\n }\n }\n\n function crossTokens(\n address tokenAddress,\n address to,\n address tokenCreator,\n bytes memory userData,\n uint256 tokenId\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\n isAddressFromCrossedOriginalToken[tokenAddress] = true;\n\n IERC721Enumerable enumerable = IERC721Enumerable(tokenAddress);\n IERC721Metadata metadataIERC = IERC721Metadata(tokenAddress);\n string memory tokenURI = metadataIERC.tokenURI(tokenId);\n\n address originalTokenAddress = tokenAddress;\n if (originalTokenAddressBySideTokenAddress[tokenAddress] != NULL_ADDRESS) {\n originalTokenAddress = originalTokenAddressBySideTokenAddress[tokenAddress];\n ERC721Burnable(tokenAddress).burn(tokenId);\n }\n\n emit Cross(\n originalTokenAddress,\n _msgSender(),\n to,\n tokenCreator,\n userData,\n enumerable.totalSupply(),\n tokenId,\n tokenURI\n );\n }\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) public pure override returns (bytes32) {\n return keccak256(\n abi.encodePacked(\n _blockHash,\n _transactionHash,\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _logIndex\n )\n );\n }\n\n function setFixedFee(uint256 amount) external onlyOwner {\n fixedFee = amount;\n emit FixedFeeNFTChanged(fixedFee);\n }\n\n function getFixedFee() external view override returns (uint256) {\n return fixedFee;\n }\n\n function changeFederation(address payable newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"NFTBridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"NFTBridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns (address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\n require(\n newSideNFTTokenFactory != NULL_ADDRESS,\n \"NFTBridge: empty SideTokenFactory\"\n );\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionDataHashes[transactionHash]];\n }\n\n /**\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\n/**\n * @title Helps contracts guard against reentrancy attacks.\n * @author Remco Bloemen , Eenae \n * @dev If you mark a function `nonReentrant`, you should also\n * mark it `external`.\n */\ncontract ReentrancyGuard is Initializable {\n /// @dev counter to allow mutex lock with only one SSTORE operation\n uint256 private _guardCounter;\n\n function initialize() public initializer {\n // The counter starts at one to prevent changing it from zero to a non-zero\n // value, which is a more expensive operation.\n _guardCounter = 1;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _guardCounter += 1;\n uint256 localCounter = _guardCounter;\n _;\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\n }\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\nimport \"../access/roles/UpgradablePauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n function __Pausable_init(address sender) public initializer {\n UpgradablePauserRole.__PauserRol_init(sender);\n\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as `account`'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `_account`.\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `_implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\n\n /**\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `_account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {ERC20Detailed}.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeERC20: low-level call failed\");\n\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n */\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./ERC721.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721Burnable is Context, ERC721 {\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n _burn(tokenId);\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\nlibrary LibEIP712 {\n\n // Hash of the EIP712 Domain Separator Schema\n // keccak256(abi.encodePacked(\n // \"EIP712Domain(\",\n // \"string name,\",\n // \"string version,\",\n // \"uint256 chainId,\",\n // \"address verifyingContract\",\n // \")\"\n // ))\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n /// @dev Calculates a EIP712 domain separator.\n /// @param name The EIP712 domain name.\n /// @param version The EIP712 domain version.\n /// @param verifyingContract The EIP712 verifying contract.\n /// @return result EIP712 domain separator.\n function hashEIP712Domain(\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n // keccak256(bytes(name)),\n // keccak256(bytes(version)),\n // chainId,\n // uint256(verifyingContract)\n // ))\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Calculate hashes of dynamic data\n let nameHash := keccak256(add(name, 32), mload(name))\n let versionHash := keccak256(add(version, 32), mload(version))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n // Store params in memory\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), nameHash)\n mstore(add(memPtr, 64), versionHash)\n mstore(add(memPtr, 96), chainId)\n mstore(add(memPtr, 128), verifyingContract)\n\n // Compute hash\n result := keccak256(memPtr, 160)\n }\n return result;\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\n /// with getDomainHash().\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to the given EIP712 Domain.\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n internal\n pure\n returns (bytes32 result)\n {\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct\n // ));\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nlibrary LibUtils {\n\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\n return uint256(10)**(18-decimals);\n }\n\n function getDecimals(address tokenToUse) internal view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"LibUtils: No decimals\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n return uint8(abi.decode(data, (uint256)));\n }\n\n function getGranularity(address tokenToUse) internal view returns (uint256) {\n //support granularity if ERC777\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\n require(success, \"LibUtils: No granularity\");\n\n return abi.decode(data, (uint256));\n }\n\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n addr := mload(add(bys,20))\n }\n }\n\n}\n"
+ },
+ "contracts/nftbridge/INFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface INFTBridge {\n struct NFTClaimData {\n address payable to;\n address from;\n uint256 tokenId;\n address tokenAddress;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFixedFee() external view returns (uint256);\n\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId\n ) external payable;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\n */\n function claim(NFTClaimData calldata _claimData) external;\n\n function claimFallback(NFTClaimData calldata _claimData) external;\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns (bytes32);\n\n event Cross(\n address indexed _originalTokenAddress,\n address indexed _from,\n address indexed _to,\n address _tokenCreator,\n bytes _userData,\n uint256 _totalSupply,\n uint256 _tokenId,\n string _tokenURI\n );\n event NewSideNFTToken(\n address indexed _newSideNFTTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol\n );\n event AcceptedNFTCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FixedFeeNFTChanged(uint256 _amount);\n event ClaimedNFTToken(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _receiver\n );\n}\n"
+ },
+ "contracts/nftbridge/ISideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideNFTToken {\n function mint(address account, uint256 tokenId) external;\n}"
+ },
+ "contracts/nftbridge/ISideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideNFTTokenFactory {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external returns(address);\n\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IWrapped {\n function balanceOf(address) external returns(uint);\n\n function deposit() external payable;\n\n function withdraw(uint wad) external;\n\n function totalSupply() external view returns (uint);\n\n function approve(address guy, uint wad) external returns (bool);\n\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad)\n external\n returns (bool);\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../Initializable.sol\";\n\nimport \"../../../GSN/Context.sol\";\nimport \"../../../access/Roles.sol\";\n\ncontract UpgradablePauserRole is Initializable, Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n function __PauserRol_init(address sender) public initializer {\n if (!isPauser(sender)) {\n _addPauser(sender);\n }\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @title Roles\n * @dev Library for managing addresses assigned to a Role.\n */\nlibrary Roles {\n struct Role {\n mapping (address => bool) bearer;\n }\n\n /**\n * @dev Give an account access to this role.\n */\n function add(Role storage role, address account) internal {\n require(!has(role, account), \"Roles: account already has role\");\n role.bearer[account] = true;\n }\n\n /**\n * @dev Remove an account's access to this role.\n */\n function remove(Role storage role, address account) internal {\n require(has(role, account), \"Roles: account doesn't have role\");\n role.bearer[account] = false;\n }\n\n /**\n * @dev Check if an account has this role.\n * @return bool\n */\n function has(Role storage role, address account) internal view returns (bool) {\n require(account != address(0), \"Roles: account is the zero address\");\n return role.bearer[account];\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _tokenOwners.contains(tokenId);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(tokenId);\n\n emit Transfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n}\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract WRBTC is IWrapped {\n string public name = \"Wrapped RBTC\";\n string public symbol = \"WRBTC\";\n uint8 public decimals = 18;\n\n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n event Deposit(address indexed dst, uint wad);\n event Withdrawal(address indexed src, uint wad);\n\n mapping (address => uint) override public balanceOf;\n mapping (address => mapping (address => uint)) public allowance;\n\n receive () external payable {\n deposit();\n }\n function deposit() override public payable {\n balanceOf[msg.sender] += msg.value;\n emit Deposit(msg.sender, msg.value);\n }\n function withdraw(uint wad) override public {\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\n balanceOf[msg.sender] -= wad;\n msg.sender.transfer(wad);\n emit Withdrawal(msg.sender, wad);\n }\n\n function totalSupply() override public view returns (uint) {\n return address(this).balance;\n }\n\n function approve(address guy, uint wad) override public returns (bool) {\n allowance[msg.sender][guy] = wad;\n emit Approval(msg.sender, guy, wad);\n return true;\n }\n\n function transfer(address dst, uint wad) override public returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad)\n override public\n returns (bool)\n {\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\n\n if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\n allowance[src][msg.sender] -= wad;\n }\n\n balanceOf[src] -= wad;\n balanceOf[dst] += wad;\n\n emit Transfer(src, dst, wad);\n\n return true;\n }\n}"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant internal NULL_ADDRESS = address(0);\n bytes32 constant internal NULL_HASH = bytes32(0);\n IERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address internal federation;\n uint256 internal feePercentage;\n string public symbolPrefix;\n // replaces uint256 internal _depprecatedLastDay;\n bytes32 public domainSeparator;\n uint256 internal _deprecatedSpentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n // Percentage with up to 2 decimals\n uint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\n //Bridge_v3 variables\n bytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\n IWrapped public wrappedCurrency;\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n // keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\n mapping(address => uint) public nonces;\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool _isUpgrading);\n event WrappedCurrencyChanged(address _wrappedCurrency);\n\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n federation = _federation;\n //keccak256(\"ERC777TokensRecipient\")\n ERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n initDomainSeparator();\n }\n\n receive () external payable {\n // The fallback function is needed to use WRBTC\n require(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n }\n\n function version() override external pure returns (string memory) {\n return \"v3\";\n }\n\n function initDomainSeparator() public {\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n domainSeparator = LibEIP712.hashEIP712Domain(\n \"RSK Token Bridge\",\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"Bridge: Not Federation\");\n require(knownTokens[_originalTokenAddress] ||\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\n \"Bridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"Bridge: Null To\");\n require(_amount > 0, \"Bridge: Amount 0\");\n require(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _amount,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed also has the previously processed using the older bridge version\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n require(!claimed[_transactionDataHash], \"Bridge: Already claimed\");\n\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\n senderAddresses[_transactionHash] = _from;\n\n emit AcceptedCrossTransfer(\n _transactionHash,\n _originalTokenAddress,\n _to,\n _from,\n _amount,\n _blockHash,\n _logIndex\n );\n }\n\n\n function createSideToken(\n uint256 _typeId,\n address _originalTokenAddress,\n uint8 _originalTokenDecimals,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n address sideToken = mappedTokens[_originalTokenAddress];\n require(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\n\n mappedTokens[_originalTokenAddress] = sideToken;\n originalTokens[sideToken] = _originalTokenAddress;\n allowTokens.setToken(sideToken, _typeId);\n\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\n }\n\n function claim(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function claimFallback(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n receivedAmount = _claim(\n _claimData,\n _msgSender(),\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function getDigest(\n ClaimData memory _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline\n ) internal returns (bytes32) {\n return LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n CLAIM_TYPEHASH,\n _claimData.to,\n _claimData.amount,\n _claimData.transactionHash,\n _relayer,\n _fee,\n nonces[_claimData.to]++,\n _deadline\n )\n )\n );\n }\n\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external override returns (uint256 receivedAmount) {\n require(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\n\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claim(\n ClaimData calldata _claimData,\n address payable _reciever,\n address payable _relayer,\n uint256 _fee\n ) internal nonReentrant returns (uint256 receivedAmount) {\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n require(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.amount,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n require(!claimed[transactionDataHash], \"Bridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (knownTokens[originalTokenAddress]) {\n receivedAmount =_claimCrossBackToToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n } else {\n receivedAmount =_claimCrossToSideToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n }\n emit Claimed(\n _claimData.transactionHash,\n originalTokenAddress,\n _claimData.to,\n senderAddresses[_claimData.transactionHash],\n _claimData.amount,\n _claimData.blockHash,\n _claimData.logIndex,\n _reciever,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claimCrossToSideToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n address sideToken = mappedTokens[_originalTokenAddress];\n uint256 granularity = IERC777(sideToken).granularity();\n uint256 formattedAmount = _amount.mul(granularity);\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n ISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n if(_fee > 0) {\n ISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n }\n return receivedAmount;\n }\n\n function _claimCrossBackToToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n //As side tokens are ERC777 they will always have 18 decimals\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n if(address(wrappedCurrency) == _originalTokenAddress) {\n wrappedCurrency.withdraw(formattedAmount);\n _receiver.transfer(receivedAmount);\n if(_fee > 0) {\n _relayer.transfer(_fee);\n }\n } else {\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n if(_fee > 0) {\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n }\n }\n return receivedAmount;\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\n address sender = _msgSender();\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, to, amount, \"\");\n }\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) override external payable {\n address sender = _msgSender();\n require(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n wrappedCurrency.deposit{ value: msg.value }();\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \"\");\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external override(IBridge, IERC777Recipient){\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to this address\");\n address tokenToUse = _msgSender();\n require(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n require(userData.length != 0 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\n crossTokens(tokenToUse, from, receiver, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\n internal whenNotUpgrading whenNotPaused nonReentrant {\n knownTokens[tokenToUse] = true;\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n uint256 amountMinusFees = amount.sub(fee);\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n // We consider the amount before fees converted to 18 decimals to check the limits\n // updateTokenTransfer revert if token not allowed\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n address originalTokenAddress = tokenToUse;\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\n //Side Token Crossing\n originalTokenAddress = originalTokens[tokenToUse];\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\n uint256 modulo = amountMinusFees.mod(granularity);\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n }\n\n emit Cross(\n originalTokenAddress,\n from,\n to,\n amountMinusFees,\n userData\n );\n\n if (fee > 0) {\n //Send the payment to the MultiSig of the Federation\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n }\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n )\n public pure override returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n }\n\n function setFeePercentage(uint amount) external onlyOwner {\n require(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() external view override returns(uint) {\n return feePercentage;\n }\n\n function changeFederation(address newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n require(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n wrappedCurrency = IWrapped(_wrappedCurrency);\n emit WrappedCurrencyChanged(_wrappedCurrency);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionsDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionsDataHashes[transactionHash]];\n }\n\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an `IERC777` token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See `IERC1820Registry` and\n * `ERC1820Implementer`.\n */\ninterface IERC777 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See `operatorSend` and `operatorBurn`.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor`.\n *\n * Emits an `AuthorizedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor` and `defaultOperators`.\n *\n * Emits a `RevokedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if `authorizeOperator` was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * `revokeOperator`, in which case `isOperatorFor` will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n\n function decimals() external returns (uint8);\n\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n}\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IBridge {\n\n struct ClaimData {\n address payable to;\n uint256 amount;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) external payable;\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n */\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external returns (uint256 receivedAmount);\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns(bytes32);\n\n event Cross(\n address indexed _tokenAddress,\n address indexed _from,\n address indexed _to,\n uint256 _amount,\n bytes _userData\n );\n event NewSideToken(\n address indexed _newSideTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 _granularity\n );\n event AcceptedCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FeePercentageChanged(uint256 _amount);\n event Claimed(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _reciever,\n address _relayer,\n uint256 _fee\n );\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideToken {\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideTokenFactory {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\n\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../SideToken/SideToken.sol\";\n\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\n external onlyPrimary override returns(address) {\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\n emit SideTokenCreated(sideToken, symbol, granularity);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\nabstract contract Secondary is Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n constructor () {\n _primary = _msgSender();\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(_primary);\n }\n}\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\nimport \"../interface/IERC677Receiver.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../lib/LibEIP712.sol\";\n\ncontract SideToken is ISideToken, ERC777 {\n using Address for address;\n using SafeMath for uint256;\n\n address public minter;\n uint256 private _granularity;\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n bytes32 public domainSeparator;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n // ERC677 Transfer Event\n event Transfer(address,address,uint256,bytes);\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\n minter = _minterAddr;\n _granularity = _newGranularity;\n\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n domainSeparator = LibEIP712.hashEIP712Domain(\n name(),\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter override\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n /**\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\n * @param recipient The address to transfer to.\n * @param amount The amount to be transferred.\n * @param data The extra data to be passed to the receiving contract.\n */\n function transferAndCall(address recipient, uint amount, bytes calldata data)\n external returns (bool success)\n {\n address from = _msgSender();\n\n _send(from, from, recipient, amount, data, \"\", false);\n emit Transfer(from, recipient, amount, data);\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\n return true;\n }\n\n function granularity() public view override returns (uint256) {\n return _granularity;\n }\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\n bytes32 digest = LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../../token/ERC20/IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\n // See https://github.com/ethereum/solidity/issues/4024.\n\n // keccak256(\"ERC777TokensSender\")\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\n\n // keccak256(\"ERC777TokensRecipient\")\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping (address => mapping (address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(\n string memory aName,\n string memory aSymbol,\n address[] memory theDefaultOperators\n ) {\n _name = aName;\n _symbol = aSymbol;\n\n _defaultOperatorsArray = theDefaultOperators;\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\n _defaultOperators[_defaultOperatorsArray[i]] = true;\n }\n\n // register interfaces\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view override(IERC777) returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view override(IERC777) returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20Detailed-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override(IERC777) returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n\n address from = _msgSender();\n\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\n\n _move(from, from, recipient, amount, \"\", \"\");\n\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(\n address operator,\n address tokenHolder\n ) public view override(IERC777) returns (bool) {\n return operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) external override(IERC777) {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) external override(IERC777) {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n )\n external override(IERC777)\n {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {Transfer} events.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\n external override(IERC777) {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\n _burn(_msgSender(), account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender)\n public view override(IERC20) returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {Transfer} and {Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount)\n external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n require(holder != address(0), \"ERC777: transfer from zero address\");\n\n address spender = _msgSender();\n\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\n\n _move(spender, holder, recipient, amount, \"\", \"\");\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\n\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address operator,\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n require(account != address(0), \"ERC777: mint to zero address\");\n\n // Update state variables\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n internal\n {\n require(from != address(0), \"ERC777: send from zero address\");\n require(to != address(0), \"ERC777: send to zero address\");\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param operator address operator requesting the operation\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(\n address operator,\n address from,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n )\n internal\n {\n require(from != address(0), \"ERC777: burn from zero address\");\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n // Update state variables\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\n _balances[to] = _balances[to].add(amount);\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n function _approve(address holder, address spender, uint256 value) internal {\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\n // currently unnecessary.\n //require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n private\n {\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n}\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * `IERC777` Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an `IERC777` token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/Bridge/BridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"./IBridgeV2.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../AllowTokens/AllowTokensV0.sol\";\nimport \"../Utils/UtilsV1.sol\";\n\ncontract BridgeV2 is Initializable, IBridgeV2, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant private NULL_ADDRESS = address(0);\n bytes32 constant private NULL_HASH = bytes32(0);\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address private federation;\n uint256 private feePercentage;\n string public symbolPrefix;\n uint256 public lastDay;\n uint256 public spentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping(bytes32 => bool) public processed; // ProcessedHash => true\n AllowTokensV0 public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n uint256 constant public FEE_PERCENTAGE_DIVIDER = 10000; // Percentage with up to 2 decimals\n bool private alreadyRun;\n\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool isUpgrading);\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = AllowTokensV0(_allowTokens);\n _changeSideTokenFactory(_sideTokenFactory);\n _changeFederation(_federation);\n //keccak256(\"ERC777TokensRecipient\")\n ERC_1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function version() external pure override returns (string memory) {\n return \"v2\";\n }\n\n modifier onlyFederation() {\n require(msg.sender == federation, \"Bridge: Sender not Federation\");\n _;\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address tokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity\n ) external onlyFederation whenNotPaused nonReentrant override returns(bool) {\n require(tokenAddress != NULL_ADDRESS, \"Bridge: Token is null\");\n require(receiver != NULL_ADDRESS, \"Bridge: Receiver is null\");\n require(amount > 0, \"Bridge: Amount 0\");\n require(bytes(symbol).length > 0, \"Bridge: Empty symbol\");\n require(blockHash != NULL_HASH, \"Bridge: BlockHash is null\");\n require(transactionHash != NULL_HASH, \"Bridge: Transaction is null\");\n require(decimals <= 18, \"Bridge: Decimals bigger 18\");\n require(UtilsV1.granularityToDecimals(granularity) <= 18, \"Bridge: invalid granularity\");\n\n _processTransaction(blockHash, transactionHash, receiver, amount, logIndex);\n\n if (knownTokens[tokenAddress]) {\n _acceptCrossBackToToken(receiver, tokenAddress, decimals, granularity, amount);\n } else {\n _acceptCrossToSideToken(receiver, tokenAddress, decimals, granularity, amount, symbol);\n }\n return true;\n }\n\n function _acceptCrossToSideToken(\n address receiver,\n address tokenAddress,\n uint8 decimals,\n uint256 granularity,\n uint256 amount,\n string memory symbol\n ) private {\n\n (uint256 calculatedGranularity,uint256 formattedAmount) = UtilsV1.calculateGranularityAndAmount(decimals, granularity, amount);\n address sideToken = mappedTokens[tokenAddress];\n if (sideToken == NULL_ADDRESS) {\n sideToken = _createSideToken(tokenAddress, symbol, calculatedGranularity);\n } else {\n require(calculatedGranularity == IERC777(sideToken).granularity(), \"Bridge: Granularity differ from side token\");\n }\n ISideToken(sideToken).mint(receiver, formattedAmount, \"\", \"\");\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, 18, calculatedGranularity);\n }\n\n function _acceptCrossBackToToken(address receiver, address tokenAddress, uint8 decimals, uint256 granularity, uint256 amount) private {\n require(decimals == 18, \"Bridge: Invalid decimals cross back\");\n //As side tokens are ERC777 we need to convert granularity to decimals\n (uint8 calculatedDecimals, uint256 formattedAmount) = UtilsV1.calculateDecimalsAndAmount(tokenAddress, granularity, amount);\n IERC20(tokenAddress).safeTransfer(receiver, formattedAmount);\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, calculatedDecimals, 1);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokens(address tokenToUse, uint256 amount) override external whenNotUpgrading whenNotPaused nonReentrant returns(bool) {\n address sender = _msgSender();\n require(!sender.isContract(), \"Bridge: Sender can't be a contract\");\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, amount, \"\");\n return true;\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external whenNotPaused whenNotUpgrading override(IBridgeV2, IERC777Recipient) {\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to address\");\n address tokenToUse = _msgSender();\n //This can only be used with trusted contracts\n crossTokens(tokenToUse, from, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, uint256 amount, bytes memory userData) private {\n bool isASideToken = originalTokens[tokenToUse] != NULL_ADDRESS;\n //Send the payment to the MultiSig of the Federation\n uint256 fee = amount.mul(feePercentage).div(FEE_PERCENTAGE_DIVIDER);\n uint256 amountMinusFees = amount.sub(fee);\n if (isASideToken) {\n uint256 modulo = amountMinusFees.mod(IERC777(tokenToUse).granularity());\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n }\n if(fee > 0) {\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n if (isASideToken) {\n verifyWithAllowTokens(tokenToUse, amount, isASideToken);\n //Side Token Crossing\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n // solium-disable-next-line max-len\n emit Cross(originalTokens[tokenToUse], from, amountMinusFees, IERC777(tokenToUse).symbol(), userData, IERC777(tokenToUse).decimals(), IERC777(tokenToUse).granularity());\n } else {\n //Main Token Crossing\n knownTokens[tokenToUse] = true;\n (uint8 decimals, uint256 granularity, string memory symbol) = UtilsV1.getTokenInfo(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n //We consider the amount before fees converted to 18 decimals to check the limits\n verifyWithAllowTokens(tokenToUse, formattedAmount, isASideToken);\n emit Cross(tokenToUse, from, amountMinusFees, symbol, userData, decimals, granularity);\n }\n }\n\n function _createSideToken(address token, string memory symbol, uint256 granularity) private returns (address sideToken){\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, symbol));\n address sideTokenAddress = sideTokenFactory.createSideToken(newSymbol, newSymbol, granularity);\n sideToken = sideTokenAddress;\n mappedTokens[token] = sideToken;\n originalTokens[sideTokenAddress] = token;\n emit NewSideToken(sideTokenAddress, token, newSymbol, granularity);\n return sideToken;\n }\n\n function verifyWithAllowTokens(address tokenToUse, uint256 amount, bool isASideToken) private {\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n // solium-disable-next-line security/no-block-members\n lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n spentToday = 0;\n }\n require(allowTokens.isValidTokenTransfer(tokenToUse, amount, spentToday, isASideToken), \"Bridge: Bigger than limit\");\n spentToday = spentToday.add(amount);\n }\n\n function getTransactionId(\n bytes32 _blockHash,\n bytes32 _transactionHash,\n address _receiver,\n uint256 _amount,\n uint32 _logIndex\n )\n public pure returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _receiver, _amount, _logIndex));\n }\n\n function _processTransaction(\n bytes32 _blockHash,\n bytes32 _transactionHash,\n address _receiver,\n uint256 _amount,\n uint32 _logIndex\n )\n private\n {\n bytes32 compiledId = getTransactionId(_blockHash, _transactionHash, _receiver, _amount, _logIndex);\n require(!processed[compiledId], \"Bridge: Already processed\");\n processed[compiledId] = true;\n }\n\n function setFeePercentage(uint amount) external onlyOwner whenNotPaused {\n require(amount < (FEE_PERCENTAGE_DIVIDER/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() override external view returns(uint) {\n return feePercentage;\n }\n\n function calcMaxWithdraw() override external view returns (uint) {\n uint spent = spentToday;\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > lastDay + 24 hours) // solhint-disable-line not-rely-on-time\n spent = 0;\n return allowTokens.calcMaxWithdraw(spent);\n }\n\n function changeFederation(address newFederation) external onlyOwner returns(bool) {\n _changeFederation(newFederation);\n return true;\n }\n\n function _changeFederation(address newFederation) internal {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner returns(bool) {\n _changeSideTokenFactory(newSideTokenFactory);\n return true;\n }\n\n function _changeSideTokenFactory(address newSideTokenFactory) internal {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function startUpgrade() external onlyOwner {\n isUpgrading = true;\n emit Upgrading(isUpgrading);\n }\n\n function endUpgrade() external onlyOwner {\n isUpgrading = false;\n emit Upgrading(isUpgrading);\n }\n\n //This method is only to recreate the USDT and USDC tokens on rsk without granularity restrictions.\n function clearSideToken() external onlyOwner returns(bool) {\n require(!alreadyRun, \"already done\");\n alreadyRun = true;\n address payable[4] memory sideTokens = [\n 0xe506F698b31a66049BD4653ed934E7a07Cbc5549,\n 0x5a42221D7AaE8e185BC0054Bb036D9757eC18857,\n 0xcdc8ccBbFB6407c53118fE47259e8d00C81F42CD,\n 0x6117C9529F15c52e2d3188d5285C745B757b5825\n ];\n for (uint i = 0; i < sideTokens.length; i++) {\n address originalToken = address(originalTokens[sideTokens[i]]);\n originalTokens[sideTokens[i]] = NULL_ADDRESS;\n mappedTokens[originalToken] = address(NULL_ADDRESS);\n }\n return true;\n }\n\n}\n"
+ },
+ "contracts/Bridge/IBridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\ninterface IBridgeV2 {function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n function calcMaxWithdraw() external view returns (uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokens(address tokenToUse, uint256 amount) external returns(bool);\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the federation contract\n */\n function acceptTransfer(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity\n ) external returns(bool);\n\n event Cross(address indexed _tokenAddress, address indexed _to, uint256 _amount, string _symbol, bytes _userData,\n uint8 _decimals, uint256 _granularity);\n event NewSideToken(address indexed _newSideTokenAddress, address indexed _originalTokenAddress, string _newSymbol, uint256 _granularity);\n event AcceptedCrossTransfer(address indexed _tokenAddress, address indexed _to, uint256 _amount, uint8 _decimals, uint256 _granularity,\n uint256 _formattedAmount, uint8 _calculatedDecimals, uint256 _calculatedGranularity);\n event FeePercentageChanged(uint256 _amount);\n}"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract AllowTokensV0 is Ownable {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n\n mapping (address => bool) public allowedTokens;\n bool private validateAllowedTokens;\n uint256 private maxTokensAllowed;\n uint256 private minTokensAllowed;\n uint256 public dailyLimit;\n\n event AllowedTokenAdded(address indexed _tokenAddress);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event AllowedTokenValidation(bool _enabled);\n event MaxTokensAllowedChanged(uint256 _maxTokens);\n event MinTokensAllowedChanged(uint256 _minTokens);\n event DailyLimitChanged(uint256 dailyLimit);\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\n _;\n }\n\n constructor(address _manager) {\n transferOwnership(_manager);\n validateAllowedTokens = true;\n maxTokensAllowed = 10000 ether;\n minTokensAllowed = 1 ether;\n dailyLimit = 100000 ether;\n }\n\n function isValidatingAllowedTokens() external view returns(bool) {\n return validateAllowedTokens;\n }\n\n function getMaxTokensAllowed() external view returns(uint256) {\n return maxTokensAllowed;\n }\n\n function getMinTokensAllowed() external view returns(uint256) {\n return minTokensAllowed;\n }\n\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\n return allowedTokens[token];\n }\n\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\n if (validateAllowedTokens) {\n return allowedTokenExist(token);\n }\n return true;\n }\n\n function addAllowedToken(address token) external onlyOwner {\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\n allowedTokens[token] = true;\n emit AllowedTokenAdded(token);\n }\n\n function removeAllowedToken(address token) external onlyOwner {\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\n allowedTokens[token] = false;\n emit AllowedTokenRemoved(token);\n }\n\n function enableAllowedTokensValidation() external onlyOwner {\n validateAllowedTokens = true;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function disableAllowedTokensValidation() external onlyOwner {\n // Before disabling Allowed Tokens Validations some kind of contract validation system\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\n validateAllowedTokens = false;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\n maxTokensAllowed = maxTokens;\n emit MaxTokensAllowedChanged(maxTokensAllowed);\n }\n\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\n minTokensAllowed = minTokens;\n emit MinTokensAllowedChanged(minTokensAllowed);\n }\n\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\n dailyLimit = _dailyLimit;\n emit DailyLimitChanged(_dailyLimit);\n }\n\n // solium-disable-next-line max-len\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\n if(amount > maxTokensAllowed)\n return false;\n if(amount < minTokensAllowed)\n return false;\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\n return false;\n if(!isSideToken && !isTokenAllowed(tokenToUse))\n return false;\n return true;\n }\n\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\n uint maxWithrow = dailyLimit - spentToday;\n if (dailyLimit < spentToday)\n return 0;\n if(maxWithrow > maxTokensAllowed)\n maxWithrow = maxTokensAllowed;\n return maxWithrow;\n }\n\n}\n"
+ },
+ "contracts/Utils/UtilsV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nlibrary UtilsV1 {\n using SafeMath for uint256;\n\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n // keccak256(\"ERC777Token\")\n bytes32 constant private TOKENS_ERC777_HASH = 0xac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054;\n\n function getTokenInfo(address tokenToUse) external view returns (uint8 decimals, uint256 granularity, string memory symbol) {\n decimals = getDecimals(tokenToUse);\n granularity = getGranularity(tokenToUse);\n symbol = getSymbol(tokenToUse);\n }\n\n function getSymbol(address tokenToUse) public view returns (string memory symbol) {\n //support 32 bytes or string symbol\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"symbol()\"));\n require(success, \"Utils: Token hasn't symbol()\");\n if (data.length == 32) {\n symbol = bytes32ToString(abi.decode(data, (bytes32)));\n } else {\n symbol = abi.decode(data, (string));\n }\n require(bytes(symbol).length > 0, \"Utils: Token empty symbol\");\n return symbol;\n }\n\n function getDecimals(address tokenToUse) public view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"Utils: No decimals\");\n require(data.length == 32, \"Utils: Decimals not uint\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n uint256 decimalsDecoded = abi.decode(data, (uint256));\n require(decimalsDecoded <= 18, \"Utils: Decimals not in 0 to 18\");\n return uint8(decimalsDecoded);\n }\n\n function getGranularity(address tokenToUse) public view returns (uint256 granularity) {\n granularity = 1;\n //support granularity if ERC777\n address implementer = ERC_1820.getInterfaceImplementer(tokenToUse, TOKENS_ERC777_HASH);\n if (implementer != address(0)) {\n granularity = IERC777(implementer).granularity();\n //Verify granularity is power of 10 to keep it compatible with ERC20 decimals\n granularityToDecimals(granularity);\n }\n return granularity;\n }\n\n /* bytes32 (fixed-size array) to string (dynamically-sized array) */\n function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) {\n uint8 i = 0;\n while(i < 32 && _bytes32[i] != 0) {\n i++;\n }\n bytes memory bytesArray = new bytes(i);\n for (i = 0; i < 32 && _bytes32[i] != 0; i++) {\n bytesArray[i] = _bytes32[i];\n }\n return string(bytesArray);\n }\n\n function decimalsToGranularity(uint8 decimals) public pure returns (uint256) {\n require(decimals <= 18, \"Utils: Decimals not in 0 to 18\");\n return uint256(10)**(18-decimals);\n }\n\n function granularityToDecimals(uint256 granularity) public pure returns (uint8) {\n if(granularity == 1) return 18;\n if(granularity == 10) return 17;\n if(granularity == 100) return 16;\n if(granularity == 1000) return 15;\n if(granularity == 10000) return 14;\n if(granularity == 100000) return 13;\n if(granularity == 1000000) return 12;\n if(granularity == 10000000) return 11;\n if(granularity == 100000000) return 10;\n if(granularity == 1000000000) return 9;\n if(granularity == 10000000000) return 8;\n if(granularity == 100000000000) return 7;\n if(granularity == 1000000000000) return 6;\n if(granularity == 10000000000000) return 5;\n if(granularity == 100000000000000) return 4;\n if(granularity == 1000000000000000) return 3;\n if(granularity == 10000000000000000) return 2;\n if(granularity == 100000000000000000) return 1;\n if(granularity == 1000000000000000000) return 0;\n require(false, \"Utils: invalid granularity\");\n return 0;\n }\n\n function calculateGranularityAndAmount(uint8 decimals, uint256 granularity, uint256 amount) external pure\n returns(uint256 calculatedGranularity, uint256 formattedAmount) {\n\n if(decimals == 18) {\n //tokenAddress is a ERC20 with 18 decimals should have 1 granularity\n //tokenAddress is a ERC777 token we give the same granularity\n calculatedGranularity = granularity;\n formattedAmount = amount;\n } else {\n //tokenAddress is a ERC20 with other than 18 decimals\n calculatedGranularity = decimalsToGranularity(decimals);\n formattedAmount = amount.mul(calculatedGranularity);\n }\n }\n\n function calculateDecimalsAndAmount(address tokenAddress, uint256 granularity, uint256 amount)\n external view returns (uint8 calculatedDecimals, uint256 formattedAmount) {\n uint8 tokenDecimals = getDecimals(tokenAddress);\n //As side tokens are ERC777 we need to convert granularity to decimals\n calculatedDecimals = granularityToDecimals(granularity);\n require(tokenDecimals == calculatedDecimals, \"Utils: Token decimals differ from decimals - granularity\");\n formattedAmount = amount.div(granularity);\n }\n\n}\n"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () {\n _owner = _msgSender();\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../interface/IBridge.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockReceiveTokensCall is IERC777Recipient {\n address public bridge;\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor(address _bridge) {\n bridge = _bridge;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount) external {\n IERC20(tokenToUse).approve(bridge, amount);\n IBridge(bridge).receiveTokensTo(tokenToUse, receiver, amount);\n }\n\n function callDepositTo(address receiver) external payable {\n IBridge(bridge).depositTo{ value: msg.value }(receiver);\n }\n\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\n IERC777(tokenToUse).send(bridge, amount, data);\n }\n\n // Mandatory for IERC777Recipient\n function tokensReceived(\n address,\n address,\n address,\n uint,\n bytes calldata,\n bytes calldata\n ) override external view {\n this;\n }\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockERC777Recipient is IERC777Recipient {\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor() {\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\n }\n\n event Success(\n address operator,\n address from,\n address to,\n uint amount,\n bytes userData,\n bytes operatorData);\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) override external {\n emit Success(operator, from, to, amount, userData, operatorData);\n }\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\n\ncontract SideTokenV1 is ERC777 {\n address public minter;\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\n minter = _minterAddr;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../SideToken/SideTokenV1.sol\";\n\ncontract SideTokenFactoryV1 is Secondary {\n event CreatedSideToken(address sideToken, string symbol);\n\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\n emit CreatedSideToken(address(sideToken), symbol);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using SafeMath for uint256;\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping (uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /*\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri_) {\n _setURI(uri_);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) external view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: balance query for the zero address\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(amount);\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, address(0), id, amount);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\n /**\n @dev Handles the receipt of a single ERC1155 token type. This function is\n called at the end of a `safeTransferFrom` after the balance has been updated.\n To accept the transfer, this must return\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n (i.e. 0xf23a6e61, or its own function selector).\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n )\n external\n returns(bytes4);\n\n /**\n @dev Handles the receipt of a multiple ERC1155 token types. This function\n is called at the end of a `safeBatchTransferFrom` after the balances have\n been updated. To accept the transfer(s), this must return\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n (i.e. 0xbc197c81, or its own function selector).\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match values array)\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n )\n external\n returns(bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC1155 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Pausable is ERC1155, Pausable {\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\nimport \"../access/roles/PauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context, PauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n constructor () {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract PauserRole is Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n constructor () {\n _addPauser(_msgSender());\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC721.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC721 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC721Pausable is ERC721, Pausable {\n /**\n * @dev See {ERC721-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../../zeppelin/ownership/Ownable.sol\";\nimport \"../../zeppelin/math/SafeMath.sol\";\nimport \"../../zeppelin/utils/Strings.sol\";\nimport \"./OpenSeaEIP712Base.sol\";\n\n\n/**\n * @title OpenSea721\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\n */\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\n using SafeMath for uint256;\n\n uint256 private _currentTokenId = 0;\n\n constructor(\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n _initializeEIP712(_name);\n }\n\n function baseTokenURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/api/creature/\";\n }\n\n function contractURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\n }\n\n /**\n * @dev Mints a token to an address with a tokenURI.\n * @param _to address of the future owner of the token\n */\n function mintTo(address _to) public onlyOwner {\n uint256 newTokenId = _getNextTokenId();\n _mint(_to, newTokenId);\n _incrementTokenId();\n }\n\n /**\n * @dev calculates the next token ID based on value of _currentTokenId\n * @return uint256 for the next token ID\n */\n function _getNextTokenId() private view returns (uint256) {\n return _currentTokenId.add(1);\n }\n\n /**\n * @dev increments the value of _currentTokenId\n */\n function _incrementTokenId() private {\n _currentTokenId++;\n }\n\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\n }\n\n}"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../zeppelin/upgradable/Initializable.sol\";\n\ncontract OpenSeaEIP712Base is Initializable {\n struct EIP712Domain {\n string name;\n string version;\n address verifyingContract;\n bytes32 salt;\n }\n\n string constant public ERC712_VERSION = \"1\";\n\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\n bytes(\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\n )\n );\n bytes32 internal domainSeperator;\n\n // supposed to be called once while initializing.\n // one of the contracts that inherits this contract follows proxy pattern\n // so it is not possible to do this in a constructor\n function _initializeEIP712(\n string memory name\n )\n internal\n initializer\n {\n _setDomainSeperator(name);\n }\n\n function _setDomainSeperator(string memory name) internal {\n domainSeperator = keccak256(\n abi.encode(\n EIP712_DOMAIN_TYPEHASH,\n keccak256(bytes(name)),\n keccak256(bytes(ERC712_VERSION)),\n address(this),\n bytes32(getChainId())\n )\n );\n }\n\n function getDomainSeperator() public view returns (bytes32) {\n return domainSeperator;\n }\n\n function getChainId() public pure returns (uint256) {\n uint256 id;\n assembly {\n id := chainid()\n }\n return id;\n }\n\n /**\n * Accept message hash and returns hash message in EIP712 compatible form\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\n * https://eips.ethereum.org/EIPS/eip-712\n * \"\\\\x19\" makes the encoding deterministic\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\n */\n function toTypedMessageHash(bytes32 messageHash)\n internal\n view\n returns (bytes32)\n {\n return\n keccak256(\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\n );\n }\n}\n"
+ },
+ "contracts/Federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../interface/IBridge.sol\";\n\ncontract FederationV2 is Initializable, UpgradableOwnable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridge public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\n public validRequirement(_members.length, _required) initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n }\n\n function version() external pure returns (string memory) {\n return \"v2\";\n }\n\n function setBridge(address _bridge) external onlyOwner {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridge(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n )\n public onlyMember returns(bool)\n {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32)\n {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}"
+ },
+ "contracts/Federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../nftbridge/INFTBridge.sol\";\nimport \"../interface/IBridge.sol\";\nimport \"../interface/IFederation.sol\";\n\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridge public bridge;\n address[] public members;\n\n /**\n @notice The minimum amount of votes to approve a transaction\n @dev It should have more members than the required amount\n */\n uint public required;\n\n /**\n @notice All the addresses that are members of the federation\n @dev The address should be a member to vote in transactions\n */\n mapping (address => bool) public isMember;\n\n /**\n (bytes32) transactionId = keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n ) => (\n (address) members => (bool) voted\n )\n @notice Votes by members by the transaction ID\n @dev usually the members should approve the transaction by 50% + 1\n */\n mapping (bytes32 => mapping (address => bool)) public votes;\n\n /**\n (bytes32) transactionId => (bool) voted\n @notice Check if that transaction was already processed\n */\n mapping(bytes32 => bool) public processed;\n\n /** Federator v3 variables */\n INFTBridge public bridgeNFT;\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner, address _bridgeNFT) public\n validRequirement(_members.length, _required) initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n _setNFTBridge(_bridgeNFT);\n }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure override returns (string memory) {\n return \"v3\";\n }\n\n /**\n @notice Sets a new bridge contract\n @dev Emits BridgeChanged event\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external onlyOwner override {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridge(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n /**\n @notice Sets a new NFT bridge contract\n @dev Emits NFTBridgeChanged event\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external onlyOwner override {\n _setNFTBridge(_bridgeNFT);\n }\n\n function _setNFTBridge(address _bridgeNFT) internal {\n require(_bridgeNFT != NULL_ADDRESS, \"Federation: Empty NFT bridge\");\n bridgeNFT = INFTBridge(_bridgeNFT);\n emit NFTBridgeChanged(_bridgeNFT);\n }\n\n function validateTransaction(bytes32 transactionId) internal view returns(bool) {\n uint transactionCount = getTransactionCount(transactionId);\n return transactionCount >= required && transactionCount >= members.length / 2 + 1;\n }\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) external onlyMember override {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return;\n\n if (votes[transactionId][_msgSender()])\n return;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n logIndex\n );\n\n if (validateTransaction(transactionId)) {\n processed[transactionId] = true;\n acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex,\n tokenType\n );\n\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n logIndex\n );\n return;\n }\n }\n\n function acceptTransfer(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) internal {\n if (tokenType == TokenType.NFT) {\n require(address(bridgeNFT) != NULL_ADDRESS, \"Federation: Empty NFTBridge\");\n bridgeNFT.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n return;\n }\n\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n }\n\n /**\n @notice Get the amount of approved votes for that transactionId\n @param transactionId The transaction hashed from getTransactionId function\n */\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n /**\n @notice Gets the hash of transaction from the following parameters encoded and keccaked\n @dev It encodes and applies keccak256 to the parameters received in the same order\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param amount Could be the amount or the tokenId\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @return The hash generated by the parameters.\n */\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32) {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner override\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner override\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view override returns (address[] memory) {\n return members;\n }\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @dev Emits the RequirementChange event\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n /**\n @notice It emits an HeartBeat like an health check\n @dev Emits HeartBeat event\n */\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember override {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface IFederation {\n enum TokenType{ COIN, NFT }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure returns (string memory);\n\n /**\n @notice Sets a new bridge contract\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external;\n\n /**\n @notice Sets a new NFT bridge contract\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external;\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) external;\n\n /**\n @notice Add a new member to the federation\n @param _newMember address of the new member\n */\n function addMember(address _newMember) external;\n\n /**\n @notice Remove a member of the federation\n @param _oldMember address of the member to be removed from federation\n */\n function removeMember(address _oldMember) external;\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view returns (address[] memory);\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external;\n\n /**\n @notice It emmits an HeartBeat like an healthy check\n */\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event NFTBridgeChanged(address bridgeNFT);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n}\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract MinterRole is Context {\n using Roles for Roles.Role;\n\n event MinterAdded(address indexed account);\n event MinterRemoved(address indexed account);\n\n Roles.Role private _minters;\n\n constructor () {\n _addMinter(_msgSender());\n }\n\n modifier onlyMinter() {\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\n _;\n }\n\n function isMinter(address account) public view returns (bool) {\n return _minters.has(account);\n }\n\n function addMinter(address account) public onlyMinter {\n _addMinter(account);\n }\n\n function renounceMinter() public {\n _removeMinter(_msgSender());\n }\n\n function _addMinter(address account) internal {\n _minters.add(account);\n emit MinterAdded(account);\n }\n\n function _removeMinter(address account) internal {\n _minters.remove(account);\n emit MinterRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20Mintable}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() override public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) override public view returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) override public returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) override public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) override public returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal {\n require(sender != address(0), \"ERC20: transfer from zero address\");\n require(recipient != address(0), \"ERC20: transfer to zero address\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: mint to zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: burn from zero address\");\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n *\n * This is internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal {\n require(owner != address(0), \"ERC20: approve from zero address\");\n require(spender != address(0), \"ERC20: approve to zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\n * from the caller's allowance.\n *\n * See {_burn} and {_approve}.\n */\n function _burnFrom(address account, uint256 amount) internal {\n _burn(account, amount);\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\n }\n}\n"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\nimport \"../interface/IERC677Receiver.sol\";\n\ncontract mockERC677Receiver is IERC677Receiver {\n event Success(address _sender, uint _value, bytes _data);\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\n emit Success(_sender, _value, _data);\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Optional functions from the ERC20 standard.\n */\nabstract contract ERC20Detailed is IERC20 {\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\n * these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\n _name = aName;\n _symbol = aSymbol;\n _decimals = theDecimals;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./Proxy.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n *\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\n * {TransparentUpgradeableProxy}.\n */\ncontract UpgradeableProxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _setImplementation(_logic);\n if(_data.length > 0) {\n Address.functionDelegateCall(_logic, _data);\n }\n }\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n bytes32 slot = _IMPLEMENTATION_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n impl := sload(slot)\n }\n }\n\n /**\n * @dev Upgrades the proxy to a new implementation.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal virtual {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\n\n bytes32 slot = _IMPLEMENTATION_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newImplementation)\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./UpgradeableProxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _setAdmin(admin_);\n }\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _admin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _admin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\n emit AdminChanged(_admin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external virtual ifAdmin {\n _upgradeTo(newImplementation);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\n _upgradeTo(newImplementation);\n Address.functionDelegateCall(newImplementation, data);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address adm) {\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n adm := sload(slot)\n }\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n bytes32 slot = _ADMIN_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newAdmin)\n }\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../ownership/Ownable.sol\";\nimport \"./TransparentUpgradeableProxy.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
+ },
+ "contracts/Federation/FederationV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../Bridge/IBridgeV2.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract FederationV1 is Ownable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridgeV2 public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n // solium-disable-next-line max-len\n event Voted(address indexed sender, bytes32 indexed transactionId, address originalTokenAddress, address receiver, uint256 amount, string symbol, bytes32 blockHash, bytes32 indexed transactionHash, uint32 logIndex, uint8 decimals, uint256 granularity);\n event Executed(bytes32 indexed transactionId);\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Caller not a Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n constructor(address[] memory _members, uint _required) validRequirement(_members.length, _required) {\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Members larger than max allowed\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n }\n\n function setBridge(address _bridge) external onlyOwner {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridgeV2(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity)\n external onlyMember returns(bool)\n {\n // solium-disable-next-line max-len\n bytes32 transactionId = getTransactionId(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n // solium-disable-next-line max-len\n emit Voted(_msgSender(), transactionId, originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bool acceptTransfer = bridge.acceptTransfer(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n require(acceptTransfer, \"Federation: Bridge acceptTransfer error\");\n emit Executed(transactionId);\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string memory symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity)\n public pure returns(bytes32)\n {\n // solium-disable-next-line max-len\n return keccak256(abi.encodePacked(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity));\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove last element\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n}"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\n\ncontract BridgeProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract FederationProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract MainToken is ERC20Detailed, ERC20 {\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\n ERC20Detailed(name, symbol, decimals)\n {\n _mint(msg.sender, totalSupply);\n }\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\n bool result = transfer(_to, _value);\n if (!result) return false;\n\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\n receiver.tokenFallback(msg.sender, _value, _data);\n\n // IMPORTANT: the ERC-677 specification does not say\n // anything about the use of the receiver contract's\n // tokenFallback method return value. Given\n // its return type matches with this method's return\n // type, returning it could be a possibility.\n // We here take the more conservative approach and\n // ignore the return value, returning true\n // to signal a succesful transfer despite tokenFallback's\n // return value -- fact being tokens are transferred\n // in any case.\n return true;\n }\n}\n\ninterface ERC677TransferReceiver {\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\n}"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract AlternativeERC20Detailed is ERC20 {\n string private _name;\n bytes32 private _symbol;\n uint256 private _decimals;\n\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\n {\n _name = aName;\n _symbol = aSymbol;\n _decimals = someDecimals;\n _mint(msg.sender, aTotalSupply);\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (bytes32) {\n return _symbol;\n }\n\n function decimals() public view returns (uint256) {\n return _decimals;\n }\n}"
+ },
+ "contracts/test/nftbridge/NFTERC721TestToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.6;\n\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\n\ncontract NFTERC721TestToken is ERC721 {\n\n string private _contractURI;\n\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\n\n function safeMint(address to, uint256 tokenId) public {\n _safeMint(to, tokenId);\n }\n\n function setBaseURI(string memory baseURI) public {\n _setBaseURI(baseURI);\n }\n\n function setContractURI(string memory contractURI_) public {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n function setTokenURI(uint256 tokenId, string memory _tokenURI) public {\n _setTokenURI(tokenId, _tokenURI);\n }\n\n}\n"
+ },
+ "contracts/nftbridge/SideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./ISideNFTToken.sol\";\nimport \"../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\n\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\n address public minter;\n string private _contractURI;\n\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\n require(_minter != address(0), \"SideToken: Empty Minter\");\n minter = _minter;\n _setBaseURI(_baseURI);\n _setContractURI(contractURI_);\n }\n\n function _setContractURI(string memory contractURI_) internal {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(address account, uint256 tokenId) external onlyMinter override {\n _mint(account, tokenId);\n }\n}"
+ },
+ "contracts/nftbridge/SideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"./SideNFTToken.sol\";\n\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external onlyPrimary override returns(address) {\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\n return sideTokenAddress;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() {\n _registerInterface(\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\n );\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721Receiver.sol\";\n\n /**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers. \n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Burnable is ERC1155 {\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n}\n"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../lib/LibUtils.sol\";\n\ncontract LibUtilsHarness {\n\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\n return LibUtils.decimalsToGranularity(decimals);\n }\n\n function getDecimals(address tokenToUse) external view returns (uint8) {\n return LibUtils.getDecimals(tokenToUse);\n }\n\n function getGranularity(address tokenToUse) external view returns (uint256) {\n return LibUtils.getGranularity(tokenToUse);\n }\n\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\n return LibUtils.bytesToAddress(bys);\n }\n\n}\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/solcInputs/c9c50994c7f4ed6c6a7c2f652aca7adb.json b/bridge/deployments/kovan/solcInputs/c9c50994c7f4ed6c6a7c2f652aca7adb.json
new file mode 100644
index 000000000..c7008191d
--- /dev/null
+++ b/bridge/deployments/kovan/solcInputs/c9c50994c7f4ed6c6a7c2f652aca7adb.json
@@ -0,0 +1,297 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/math/SafeMath.sol\";\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\n\nimport \"../interface/IAllowTokens.sol\";\n\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n uint256 constant public MAX_TYPES = 250;\n mapping (address => TokenInfo) public allowedTokens;\n mapping (uint256 => Limits) public typeLimits;\n uint256 public smallAmountConfirmations;\n uint256 public mediumAmountConfirmations;\n uint256 public largeAmountConfirmations;\n string[] public typeDescriptions;\n\n event SetToken(address indexed _tokenAddress, uint256 _typeId);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\n event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\n event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\n event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\n\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\n _;\n }\n\n function initialize(\n address _manager,\n address _primary,\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations,\n TypeInfo[] memory typesInfo) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradableSecondary.__Secondary_init(_primary);\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n for(uint i = 0; i < typesInfo.length; i = i + 1) {\n _addTokenType(typesInfo[i].description, typesInfo[i].limits);\n }\n }\n\n function version() override external pure returns (string memory) {\n return \"v1\";\n }\n\n function getInfoAndLimits(address token) override public view\n returns (TokenInfo memory info, Limits memory limit) {\n info = allowedTokens[token];\n limit = typeLimits[info.typeId];\n return (info, limit);\n }\n function calcMaxWithdraw(address token) override public view returns (uint256 maxWithdraw) {\n (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\n return _calcMaxWithdraw(info, limits);\n }\n\n function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n info.spentToday = 0;\n }\n if (limits.daily <= info.spentToday)\n return 0;\n maxWithdraw = limits.daily - info.spentToday;\n if(maxWithdraw > limits.max)\n maxWithdraw = limits.max;\n return maxWithdraw;\n }\n\n // solium-disable-next-line max-len\n function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\n (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\n require(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\n require(amount >= limit.min, \"AllowTokens: Lower than limit\");\n\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n // solium-disable-next-line security/no-block-members\n info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n info.spentToday = 0;\n }\n uint maxWithdraw = _calcMaxWithdraw(info, limit);\n require(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\n info.spentToday = info.spentToday.add(amount);\n allowedTokens[token] = info;\n\n emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\n }\n\n function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\n require(bytes(description).length > 0, \"AllowTokens: Empty description\");\n len = typeDescriptions.length;\n require(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\n typeDescriptions.push(description);\n _setTypeLimits(len, limits);\n emit TokenTypeAdded(len, description);\n return len;\n }\n\n function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\n return _addTokenType(description, limits);\n }\n\n function _setTypeLimits(uint256 typeId, Limits memory limits) private {\n require(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\n require(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\n require(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\n require(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\n require(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\n typeLimits[typeId] = limits;\n emit TypeLimitsChanged(typeId, limits);\n }\n\n function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\n _setTypeLimits(typeId, limits);\n }\n\n function getTypesLimits() external view override returns(Limits[] memory limits) {\n limits = new Limits[](typeDescriptions.length);\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\n limits[i] = typeLimits[i];\n }\n return limits;\n }\n\n function getTypeDescriptionsLength() external view override returns(uint256) {\n return typeDescriptions.length;\n }\n\n function getTypeDescriptions() external view override returns(string[] memory descriptions) {\n descriptions = new string[](typeDescriptions.length);\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\n descriptions[i] = typeDescriptions[i];\n }\n return descriptions;\n }\n\n function isTokenAllowed(address token) public view notNull(token) override returns (bool) {\n return allowedTokens[token].allowed;\n }\n\n function setToken(address token, uint256 typeId) override public notNull(token) {\n require(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n require(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\n TokenInfo memory info = allowedTokens[token];\n info.allowed = true;\n info.typeId = typeId;\n allowedTokens[token] = info;\n emit SetToken(token, typeId);\n }\n\n function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\n require(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\n for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\n setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\n }\n }\n\n function removeAllowedToken(address token) external notNull(token) onlyOwner {\n TokenInfo memory info = allowedTokens[token];\n require(info.allowed, \"AllowTokens: Not Allowed\");\n info.allowed = false;\n allowedTokens[token] = info;\n emit AllowedTokenRemoved(token);\n }\n\n function setConfirmations(\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations) external onlyOwner {\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n }\n\n function _setConfirmations(\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations) private {\n require(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\n require(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\n smallAmountConfirmations = _smallAmountConfirmations;\n mediumAmountConfirmations = _mediumAmountConfirmations;\n largeAmountConfirmations = _largeAmountConfirmations;\n emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n }\n\n function getConfirmations() external view override\n returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount) {\n return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\n }\n\n}\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @title Initializable\n *\n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(initializing || !initialized, \"Contract instance is already initialized\");\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\n * the owner.\n */\ncontract UpgradableOwnable is Initializable, Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function initialize(address sender) public initializer {\n _owner = sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * > Note: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\ncontract UpgradableSecondary is Initializable, Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n function __Secondary_init(address sender) public initializer {\n _primary = sender;\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(recipient);\n }\n\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IAllowTokens {\n\n struct Limits {\n uint256 min;\n uint256 max;\n uint256 daily;\n uint256 mediumAmount;\n uint256 largeAmount;\n }\n\n struct TokenInfo {\n bool allowed;\n uint256 typeId;\n uint256 spentToday;\n uint256 lastDay;\n }\n\n struct TypeInfo {\n string description;\n Limits limits;\n }\n\n struct TokensAndType {\n address token;\n uint256 typeId;\n }\n\n function version() external pure returns (string memory);\n\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\n\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\n\n function getTypesLimits() external view returns(Limits[] memory limits);\n\n function getTypeDescriptionsLength() external view returns(uint256);\n\n function getTypeDescriptions() external view returns(string[] memory descriptions);\n\n function setToken(address token, uint256 typeId) external;\n\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\n\n function isTokenAllowed(address token) external view returns (bool);\n\n function updateTokenTransfer(address token, uint256 amount) external;\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n\n function _msgSender() internal view returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
+ },
+ "contracts/nftbridge/NFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC721/IERC721.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Metadata.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Enumerable.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Receiver.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./INFTBridge.sol\";\nimport \"./ISideNFTToken.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract NFTBridge is\n Initializable,\n INFTBridge,\n UpgradablePausable,\n UpgradableOwnable,\n ReentrancyGuard,\n IERC721Receiver {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address internal constant NULL_ADDRESS = address(0);\n bytes32 internal constant NULL_HASH = bytes32(0);\n IERC1820Registry internal constant ERC1820 =\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address payable internal federation;\n uint256 internal fixedFee;\n string public symbolPrefix;\n\n mapping(address => address) public sideTokenAddressByOriginalTokenAddress;\n mapping(address => address) public originalTokenAddressBySideTokenAddress;\n mapping(address => bool) public isAddressFromCrossedOriginalToken; // address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideNFTTokenFactory public sideTokenFactory;\n bool public isUpgrading;\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\n event Upgrading(bool _isUpgrading);\n\n function initialize(\n address _manager,\n address payable _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\n federation = _federation;\n ERC1820.setInterfaceImplementer(\n address(this),\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\n address(this)\n );\n }\n\n function version() external pure override returns (string memory) {\n return \"v1\";\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _tokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external override whenNotPaused nonReentrant {\n require(_msgSender() == federation, \"NFTBridge: Not Federation\");\n require(\n isAddressFromCrossedOriginalToken[_tokenAddress] ||\n sideTokenAddressByOriginalTokenAddress[_tokenAddress] != NULL_ADDRESS,\n \"NFTBridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"NFTBridge: Null To\");\n require(_from != NULL_ADDRESS, \"NFTBridge: Null From\");\n require(_blockHash != NULL_HASH, \"NFTBridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"NFTBridge: Null TxHash\");\n require(\n transactionDataHashes[_transactionHash] == bytes32(0),\n \"NFTBridge: Already accepted\"\n );\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\n require(!claimed[_transactionDataHash], \"NFTBridge: Already claimed\");\n\n transactionDataHashes[_transactionHash] = _transactionDataHash;\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\n// senderAddresses[_transactionHash] = _from;\n\n emit AcceptedNFTCrossTransfer(\n _transactionHash,\n _tokenAddress,\n _to,\n _from,\n _tokenId,\n _blockHash,\n _logIndex\n );\n }\n\n function createSideNFTToken(\n address _originalTokenAddress,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName,\n string calldata _baseURI,\n string calldata _contractURI\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"NFTBridge: Null original token address\");\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[_originalTokenAddress];\n require(sideTokenAddress == NULL_ADDRESS, \"NFTBridge: Side token already exists\");\n string memory sideTokenSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideTokenAddress = sideTokenFactory.createSideNFTToken(_originalTokenName, sideTokenSymbol, _baseURI, _contractURI);\n\n sideTokenAddressByOriginalTokenAddress[_originalTokenAddress] = sideTokenAddress;\n originalTokenAddressBySideTokenAddress[sideTokenAddress] = _originalTokenAddress;\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, sideTokenSymbol);\n }\n\n function claim(NFTClaimData calldata _claimData) external override {\n _claim(_claimData, _claimData.to);\n }\n\n function claimFallback(NFTClaimData calldata _claimData) external override {\n require(_msgSender() == _claimData.from, \"NFTBridge: invalid sender\");\n _claim(_claimData, _msgSender());\n }\n\n function _claim(\n NFTClaimData calldata _claimData,\n address payable _receiver\n ) internal {\n address tokenAddress = _claimData.tokenAddress;\n uint256 tokenId = _claimData.tokenId;\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.from,\n tokenId,\n tokenAddress,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\n \"NFTBridge: Wrong txDataHash\"\n );\n require(!claimed[transactionDataHash], \"NFTBridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n bool isClaimBeingRequestedInMainChain = isAddressFromCrossedOriginalToken[tokenAddress];\n if (isClaimBeingRequestedInMainChain) {\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\n } else {\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[tokenAddress];\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\n }\n\n emit ClaimedNFTToken(\n _claimData.transactionHash,\n tokenAddress,\n _claimData.to,\n _claimData.from,\n _claimData.tokenId,\n _claimData.blockHash,\n _claimData.logIndex,\n _receiver\n );\n }\n\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\"creator()\"));\n if (success) {\n return abi.decode(data, (address));\n }\n\n return IERC721(tokenAddress).ownerOf(tokenId);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId\n ) public payable override {\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\n\n address payable sender = _msgSender();\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\n\n crossTokens(tokenAddress, to, tokenCreator, \"\", tokenId);\n\n if (fixedFee > 0) {\n require(msg.value >= fixedFee, \"NFTBridge: value is smaller than fixed fee\");\n\n // Send the payment to the MultiSig of the Federation\n federation.transfer(fixedFee);\n if (msg.value > fixedFee) { // refund of unused value\n sender.transfer(msg.value.sub(fixedFee));\n }\n }\n }\n\n function crossTokens(\n address tokenAddress,\n address to,\n address tokenCreator,\n bytes memory userData,\n uint256 tokenId\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\n isAddressFromCrossedOriginalToken[tokenAddress] = true;\n\n IERC721Enumerable enumerable = IERC721Enumerable(tokenAddress);\n IERC721Metadata metadataIERC = IERC721Metadata(tokenAddress);\n string memory tokenURI = metadataIERC.tokenURI(tokenId);\n\n address originalTokenAddress = tokenAddress;\n if (originalTokenAddressBySideTokenAddress[tokenAddress] != NULL_ADDRESS) {\n originalTokenAddress = originalTokenAddressBySideTokenAddress[tokenAddress];\n ERC721Burnable(tokenAddress).burn(tokenId);\n }\n\n emit Cross(\n originalTokenAddress,\n _msgSender(),\n to,\n tokenCreator,\n userData,\n enumerable.totalSupply(),\n tokenId,\n tokenURI\n );\n }\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) public pure override returns (bytes32) {\n return keccak256(\n abi.encodePacked(\n _blockHash,\n _transactionHash,\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _logIndex\n )\n );\n }\n\n function setFixedFee(uint256 amount) external onlyOwner {\n fixedFee = amount;\n emit FixedFeeNFTChanged(fixedFee);\n }\n\n function getFixedFee() external view override returns (uint256) {\n return fixedFee;\n }\n\n function changeFederation(address payable newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"NFTBridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"NFTBridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns (address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\n require(\n newSideNFTTokenFactory != NULL_ADDRESS,\n \"NFTBridge: empty SideTokenFactory\"\n );\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionDataHashes[transactionHash]];\n }\n\n /**\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\n/**\n * @title Helps contracts guard against reentrancy attacks.\n * @author Remco Bloemen , Eenae \n * @dev If you mark a function `nonReentrant`, you should also\n * mark it `external`.\n */\ncontract ReentrancyGuard is Initializable {\n /// @dev counter to allow mutex lock with only one SSTORE operation\n uint256 private _guardCounter;\n\n function initialize() public initializer {\n // The counter starts at one to prevent changing it from zero to a non-zero\n // value, which is a more expensive operation.\n _guardCounter = 1;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _guardCounter += 1;\n uint256 localCounter = _guardCounter;\n _;\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\n }\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\nimport \"../access/roles/UpgradablePauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n function __Pausable_init(address sender) public initializer {\n UpgradablePauserRole.__PauserRol_init(sender);\n\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as `account`'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `_account`.\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `_implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\n\n /**\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `_account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {ERC20Detailed}.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeERC20: low-level call failed\");\n\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n */\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./ERC721.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721Burnable is Context, ERC721 {\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n _burn(tokenId);\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\nlibrary LibEIP712 {\n\n // Hash of the EIP712 Domain Separator Schema\n // keccak256(abi.encodePacked(\n // \"EIP712Domain(\",\n // \"string name,\",\n // \"string version,\",\n // \"uint256 chainId,\",\n // \"address verifyingContract\",\n // \")\"\n // ))\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n /// @dev Calculates a EIP712 domain separator.\n /// @param name The EIP712 domain name.\n /// @param version The EIP712 domain version.\n /// @param verifyingContract The EIP712 verifying contract.\n /// @return result EIP712 domain separator.\n function hashEIP712Domain(\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n // keccak256(bytes(name)),\n // keccak256(bytes(version)),\n // chainId,\n // uint256(verifyingContract)\n // ))\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Calculate hashes of dynamic data\n let nameHash := keccak256(add(name, 32), mload(name))\n let versionHash := keccak256(add(version, 32), mload(version))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n // Store params in memory\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), nameHash)\n mstore(add(memPtr, 64), versionHash)\n mstore(add(memPtr, 96), chainId)\n mstore(add(memPtr, 128), verifyingContract)\n\n // Compute hash\n result := keccak256(memPtr, 160)\n }\n return result;\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\n /// with getDomainHash().\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to the given EIP712 Domain.\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n internal\n pure\n returns (bytes32 result)\n {\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct\n // ));\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nlibrary LibUtils {\n\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\n return uint256(10)**(18-decimals);\n }\n\n function getDecimals(address tokenToUse) internal view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"LibUtils: No decimals\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n return uint8(abi.decode(data, (uint256)));\n }\n\n function getGranularity(address tokenToUse) internal view returns (uint256) {\n //support granularity if ERC777\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\n require(success, \"LibUtils: No granularity\");\n\n return abi.decode(data, (uint256));\n }\n\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n addr := mload(add(bys,20))\n }\n }\n\n}\n"
+ },
+ "contracts/nftbridge/INFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface INFTBridge {\n struct NFTClaimData {\n address payable to;\n address from;\n uint256 tokenId;\n address tokenAddress;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFixedFee() external view returns (uint256);\n\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId\n ) external payable;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\n */\n function claim(NFTClaimData calldata _claimData) external;\n\n function claimFallback(NFTClaimData calldata _claimData) external;\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns (bytes32);\n\n event Cross(\n address indexed _originalTokenAddress,\n address indexed _from,\n address indexed _to,\n address _tokenCreator,\n bytes _userData,\n uint256 _totalSupply,\n uint256 _tokenId,\n string _tokenURI\n );\n event NewSideNFTToken(\n address indexed _newSideNFTTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol\n );\n event AcceptedNFTCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FixedFeeNFTChanged(uint256 _amount);\n event ClaimedNFTToken(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _receiver\n );\n}\n"
+ },
+ "contracts/nftbridge/ISideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\ninterface ISideNFTToken {\n function mint(address account, uint256 tokenId) external;\n}"
+ },
+ "contracts/nftbridge/ISideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\ninterface ISideNFTTokenFactory {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external returns(address);\n\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IWrapped {\n function balanceOf(address) external returns(uint);\n\n function deposit() external payable;\n\n function withdraw(uint wad) external;\n\n function totalSupply() external view returns (uint);\n\n function approve(address guy, uint wad) external returns (bool);\n\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad)\n external\n returns (bool);\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../Initializable.sol\";\n\nimport \"../../../GSN/Context.sol\";\nimport \"../../../access/Roles.sol\";\n\ncontract UpgradablePauserRole is Initializable, Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n function __PauserRol_init(address sender) public initializer {\n if (!isPauser(sender)) {\n _addPauser(sender);\n }\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @title Roles\n * @dev Library for managing addresses assigned to a Role.\n */\nlibrary Roles {\n struct Role {\n mapping (address => bool) bearer;\n }\n\n /**\n * @dev Give an account access to this role.\n */\n function add(Role storage role, address account) internal {\n require(!has(role, account), \"Roles: account already has role\");\n role.bearer[account] = true;\n }\n\n /**\n * @dev Remove an account's access to this role.\n */\n function remove(Role storage role, address account) internal {\n require(has(role, account), \"Roles: account doesn't have role\");\n role.bearer[account] = false;\n }\n\n /**\n * @dev Check if an account has this role.\n * @return bool\n */\n function has(Role storage role, address account) internal view returns (bool) {\n require(account != address(0), \"Roles: account is the zero address\");\n return role.bearer[account];\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _tokenOwners.contains(tokenId);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(tokenId);\n\n emit Transfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n}\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract WRBTC is IWrapped {\n string public name = \"Wrapped RBTC\";\n string public symbol = \"WRBTC\";\n uint8 public decimals = 18;\n\n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n event Deposit(address indexed dst, uint wad);\n event Withdrawal(address indexed src, uint wad);\n\n mapping (address => uint) override public balanceOf;\n mapping (address => mapping (address => uint)) public allowance;\n\n receive () external payable {\n deposit();\n }\n function deposit() override public payable {\n balanceOf[msg.sender] += msg.value;\n emit Deposit(msg.sender, msg.value);\n }\n function withdraw(uint wad) override public {\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\n balanceOf[msg.sender] -= wad;\n msg.sender.transfer(wad);\n emit Withdrawal(msg.sender, wad);\n }\n\n function totalSupply() override public view returns (uint) {\n return address(this).balance;\n }\n\n function approve(address guy, uint wad) override public returns (bool) {\n allowance[msg.sender][guy] = wad;\n emit Approval(msg.sender, guy, wad);\n return true;\n }\n\n function transfer(address dst, uint wad) override public returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad)\n override public\n returns (bool)\n {\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\n\n if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\n allowance[src][msg.sender] -= wad;\n }\n\n balanceOf[src] -= wad;\n balanceOf[dst] += wad;\n\n emit Transfer(src, dst, wad);\n\n return true;\n }\n}"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant internal NULL_ADDRESS = address(0);\n bytes32 constant internal NULL_HASH = bytes32(0);\n IERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address internal federation;\n uint256 internal feePercentage;\n string public symbolPrefix;\n // replaces uint256 internal _depprecatedLastDay;\n bytes32 public domainSeparator;\n uint256 internal _deprecatedSpentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n // Percentage with up to 2 decimals\n uint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\n //Bridge_v3 variables\n bytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\n IWrapped public wrappedCurrency;\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n // keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\n mapping(address => uint) public nonces;\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool _isUpgrading);\n event WrappedCurrencyChanged(address _wrappedCurrency);\n\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n federation = _federation;\n //keccak256(\"ERC777TokensRecipient\")\n ERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n initDomainSeparator();\n }\n\n receive () external payable {\n // The fallback function is needed to use WRBTC\n require(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n }\n\n function version() override external pure returns (string memory) {\n return \"v3\";\n }\n\n function initDomainSeparator() public {\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n domainSeparator = LibEIP712.hashEIP712Domain(\n \"RSK Token Bridge\",\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"Bridge: Not Federation\");\n require(knownTokens[_originalTokenAddress] ||\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\n \"Bridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"Bridge: Null To\");\n require(_amount > 0, \"Bridge: Amount 0\");\n require(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _amount,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed also has the previously processed using the older bridge version\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n require(!claimed[_transactionDataHash], \"Bridge: Already claimed\");\n\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\n senderAddresses[_transactionHash] = _from;\n\n emit AcceptedCrossTransfer(\n _transactionHash,\n _originalTokenAddress,\n _to,\n _from,\n _amount,\n _blockHash,\n _logIndex\n );\n }\n\n\n function createSideToken(\n uint256 _typeId,\n address _originalTokenAddress,\n uint8 _originalTokenDecimals,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n address sideToken = mappedTokens[_originalTokenAddress];\n require(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\n\n mappedTokens[_originalTokenAddress] = sideToken;\n originalTokens[sideToken] = _originalTokenAddress;\n allowTokens.setToken(sideToken, _typeId);\n\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\n }\n\n function claim(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function claimFallback(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n receivedAmount = _claim(\n _claimData,\n _msgSender(),\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function getDigest(\n ClaimData memory _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline\n ) internal returns (bytes32) {\n return LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n CLAIM_TYPEHASH,\n _claimData.to,\n _claimData.amount,\n _claimData.transactionHash,\n _relayer,\n _fee,\n nonces[_claimData.to]++,\n _deadline\n )\n )\n );\n }\n\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external override returns (uint256 receivedAmount) {\n require(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\n\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claim(\n ClaimData calldata _claimData,\n address payable _reciever,\n address payable _relayer,\n uint256 _fee\n ) internal nonReentrant returns (uint256 receivedAmount) {\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n require(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.amount,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n require(!claimed[transactionDataHash], \"Bridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (knownTokens[originalTokenAddress]) {\n receivedAmount =_claimCrossBackToToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n } else {\n receivedAmount =_claimCrossToSideToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n }\n emit Claimed(\n _claimData.transactionHash,\n originalTokenAddress,\n _claimData.to,\n senderAddresses[_claimData.transactionHash],\n _claimData.amount,\n _claimData.blockHash,\n _claimData.logIndex,\n _reciever,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claimCrossToSideToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n address sideToken = mappedTokens[_originalTokenAddress];\n uint256 granularity = IERC777(sideToken).granularity();\n uint256 formattedAmount = _amount.mul(granularity);\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n ISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n if(_fee > 0) {\n ISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n }\n return receivedAmount;\n }\n\n function _claimCrossBackToToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n //As side tokens are ERC777 they will always have 18 decimals\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n if(address(wrappedCurrency) == _originalTokenAddress) {\n wrappedCurrency.withdraw(formattedAmount);\n _receiver.transfer(receivedAmount);\n if(_fee > 0) {\n _relayer.transfer(_fee);\n }\n } else {\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n if(_fee > 0) {\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n }\n }\n return receivedAmount;\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\n address sender = _msgSender();\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, to, amount, \"\");\n }\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) override external payable {\n address sender = _msgSender();\n require(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n wrappedCurrency.deposit{ value: msg.value }();\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \"\");\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external override(IBridge, IERC777Recipient){\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to this address\");\n address tokenToUse = _msgSender();\n require(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n require(userData.length != 0 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\n crossTokens(tokenToUse, from, receiver, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\n internal whenNotUpgrading whenNotPaused nonReentrant {\n knownTokens[tokenToUse] = true;\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n uint256 amountMinusFees = amount.sub(fee);\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n // We consider the amount before fees converted to 18 decimals to check the limits\n // updateTokenTransfer revert if token not allowed\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n address originalTokenAddress = tokenToUse;\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\n //Side Token Crossing\n originalTokenAddress = originalTokens[tokenToUse];\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\n uint256 modulo = amountMinusFees.mod(granularity);\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n }\n\n emit Cross(\n originalTokenAddress,\n from,\n to,\n amountMinusFees,\n userData\n );\n\n if (fee > 0) {\n //Send the payment to the MultiSig of the Federation\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n }\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n )\n public pure override returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n }\n\n function setFeePercentage(uint amount) external onlyOwner {\n require(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() external view override returns(uint) {\n return feePercentage;\n }\n\n function changeFederation(address newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n require(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n wrappedCurrency = IWrapped(_wrappedCurrency);\n emit WrappedCurrencyChanged(_wrappedCurrency);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionsDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionsDataHashes[transactionHash]];\n }\n\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an `IERC777` token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See `IERC1820Registry` and\n * `ERC1820Implementer`.\n */\ninterface IERC777 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See `operatorSend` and `operatorBurn`.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor`.\n *\n * Emits an `AuthorizedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor` and `defaultOperators`.\n *\n * Emits a `RevokedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if `authorizeOperator` was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * `revokeOperator`, in which case `isOperatorFor` will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n\n function decimals() external returns (uint8);\n\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n}\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IBridge {\n\n struct ClaimData {\n address payable to;\n uint256 amount;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) external payable;\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n */\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external returns (uint256 receivedAmount);\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns(bytes32);\n\n event Cross(\n address indexed _tokenAddress,\n address indexed _from,\n address indexed _to,\n uint256 _amount,\n bytes _userData\n );\n event NewSideToken(\n address indexed _newSideTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 _granularity\n );\n event AcceptedCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FeePercentageChanged(uint256 _amount);\n event Claimed(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _reciever,\n address _relayer,\n uint256 _fee\n );\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideToken {\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideTokenFactory {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\n\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../SideToken/SideToken.sol\";\n\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\n external onlyPrimary override returns(address) {\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\n emit SideTokenCreated(sideToken, symbol, granularity);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\nabstract contract Secondary is Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n constructor () {\n _primary = _msgSender();\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(_primary);\n }\n}\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\nimport \"../interface/IERC677Receiver.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../lib/LibEIP712.sol\";\n\ncontract SideToken is ISideToken, ERC777 {\n using Address for address;\n using SafeMath for uint256;\n\n address public minter;\n uint256 private _granularity;\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n bytes32 public domainSeparator;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n // ERC677 Transfer Event\n event Transfer(address,address,uint256,bytes);\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\n minter = _minterAddr;\n _granularity = _newGranularity;\n\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n domainSeparator = LibEIP712.hashEIP712Domain(\n name(),\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter override\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n /**\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\n * @param recipient The address to transfer to.\n * @param amount The amount to be transferred.\n * @param data The extra data to be passed to the receiving contract.\n */\n function transferAndCall(address recipient, uint amount, bytes calldata data)\n external returns (bool success)\n {\n address from = _msgSender();\n\n _send(from, from, recipient, amount, data, \"\", false);\n emit Transfer(from, recipient, amount, data);\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\n return true;\n }\n\n function granularity() public view override returns (uint256) {\n return _granularity;\n }\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\n bytes32 digest = LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../../token/ERC20/IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\n // See https://github.com/ethereum/solidity/issues/4024.\n\n // keccak256(\"ERC777TokensSender\")\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\n\n // keccak256(\"ERC777TokensRecipient\")\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping (address => mapping (address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(\n string memory aName,\n string memory aSymbol,\n address[] memory theDefaultOperators\n ) {\n _name = aName;\n _symbol = aSymbol;\n\n _defaultOperatorsArray = theDefaultOperators;\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\n _defaultOperators[_defaultOperatorsArray[i]] = true;\n }\n\n // register interfaces\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view override(IERC777) returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view override(IERC777) returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20Detailed-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override(IERC777) returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n\n address from = _msgSender();\n\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\n\n _move(from, from, recipient, amount, \"\", \"\");\n\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(\n address operator,\n address tokenHolder\n ) public view override(IERC777) returns (bool) {\n return operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) external override(IERC777) {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) external override(IERC777) {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n )\n external override(IERC777)\n {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {Transfer} events.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\n external override(IERC777) {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\n _burn(_msgSender(), account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender)\n public view override(IERC20) returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {Transfer} and {Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount)\n external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n require(holder != address(0), \"ERC777: transfer from zero address\");\n\n address spender = _msgSender();\n\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\n\n _move(spender, holder, recipient, amount, \"\", \"\");\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\n\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address operator,\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n require(account != address(0), \"ERC777: mint to zero address\");\n\n // Update state variables\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n internal\n {\n require(from != address(0), \"ERC777: send from zero address\");\n require(to != address(0), \"ERC777: send to zero address\");\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param operator address operator requesting the operation\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(\n address operator,\n address from,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n )\n internal\n {\n require(from != address(0), \"ERC777: burn from zero address\");\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n // Update state variables\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\n _balances[to] = _balances[to].add(amount);\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n function _approve(address holder, address spender, uint256 value) internal {\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\n // currently unnecessary.\n //require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n private\n {\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n}\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * `IERC777` Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an `IERC777` token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/Bridge/BridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"./IBridgeV2.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../AllowTokens/AllowTokensV0.sol\";\nimport \"../Utils/UtilsV1.sol\";\n\ncontract BridgeV2 is Initializable, IBridgeV2, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant private NULL_ADDRESS = address(0);\n bytes32 constant private NULL_HASH = bytes32(0);\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address private federation;\n uint256 private feePercentage;\n string public symbolPrefix;\n uint256 public lastDay;\n uint256 public spentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping(bytes32 => bool) public processed; // ProcessedHash => true\n AllowTokensV0 public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n uint256 constant public FEE_PERCENTAGE_DIVIDER = 10000; // Percentage with up to 2 decimals\n bool private alreadyRun;\n\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool isUpgrading);\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = AllowTokensV0(_allowTokens);\n _changeSideTokenFactory(_sideTokenFactory);\n _changeFederation(_federation);\n //keccak256(\"ERC777TokensRecipient\")\n ERC_1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function version() external pure override returns (string memory) {\n return \"v2\";\n }\n\n modifier onlyFederation() {\n require(msg.sender == federation, \"Bridge: Sender not Federation\");\n _;\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address tokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity\n ) external onlyFederation whenNotPaused nonReentrant override returns(bool) {\n require(tokenAddress != NULL_ADDRESS, \"Bridge: Token is null\");\n require(receiver != NULL_ADDRESS, \"Bridge: Receiver is null\");\n require(amount > 0, \"Bridge: Amount 0\");\n require(bytes(symbol).length > 0, \"Bridge: Empty symbol\");\n require(blockHash != NULL_HASH, \"Bridge: BlockHash is null\");\n require(transactionHash != NULL_HASH, \"Bridge: Transaction is null\");\n require(decimals <= 18, \"Bridge: Decimals bigger 18\");\n require(UtilsV1.granularityToDecimals(granularity) <= 18, \"Bridge: invalid granularity\");\n\n _processTransaction(blockHash, transactionHash, receiver, amount, logIndex);\n\n if (knownTokens[tokenAddress]) {\n _acceptCrossBackToToken(receiver, tokenAddress, decimals, granularity, amount);\n } else {\n _acceptCrossToSideToken(receiver, tokenAddress, decimals, granularity, amount, symbol);\n }\n return true;\n }\n\n function _acceptCrossToSideToken(\n address receiver,\n address tokenAddress,\n uint8 decimals,\n uint256 granularity,\n uint256 amount,\n string memory symbol\n ) private {\n\n (uint256 calculatedGranularity,uint256 formattedAmount) = UtilsV1.calculateGranularityAndAmount(decimals, granularity, amount);\n address sideToken = mappedTokens[tokenAddress];\n if (sideToken == NULL_ADDRESS) {\n sideToken = _createSideToken(tokenAddress, symbol, calculatedGranularity);\n } else {\n require(calculatedGranularity == IERC777(sideToken).granularity(), \"Bridge: Granularity differ from side token\");\n }\n ISideToken(sideToken).mint(receiver, formattedAmount, \"\", \"\");\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, 18, calculatedGranularity);\n }\n\n function _acceptCrossBackToToken(address receiver, address tokenAddress, uint8 decimals, uint256 granularity, uint256 amount) private {\n require(decimals == 18, \"Bridge: Invalid decimals cross back\");\n //As side tokens are ERC777 we need to convert granularity to decimals\n (uint8 calculatedDecimals, uint256 formattedAmount) = UtilsV1.calculateDecimalsAndAmount(tokenAddress, granularity, amount);\n IERC20(tokenAddress).safeTransfer(receiver, formattedAmount);\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, calculatedDecimals, 1);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokens(address tokenToUse, uint256 amount) override external whenNotUpgrading whenNotPaused nonReentrant returns(bool) {\n address sender = _msgSender();\n require(!sender.isContract(), \"Bridge: Sender can't be a contract\");\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, amount, \"\");\n return true;\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external whenNotPaused whenNotUpgrading override(IBridgeV2, IERC777Recipient) {\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to address\");\n address tokenToUse = _msgSender();\n //This can only be used with trusted contracts\n crossTokens(tokenToUse, from, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, uint256 amount, bytes memory userData) private {\n bool isASideToken = originalTokens[tokenToUse] != NULL_ADDRESS;\n //Send the payment to the MultiSig of the Federation\n uint256 fee = amount.mul(feePercentage).div(FEE_PERCENTAGE_DIVIDER);\n uint256 amountMinusFees = amount.sub(fee);\n if (isASideToken) {\n uint256 modulo = amountMinusFees.mod(IERC777(tokenToUse).granularity());\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n }\n if(fee > 0) {\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n if (isASideToken) {\n verifyWithAllowTokens(tokenToUse, amount, isASideToken);\n //Side Token Crossing\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n // solium-disable-next-line max-len\n emit Cross(originalTokens[tokenToUse], from, amountMinusFees, IERC777(tokenToUse).symbol(), userData, IERC777(tokenToUse).decimals(), IERC777(tokenToUse).granularity());\n } else {\n //Main Token Crossing\n knownTokens[tokenToUse] = true;\n (uint8 decimals, uint256 granularity, string memory symbol) = UtilsV1.getTokenInfo(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n //We consider the amount before fees converted to 18 decimals to check the limits\n verifyWithAllowTokens(tokenToUse, formattedAmount, isASideToken);\n emit Cross(tokenToUse, from, amountMinusFees, symbol, userData, decimals, granularity);\n }\n }\n\n function _createSideToken(address token, string memory symbol, uint256 granularity) private returns (address sideToken){\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, symbol));\n address sideTokenAddress = sideTokenFactory.createSideToken(newSymbol, newSymbol, granularity);\n sideToken = sideTokenAddress;\n mappedTokens[token] = sideToken;\n originalTokens[sideTokenAddress] = token;\n emit NewSideToken(sideTokenAddress, token, newSymbol, granularity);\n return sideToken;\n }\n\n function verifyWithAllowTokens(address tokenToUse, uint256 amount, bool isASideToken) private {\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n // solium-disable-next-line security/no-block-members\n lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n spentToday = 0;\n }\n require(allowTokens.isValidTokenTransfer(tokenToUse, amount, spentToday, isASideToken), \"Bridge: Bigger than limit\");\n spentToday = spentToday.add(amount);\n }\n\n function getTransactionId(\n bytes32 _blockHash,\n bytes32 _transactionHash,\n address _receiver,\n uint256 _amount,\n uint32 _logIndex\n )\n public pure returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _receiver, _amount, _logIndex));\n }\n\n function _processTransaction(\n bytes32 _blockHash,\n bytes32 _transactionHash,\n address _receiver,\n uint256 _amount,\n uint32 _logIndex\n )\n private\n {\n bytes32 compiledId = getTransactionId(_blockHash, _transactionHash, _receiver, _amount, _logIndex);\n require(!processed[compiledId], \"Bridge: Already processed\");\n processed[compiledId] = true;\n }\n\n function setFeePercentage(uint amount) external onlyOwner whenNotPaused {\n require(amount < (FEE_PERCENTAGE_DIVIDER/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() override external view returns(uint) {\n return feePercentage;\n }\n\n function calcMaxWithdraw() override external view returns (uint) {\n uint spent = spentToday;\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > lastDay + 24 hours) // solhint-disable-line not-rely-on-time\n spent = 0;\n return allowTokens.calcMaxWithdraw(spent);\n }\n\n function changeFederation(address newFederation) external onlyOwner returns(bool) {\n _changeFederation(newFederation);\n return true;\n }\n\n function _changeFederation(address newFederation) internal {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner returns(bool) {\n _changeSideTokenFactory(newSideTokenFactory);\n return true;\n }\n\n function _changeSideTokenFactory(address newSideTokenFactory) internal {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function startUpgrade() external onlyOwner {\n isUpgrading = true;\n emit Upgrading(isUpgrading);\n }\n\n function endUpgrade() external onlyOwner {\n isUpgrading = false;\n emit Upgrading(isUpgrading);\n }\n\n //This method is only to recreate the USDT and USDC tokens on rsk without granularity restrictions.\n function clearSideToken() external onlyOwner returns(bool) {\n require(!alreadyRun, \"already done\");\n alreadyRun = true;\n address payable[4] memory sideTokens = [\n 0xe506F698b31a66049BD4653ed934E7a07Cbc5549,\n 0x5a42221D7AaE8e185BC0054Bb036D9757eC18857,\n 0xcdc8ccBbFB6407c53118fE47259e8d00C81F42CD,\n 0x6117C9529F15c52e2d3188d5285C745B757b5825\n ];\n for (uint i = 0; i < sideTokens.length; i++) {\n address originalToken = address(originalTokens[sideTokens[i]]);\n originalTokens[sideTokens[i]] = NULL_ADDRESS;\n mappedTokens[originalToken] = address(NULL_ADDRESS);\n }\n return true;\n }\n\n}\n"
+ },
+ "contracts/Bridge/IBridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\ninterface IBridgeV2 {function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n function calcMaxWithdraw() external view returns (uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokens(address tokenToUse, uint256 amount) external returns(bool);\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the federation contract\n */\n function acceptTransfer(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity\n ) external returns(bool);\n\n event Cross(address indexed _tokenAddress, address indexed _to, uint256 _amount, string _symbol, bytes _userData,\n uint8 _decimals, uint256 _granularity);\n event NewSideToken(address indexed _newSideTokenAddress, address indexed _originalTokenAddress, string _newSymbol, uint256 _granularity);\n event AcceptedCrossTransfer(address indexed _tokenAddress, address indexed _to, uint256 _amount, uint8 _decimals, uint256 _granularity,\n uint256 _formattedAmount, uint8 _calculatedDecimals, uint256 _calculatedGranularity);\n event FeePercentageChanged(uint256 _amount);\n}"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract AllowTokensV0 is Ownable {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n\n mapping (address => bool) public allowedTokens;\n bool private validateAllowedTokens;\n uint256 private maxTokensAllowed;\n uint256 private minTokensAllowed;\n uint256 public dailyLimit;\n\n event AllowedTokenAdded(address indexed _tokenAddress);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event AllowedTokenValidation(bool _enabled);\n event MaxTokensAllowedChanged(uint256 _maxTokens);\n event MinTokensAllowedChanged(uint256 _minTokens);\n event DailyLimitChanged(uint256 dailyLimit);\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\n _;\n }\n\n constructor(address _manager) {\n transferOwnership(_manager);\n validateAllowedTokens = true;\n maxTokensAllowed = 10000 ether;\n minTokensAllowed = 1 ether;\n dailyLimit = 100000 ether;\n }\n\n function isValidatingAllowedTokens() external view returns(bool) {\n return validateAllowedTokens;\n }\n\n function getMaxTokensAllowed() external view returns(uint256) {\n return maxTokensAllowed;\n }\n\n function getMinTokensAllowed() external view returns(uint256) {\n return minTokensAllowed;\n }\n\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\n return allowedTokens[token];\n }\n\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\n if (validateAllowedTokens) {\n return allowedTokenExist(token);\n }\n return true;\n }\n\n function addAllowedToken(address token) external onlyOwner {\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\n allowedTokens[token] = true;\n emit AllowedTokenAdded(token);\n }\n\n function removeAllowedToken(address token) external onlyOwner {\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\n allowedTokens[token] = false;\n emit AllowedTokenRemoved(token);\n }\n\n function enableAllowedTokensValidation() external onlyOwner {\n validateAllowedTokens = true;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function disableAllowedTokensValidation() external onlyOwner {\n // Before disabling Allowed Tokens Validations some kind of contract validation system\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\n validateAllowedTokens = false;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\n maxTokensAllowed = maxTokens;\n emit MaxTokensAllowedChanged(maxTokensAllowed);\n }\n\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\n minTokensAllowed = minTokens;\n emit MinTokensAllowedChanged(minTokensAllowed);\n }\n\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\n dailyLimit = _dailyLimit;\n emit DailyLimitChanged(_dailyLimit);\n }\n\n // solium-disable-next-line max-len\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\n if(amount > maxTokensAllowed)\n return false;\n if(amount < minTokensAllowed)\n return false;\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\n return false;\n if(!isSideToken && !isTokenAllowed(tokenToUse))\n return false;\n return true;\n }\n\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\n uint maxWithrow = dailyLimit - spentToday;\n if (dailyLimit < spentToday)\n return 0;\n if(maxWithrow > maxTokensAllowed)\n maxWithrow = maxTokensAllowed;\n return maxWithrow;\n }\n\n}\n"
+ },
+ "contracts/Utils/UtilsV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nlibrary UtilsV1 {\n using SafeMath for uint256;\n\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n // keccak256(\"ERC777Token\")\n bytes32 constant private TOKENS_ERC777_HASH = 0xac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054;\n\n function getTokenInfo(address tokenToUse) external view returns (uint8 decimals, uint256 granularity, string memory symbol) {\n decimals = getDecimals(tokenToUse);\n granularity = getGranularity(tokenToUse);\n symbol = getSymbol(tokenToUse);\n }\n\n function getSymbol(address tokenToUse) public view returns (string memory symbol) {\n //support 32 bytes or string symbol\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"symbol()\"));\n require(success, \"Utils: Token hasn't symbol()\");\n if (data.length == 32) {\n symbol = bytes32ToString(abi.decode(data, (bytes32)));\n } else {\n symbol = abi.decode(data, (string));\n }\n require(bytes(symbol).length > 0, \"Utils: Token empty symbol\");\n return symbol;\n }\n\n function getDecimals(address tokenToUse) public view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"Utils: No decimals\");\n require(data.length == 32, \"Utils: Decimals not uint\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n uint256 decimalsDecoded = abi.decode(data, (uint256));\n require(decimalsDecoded <= 18, \"Utils: Decimals not in 0 to 18\");\n return uint8(decimalsDecoded);\n }\n\n function getGranularity(address tokenToUse) public view returns (uint256 granularity) {\n granularity = 1;\n //support granularity if ERC777\n address implementer = ERC_1820.getInterfaceImplementer(tokenToUse, TOKENS_ERC777_HASH);\n if (implementer != address(0)) {\n granularity = IERC777(implementer).granularity();\n //Verify granularity is power of 10 to keep it compatible with ERC20 decimals\n granularityToDecimals(granularity);\n }\n return granularity;\n }\n\n /* bytes32 (fixed-size array) to string (dynamically-sized array) */\n function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) {\n uint8 i = 0;\n while(i < 32 && _bytes32[i] != 0) {\n i++;\n }\n bytes memory bytesArray = new bytes(i);\n for (i = 0; i < 32 && _bytes32[i] != 0; i++) {\n bytesArray[i] = _bytes32[i];\n }\n return string(bytesArray);\n }\n\n function decimalsToGranularity(uint8 decimals) public pure returns (uint256) {\n require(decimals <= 18, \"Utils: Decimals not in 0 to 18\");\n return uint256(10)**(18-decimals);\n }\n\n function granularityToDecimals(uint256 granularity) public pure returns (uint8) {\n if(granularity == 1) return 18;\n if(granularity == 10) return 17;\n if(granularity == 100) return 16;\n if(granularity == 1000) return 15;\n if(granularity == 10000) return 14;\n if(granularity == 100000) return 13;\n if(granularity == 1000000) return 12;\n if(granularity == 10000000) return 11;\n if(granularity == 100000000) return 10;\n if(granularity == 1000000000) return 9;\n if(granularity == 10000000000) return 8;\n if(granularity == 100000000000) return 7;\n if(granularity == 1000000000000) return 6;\n if(granularity == 10000000000000) return 5;\n if(granularity == 100000000000000) return 4;\n if(granularity == 1000000000000000) return 3;\n if(granularity == 10000000000000000) return 2;\n if(granularity == 100000000000000000) return 1;\n if(granularity == 1000000000000000000) return 0;\n require(false, \"Utils: invalid granularity\");\n return 0;\n }\n\n function calculateGranularityAndAmount(uint8 decimals, uint256 granularity, uint256 amount) external pure\n returns(uint256 calculatedGranularity, uint256 formattedAmount) {\n\n if(decimals == 18) {\n //tokenAddress is a ERC20 with 18 decimals should have 1 granularity\n //tokenAddress is a ERC777 token we give the same granularity\n calculatedGranularity = granularity;\n formattedAmount = amount;\n } else {\n //tokenAddress is a ERC20 with other than 18 decimals\n calculatedGranularity = decimalsToGranularity(decimals);\n formattedAmount = amount.mul(calculatedGranularity);\n }\n }\n\n function calculateDecimalsAndAmount(address tokenAddress, uint256 granularity, uint256 amount)\n external view returns (uint8 calculatedDecimals, uint256 formattedAmount) {\n uint8 tokenDecimals = getDecimals(tokenAddress);\n //As side tokens are ERC777 we need to convert granularity to decimals\n calculatedDecimals = granularityToDecimals(granularity);\n require(tokenDecimals == calculatedDecimals, \"Utils: Token decimals differ from decimals - granularity\");\n formattedAmount = amount.div(granularity);\n }\n\n}\n"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () {\n _owner = _msgSender();\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../interface/IBridge.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockReceiveTokensCall is IERC777Recipient {\n address public bridge;\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor(address _bridge) {\n bridge = _bridge;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount) external {\n IERC20(tokenToUse).approve(bridge, amount);\n IBridge(bridge).receiveTokensTo(tokenToUse, receiver, amount);\n }\n\n function callDepositTo(address receiver) external payable {\n IBridge(bridge).depositTo{ value: msg.value }(receiver);\n }\n\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\n IERC777(tokenToUse).send(bridge, amount, data);\n }\n\n // Mandatory for IERC777Recipient\n function tokensReceived(\n address,\n address,\n address,\n uint,\n bytes calldata,\n bytes calldata\n ) override external view {\n this;\n }\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockERC777Recipient is IERC777Recipient {\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor() {\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\n }\n\n event Success(\n address operator,\n address from,\n address to,\n uint amount,\n bytes userData,\n bytes operatorData);\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) override external {\n emit Success(operator, from, to, amount, userData, operatorData);\n }\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\n\ncontract SideTokenV1 is ERC777 {\n address public minter;\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\n minter = _minterAddr;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../SideToken/SideTokenV1.sol\";\n\ncontract SideTokenFactoryV1 is Secondary {\n event CreatedSideToken(address sideToken, string symbol);\n\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\n emit CreatedSideToken(address(sideToken), symbol);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using SafeMath for uint256;\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping (uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /*\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri_) {\n _setURI(uri_);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) external view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: balance query for the zero address\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(amount);\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, address(0), id, amount);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\n /**\n @dev Handles the receipt of a single ERC1155 token type. This function is\n called at the end of a `safeTransferFrom` after the balance has been updated.\n To accept the transfer, this must return\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n (i.e. 0xf23a6e61, or its own function selector).\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n )\n external\n returns(bytes4);\n\n /**\n @dev Handles the receipt of a multiple ERC1155 token types. This function\n is called at the end of a `safeBatchTransferFrom` after the balances have\n been updated. To accept the transfer(s), this must return\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n (i.e. 0xbc197c81, or its own function selector).\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match values array)\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n )\n external\n returns(bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC1155 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Pausable is ERC1155, Pausable {\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\nimport \"../access/roles/PauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context, PauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n constructor () {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract PauserRole is Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n constructor () {\n _addPauser(_msgSender());\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC721.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC721 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC721Pausable is ERC721, Pausable {\n /**\n * @dev See {ERC721-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../../zeppelin/ownership/Ownable.sol\";\nimport \"../../zeppelin/math/SafeMath.sol\";\nimport \"../../zeppelin/utils/Strings.sol\";\nimport \"./OpenSeaEIP712Base.sol\";\n\n\n/**\n * @title OpenSea721\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\n */\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\n using SafeMath for uint256;\n\n uint256 private _currentTokenId = 0;\n\n constructor(\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n _initializeEIP712(_name);\n }\n\n function baseTokenURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/api/creature/\";\n }\n\n function contractURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\n }\n\n /**\n * @dev Mints a token to an address with a tokenURI.\n * @param _to address of the future owner of the token\n */\n function mintTo(address _to) public onlyOwner {\n uint256 newTokenId = _getNextTokenId();\n _mint(_to, newTokenId);\n _incrementTokenId();\n }\n\n /**\n * @dev calculates the next token ID based on value of _currentTokenId\n * @return uint256 for the next token ID\n */\n function _getNextTokenId() private view returns (uint256) {\n return _currentTokenId.add(1);\n }\n\n /**\n * @dev increments the value of _currentTokenId\n */\n function _incrementTokenId() private {\n _currentTokenId++;\n }\n\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\n }\n\n}"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../zeppelin/upgradable/Initializable.sol\";\n\ncontract OpenSeaEIP712Base is Initializable {\n struct EIP712Domain {\n string name;\n string version;\n address verifyingContract;\n bytes32 salt;\n }\n\n string constant public ERC712_VERSION = \"1\";\n\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\n bytes(\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\n )\n );\n bytes32 internal domainSeperator;\n\n // supposed to be called once while initializing.\n // one of the contracts that inherits this contract follows proxy pattern\n // so it is not possible to do this in a constructor\n function _initializeEIP712(\n string memory name\n )\n internal\n initializer\n {\n _setDomainSeperator(name);\n }\n\n function _setDomainSeperator(string memory name) internal {\n domainSeperator = keccak256(\n abi.encode(\n EIP712_DOMAIN_TYPEHASH,\n keccak256(bytes(name)),\n keccak256(bytes(ERC712_VERSION)),\n address(this),\n bytes32(getChainId())\n )\n );\n }\n\n function getDomainSeperator() public view returns (bytes32) {\n return domainSeperator;\n }\n\n function getChainId() public pure returns (uint256) {\n uint256 id;\n assembly {\n id := chainid()\n }\n return id;\n }\n\n /**\n * Accept message hash and returns hash message in EIP712 compatible form\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\n * https://eips.ethereum.org/EIPS/eip-712\n * \"\\\\x19\" makes the encoding deterministic\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\n */\n function toTypedMessageHash(bytes32 messageHash)\n internal\n view\n returns (bytes32)\n {\n return\n keccak256(\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\n );\n }\n}\n"
+ },
+ "contracts/Federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../interface/IBridge.sol\";\n\ncontract FederationV2 is Initializable, UpgradableOwnable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridge public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\n public validRequirement(_members.length, _required) initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n }\n\n function version() external pure returns (string memory) {\n return \"v2\";\n }\n\n function setBridge(address _bridge) external onlyOwner {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridge(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n )\n public onlyMember returns(bool)\n {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32)\n {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}"
+ },
+ "contracts/Federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../nftbridge/INFTBridge.sol\";\nimport \"../interface/IBridge.sol\";\nimport \"../interface/IFederation.sol\";\n\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridge public bridge;\n address[] public members;\n\n /**\n @notice The minimum amount of votes to approve a transaction\n @dev It should have more members than the required amount\n */\n uint public required;\n\n /**\n @notice All the addresses that are members of the federation\n @dev The address should be a member to vote in transactions\n */\n mapping (address => bool) public isMember;\n\n /**\n (bytes32) transactionId = keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n ) => (\n (address) members => (bool) voted\n )\n @notice Votes by members by the transaction ID\n @dev usually the members should approve the transaction by 50% + 1\n */\n mapping (bytes32 => mapping (address => bool)) public votes;\n\n /**\n (bytes32) transactionId => (bool) voted\n @notice Check if that transaction was already processed\n */\n mapping(bytes32 => bool) public processed;\n\n /** Federator v3 variables */\n INFTBridge public bridgeNFT;\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner, address _bridgeNFT) public\n validRequirement(_members.length, _required) initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n _setNFTBridge(_bridgeNFT);\n }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure override returns (string memory) {\n return \"v3\";\n }\n\n /**\n @notice Sets a new bridge contract\n @dev Emits BridgeChanged event\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external onlyOwner override {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridge(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n /**\n @notice Sets a new NFT bridge contract\n @dev Emits NFTBridgeChanged event\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external onlyOwner override {\n _setNFTBridge(_bridgeNFT);\n }\n\n function _setNFTBridge(address _bridgeNFT) internal {\n require(_bridgeNFT != NULL_ADDRESS, \"Federation: Empty NFT bridge\");\n bridgeNFT = INFTBridge(_bridgeNFT);\n emit NFTBridgeChanged(_bridgeNFT);\n }\n\n function validateTransaction(bytes32 transactionId) internal view returns(bool) {\n uint transactionCount = getTransactionCount(transactionId);\n return transactionCount >= required && transactionCount >= members.length / 2 + 1;\n }\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) external onlyMember override {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return;\n\n if (votes[transactionId][_msgSender()])\n return;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n logIndex\n );\n\n if (validateTransaction(transactionId)) {\n processed[transactionId] = true;\n acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex,\n tokenType\n );\n\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n logIndex\n );\n return;\n }\n }\n\n function acceptTransfer(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) internal {\n if (tokenType == TokenType.NFT) {\n require(address(bridgeNFT) != NULL_ADDRESS, \"Federation: Empty NFTBridge\");\n bridgeNFT.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n return;\n }\n\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n }\n\n /**\n @notice Get the amount of approved votes for that transactionId\n @param transactionId The transaction hashed from getTransactionId function\n */\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n /**\n @notice Gets the hash of transaction from the following parameters encoded and keccaked\n @dev It encodes and applies keccak256 to the parameters received in the same order\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param amount Could be the amount or the tokenId\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @return The hash generated by the parameters.\n */\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32) {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner override\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner override\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view override returns (address[] memory) {\n return members;\n }\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @dev Emits the RequirementChange event\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n /**\n @notice It emits an HeartBeat like an health check\n @dev Emits HeartBeat event\n */\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember override {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface IFederation {\n enum TokenType{ COIN, NFT }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure returns (string memory);\n\n /**\n @notice Sets a new bridge contract\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external;\n\n /**\n @notice Sets a new NFT bridge contract\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external;\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) external;\n\n /**\n @notice Add a new member to the federation\n @param _newMember address of the new member\n */\n function addMember(address _newMember) external;\n\n /**\n @notice Remove a member of the federation\n @param _oldMember address of the member to be removed from federation\n */\n function removeMember(address _oldMember) external;\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view returns (address[] memory);\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external;\n\n /**\n @notice It emmits an HeartBeat like an healthy check\n */\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event NFTBridgeChanged(address bridgeNFT);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n}\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract MinterRole is Context {\n using Roles for Roles.Role;\n\n event MinterAdded(address indexed account);\n event MinterRemoved(address indexed account);\n\n Roles.Role private _minters;\n\n constructor () {\n _addMinter(_msgSender());\n }\n\n modifier onlyMinter() {\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\n _;\n }\n\n function isMinter(address account) public view returns (bool) {\n return _minters.has(account);\n }\n\n function addMinter(address account) public onlyMinter {\n _addMinter(account);\n }\n\n function renounceMinter() public {\n _removeMinter(_msgSender());\n }\n\n function _addMinter(address account) internal {\n _minters.add(account);\n emit MinterAdded(account);\n }\n\n function _removeMinter(address account) internal {\n _minters.remove(account);\n emit MinterRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20Mintable}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() override public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) override public view returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) override public returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) override public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) override public returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal {\n require(sender != address(0), \"ERC20: transfer from zero address\");\n require(recipient != address(0), \"ERC20: transfer to zero address\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: mint to zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: burn from zero address\");\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n *\n * This is internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal {\n require(owner != address(0), \"ERC20: approve from zero address\");\n require(spender != address(0), \"ERC20: approve to zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\n * from the caller's allowance.\n *\n * See {_burn} and {_approve}.\n */\n function _burnFrom(address account, uint256 amount) internal {\n _burn(account, amount);\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\n }\n}\n"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\nimport \"../interface/IERC677Receiver.sol\";\n\ncontract mockERC677Receiver is IERC677Receiver {\n event Success(address _sender, uint _value, bytes _data);\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\n emit Success(_sender, _value, _data);\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Optional functions from the ERC20 standard.\n */\nabstract contract ERC20Detailed is IERC20 {\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\n * these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\n _name = aName;\n _symbol = aSymbol;\n _decimals = theDecimals;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./Proxy.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n *\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\n * {TransparentUpgradeableProxy}.\n */\ncontract UpgradeableProxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _setImplementation(_logic);\n if(_data.length > 0) {\n Address.functionDelegateCall(_logic, _data);\n }\n }\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n bytes32 slot = _IMPLEMENTATION_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n impl := sload(slot)\n }\n }\n\n /**\n * @dev Upgrades the proxy to a new implementation.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal virtual {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\n\n bytes32 slot = _IMPLEMENTATION_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newImplementation)\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./UpgradeableProxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _setAdmin(admin_);\n }\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _admin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _admin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\n emit AdminChanged(_admin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external virtual ifAdmin {\n _upgradeTo(newImplementation);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\n _upgradeTo(newImplementation);\n Address.functionDelegateCall(newImplementation, data);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address adm) {\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n adm := sload(slot)\n }\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n bytes32 slot = _ADMIN_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newAdmin)\n }\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../ownership/Ownable.sol\";\nimport \"./TransparentUpgradeableProxy.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
+ },
+ "contracts/Federation/FederationV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../Bridge/IBridgeV2.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract FederationV1 is Ownable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridgeV2 public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n // solium-disable-next-line max-len\n event Voted(address indexed sender, bytes32 indexed transactionId, address originalTokenAddress, address receiver, uint256 amount, string symbol, bytes32 blockHash, bytes32 indexed transactionHash, uint32 logIndex, uint8 decimals, uint256 granularity);\n event Executed(bytes32 indexed transactionId);\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Caller not a Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n constructor(address[] memory _members, uint _required) validRequirement(_members.length, _required) {\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Members larger than max allowed\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n }\n\n function setBridge(address _bridge) external onlyOwner {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridgeV2(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity)\n external onlyMember returns(bool)\n {\n // solium-disable-next-line max-len\n bytes32 transactionId = getTransactionId(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n // solium-disable-next-line max-len\n emit Voted(_msgSender(), transactionId, originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bool acceptTransfer = bridge.acceptTransfer(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n require(acceptTransfer, \"Federation: Bridge acceptTransfer error\");\n emit Executed(transactionId);\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string memory symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity)\n public pure returns(bytes32)\n {\n // solium-disable-next-line max-len\n return keccak256(abi.encodePacked(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity));\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove last element\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n}"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\n\ncontract BridgeProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract FederationProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract MainToken is ERC20Detailed, ERC20 {\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\n ERC20Detailed(name, symbol, decimals)\n {\n _mint(msg.sender, totalSupply);\n }\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\n bool result = transfer(_to, _value);\n if (!result) return false;\n\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\n receiver.tokenFallback(msg.sender, _value, _data);\n\n // IMPORTANT: the ERC-677 specification does not say\n // anything about the use of the receiver contract's\n // tokenFallback method return value. Given\n // its return type matches with this method's return\n // type, returning it could be a possibility.\n // We here take the more conservative approach and\n // ignore the return value, returning true\n // to signal a succesful transfer despite tokenFallback's\n // return value -- fact being tokens are transferred\n // in any case.\n return true;\n }\n}\n\ninterface ERC677TransferReceiver {\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\n}"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract AlternativeERC20Detailed is ERC20 {\n string private _name;\n bytes32 private _symbol;\n uint256 private _decimals;\n\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\n {\n _name = aName;\n _symbol = aSymbol;\n _decimals = someDecimals;\n _mint(msg.sender, aTotalSupply);\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (bytes32) {\n return _symbol;\n }\n\n function decimals() public view returns (uint256) {\n return _decimals;\n }\n}"
+ },
+ "contracts/test/nftbridge/NFTERC721TestToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.6;\n\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\n\ncontract NFTERC721TestToken is ERC721 {\n\n string private _contractURI;\n\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\n\n function safeMint(address to, uint256 tokenId) public {\n _safeMint(to, tokenId);\n }\n\n function setBaseURI(string memory baseURI) public {\n _setBaseURI(baseURI);\n }\n\n function setContractURI(string memory contractURI_) public {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n function setTokenURI(uint256 tokenId, string memory _tokenURI) public {\n _setTokenURI(tokenId, _tokenURI);\n }\n\n}\n"
+ },
+ "contracts/nftbridge/SideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ISideNFTToken.sol\";\nimport \"../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\n\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\n address public minter;\n string private _contractURI;\n\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\n require(_minter != address(0), \"SideToken: Empty Minter\");\n minter = _minter;\n _setBaseURI(_baseURI);\n _setContractURI(contractURI_);\n }\n\n function _setContractURI(string memory contractURI_) internal {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(address account, uint256 tokenId) external onlyMinter override {\n _mint(account, tokenId);\n }\n}"
+ },
+ "contracts/nftbridge/SideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"./SideNFTToken.sol\";\n\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external onlyPrimary override returns(address) {\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\n return sideTokenAddress;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() {\n _registerInterface(\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\n );\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721Receiver.sol\";\n\n /**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers. \n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Burnable is ERC1155 {\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n}\n"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../lib/LibUtils.sol\";\n\ncontract LibUtilsHarness {\n\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\n return LibUtils.decimalsToGranularity(decimals);\n }\n\n function getDecimals(address tokenToUse) external view returns (uint8) {\n return LibUtils.getDecimals(tokenToUse);\n }\n\n function getGranularity(address tokenToUse) external view returns (uint256) {\n return LibUtils.getGranularity(tokenToUse);\n }\n\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\n return LibUtils.bytesToAddress(bys);\n }\n\n}\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/kovan/solcInputs/f27c8e19ddc2cd2a95162a1eabc0e272.json b/bridge/deployments/kovan/solcInputs/f27c8e19ddc2cd2a95162a1eabc0e272.json
new file mode 100644
index 000000000..3b6294411
--- /dev/null
+++ b/bridge/deployments/kovan/solcInputs/f27c8e19ddc2cd2a95162a1eabc0e272.json
@@ -0,0 +1,294 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/math/SafeMath.sol\";\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\n\nimport \"../interface/IAllowTokens.sol\";\n\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\n\tusing SafeMath for uint256;\n\n\taddress constant private NULL_ADDRESS = address(0);\n\tuint256 constant public MAX_TYPES = 250;\n\tmapping (address => TokenInfo) public allowedTokens;\n\tmapping (uint256 => Limits) public typeLimits;\n\tuint256 public smallAmountConfirmations;\n\tuint256 public mediumAmountConfirmations;\n\tuint256 public largeAmountConfirmations;\n\tstring[] public typeDescriptions;\n\n\tevent SetToken(address indexed _tokenAddress, uint256 _typeId);\n\tevent AllowedTokenRemoved(address indexed _tokenAddress);\n\tevent TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\n\tevent TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\n\tevent UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\n\tevent ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\n\n\tmodifier notNull(address _address) {\n\t\trequire(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\n\t\t_;\n\t}\n\n\tfunction initialize(\n\t\taddress _manager,\n\t\taddress _primary,\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations,\n\t\tTypeInfo[] memory typesInfo) public initializer {\n\t\tUpgradableOwnable.initialize(_manager);\n\t\tUpgradableSecondary.__Secondary_init(_primary);\n\t\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t\tfor(uint i = 0; i < typesInfo.length; i = i + 1) {\n\t\t\t_addTokenType(typesInfo[i].description, typesInfo[i].limits);\n\t\t}\n\t}\n\n\tfunction version() override external pure returns (string memory) {\n\t\treturn \"v1\";\n\t}\n\n\tfunction tokenInfo(address tokenAddress) public view returns(TokenInfo memory) {\n\t\treturn allowedTokens[tokenAddress];\n\t}\n\n\tfunction setTokenInfoByTokenAddress(address tokenAddress, TokenInfo memory info) public {\n\t\trequire(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n\t\tallowedTokens[tokenAddress] = info;\n\t}\n\n\tfunction getInfoAndLimits(\n\t\taddress tokenAddress\n\t) public view override returns (\n\t\tTokenInfo memory info,\n\t\tLimits memory limit\n\t) {\n\t\tinfo = tokenInfo(tokenAddress);\n\t\tlimit = typeLimits[info.typeId];\n\t\treturn (info, limit);\n\t}\n\n\tfunction calcMaxWithdraw(address token) public view override returns (uint256 maxWithdraw) {\n\t\t(TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\n\t\treturn _calcMaxWithdraw(info, limits);\n\t}\n\n\tfunction _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\n\t\t// solium-disable-next-line security/no-block-members\n\t\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n\t\t\tinfo.spentToday = 0;\n\t\t}\n\t\tif (limits.daily <= info.spentToday) {\n\t\t\treturn 0;\n\t\t}\n\t\tmaxWithdraw = limits.daily - info.spentToday;\n\t\tif (maxWithdraw > limits.max) {\n\t\t\tmaxWithdraw = limits.max;\n\t\t}\n\t\treturn maxWithdraw;\n\t}\n\n\tfunction updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\n\t\t(TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\n\t\trequire(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\n\t\trequire(amount >= limit.min, \"AllowTokens: Lower than limit\");\n\n\t\t// solium-disable-next-line security/no-block-members\n\t\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n\t\t\t// solium-disable-next-line security/no-block-members\n\t\t\tinfo.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n\t\t\tinfo.spentToday = 0;\n\t\t}\n\t\tuint maxWithdraw = _calcMaxWithdraw(info, limit);\n\t\trequire(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\n\t\tinfo.spentToday = info.spentToday.add(amount);\n\t\tsetTokenInfoByTokenAddress(token, info);\n\n\t\temit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\n\t}\n\n\tfunction _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\n\t\trequire(bytes(description).length > 0, \"AllowTokens: Empty description\");\n\t\tlen = typeDescriptions.length;\n\t\trequire(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\n\t\ttypeDescriptions.push(description);\n\t\t_setTypeLimits(len, limits);\n\t\temit TokenTypeAdded(len, description);\n\t\treturn len;\n\t}\n\n\tfunction addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\n\t\treturn _addTokenType(description, limits);\n\t}\n\n\tfunction _setTypeLimits(uint256 typeId, Limits memory limits) private {\n\t\trequire(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\n\t\trequire(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\n\t\trequire(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\n\t\trequire(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\n\t\trequire(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\n\t\ttypeLimits[typeId] = limits;\n\t\temit TypeLimitsChanged(typeId, limits);\n\t}\n\n\tfunction setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\n\t\t_setTypeLimits(typeId, limits);\n\t}\n\n\tfunction getTypesLimits() external view override returns(Limits[] memory limits) {\n\t\tlimits = new Limits[](typeDescriptions.length);\n\t\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\n\t\t\tlimits[i] = typeLimits[i];\n\t\t}\n\t\treturn limits;\n\t}\n\n\tfunction getTypeDescriptionsLength() external view override returns(uint256) {\n\t\treturn typeDescriptions.length;\n\t}\n\n\tfunction getTypeDescriptions() external view override returns(string[] memory descriptions) {\n\t\tdescriptions = new string[](typeDescriptions.length);\n\t\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\n\t\t\tdescriptions[i] = typeDescriptions[i];\n\t\t}\n\t\treturn descriptions;\n\t}\n\n\tfunction isTokenAllowed(address token) public view notNull(token) override returns (bool) {\n\t\treturn tokenInfo(token).allowed;\n\t}\n\n\tfunction setToken(address token, uint256 typeId) override public notNull(token) {\n\t\trequire(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n\t\trequire(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\n\t\tTokenInfo memory info = tokenInfo(token);\n\t\tinfo.allowed = true;\n\t\tinfo.typeId = typeId;\n\t\tsetTokenInfoByTokenAddress(token, info);\n\t\temit SetToken(token, typeId);\n\t}\n\n\tfunction setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\n\t\trequire(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\n\t\tfor(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\n\t\t\tsetToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\n\t\t}\n\t}\n\n\tfunction removeAllowedToken(address token) external notNull(token) onlyOwner {\n\t\tTokenInfo memory info = tokenInfo(token);\n\t\trequire(info.allowed, \"AllowTokens: Not Allowed\");\n\t\tinfo.allowed = false;\n\t\tsetTokenInfoByTokenAddress(token, info);\n\t\temit AllowedTokenRemoved(token);\n\t}\n\n\tfunction setConfirmations(\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations) external onlyOwner {\n\t\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t}\n\n\tfunction _setConfirmations(\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations) private {\n\t\trequire(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\n\t\trequire(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\n\t\tsmallAmountConfirmations = _smallAmountConfirmations;\n\t\tmediumAmountConfirmations = _mediumAmountConfirmations;\n\t\tlargeAmountConfirmations = _largeAmountConfirmations;\n\t\temit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t}\n\n\tfunction getConfirmations() external view override\n\t\treturns (\n\t\tuint256 smallAmount,\n\t\tuint256 mediumAmount,\n\t\tuint256 largeAmount\n\t) {\n\t\treturn (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\n\t}\n\n}\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @title Initializable\n *\n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(initializing || !initialized, \"Contract instance is already initialized\");\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\n * the owner.\n */\ncontract UpgradableOwnable is Initializable, Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function initialize(address sender) public initializer {\n _owner = sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * > Note: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\ncontract UpgradableSecondary is Initializable, Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n function __Secondary_init(address sender) public initializer {\n _primary = sender;\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(recipient);\n }\n\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IAllowTokens {\n\n\tstruct Limits {\n\t\tuint256 min;\n\t\tuint256 max;\n\t\tuint256 daily;\n\t\tuint256 mediumAmount;\n\t\tuint256 largeAmount;\n\t}\n\n\tstruct TokenInfo {\n\t\tbool allowed;\n\t\tuint256 typeId;\n\t\tuint256 spentToday;\n\t\tuint256 lastDay;\n\t}\n\n\tstruct TypeInfo {\n\t\tstring description;\n\t\tLimits limits;\n\t}\n\n\tstruct TokensAndType {\n\t\taddress token;\n\t\tuint256 typeId;\n\t}\n\n\tfunction version() external pure returns (string memory);\n\n\tfunction getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\n\n\tfunction calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\n\n\tfunction getTypesLimits() external view returns(Limits[] memory limits);\n\n\tfunction getTypeDescriptionsLength() external view returns(uint256);\n\n\tfunction getTypeDescriptions() external view returns(string[] memory descriptions);\n\n\tfunction setToken(address token, uint256 typeId) external;\n\n\tfunction getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\n\n\tfunction isTokenAllowed(address token) external view returns (bool);\n\n\tfunction updateTokenTransfer(address token, uint256 amount) external;\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n\n function _msgSender() internal view returns (address payable) {\n return payable(msg.sender);\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
+ },
+ "contracts/nftbridge/NFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC721/IERC721.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Metadata.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Enumerable.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Receiver.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./INFTBridge.sol\";\nimport \"./ISideNFTToken.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract NFTBridge is\n Initializable,\n INFTBridge,\n UpgradablePausable,\n UpgradableOwnable,\n ReentrancyGuard,\n IERC721Receiver {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address internal constant NULL_ADDRESS = address(0);\n bytes32 internal constant NULL_HASH = bytes32(0);\n IERC1820Registry internal constant ERC1820 =\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address payable internal federation;\n uint256 internal fixedFee;\n\n mapping(uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain;\n mapping(address => OriginalNft) public originalTokenBySideToken;\n mapping(uint256 => mapping(address => bool)) public isAddressFromCrossedOriginalTokenByChain; // uint256 => address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n\n IAllowTokens public allowTokens;\n ISideNFTTokenFactory public sideTokenFactory;\n bool public isUpgrading;\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\n event Upgrading(bool _isUpgrading);\n\n function initialize(\n address _manager,\n address payable _federation,\n address _allowTokens,\n address _sideTokenFactory\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\n federation = _federation;\n ERC1820.setInterfaceImplementer(\n address(this),\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\n address(this)\n );\n }\n\n function version() external pure override returns (string memory) {\n return \"v1\";\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _tokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n uint256\t_destinationChainId\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"NFTBridge: Not Federation\");\n checkChainId(_originChainId);\n shouldBeCurrentChainId(_destinationChainId);\n require(\n isAddressFromCrossedOriginalToken(_originChainId, _tokenAddress) ||\n getSideTokenByOriginalToken(_originChainId, _tokenAddress) != NULL_ADDRESS,\n \"NFTBridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"NFTBridge: Null To\");\n require(_from != NULL_ADDRESS, \"NFTBridge: Null From\");\n require(_blockHash != NULL_HASH, \"NFTBridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"NFTBridge: Null TxHash\");\n require(\n transactionDataHashes[_transactionHash] == bytes32(0),\n \"NFTBridge: Already accepted\"\n );\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _blockHash,\n _transactionHash,\n _logIndex,\n _originChainId,\n\t _destinationChainId\n );\n\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\n require(!claimed[_transactionDataHash], \"NFTBridge: Already claimed\");\n transactionDataHashes[_transactionHash] = _transactionDataHash;\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\n// senderAddresses[_transactionHash] = _from;\n\n emit AcceptedNFTCrossTransfer(\n _transactionHash,\n _tokenAddress,\n _to,\n _from,\n _tokenId,\n _blockHash,\n _logIndex,\n _originChainId,\n\t _destinationChainId\n );\n }\n\n function shouldBeCurrentChainId(uint256 chainId) internal view {\n require(chainId == block.chainid, \"NFTBridge: Not block.chainid\");\n }\n\n function getSideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\n return sideTokenByOriginalTokenByChain[chainId][originalToken];\n }\n\n function _setSideTokenByOriginalToken(uint256 chainId, address originalToken, address sideToken) internal {\n sideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\n }\n\n function getOriginalTokenBySideToken(address sideToken) public view returns(OriginalNft memory) {\n return originalTokenBySideToken[sideToken];\n }\n\n function _setOriginalTokenBySideToken(address sideToken, OriginalNft memory originalToken) internal {\n originalTokenBySideToken[sideToken] = originalToken;\n }\n\n function isAddressFromCrossedOriginalToken(uint256 chainId, address originalToken) public view returns(bool addressHasCrossed) {\n return isAddressFromCrossedOriginalTokenByChain[chainId][originalToken];\n }\n\n function _setAddressFromCrossedOriginalToken(uint256 chainId, address originalToken, bool addressHasCrossed) internal {\n isAddressFromCrossedOriginalTokenByChain[chainId][originalToken] = addressHasCrossed;\n }\n\n function createSideNFTToken(\n address _originalTokenAddress,\n string calldata _tokenSymbol,\n string calldata _tokenName,\n string calldata _baseURI,\n string calldata _contractURI,\n uint256 originChainId\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"NFTBridge: Null original token address\");\n\n require(getSideTokenByOriginalToken(originChainId, _originalTokenAddress) == NULL_ADDRESS, \"NFTBridge: Side token already exists\");\n\n // Create side token\n address sideTokenAddress = sideTokenFactory.createSideNFTToken(_tokenName, _tokenSymbol, _baseURI, _contractURI);\n\n _setSideTokenByOriginalToken(originChainId, _originalTokenAddress, sideTokenAddress);\n\n OriginalNft memory originalNft;\n originalNft.originChainId = originChainId;\n originalNft.nftAddress = _originalTokenAddress;\n _setOriginalTokenBySideToken(sideTokenAddress, originalNft);\n\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, _tokenSymbol, originChainId);\n }\n\n function checkChainId(uint256 chainId) internal pure {\n require(chainId > 0, \"NFTBridge: ChainId is 0\");\n }\n\n function claim(NFTClaimData calldata _claimData) external override {\n _claim(_claimData, _claimData.to);\n }\n\n function claimFallback(NFTClaimData calldata _claimData) external override {\n require(_msgSender() == _claimData.from, \"NFTBridge: invalid sender\");\n _claim(_claimData, _msgSender());\n }\n\n function _claim(\n NFTClaimData calldata _claimData,\n address payable _receiver\n ) internal {\n address tokenAddress = _claimData.tokenAddress;\n uint256 tokenId = _claimData.tokenId;\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.from,\n tokenId,\n tokenAddress,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex,\n _claimData.originChainId,\n block.chainid\n );\n\n\n require(\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\n \"NFTBridge: Wrong txDataHash\"\n );\n require(!claimed[transactionDataHash], \"NFTBridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (isAddressFromCrossedOriginalToken(_claimData.originChainId, tokenAddress)) {\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\n } else {\n address sideTokenAddress = getSideTokenByOriginalToken(_claimData.originChainId, tokenAddress);\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\n }\n\n emit ClaimedNFTToken(\n _claimData.transactionHash,\n tokenAddress,\n _claimData.to,\n _claimData.from,\n _claimData.tokenId,\n _claimData.blockHash,\n _claimData.logIndex,\n _receiver,\n _claimData.originChainId,\n block.chainid\n );\n }\n\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\"creator()\"));\n if (success) {\n return abi.decode(data, (address));\n }\n\n return IERC721(tokenAddress).ownerOf(tokenId);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId,\n uint256 destinationChainId\n ) public payable override {\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\n address payable sender = _msgSender();\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\n\n crossTokens(tokenAddress, to, tokenCreator, tokenId, destinationChainId, \"\");\n\n if (fixedFee == 0) {\n return;\n }\n uint256 msgValue = msg.value;\n require(msgValue >= fixedFee, \"NFTBridge: value is smaller than fixed fee\");\n\n // Send the payment to the MultiSig of the Federation\n federation.transfer(fixedFee);\n\n if (msgValue > fixedFee) { // refund of unused value\n sender.transfer(msgValue.sub(fixedFee));\n }\n }\n\n function crossTokens(\n address tokenAddress,\n address to,\n address tokenCreator,\n uint256 tokenId,\n uint256 destinationChainId,\n bytes memory userData\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\n require(block.chainid != destinationChainId, \"NFTBridge: destination chain id equal current chain id\");\n _setAddressFromCrossedOriginalToken(destinationChainId, tokenAddress, true);\n\n string memory tokenURI = IERC721Metadata(tokenAddress).tokenURI(tokenId);\n\n OriginalNft memory originalToken = getOriginalTokenBySideToken(tokenAddress);\n address originalTokenAddress = tokenAddress;\n if (originalToken.nftAddress != NULL_ADDRESS) {\n ERC721Burnable(tokenAddress).burn(tokenId);\n originalTokenAddress = originalToken.nftAddress;\n }\n\n uint256 totalSupply = IERC721Enumerable(tokenAddress).totalSupply();\n emit Cross(\n originalTokenAddress,\n to,\n destinationChainId,\n _msgSender(),\n block.chainid,\n tokenCreator,\n totalSupply,\n tokenId,\n tokenURI,\n userData\n );\n }\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n ) public pure override returns (bytes32) {\n return keccak256(\n abi.encodePacked(\n _blockHash,\n _transactionHash,\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _logIndex,\n _originChainId,\n _destinationChainId\n )\n );\n }\n\n function setFixedFee(uint256 amount) external onlyOwner {\n fixedFee = amount;\n emit FixedFeeNFTChanged(fixedFee);\n }\n\n function getFixedFee() external view override returns (uint256) {\n return fixedFee;\n }\n\n function changeFederation(address payable newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"NFTBridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"NFTBridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns (address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\n require(\n newSideNFTTokenFactory != NULL_ADDRESS,\n \"NFTBridge: empty SideTokenFactory\"\n );\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionDataHashes[transactionHash]];\n }\n\n /**\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\n/**\n * @title Helps contracts guard against reentrancy attacks.\n * @author Remco Bloemen , Eenae \n * @dev If you mark a function `nonReentrant`, you should also\n * mark it `external`.\n */\ncontract ReentrancyGuard is Initializable {\n /// @dev counter to allow mutex lock with only one SSTORE operation\n uint256 private _guardCounter;\n\n function initialize() public initializer {\n // The counter starts at one to prevent changing it from zero to a non-zero\n // value, which is a more expensive operation.\n _guardCounter = 1;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _guardCounter += 1;\n uint256 localCounter = _guardCounter;\n _;\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\n }\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\nimport \"../access/roles/UpgradablePauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n function __Pausable_init(address sender) public initializer {\n UpgradablePauserRole.__PauserRol_init(sender);\n\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as `account`'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `_account`.\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `_implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\n\n /**\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `_account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {ERC20Detailed}.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeERC20: low-level call failed\");\n\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n */\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./ERC721.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721Burnable is Context, ERC721 {\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n _burn(tokenId);\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\nlibrary LibEIP712 {\n\n // Hash of the EIP712 Domain Separator Schema\n // keccak256(abi.encodePacked(\n // \"EIP712Domain(\",\n // \"string name,\",\n // \"string version,\",\n // \"uint256 chainId,\",\n // \"address verifyingContract\",\n // \")\"\n // ))\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n /// @dev Calculates a EIP712 domain separator.\n /// @param name The EIP712 domain name.\n /// @param version The EIP712 domain version.\n /// @param verifyingContract The EIP712 verifying contract.\n /// @return result EIP712 domain separator.\n function hashEIP712Domain(\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n // keccak256(bytes(name)),\n // keccak256(bytes(version)),\n // chainId,\n // uint256(verifyingContract)\n // ))\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Calculate hashes of dynamic data\n let nameHash := keccak256(add(name, 32), mload(name))\n let versionHash := keccak256(add(version, 32), mload(version))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n // Store params in memory\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), nameHash)\n mstore(add(memPtr, 64), versionHash)\n mstore(add(memPtr, 96), chainId)\n mstore(add(memPtr, 128), verifyingContract)\n\n // Compute hash\n result := keccak256(memPtr, 160)\n }\n return result;\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\n /// with getDomainHash().\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to the given EIP712 Domain.\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n internal\n pure\n returns (bytes32 result)\n {\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct\n // ));\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nlibrary LibUtils {\n\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\n return uint256(10)**(18-decimals);\n }\n\n function getDecimals(address tokenToUse) internal view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"LibUtils: No decimals\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n return uint8(abi.decode(data, (uint256)));\n }\n\n function getGranularity(address tokenToUse) internal view returns (uint256) {\n //support granularity if ERC777\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\n require(success, \"LibUtils: No granularity\");\n\n return abi.decode(data, (uint256));\n }\n\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n addr := mload(add(bys,20))\n }\n }\n\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\n require(_bytes.length >= _start + 20, \"LibUtils: toAddress_outOfBounds\");\n address tempAddress;\n\n assembly {\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n }\n\n return tempAddress;\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\n require(_bytes.length >= _start + 16, \"LibUtils: toUint128_outOfBounds\");\n uint128 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x10), _start))\n }\n\n return tempUint;\n }\n\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\n\t\trequire(_bytes.length >= _start + 32, \"LibUtils: toUint256_outOfBounds\");\n\t\tuint256 tempUint;\n\n // solium-disable-next-line security/no-inline-assembly\n\t\tassembly {\n\t\t\ttempUint := mload(add(add(_bytes, 0x20), _start))\n\t\t}\n\n\t\treturn tempUint;\n\t}\n}\n"
+ },
+ "contracts/nftbridge/INFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface INFTBridge {\n\n struct NFTClaimData {\n address payable to;\n address from;\n uint256 tokenId;\n address tokenAddress;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n uint256 originChainId;\n }\n\n\tstruct OriginalNft {\n\t\taddress nftAddress;\n\t\tuint256 originChainId;\n\t}\n\n function version() external pure returns (string memory);\n\n function getFixedFee() external view returns (uint256);\n\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId,\n uint256 destinationChainId\n ) external payable;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\n */\n function claim(NFTClaimData calldata _claimData) external;\n\n function claimFallback(NFTClaimData calldata _claimData) external;\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\t\tuint256\t_destinationChainId\n ) external returns (bytes32);\n\n event Cross(\n address indexed _originalTokenAddress,\n address indexed _to,\n uint256 indexed _destinationChainId,\n address _from,\n uint256 _originChainId,\n address _tokenCreator,\n uint256 _totalSupply,\n uint256 _tokenId,\n string _tokenURI,\n bytes _userData\n );\n\n event NewSideNFTToken(\n address indexed _newSideNFTTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 originChainId\n );\n event AcceptedNFTCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n );\n event FixedFeeNFTChanged(uint256 _amount);\n event ClaimedNFTToken(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _receiver,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n );\n}\n"
+ },
+ "contracts/nftbridge/ISideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideNFTToken {\n function mint(address account, uint256 tokenId) external;\n}"
+ },
+ "contracts/nftbridge/ISideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideNFTTokenFactory {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external returns(address);\n\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IWrapped {\n function balanceOf(address) external returns(uint);\n\n function deposit() external payable;\n\n function withdraw(uint wad) external;\n\n function totalSupply() external view returns (uint);\n\n function approve(address guy, uint wad) external returns (bool);\n\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad)\n external\n returns (bool);\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../Initializable.sol\";\n\nimport \"../../../GSN/Context.sol\";\nimport \"../../../access/Roles.sol\";\n\ncontract UpgradablePauserRole is Initializable, Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n function __PauserRol_init(address sender) public initializer {\n if (!isPauser(sender)) {\n _addPauser(sender);\n }\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @title Roles\n * @dev Library for managing addresses assigned to a Role.\n */\nlibrary Roles {\n struct Role {\n mapping (address => bool) bearer;\n }\n\n /**\n * @dev Give an account access to this role.\n */\n function add(Role storage role, address account) internal {\n require(!has(role, account), \"Roles: account already has role\");\n role.bearer[account] = true;\n }\n\n /**\n * @dev Remove an account's access to this role.\n */\n function remove(Role storage role, address account) internal {\n require(has(role, account), \"Roles: account doesn't have role\");\n role.bearer[account] = false;\n }\n\n /**\n * @dev Check if an account has this role.\n * @return bool\n */\n function has(Role storage role, address account) internal view returns (bool) {\n require(account != address(0), \"Roles: account is the zero address\");\n return role.bearer[account];\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _tokenOwners.contains(tokenId);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(tokenId);\n\n emit Transfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n}\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n}\n"
+ },
+ "contracts/test/nftbridge/NFTInheritedBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport \"../../nftbridge/NFTBridge.sol\";\n\ncontract NFTInheritedBridge is NFTBridge {\n function checkChainIdExposed(uint256 chainId) public pure {\n return checkChainId(chainId);\n } \n\n function shouldBeCurrentChainIdExposed(uint256 chainId) public view {\n return shouldBeCurrentChainId(chainId);\n } \n}"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract WRBTC is IWrapped {\n string public name = \"Wrapped RBTC\";\n string public symbol = \"WRBTC\";\n uint8 public decimals = 18;\n\n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n event Deposit(address indexed dst, uint wad);\n event Withdrawal(address indexed src, uint wad);\n\n mapping (address => uint) override public balanceOf;\n mapping (address => mapping (address => uint)) public allowance;\n\n receive () external payable {\n deposit();\n }\n function deposit() override public payable {\n balanceOf[msg.sender] += msg.value;\n emit Deposit(msg.sender, msg.value);\n }\n function withdraw(uint wad) override public {\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\n balanceOf[msg.sender] -= wad;\n (bool success, ) = msg.sender.call{value:wad, gas:23000}(\"\");\n require(success, \"WRBTC: transfer fail\");\n emit Withdrawal(msg.sender, wad);\n }\n\n function totalSupply() override public view returns (uint) {\n return address(this).balance;\n }\n\n function approve(address guy, uint wad) override public returns (bool) {\n allowance[msg.sender][guy] = wad;\n emit Approval(msg.sender, guy, wad);\n return true;\n }\n\n function transfer(address dst, uint wad) override public returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad)\n override public\n returns (bool)\n {\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\n\n if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\n allowance[src][msg.sender] -= wad;\n }\n\n balanceOf[src] -= wad;\n balanceOf[dst] += wad;\n\n emit Transfer(src, dst, wad);\n\n return true;\n }\n}"
+ },
+ "contracts/Bridge/BridgeV3.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// import \"hardhat/console.sol\";\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./IBridgeV3.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n\ncontract BridgeV3 is Initializable, IBridgeV3, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant internal NULL_ADDRESS = address(0);\n bytes32 constant internal NULL_HASH = bytes32(0);\n IERC1820Registry constant internal erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address internal federation;\n uint256 internal feePercentage;\n string public symbolPrefix;\n bytes32 public DOMAIN_SEPARATOR; // replaces uint256 internal _depprecatedLastDay;\n uint256 internal _deprecatedSpentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n uint256 constant public feePercentageDivider = 10000; // Porcentage with up to 2 decimals\n //Bridge_v3 variables\n bytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\");\n IWrapped public wrappedCurrency;\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n // keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\n mapping(address => uint) public nonces;\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool _isUpgrading);\n event WrappedCurrencyChanged(address _wrappedCurrency);\n\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n federation = _federation;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n initDomainSeparator();\n }\n\n receive () external payable {\n // The fallback function is needed to use WRBTC\n require(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n }\n\n function version() override external pure returns (string memory) {\n return \"v3\";\n }\n\n function initDomainSeparator() public {\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n DOMAIN_SEPARATOR = LibEIP712.hashEIP712Domain(\n \"RSK Token Bridge\",\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"Bridge: Not Federation\");\n require(knownTokens[_originalTokenAddress] ||\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\n \"Bridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"Bridge: Null To\");\n require(_amount > 0, \"Bridge: Amount 0\");\n require(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _amount,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed also has the previously processed using the older bridge version\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n require(!claimed[_transactionDataHash], \"Bridge: Already claimed\");\n\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\n senderAddresses[_transactionHash] = _from;\n\n emit AcceptedCrossTransfer(\n _transactionHash,\n _originalTokenAddress,\n _to,\n _from,\n _amount,\n _blockHash,\n _logIndex\n );\n }\n\n\n function createSideToken(\n uint256 _typeId,\n address _originalTokenAddress,\n uint8 _originalTokenDecimals,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n address sideToken = mappedTokens[_originalTokenAddress];\n require(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\n\n mappedTokens[_originalTokenAddress] = sideToken;\n originalTokens[sideToken] = _originalTokenAddress;\n allowTokens.setToken(sideToken, _typeId);\n\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\n }\n\n function claim(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function claimFallback(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n receivedAmount = _claim(\n _claimData,\n _msgSender(),\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function getDigest(\n ClaimData memory _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline\n ) internal returns (bytes32) {\n return LibEIP712.hashEIP712Message(\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n CLAIM_TYPEHASH,\n _claimData.to,\n _claimData.amount,\n _claimData.transactionHash,\n _relayer,\n _fee,\n nonces[_claimData.to]++,\n _deadline\n )\n )\n );\n }\n\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external override returns (uint256 receivedAmount) {\n require(_deadline >= block.timestamp, \"Bridge: EXPIRED\");\n\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claim(\n ClaimData calldata _claimData,\n address payable _reciever,\n address payable _relayer,\n uint256 _fee\n ) internal nonReentrant returns (uint256 receivedAmount) {\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n require(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.amount,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n require(!claimed[transactionDataHash], \"Bridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (knownTokens[originalTokenAddress]) {\n receivedAmount =_claimCrossBackToToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n } else {\n receivedAmount =_claimCrossToSideToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n }\n emit Claimed(\n _claimData.transactionHash,\n originalTokenAddress,\n _claimData.to,\n senderAddresses[_claimData.transactionHash],\n _claimData.amount,\n _claimData.blockHash,\n _claimData.logIndex,\n _reciever,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claimCrossToSideToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n address sideToken = mappedTokens[_originalTokenAddress];\n uint256 granularity = IERC777(sideToken).granularity();\n uint256 formattedAmount = _amount.mul(granularity);\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n ISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n if(_fee > 0) {\n ISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n }\n return receivedAmount;\n }\n\n function _claimCrossBackToToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n //As side tokens are ERC777 they will always have 18 decimals\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n if(address(wrappedCurrency) == _originalTokenAddress) {\n wrappedCurrency.withdraw(formattedAmount);\n _receiver.transfer(receivedAmount);\n if(_fee > 0) {\n _relayer.transfer(_fee);\n }\n } else {\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n if(_fee > 0) {\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n }\n }\n return receivedAmount;\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\n address sender = _msgSender();\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, to, amount, \"\");\n }\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) override external payable {\n address sender = _msgSender();\n require(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n wrappedCurrency.deposit{ value: msg.value }();\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \"\");\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external override(IBridgeV3, IERC777Recipient){\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to this address\");\n address tokenToUse = _msgSender();\n require(erc1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n require(userData.length != 0 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\n crossTokens(tokenToUse, from, receiver, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\n internal whenNotUpgrading whenNotPaused nonReentrant {\n knownTokens[tokenToUse] = true;\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n uint256 amountMinusFees = amount.sub(fee);\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n // We consider the amount before fees converted to 18 decimals to check the limits\n // updateTokenTransfer revert if token not allowed\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n address originalTokenAddress = tokenToUse;\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\n //Side Token Crossing\n originalTokenAddress = originalTokens[tokenToUse];\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\n uint256 modulo = amountMinusFees.mod(granularity);\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n }\n\n emit Cross(\n originalTokenAddress,\n from,\n to,\n amountMinusFees,\n userData\n );\n\n if (fee > 0) {\n //Send the payment to the MultiSig of the Federation\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n }\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n )\n public pure override returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n }\n\n function setFeePercentage(uint amount) external onlyOwner {\n require(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() external view override returns(uint) {\n return feePercentage;\n }\n\n function changeFederation(address newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n require(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n wrappedCurrency = IWrapped(_wrappedCurrency);\n emit WrappedCurrencyChanged(_wrappedCurrency);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionsDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionsDataHashes[transactionHash]];\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an `IERC777` token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See `IERC1820Registry` and\n * `ERC1820Implementer`.\n */\ninterface IERC777 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See `operatorSend` and `operatorBurn`.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor`.\n *\n * Emits an `AuthorizedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor` and `defaultOperators`.\n *\n * Emits a `RevokedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if `authorizeOperator` was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * `revokeOperator`, in which case `isOperatorFor` will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n\n function decimals() external returns (uint8);\n\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n}\n"
+ },
+ "contracts/Bridge/IBridgeV3.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IBridgeV3 {\n\n struct ClaimData {\n address payable to;\n uint256 amount;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) external payable;\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n */\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external returns (uint256 receivedAmount);\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns(bytes32);\n\n event Cross(\n address indexed _tokenAddress,\n address indexed _from,\n address indexed _to,\n uint256 _amount,\n bytes _userData\n );\n event NewSideToken(\n address indexed _newSideTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 _granularity\n );\n event AcceptedCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FeePercentageChanged(uint256 _amount);\n event Claimed(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _reciever,\n address _relayer,\n uint256 _fee\n );\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideToken {\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideTokenFactory {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\n\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../SideToken/SideToken.sol\";\n\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\n external onlyPrimary override returns(address) {\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\n emit SideTokenCreated(sideToken, symbol, granularity);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\nabstract contract Secondary is Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n constructor () {\n _primary = _msgSender();\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(_primary);\n }\n}\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\nimport \"../interface/IERC677Receiver.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../lib/LibEIP712.sol\";\n\ncontract SideToken is ISideToken, ERC777 {\n using SafeMath for uint256;\n\n address public minter;\n uint256 private _granularity;\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n bytes32 public domainSeparator;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n // ERC677 Transfer Event\n event Transfer(address,address,uint256,bytes);\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\n minter = _minterAddr;\n _granularity = _newGranularity;\n\n domainSeparator = LibEIP712.hashEIP712Domain(\n name(),\n \"1\",\n block.chainid,\n address(this)\n );\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter override\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n /**\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\n * @param recipient The address to transfer to.\n * @param amount The amount to be transferred.\n * @param data The extra data to be passed to the receiving contract.\n */\n function transferAndCall(address recipient, uint amount, bytes calldata data)\n external returns (bool success)\n {\n address from = _msgSender();\n\n _send(from, from, recipient, amount, data, \"\", false);\n emit Transfer(from, recipient, amount, data);\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\n return true;\n }\n\n function granularity() public view override returns (uint256) {\n return _granularity;\n }\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\n bytes32 digest = LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../../token/ERC20/IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\n // See https://github.com/ethereum/solidity/issues/4024.\n\n // keccak256(\"ERC777TokensSender\")\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\n\n // keccak256(\"ERC777TokensRecipient\")\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping (address => mapping (address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(\n string memory aName,\n string memory aSymbol,\n address[] memory theDefaultOperators\n ) {\n _name = aName;\n _symbol = aSymbol;\n\n _defaultOperatorsArray = theDefaultOperators;\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\n _defaultOperators[_defaultOperatorsArray[i]] = true;\n }\n\n // register interfaces\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view override(IERC777) returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view override(IERC777) returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20Detailed-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override(IERC777) returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n\n address from = _msgSender();\n\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\n\n _move(from, from, recipient, amount, \"\", \"\");\n\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(\n address operator,\n address tokenHolder\n ) public view override(IERC777) returns (bool) {\n return operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) external override(IERC777) {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) external override(IERC777) {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n )\n external override(IERC777)\n {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {Transfer} events.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\n external override(IERC777) {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\n _burn(_msgSender(), account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender)\n public view override(IERC20) returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {Transfer} and {Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount)\n external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n require(holder != address(0), \"ERC777: transfer from zero address\");\n\n address spender = _msgSender();\n\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\n\n _move(spender, holder, recipient, amount, \"\", \"\");\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\n\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address operator,\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n require(account != address(0), \"ERC777: mint to zero address\");\n\n // Update state variables\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n internal\n {\n require(from != address(0), \"ERC777: send from zero address\");\n require(to != address(0), \"ERC777: send to zero address\");\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param operator address operator requesting the operation\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(\n address operator,\n address from,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n )\n internal\n {\n require(from != address(0), \"ERC777: burn from zero address\");\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n // Update state variables\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\n _balances[to] = _balances[to].add(amount);\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n function _approve(address holder, address spender, uint256 value) internal {\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\n // currently unnecessary.\n //require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n private\n {\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n}\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * `IERC777` Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an `IERC777` token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// import \"hardhat/console.sol\";\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n\tusing SafeMath for uint256;\n\tusing SafeERC20 for IERC20;\n\tusing Address for address;\n\n\taddress constant internal NULL_ADDRESS = address(0);\n\tbytes32 constant internal NULL_HASH = bytes32(0);\n\tIERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n\taddress internal federation;\n\tuint256 internal feePercentage;\n\tstring public deprecatedSymbolPrefix;\n\t// domainSeparator replaces uint256 internal _depprecatedLastDay;\n\tbytes32 public domainSeparator;\n\tuint256 internal _deprecatedSpentToday;\n\n\tmapping (address => address) public deprecatedMappedTokens; // OriginalToken => SideToken\n\tmapping (address => address) public deprecatedOriginalTokens; // SideToken => OriginalToken\n\tmapping (address => bool) public deprecatedKnownTokens; // OriginalToken => true\n\n\t// claimed can use the same of bytes32\n\tmapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n\n\tIAllowTokens public allowTokens;\n\tISideTokenFactory public sideTokenFactory;\n\t//Bridge_v1 variables\n\tbool public isUpgrading;\n\t// Percentage with up to 2 decimals\n\tuint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\n\t//Bridge_v2 variables\n\tbytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\n\tIWrapped public wrappedCurrency;\n\tmapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n\tmapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n\tmapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n\t// keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,uint256 originChainId,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n\tbytes32 public constant CLAIM_TYPEHASH = 0xaf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c;\n\tmapping(address => uint) public nonces;\n\n\t//Bridge_v3 variables multichain\n\tmapping (uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain; // chainId => OriginalToken Address => SideToken Address\n\tmapping (address => OriginalToken) public originalTokenBySideToken; // SideTokenAddress => struct {}\n\tmapping (uint256 => mapping(address => bool)) public knownTokenByChain; // chainId => OriginalToken Address => Know\n\n\tevent AllowTokensChanged(address _newAllowTokens);\n\tevent FederationChanged(address _newFederation);\n\tevent SideTokenFactoryChanged(address _newSideTokenFactory);\n\tevent Upgrading(bool _isUpgrading);\n\tevent WrappedCurrencyChanged(address _wrappedCurrency);\n\n\tfunction initialize(\n\t\taddress _manager,\n\t\taddress _federation,\n\t\taddress _allowTokens,\n\t\taddress _sideTokenFactory\n\t) public initializer {\n\t\tUpgradableOwnable.initialize(_manager);\n\t\tUpgradablePausable.__Pausable_init(_manager);\n\t\tallowTokens = IAllowTokens(_allowTokens);\n\t\tsideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n\t\tfederation = _federation;\n\t\t//keccak256(\"ERC777TokensRecipient\")\n\t\tERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n\t\tinitDomainSeparator();\n\t}\n\n\treceive () external payable {\n\t\t// The fallback function is needed to use WRBTC\n\t\trequire(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n\t}\n\n\tfunction version() override external pure returns (string memory) {\n\t\treturn \"v4\";\n\t}\n\n\tfunction initDomainSeparator() public {\n\t\tdomainSeparator = LibEIP712.hashEIP712Domain(\n\t\t\t\"RSK Token Bridge\",\n\t\t\t\"1\",\n\t\t\tblock.chainid,\n\t\t\taddress(this)\n\t\t);\n\t}\n\n\tmodifier whenNotUpgrading() {\n\t\trequire(!isUpgrading, \"Bridge: Upgrading\");\n\t\t_;\n\t}\n\n\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\n\t\trequire(chainId == block.chainid, \"Bridge: Not block.chainid\");\n\t}\n\n\tfunction sideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\n\t\taddress sideTokenAddr = sideTokenByOriginalTokenByChain[chainId][originalToken];\n\n\t\tif (sideTokenAddr != NULL_ADDRESS) {\n\t\t\treturn sideTokenAddr;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\treturn deprecatedMappedTokens[originalToken];\n\t}\n\n\tfunction setSideTokenByOriginalAddressByChain(uint256 chainId, address originalToken, address sideToken) public onlyOwner {\n\t\tsideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\n\t}\n\n\tfunction getOriginalTokenBySideToken(address sideToken) public view returns(OriginalToken memory originalToken) {\n\t\toriginalToken = originalTokenBySideToken[sideToken];\n\t\tif (originalToken.tokenAddress != NULL_ADDRESS) {\n\t\t\treturn originalToken;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\toriginalToken.originChainId = 1; // ethereum main chain id\n\t\toriginalToken.tokenAddress = deprecatedOriginalTokens[sideToken];\n\t\treturn originalToken;\n\t}\n\n\tfunction setOriginalTokenBySideTokenByChain(address sideToken, OriginalToken memory originalToken) public onlyOwner {\n\t\toriginalTokenBySideToken[sideToken] = originalToken;\n\t}\n\n\tfunction knownToken(uint256 chainId, address originalToken) public view returns(bool) {\n\t\tbool knowToken = knownTokenByChain[chainId][originalToken];\n\t\tif (knowToken) {\n\t\t\treturn knowToken;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\treturn deprecatedKnownTokens[originalToken];\n\t}\n\n\tfunction _setKnownTokenByChain(uint256 chainId, address originalToken, bool knownTokenValue) internal {\n\t\tknownTokenByChain[chainId][originalToken] = knownTokenValue;\n\t}\n\n\tfunction acceptTransfer(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _from,\n\t\taddress payable _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) external whenNotPaused nonReentrant override {\n\t\trequire(_msgSender() == federation, \"Bridge: Not Federation\");\n\t\tcheckChainId(_originChainId);\n\t\tshouldBeCurrentChainId(_destinationChainId);\n\t\trequire(knownToken(_originChainId, _originalTokenAddress) ||\n\t\t\tsideTokenByOriginalToken(_originChainId, _originalTokenAddress) != NULL_ADDRESS,\n\t\t\t\"Bridge: Unknown token\"\n\t\t);\n\t\trequire(_to != NULL_ADDRESS, \"Bridge: Null To\");\n\t\trequire(_amount > 0, \"Bridge: Amount 0\");\n\t\trequire(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n\t\trequire(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n\t\trequire(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n\t\tbytes32 _transactionDataHash = getTransactionDataHash(\n\t\t\t_to,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_transactionHash,\n\t\t\t_logIndex\n\t\t);\n\n\t\tbytes32 _transactionDataHashMultichain = getTransactionDataHash(\n\t\t\t_to,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_transactionHash,\n\t\t\t_logIndex,\n\t\t\t_originChainId,\n\t\t\t_destinationChainId\n\t\t);\n\t\t// Do not remove, claimed also has the previously processed using the older bridge version\n\t\t// https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n\t\trequire(!isClaimed(_transactionDataHash, _transactionDataHashMultichain), \"Bridge: Already claimed\");\n\n\t\ttransactionsDataHashes[_transactionHash] = _transactionDataHashMultichain;\n\t\toriginalTokenAddresses[_transactionHash] = _originalTokenAddress;\n\t\tsenderAddresses[_transactionHash] = _from;\n\n\t\temit AcceptedCrossTransfer(\n\t\t\t_transactionHash,\n\t\t\t_originalTokenAddress,\n\t\t\t_to,\n\t\t\t_from,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_logIndex,\n\t\t\t_originChainId,\n\t\t\t_destinationChainId\n\t\t);\n\t}\n\n\tfunction checkChainId(uint256 chainId) internal pure {\n\t\trequire(chainId > 0, \"Bridge: ChainId is 0\");\n\t}\n\n\tfunction createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _tokenSymbol,\n\t\tstring calldata _tokenName,\n\t\tuint256 _originChainId\n\t) external onlyOwner override {\n\t\trequire(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n\t\tcheckChainId(_originChainId);\n\t\taddress sideToken = sideTokenByOriginalToken(_originChainId, _originalTokenAddress);\n\t\trequire(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n\n\t\tuint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n\n\t\t// Create side token\n\t\tsideToken = sideTokenFactory.createSideToken(_tokenName, _tokenSymbol, granularity);\n\n\t\tsetSideTokenByOriginalAddressByChain(_originChainId, _originalTokenAddress, sideToken);\n\n\t\tOriginalToken memory originalToken;\n\t\toriginalToken.originChainId = _originChainId;\n\t\toriginalToken.tokenAddress = _originalTokenAddress;\n\t\tsetOriginalTokenBySideTokenByChain(sideToken, originalToken);\n\t\tallowTokens.setToken(sideToken, _typeId);\n\n\t\temit NewSideToken(sideToken, _originalTokenAddress, _tokenSymbol, granularity, _originChainId);\n\t}\n\n\tfunction claim(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\n\t\treceivedAmount = _claim(\n\t\t\t_claimData,\n\t\t\t_claimData.to,\n\t\t\tpayable(address(0)),\n\t\t\t0\n\t\t);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction claimFallback(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\n\t\trequire(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n\t\treceivedAmount = _claim(\n\t\t\t_claimData,\n\t\t\t_msgSender(),\n\t\t\tpayable(address(0)),\n\t\t\t0\n\t\t);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction getDigest(\n\t\tClaimData memory _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline\n\t) internal returns (bytes32) {\n\t\treturn LibEIP712.hashEIP712Message(\n\t\t\tdomainSeparator,\n\t\t\tkeccak256(\n\t\t\t\tabi.encode(\n\t\t\t\t\tCLAIM_TYPEHASH,\n\t\t\t\t\t_claimData.to,\n\t\t\t\t\t_claimData.amount,\n\t\t\t\t\t_claimData.transactionHash,\n\t\t\t\t\t_claimData.originChainId,\n\t\t\t\t\t_relayer,\n\t\t\t\t\t_fee,\n\t\t\t\t\tnonces[_claimData.to]++,\n\t\t\t\t\t_deadline\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t}\n\n\t// Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n\tfunction claimGasless(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline,\n\t\tuint8 _v,\n\t\tbytes32 _r,\n\t\tbytes32 _s\n\t) external override returns (uint256 receivedAmount) {\n\t\trequire(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\n\n\t\tbytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n\t\taddress recoveredAddress = ecrecover(digest, _v, _r, _s);\n\t\trequire(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n\t\treturn _claim(\n\t\t\t_claimData,\n\t\t\t_claimData.to,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\t}\n\n\tfunction isClaimed(bytes32 transactionDataHash, bytes32 transactionDataHashMultichain) public view returns(bool) {\n\t\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\n\t}\n\n\tfunction isClaimed(ClaimData calldata _claimData, bytes32 transactionDataHashMultichain) public view returns(bool) {\n\t\tbytes32 transactionDataHash = getTransactionDataHash(\n\t\t\t_claimData.to,\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.transactionHash,\n\t\t\t_claimData.logIndex\n\t\t);\n\n\t\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\n\t}\n\n\tfunction _claim(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _reciever,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal nonReentrant returns (uint256 receivedAmount) {\n\t\taddress originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n\t\trequire(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n\t\tbytes32 transactionDataHash = getTransactionDataHash(\n\t\t\t_claimData.to,\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.transactionHash,\n\t\t\t_claimData.logIndex,\n\t\t\t_claimData.originChainId,\n\t\t\tblock.chainid\n\t\t);\n\n\t\trequire(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n\t\trequire(!isClaimed(_claimData, transactionDataHash), \"Bridge: Already claimed\");\n\t\tclaimed[transactionDataHash] = true;\n\n\t\treceivedAmount = _claimCross(\n\t\t\t_claimData.originChainId,\n\t\t\toriginalTokenAddress,\n\t\t\t_reciever,\n\t\t\t_claimData.amount,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\n\t\temitClaimed(_claimData, originalTokenAddress, _reciever, _relayer, _fee);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction emitClaimed(\n\t\tClaimData calldata _claimData,\n\t\taddress _originalTokenAddress,\n\t\taddress payable _reciever,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal {\n\t\temit Claimed(\n\t\t\t_claimData.transactionHash,\n\t\t\t_originalTokenAddress,\n\t\t\t_claimData.to,\n\t\t\tsenderAddresses[_claimData.transactionHash],\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.logIndex,\n\t\t\t_reciever,\n\t\t\t_relayer,\n\t\t\t_fee,\n\t\t\t_claimData.originChainId,\n\t\t\tblock.chainid\n\t\t);\n\t}\n\n\tfunction _claimCross(\n\t\tuint256 _originalChainId,\n\t\taddress _originalTokenAddress,\n\t\taddress payable _reciever,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256) {\n\t\tcheckChainId(_originalChainId);\n\t\tif (knownToken(_originalChainId, _originalTokenAddress)) {\n\t\t\treturn _claimCrossBackToToken(\n\t\t\t\t_originalTokenAddress,\n\t\t\t\t_reciever,\n\t\t\t\t_amount,\n\t\t\t\t_relayer,\n\t\t\t\t_fee\n\t\t\t);\n\t\t}\n\n\t\treturn _claimCrossToSideToken(\n\t\t\tsideTokenByOriginalToken(_originalChainId, _originalTokenAddress),\n\t\t\t_reciever,\n\t\t\t_amount,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\t}\n\n\tfunction _claimCrossToSideToken(\n\t\taddress _sideToken,\n\t\taddress payable _receiver,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256 receivedAmount) {\n\t\trequire(_sideToken != NULL_ADDRESS, \"Bridge: side token is null\");\n\t\tuint256 granularity = IERC777(_sideToken).granularity();\n\t\tuint256 formattedAmount = _amount.mul(granularity);\n\t\trequire(_fee <= formattedAmount, \"Bridge: fee too high\");\n\t\treceivedAmount = formattedAmount.sub(_fee);\n\t\tISideToken(_sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n\t\tif (_fee > 0) {\n\t\t\tISideToken(_sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n\t\t}\n\t\treturn receivedAmount;\n\t}\n\n\tfunction _claimCrossBackToToken(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _receiver,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256 receivedAmount) {\n\t\tuint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n\t\t//As side tokens are ERC777 they will always have 18 decimals\n\t\tuint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n\t\trequire(_fee <= formattedAmount, \"Bridge: fee too high\");\n\t\treceivedAmount = formattedAmount.sub(_fee);\n\t\tif (address(wrappedCurrency) == _originalTokenAddress) {\n\t\t\twrappedCurrency.withdraw(formattedAmount);\n\t\t\t_receiver.transfer(receivedAmount);\n\t\t\tif(_fee > 0) {\n\t\t\t\t_relayer.transfer(_fee);\n\t\t\t}\n\t\t} else {\n\t\t\tIERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n\t\t\tif(_fee > 0) {\n\t\t\t\tIERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n\t\t\t}\n\t\t}\n\t\treturn receivedAmount;\n\t}\n\n\t/**\n\t\t* ERC-20 tokens approve and transferFrom pattern\n\t\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n\t\t*/\n\tfunction receiveTokensTo(uint256 destinationChainId, address tokenToUse, address to, uint256 amount) external override {\n\t\taddress sender = _msgSender();\n\t\t//Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n\t\tIERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n\t\tcrossTokens(tokenToUse, sender, to, amount, \"\", destinationChainId);\n\t}\n\n\t/**\n\t\t* Use network currency and cross it.\n\t\t*/\n\tfunction depositTo(uint256 chainId, address to) external payable override {\n\t\taddress sender = _msgSender();\n\t\trequire(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n\t\twrappedCurrency.deposit{ value: msg.value }();\n\t\tcrossTokens(address(wrappedCurrency), sender, to, msg.value, \"\", chainId);\n\t}\n\n\t/**\n\t\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n\t\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n\t\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\n\t\t* const userData = web3.eth.abi.encodeParameters(\n * [\"address\", \"uint256\"],\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\n * );\n\t\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\n\t\t* const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\n\t\t*/\n\tfunction tokensReceived(\n\t\taddress operator,\n\t\taddress from,\n\t\taddress to,\n\t\tuint amount,\n\t\tbytes calldata userData, // [address,uint256] user addrest receiver, destinationChainId || [uint256] same as from, destinationChainId\n\t\tbytes calldata\n\t) external override(IBridge, IERC777Recipient) {\n\t\t//Hook from ERC777address\n\t\tif(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n\t\trequire(to == address(this), \"Bridge: Not to this address\");\n\t\taddress tokenToUse = _msgSender();\n\t\trequire(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n\t\trequire(userData.length >= 32, \"Bridge: user data with at least the destinationChainId\");\n\t\trequire(userData.length == 64 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n\t\taddress receiver = userData.length == 32 ? from : LibUtils.toAddress(userData, 12);\n\t\tuint256 destinationChainId = LibUtils.toUint256(userData, userData.length - 32);\n\t\tcrossTokens(tokenToUse, from, receiver, amount, userData, destinationChainId);\n\t}\n\n\tfunction crossTokens(\n\t\taddress tokenToUse,\n\t\taddress from,\n\t\taddress to,\n\t\tuint256 amount,\n\t\tbytes memory userData,\n\t\tuint256 destinationChainId\n\t) internal whenNotUpgrading whenNotPaused nonReentrant {\n\t\trequire(block.chainid != destinationChainId, \"Bridge: destination chain id equal current chain id\");\n\t\tcheckChainId(destinationChainId);\n\t\t_setKnownTokenByChain(destinationChainId, tokenToUse, true);\n\t\tuint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n\t\tuint256 amountMinusFees = amount.sub(fee);\n\t\tuint8 decimals = LibUtils.getDecimals(tokenToUse);\n\t\tuint formattedAmount = amount;\n\t\tif (decimals != 18) {\n\t\t\tformattedAmount = amount.mul(uint256(10)**(18-decimals));\n\t\t}\n\t\t// We consider the amount before fees converted to 18 decimals to check the limits\n\t\t// updateTokenTransfer revert if token not allowed\n\t\tallowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n\n\t\tOriginalToken memory sideToken = getOriginalTokenBySideToken(tokenToUse);\n\t\tif (sideToken.tokenAddress != NULL_ADDRESS) {\n\t\t\t// Side Token Crossing back\n\t\t\t{ // Created scope to avoid stack too deep\n\t\t\t\tuint256 granularity = LibUtils.getGranularity(tokenToUse);\n\t\t\t\tuint256 modulo = amountMinusFees.mod(granularity);\n\t\t\t\tfee = fee.add(modulo);\n\t\t\t\tamountMinusFees = amountMinusFees.sub(modulo);\n\t\t\t\tIERC777(tokenToUse).burn(amountMinusFees, userData);\n\t\t\t}\n\t\t\temit Cross(\n\t\t\t\tsideToken.tokenAddress,\n\t\t\t\tto,\n\t\t\t\tdestinationChainId,\n\t\t\t\tfrom,\n\t\t\t\tblock.chainid,\n\t\t\t\tamountMinusFees,\n\t\t\t\tuserData\n\t\t\t);\n\t\t} else {\n\t\t\temit Cross(\n\t\t\t\ttokenToUse,\n\t\t\t\tto,\n\t\t\t\tdestinationChainId,\n\t\t\t\tfrom,\n\t\t\t\tblock.chainid,\n\t\t\t\tamountMinusFees,\n\t\t\t\tuserData\n\t\t\t);\n\t\t}\n\n\t\tif (fee > 0) {\n\t\t\t//Send the payment to the MultiSig of the Federation\n\t\t\tIERC20(tokenToUse).safeTransfer(owner(), fee);\n\t\t}\n\t}\n\n\t// function for retrocompatibility\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex\n\t) internal pure returns(bytes32) {\n\t\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n\t}\n\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) public pure override returns(bytes32) {\n\t\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex, _originChainId, _destinationChainId));\n\t}\n\n\tfunction setFeePercentage(uint amount) external onlyOwner {\n\t\trequire(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n\t\tfeePercentage = amount;\n\t\temit FeePercentageChanged(feePercentage);\n\t}\n\n\tfunction getFeePercentage() external view override returns(uint) {\n\t\treturn feePercentage;\n\t}\n\n\tfunction changeFederation(address newFederation) external onlyOwner {\n\t\trequire(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n\t\tfederation = newFederation;\n\t\temit FederationChanged(federation);\n\t}\n\n\tfunction changeAllowTokens(address newAllowTokens) external onlyOwner {\n\t\trequire(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n\t\tallowTokens = IAllowTokens(newAllowTokens);\n\t\temit AllowTokensChanged(newAllowTokens);\n\t}\n\n\tfunction getFederation() external view returns(address) {\n\t\treturn federation;\n\t}\n\n\tfunction changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n\t\trequire(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n\t\tsideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n\t\temit SideTokenFactoryChanged(newSideTokenFactory);\n\t}\n\n\tfunction setUpgrading(bool _isUpgrading) external onlyOwner {\n\t\tisUpgrading = _isUpgrading;\n\t\temit Upgrading(isUpgrading);\n\t}\n\n\tfunction setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n\t\trequire(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n\t\twrappedCurrency = IWrapped(_wrappedCurrency);\n\t\temit WrappedCurrencyChanged(_wrappedCurrency);\n\t}\n\n\tfunction hasCrossed(bytes32 transactionHash) public view returns (bool) {\n\t\treturn transactionsDataHashes[transactionHash] != bytes32(0);\n\t}\n\n\tfunction hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n\t\treturn claimed[transactionsDataHashes[transactionHash]];\n\t}\n\n}\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IBridge {\n\n\tstruct ClaimData {\n\t\taddress payable to;\n\t\tuint256 amount;\n\t\tbytes32 blockHash;\n\t\tbytes32 transactionHash;\n\t\tuint32 logIndex;\n\t\tuint256 originChainId;\n\t}\n\n\tstruct OriginalToken {\n\t\taddress tokenAddress;\n\t\tuint256 originChainId;\n\t}\n\n\tfunction version() external pure returns (string memory);\n\n\tfunction getFeePercentage() external view returns(uint);\n\n\t/**\n\t\t* ERC-20 tokens approve and transferFrom pattern\n\t\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n\t\t*/\n\tfunction receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;\n\n\t/**\n\t\t* Use network currency and cross it.\n\t\t*/\n\tfunction depositTo(uint256 chainId, address to) external payable;\n\n\t/**\n\t\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n\t\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n\t\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\n\t\t* const userData = web3.eth.abi.encodeParameters(\n * [\"address\", \"uint256\"],\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\n * );\n\t\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\n\t\t* const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\n\t\t*/\n\tfunction tokensReceived (\n\t\taddress operator,\n\t\taddress from,\n\t\taddress to,\n\t\tuint amount,\n\t\tbytes calldata userData,\n\t\tbytes calldata operatorData\n\t) external;\n\n\t/**\n\t\t* Accepts the transaction from the other chain that was voted and sent by the Federation contract\n\t\t*/\n\tfunction acceptTransfer(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _from,\n\t\taddress payable _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) external;\n\n\t/**\n\t\t* Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n\t\t*/\n\tfunction claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n\tfunction claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n\tfunction claimGasless(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline,\n\t\tuint8 _v,\n\t\tbytes32 _r,\n\t\tbytes32 _s\n\t) external returns (uint256 receivedAmount);\n\n\tfunction createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _originalTokenSymbol,\n\t\tstring calldata _originalTokenName,\n\t\tuint256 _chainId\n\t) external;\n\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256 _destinationChainId\n\t) external returns(bytes32);\n\n\tevent Cross(\n\t\taddress indexed _tokenAddress,\n\t\taddress indexed _to,\n\t\tuint256 indexed _destinationChainId,\n\t\taddress _from,\n\t\tuint256 _originChainId,\n\t\tuint256 _amount,\n\t\tbytes _userData\n\t);\n\n\tevent NewSideToken(\n\t\taddress indexed _newSideTokenAddress,\n\t\taddress indexed _originalTokenAddress,\n\t\tstring _newSymbol,\n\t\tuint256 _granularity,\n\t\tuint256 _chainId\n\t);\n\tevent AcceptedCrossTransfer(\n\t\tbytes32 indexed _transactionHash,\n\t\taddress indexed _originalTokenAddress,\n\t\taddress indexed _to,\n\t\taddress _from,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tuint256 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t);\n\tevent FeePercentageChanged(uint256 _amount);\n\tevent Claimed(\n\t\tbytes32 indexed _transactionHash,\n\t\taddress indexed _originalTokenAddress,\n\t\taddress indexed _to,\n\t\taddress _sender,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tuint256 _logIndex,\n\t\taddress _reciever,\n\t\taddress _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _destinationChainId,\n\t\tuint256 _originChainId\n\t);\n}"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IBridge.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockReceiveTokensCall is IERC777Recipient {\n address public bridge;\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor(address _bridge) {\n bridge = _bridge;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount, uint256 destinationChainId) external {\n IERC20(tokenToUse).approve(bridge, amount);\n IBridge(bridge).receiveTokensTo(destinationChainId, tokenToUse, receiver, amount);\n }\n\n function callDepositTo(address receiver, uint256 destinationChainId) external payable {\n IBridge(bridge).depositTo{ value: msg.value }(destinationChainId, receiver);\n }\n\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\n IERC777(tokenToUse).send(bridge, amount, data);\n }\n\n // Mandatory for IERC777Recipient\n function tokensReceived(\n address,\n address,\n address,\n uint,\n bytes calldata,\n bytes calldata\n ) override external view {\n this;\n }\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockERC777Recipient is IERC777Recipient {\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor() {\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\n }\n\n event Success(\n address operator,\n address from,\n address to,\n uint amount,\n bytes userData,\n bytes operatorData);\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) override external {\n emit Success(operator, from, to, amount, userData, operatorData);\n }\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\n\ncontract SideTokenV1 is ERC777 {\n address public minter;\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\n minter = _minterAddr;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../SideToken/SideTokenV1.sol\";\n\ncontract SideTokenFactoryV1 is Secondary {\n event CreatedSideToken(address sideToken, string symbol);\n\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\n emit CreatedSideToken(address(sideToken), symbol);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using SafeMath for uint256;\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping (uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /*\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri_) {\n _setURI(uri_);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) external view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: balance query for the zero address\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(amount);\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, address(0), id, amount);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\n /**\n @dev Handles the receipt of a single ERC1155 token type. This function is\n called at the end of a `safeTransferFrom` after the balance has been updated.\n To accept the transfer, this must return\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n (i.e. 0xf23a6e61, or its own function selector).\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n )\n external\n returns(bytes4);\n\n /**\n @dev Handles the receipt of a multiple ERC1155 token types. This function\n is called at the end of a `safeBatchTransferFrom` after the balances have\n been updated. To accept the transfer(s), this must return\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n (i.e. 0xbc197c81, or its own function selector).\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match values array)\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n )\n external\n returns(bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC1155 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Pausable is ERC1155, Pausable {\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\nimport \"../access/roles/PauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context, PauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n constructor () {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract PauserRole is Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n constructor () {\n _addPauser(_msgSender());\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC721.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC721 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC721Pausable is ERC721, Pausable {\n /**\n * @dev See {ERC721-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../../zeppelin/ownership/Ownable.sol\";\nimport \"../../zeppelin/math/SafeMath.sol\";\nimport \"../../zeppelin/utils/Strings.sol\";\nimport \"./OpenSeaEIP712Base.sol\";\n\n\n/**\n * @title OpenSea721\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\n */\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\n using SafeMath for uint256;\n\n uint256 private _currentTokenId = 0;\n\n constructor(\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n _initializeEIP712(_name);\n }\n\n function baseTokenURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/api/creature/\";\n }\n\n function contractURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\n }\n\n /**\n * @dev Mints a token to an address with a tokenURI.\n * @param _to address of the future owner of the token\n */\n function mintTo(address _to) public onlyOwner {\n uint256 newTokenId = _getNextTokenId();\n _mint(_to, newTokenId);\n _incrementTokenId();\n }\n\n /**\n * @dev calculates the next token ID based on value of _currentTokenId\n * @return uint256 for the next token ID\n */\n function _getNextTokenId() private view returns (uint256) {\n return _currentTokenId.add(1);\n }\n\n /**\n * @dev increments the value of _currentTokenId\n */\n function _incrementTokenId() private {\n _currentTokenId++;\n }\n\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\n }\n\n}"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () {\n _owner = _msgSender();\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../zeppelin/upgradable/Initializable.sol\";\n\ncontract OpenSeaEIP712Base is Initializable {\n struct EIP712Domain {\n string name;\n string version;\n address verifyingContract;\n bytes32 salt;\n }\n\n string constant public ERC712_VERSION = \"1\";\n\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\n bytes(\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\n )\n );\n bytes32 internal domainSeperator;\n\n // supposed to be called once while initializing.\n // one of the contracts that inherits this contract follows proxy pattern\n // so it is not possible to do this in a constructor\n function _initializeEIP712(\n string memory name\n )\n internal\n initializer\n {\n _setDomainSeperator(name);\n }\n\n function _setDomainSeperator(string memory name) internal {\n domainSeperator = keccak256(\n abi.encode(\n EIP712_DOMAIN_TYPEHASH,\n keccak256(bytes(name)),\n keccak256(bytes(ERC712_VERSION)),\n address(this),\n bytes32(block.chainid)\n )\n );\n }\n\n function getDomainSeperator() public view returns (bytes32) {\n return domainSeperator;\n }\n\n /**\n * Accept message hash and returns hash message in EIP712 compatible form\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\n * https://eips.ethereum.org/EIPS/eip-712\n * \"\\\\x19\" makes the encoding deterministic\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\n */\n function toTypedMessageHash(bytes32 messageHash)\n internal\n view\n returns (bytes32)\n {\n return\n keccak256(\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\n );\n }\n}\n"
+ },
+ "contracts/federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../Bridge/IBridgeV3.sol\";\n\ncontract FederationV2 is Initializable, UpgradableOwnable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridgeV3 public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\n validRequirement(_members.length, _required) public initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n }\n\n function version() external pure returns (string memory) {\n return \"v2\";\n }\n\n function setBridge(address _bridge) external onlyOwner {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridgeV3(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n )\n public onlyMember returns(bool)\n {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32)\n {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}"
+ },
+ "contracts/federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../nftbridge/INFTBridge.sol\";\nimport \"../interface/IBridge.sol\";\nimport \"../interface/IFederation.sol\";\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\n\tuint constant public MAX_MEMBER_COUNT = 50;\n\taddress constant private NULL_ADDRESS = address(0);\n\n\tIBridge public bridge;\n\taddress[] public members;\n\n\t/**\n\t\t@notice The minimum amount of votes to approve a transaction\n\t\t@dev It should have at least the required amount of members\n\t\t*/\n\tuint public required;\n\n\t/**\n\t\t@notice All the addresses that are members of the federation\n\t\t@dev The address should be a member to vote in transactions\n\t\t*/\n\tmapping (address => bool) public isMember;\n\n\t/**\n\t\t(bytes32) transactionId = keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tamount,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex\n\t\t\t)\n\t\t) => (\n\t\t\t(address) members => (bool) voted\n\t\t)\n\t\t@notice Votes by members by the transaction ID\n\t\t@dev the members should approve the transaction by 50% + 1\n\t\t*/\n\tmapping (bytes32 => mapping (address => bool)) public votes;\n\n\t/**\n\t\t(bytes32) transactionId => (bool) voted\n\t\t@notice Check if that transaction was already processed\n\t*/\n\tmapping(bytes32 => bool) public processed;\n\n\t/** Federator v3 variables */\n\tINFTBridge public bridgeNFT;\n\n\tmodifier onlyMember() {\n\t\trequire(isMember[_msgSender()], \"Federation: Not Federator\");\n\t\t_;\n\t}\n\n\tmodifier validRequirement(uint membersCount, uint _required) {\n\t\trequire(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n\t\t_;\n\t}\n\n\tfunction initialize(\n\t\taddress[] calldata _members,\n\t\tuint _required,\n\t\taddress _bridge,\n\t\taddress owner,\n\t\taddress _bridgeNFT\n\t) public validRequirement(_members.length, _required) initializer {\n\t\tUpgradableOwnable.initialize(owner);\n\t\trequire(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n\t\tmembers = _members;\n\t\tfor (uint i = 0; i < _members.length; i++) {\n\t\t\trequire(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n\t\t\tisMember[_members[i]] = true;\n\t\t\temit MemberAddition(_members[i]);\n\t\t}\n\t\trequired = _required;\n\t\temit RequirementChange(required);\n\t\t_setBridge(_bridge);\n\t\t_setNFTBridge(_bridgeNFT);\n\t}\n\n\t/**\n\t\t@notice Current version of the contract\n\t\t@return version in v{Number}\n\t\t*/\n\tfunction version() external pure override returns (string memory) {\n\t\treturn \"v3\";\n\t}\n\n\t/**\n\t\t@notice Sets a new bridge contract\n\t\t@dev Emits BridgeChanged event\n\t\t@param _bridge the new bridge contract address that should implement the IBridge interface\n\t\t*/\n\tfunction setBridge(address _bridge) external onlyOwner override {\n\t\t_setBridge(_bridge);\n\t}\n\n\tfunction _setBridge(address _bridge) internal {\n\t\trequire(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n\t\tbridge = IBridge(_bridge);\n\t\temit BridgeChanged(_bridge);\n\t}\n\n\t/**\n\t\t@notice Sets a new NFT bridge contract\n\t\t@dev Emits NFTBridgeChanged event\n\t\t@param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n\t\t*/\n\tfunction setNFTBridge(address _bridgeNFT) external onlyOwner override {\n\t\trequire(_bridgeNFT != NULL_ADDRESS, \"Federation: Empty NFT bridge\");\n\t\t_setNFTBridge(_bridgeNFT);\n\t}\n\n\tfunction _setNFTBridge(address _bridgeNFT) internal {\n\t\tbridgeNFT = INFTBridge(_bridgeNFT);\n\t\temit NFTBridgeChanged(_bridgeNFT);\n\t}\n\n\tfunction validateTransaction(bytes32 transactionId, bytes32 transactionIdMultichain) internal view returns(bool) {\n\t\tuint256 minimumVotes = getMinimalNumberOfVotes();\n\t\tuint256 amountVotes = 0;\n\n for (uint256 i = 0; i < members.length; i++) {\n if (votes[transactionIdMultichain][members[i]]) {\n amountVotes += 1;\n\t\t\t} else if (votes[transactionId][members[i]]) {\n amountVotes += 1;\n\t\t\t}\n\n\t\t\tif (amountVotes >= minimumVotes && amountVotes >= required) {\n\t\t\t\treturn true;\n\t\t\t}\n }\n\n\t\treturn false;\n\t}\n\n\tfunction getMinimalNumberOfVotes() internal view returns(uint256) {\n\t\treturn members.length / 2 + 1;\n\t}\n\n\tfunction isProcessed(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\n\t\treturn processed[transactionIdMultichain] || processed[transactionId];\n\t}\n\n\tfunction isVoted(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\n\t\treturn votes[transactionIdMultichain][_msgSender()] || votes[transactionId][_msgSender()];\n\t}\n\n\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\n\t\trequire(chainId == block.chainid, \"Federation: Not block.chainid\");\n\t}\n\n\t/**\n\t\t@notice Vote in a transaction, if it has enough votes it accepts the transfer\n\t\t@param originalTokenAddress The address of the token in the origin (main) chain\n\t\t@param sender The address who solicited the cross token\n\t\t@param receiver Who is going to receive the token in the opposite chain\n\t\t@param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n\t\t@param blockHash The block hash in which the transaction with the cross event occurred\n\t\t@param transactionHash The transaction in which the cross event occurred\n\t\t@param logIndex Index of the event in the logs\n\t\t@param tokenType Is the type of bridge to be used\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n\t\t*/\n\tfunction voteTransaction(\n\t\taddress originalTokenAddress,\n\t\taddress payable sender,\n\t\taddress payable receiver,\n\t\tuint256 value,\n\t\tbytes32 blockHash,\n\t\tbytes32 transactionHash,\n\t\tuint32 logIndex,\n\t\tTokenType tokenType,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n\t) external onlyMember override {\n\t\tshouldBeCurrentChainId(destinationChainId);\n\t\tbytes32 transactionId = keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex\n\t\t\t)\n\t\t);\n\n\t\tbytes32 transactionIdMultichain = getTransactionId(\n\t\t\toriginalTokenAddress,\n\t\t\tsender,\n\t\t\treceiver,\n\t\t\tvalue,\n\t\t\tblockHash,\n\t\t\ttransactionHash,\n\t\t\tlogIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n\t\t);\n\n\t\tif (isProcessed(transactionId, transactionIdMultichain))\n\t\t\treturn;\n\n\t\tif (isVoted(transactionId, transactionIdMultichain))\n\t\t\treturn;\n\n\t\tvotes[transactionIdMultichain][_msgSender()] = true;\n\t\temit Voted(\n\t\t\t_msgSender(),\n\t\t\ttransactionHash,\n\t\t\ttransactionIdMultichain,\n\t\t\toriginalTokenAddress,\n\t\t\tsender,\n\t\t\treceiver,\n\t\t\tvalue,\n\t\t\tblockHash,\n\t\t\tlogIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n\t\t);\n\n\t\tif (validateTransaction(transactionId, transactionIdMultichain)) {\n\t\t\tprocessed[transactionIdMultichain] = true;\n\n\t\t\tacceptTransfer(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex,\n\t\t\t\ttokenType,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\n\t\t\temit Executed(\n\t\t\t\t_msgSender(),\n\t\t\t\ttransactionHash,\n\t\t\t\ttransactionIdMultichain,\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\tlogIndex,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\t\t}\n\t}\n\n function acceptTransfer(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType,\n\tuint256 originChainId,\n\tuint256\tdestinationChainId\n ) internal {\n if (tokenType == TokenType.NFT) {\n require(address(bridgeNFT) != NULL_ADDRESS, \"Federation: Empty NFTBridge\");\n bridgeNFT.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex,\n\t\toriginChainId,\n\t\tdestinationChainId\n );\n } else {\n\t bridge.acceptTransfer(\n\t\toriginalTokenAddress,\n\t\tsender,\n\t\treceiver,\n\t\tvalue,\n\t\tblockHash,\n\t\ttransactionHash,\n\t\tlogIndex,\n\t\toriginChainId,\n\t\tdestinationChainId\n\t );\n\t}\n }\n\n /**\n @notice Get the amount of approved votes for that transactionId\n @param transactionId The transaction hashed from getTransactionId function\n */\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n\tfunction hasVoted(bytes32 transactionId) external view returns(bool) {\n\t\treturn votes[transactionId][_msgSender()];\n\t}\n\n\tfunction transactionWasProcessed(bytes32 transactionId) external view returns(bool) {\n\t\treturn processed[transactionId];\n\t}\n\n\t/**\n\t\t@notice Gets the hash of transaction from the following parameters encoded and keccaked\n\t\t@dev It encodes and applies keccak256 to the parameters received in the same order\n\t\t@param originalTokenAddress The address of the token in the origin (main) chain\n\t\t@param sender The address who solicited the cross token\n\t\t@param receiver Who is going to receive the token in the opposite chain\n\t\t@param amount Could be the amount or the tokenId\n\t\t@param blockHash The block hash in which the transaction with the cross event occurred\n\t\t@param transactionHash The transaction in which the cross event occurred\n\t\t@param logIndex Index of the event in the logs\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n\t\t@return The hash generated by the parameters.\n\t*/\n\tfunction getTransactionId(\n\t\taddress originalTokenAddress,\n\t\taddress sender,\n\t\taddress receiver,\n\t\tuint256 amount,\n\t\tbytes32 blockHash,\n\t\tbytes32 transactionHash,\n\t\tuint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n\t) public pure returns(bytes32) {\n\t\treturn keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tamount,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t)\n\t\t);\n\t}\n\n\tfunction addMember(address _newMember) external onlyOwner override {\n\t\trequire(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n\t\trequire(!isMember[_newMember], \"Federation: Member already exists\");\n\t\trequire(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n\t\tisMember[_newMember] = true;\n\t\tmembers.push(_newMember);\n\t\temit MemberAddition(_newMember);\n\t}\n\n\tfunction removeMember(address _oldMember) external onlyOwner override {\n\t\trequire(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n\t\trequire(isMember[_oldMember], \"Federation: Member doesn't exists\");\n\t\trequire(members.length > 1, \"Federation: Can't remove all the members\");\n\t\trequire(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n\t\tisMember[_oldMember] = false;\n\t\tfor (uint i = 0; i < members.length - 1; i++) {\n\t\t\tif (members[i] == _oldMember) {\n\t\t\t\tmembers[i] = members[members.length - 1];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tmembers.pop(); // remove an element from the end of the array.\n\t\temit MemberRemoval(_oldMember);\n\t}\n\n\t/**\n\t\t@notice Return all the current members of the federation\n\t\t@return Current members\n\t\t*/\n\tfunction getMembers() external view override returns (address[] memory) {\n\t\treturn members;\n\t}\n\n\t/**\n\t\t@notice Changes the number of required members to vote and approve an transaction\n\t\t@dev Emits the RequirementChange event\n\t\t@param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n\t\t*/\n\tfunction changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\n\t\trequire(_required >= 2, \"Federation: Requires at least 2\");\n\t\trequired = _required;\n\t\temit RequirementChange(_required);\n\t}\n\n\t/**\n\t\t@notice It emits an HeartBeat like an health check\n\t\t@dev Emits HeartBeat event\n\t\t*/\n\tfunction emitHeartbeat(\n\t\tstring calldata fedVersion,\n\t\tuint256[] calldata fedChainsIds,\n\t\tuint256[] calldata fedChainsBlocks,\n\t\tstring[] calldata fedChainsInfo\n\t) external onlyMember override {\n\t\trequire(fedChainsIds.length == fedChainsBlocks.length &&\n\t\t\tfedChainsIds.length == fedChainsInfo.length, \"Federation: Length missmatch\");\n\t\temit HeartBeat(\n\t\t\t_msgSender(),\n\t\t\tblock.chainid,\n\t\t\tblock.number,\n\t\t\tfedVersion,\n\t\t\tfedChainsIds,\n\t\t\tfedChainsBlocks,\n\t\t\tfedChainsInfo\n\t\t);\n\t}\n}\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface IFederation {\n enum TokenType{ COIN, NFT }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure returns (string memory);\n\n /**\n @notice Sets a new bridge contract\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external;\n\n /**\n @notice Sets a new NFT bridge contract\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external;\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType,\n\t uint256 originChainId,\n\t uint256\tdestinationChainId\n ) external;\n\n /**\n @notice Add a new member to the federation\n @param _newMember address of the new member\n */\n function addMember(address _newMember) external;\n\n /**\n @notice Remove a member of the federation\n @param _oldMember address of the member to be removed from federation\n */\n function removeMember(address _oldMember) external;\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view returns (address[] memory);\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external;\n\n /**\n @notice It emmits an HeartBeat like an healthy check\n */\n function emitHeartbeat(\n string calldata federatorVersion,\n\t\tuint256[] calldata fedChainsIds,\n\t\tuint256[] calldata fedChainsBlocks,\n\t\tstring[] calldata fedChainsInfo\n ) external;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event NFTBridgeChanged(address bridgeNFT);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex,\n uint256 originChainId,\n\t\tuint256\tdestinationChainId\n );\n event HeartBeat(\n address indexed sender,\n uint256 currentChainId,\n uint256 currentBlock,\n string fedVersion,\n uint256[] fedChainsIds,\n\t\tuint256[] fedChainsBlocks,\n\t\tstring[] fedChainsInfo\n );\n\n}\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract MinterRole is Context {\n using Roles for Roles.Role;\n\n event MinterAdded(address indexed account);\n event MinterRemoved(address indexed account);\n\n Roles.Role private _minters;\n\n constructor () {\n _addMinter(_msgSender());\n }\n\n modifier onlyMinter() {\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\n _;\n }\n\n function isMinter(address account) public view returns (bool) {\n return _minters.has(account);\n }\n\n function addMinter(address account) public onlyMinter {\n _addMinter(account);\n }\n\n function renounceMinter() public {\n _removeMinter(_msgSender());\n }\n\n function _addMinter(address account) internal {\n _minters.add(account);\n emit MinterAdded(account);\n }\n\n function _removeMinter(address account) internal {\n _minters.remove(account);\n emit MinterRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20Mintable}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() override public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) override public view returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) override public returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) override public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) override public returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal {\n require(sender != address(0), \"ERC20: transfer from zero address\");\n require(recipient != address(0), \"ERC20: transfer to zero address\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: mint to zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: burn from zero address\");\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n *\n * This is internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal {\n require(owner != address(0), \"ERC20: approve from zero address\");\n require(spender != address(0), \"ERC20: approve to zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\n * from the caller's allowance.\n *\n * See {_burn} and {_approve}.\n */\n function _burnFrom(address account, uint256 amount) internal {\n _burn(account, amount);\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\n }\n}\n"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\nimport \"../interface/IERC677Receiver.sol\";\n\ncontract mockERC677Receiver is IERC677Receiver {\n event Success(address _sender, uint _value, bytes _data);\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\n emit Success(_sender, _value, _data);\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Optional functions from the ERC20 standard.\n */\nabstract contract ERC20Detailed is IERC20 {\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\n * these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\n _name = aName;\n _symbol = aSymbol;\n _decimals = theDecimals;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./Proxy.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n *\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\n * {TransparentUpgradeableProxy}.\n */\ncontract UpgradeableProxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _setImplementation(_logic);\n if(_data.length > 0) {\n Address.functionDelegateCall(_logic, _data);\n }\n }\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n bytes32 slot = _IMPLEMENTATION_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n impl := sload(slot)\n }\n }\n\n /**\n * @dev Upgrades the proxy to a new implementation.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal virtual {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\n\n bytes32 slot = _IMPLEMENTATION_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newImplementation)\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./UpgradeableProxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _setAdmin(admin_);\n }\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _admin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _admin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\n emit AdminChanged(_admin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external virtual ifAdmin {\n _upgradeTo(newImplementation);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\n _upgradeTo(newImplementation);\n Address.functionDelegateCall(newImplementation, data);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address adm) {\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n adm := sload(slot)\n }\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n bytes32 slot = _ADMIN_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newAdmin)\n }\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../ownership/Ownable.sol\";\nimport \"./TransparentUpgradeableProxy.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract AllowTokensV0 is Ownable {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n\n mapping (address => bool) public allowedTokens;\n bool private validateAllowedTokens;\n uint256 private maxTokensAllowed;\n uint256 private minTokensAllowed;\n uint256 public dailyLimit;\n\n event AllowedTokenAdded(address indexed _tokenAddress);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event AllowedTokenValidation(bool _enabled);\n event MaxTokensAllowedChanged(uint256 _maxTokens);\n event MinTokensAllowedChanged(uint256 _minTokens);\n event DailyLimitChanged(uint256 dailyLimit);\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\n _;\n }\n\n constructor(address _manager) {\n transferOwnership(_manager);\n validateAllowedTokens = true;\n maxTokensAllowed = 10000 ether;\n minTokensAllowed = 1 ether;\n dailyLimit = 100000 ether;\n }\n\n function isValidatingAllowedTokens() external view returns(bool) {\n return validateAllowedTokens;\n }\n\n function getMaxTokensAllowed() external view returns(uint256) {\n return maxTokensAllowed;\n }\n\n function getMinTokensAllowed() external view returns(uint256) {\n return minTokensAllowed;\n }\n\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\n return allowedTokens[token];\n }\n\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\n if (validateAllowedTokens) {\n return allowedTokenExist(token);\n }\n return true;\n }\n\n function addAllowedToken(address token) external onlyOwner {\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\n allowedTokens[token] = true;\n emit AllowedTokenAdded(token);\n }\n\n function removeAllowedToken(address token) external onlyOwner {\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\n allowedTokens[token] = false;\n emit AllowedTokenRemoved(token);\n }\n\n function enableAllowedTokensValidation() external onlyOwner {\n validateAllowedTokens = true;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function disableAllowedTokensValidation() external onlyOwner {\n // Before disabling Allowed Tokens Validations some kind of contract validation system\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\n validateAllowedTokens = false;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\n maxTokensAllowed = maxTokens;\n emit MaxTokensAllowedChanged(maxTokensAllowed);\n }\n\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\n minTokensAllowed = minTokens;\n emit MinTokensAllowedChanged(minTokensAllowed);\n }\n\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\n dailyLimit = _dailyLimit;\n emit DailyLimitChanged(_dailyLimit);\n }\n\n // solium-disable-next-line max-len\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\n if(amount > maxTokensAllowed)\n return false;\n if(amount < minTokensAllowed)\n return false;\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\n return false;\n if(!isSideToken && !isTokenAllowed(tokenToUse))\n return false;\n return true;\n }\n\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\n uint maxWithrow = dailyLimit - spentToday;\n if (dailyLimit < spentToday)\n return 0;\n if(maxWithrow > maxTokensAllowed)\n maxWithrow = maxTokensAllowed;\n return maxWithrow;\n }\n\n}\n"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\n\ncontract BridgeProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract FederationProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract MainToken is ERC20Detailed, ERC20 {\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\n ERC20Detailed(name, symbol, decimals)\n {\n _mint(msg.sender, totalSupply);\n }\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\n bool result = transfer(_to, _value);\n if (!result) return false;\n\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\n receiver.tokenFallback(msg.sender, _value, _data);\n\n // IMPORTANT: the ERC-677 specification does not say\n // anything about the use of the receiver contract's\n // tokenFallback method return value. Given\n // its return type matches with this method's return\n // type, returning it could be a possibility.\n // We here take the more conservative approach and\n // ignore the return value, returning true\n // to signal a succesful transfer despite tokenFallback's\n // return value -- fact being tokens are transferred\n // in any case.\n return true;\n }\n}\n\ninterface ERC677TransferReceiver {\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\n}"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract AlternativeERC20Detailed is ERC20 {\n string private _name;\n bytes32 private _symbol;\n uint256 private _decimals;\n\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\n {\n _name = aName;\n _symbol = aSymbol;\n _decimals = someDecimals;\n _mint(msg.sender, aTotalSupply);\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (bytes32) {\n return _symbol;\n }\n\n function decimals() public view returns (uint256) {\n return _decimals;\n }\n}"
+ },
+ "contracts/test/nftbridge/NFTERC721TestToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\n\ncontract NFTERC721TestToken is ERC721 {\n\n string private _contractURI;\n\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\n\n function safeMint(address to, uint256 tokenId) public {\n _safeMint(to, tokenId);\n }\n\n function setBaseURI(string memory baseURI) public {\n _setBaseURI(baseURI);\n }\n\n function setContractURI(string memory contractURI_) public {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n function setTokenURI(uint256 tokenId, string memory _tokenURI) public {\n _setTokenURI(tokenId, _tokenURI);\n }\n\n}\n"
+ },
+ "contracts/nftbridge/SideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./ISideNFTToken.sol\";\nimport \"../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\n\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\n address public minter;\n string private _contractURI;\n\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\n require(_minter != address(0), \"SideToken: Empty Minter\");\n minter = _minter;\n _setBaseURI(_baseURI);\n _setContractURI(contractURI_);\n }\n\n function _setContractURI(string memory contractURI_) internal {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(address account, uint256 tokenId) external onlyMinter override {\n _mint(account, tokenId);\n }\n}"
+ },
+ "contracts/nftbridge/SideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"./SideNFTToken.sol\";\n\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external onlyPrimary override returns(address) {\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\n return sideTokenAddress;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() {\n _registerInterface(\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\n );\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Receiver.sol\";\n\n /**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers. \n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Burnable is ERC1155 {\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n}\n"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../lib/LibUtils.sol\";\n\ncontract LibUtilsHarness {\n\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\n return LibUtils.decimalsToGranularity(decimals);\n }\n\n function getDecimals(address tokenToUse) external view returns (uint8) {\n return LibUtils.getDecimals(tokenToUse);\n }\n\n function getGranularity(address tokenToUse) external view returns (uint256) {\n return LibUtils.getGranularity(tokenToUse);\n }\n\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\n return LibUtils.bytesToAddress(bys);\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) external pure returns (uint128) {\n return LibUtils.toUint128(_bytes, _start);\n }\n\n}\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/.chainId b/bridge/deployments/rinkeby/.chainId
new file mode 100644
index 000000000..bf0d87ab1
--- /dev/null
+++ b/bridge/deployments/rinkeby/.chainId
@@ -0,0 +1 @@
+4
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/AllowTokens.json b/bridge/deployments/rinkeby/AllowTokens.json
new file mode 100644
index 000000000..c2bee724b
--- /dev/null
+++ b/bridge/deployments/rinkeby/AllowTokens.json
@@ -0,0 +1,1196 @@
+{
+ "address": "0xBC7a3f163b2fe1d6810a942417922F09F1fe82eD",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ }
+ ],
+ "name": "AllowedTokenRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "ConfirmationsChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ }
+ ],
+ "name": "SetToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_typeDescription",
+ "type": "string"
+ }
+ ],
+ "name": "TokenTypeAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "indexed": false,
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "TypeLimitsChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_lastDay",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_spentToday",
+ "type": "uint256"
+ }
+ ],
+ "name": "UpdateTokensTransfered",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_TYPES",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Secondary_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "description",
+ "type": "string"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "addTokenType",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "len",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "allowedTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "calcMaxWithdraw",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "maxWithdraw",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "smallAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "getInfoAndLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokenInfo",
+ "name": "info",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limit",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypeDescriptions",
+ "outputs": [
+ {
+ "internalType": "string[]",
+ "name": "descriptions",
+ "type": "string[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypeDescriptionsLength",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypesLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits[]",
+ "name": "limits",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_primary",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "string",
+ "name": "description",
+ "type": "string"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TypeInfo[]",
+ "name": "typesInfo",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "isTokenAllowed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "largeAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "mediumAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "removeAllowedToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "setConfirmations",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokensAndType[]",
+ "name": "tokensAndTypes",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "setMultipleTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ }
+ ],
+ "name": "setToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "setTypeLimits",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "smallAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "typeDescriptions",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "typeLimits",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "updateTokenTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x952fc5c38f4d1733c017742bc3b8f7e49573e3686226cedeb23e0a1bab87f1c1",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0xBC7a3f163b2fe1d6810a942417922F09F1fe82eD",
+ "transactionIndex": 3,
+ "gasUsed": "1999182",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x5970161b2fe130ccad70edc0dc39e426ddaa8f885f6c22eb126521c14814be7c",
+ "transactionHash": "0x952fc5c38f4d1733c017742bc3b8f7e49573e3686226cedeb23e0a1bab87f1c1",
+ "logs": [],
+ "blockNumber": 9264198,
+ "cumulativeGasUsed": "2205164",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"}],\"name\":\"AllowedTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"}],\"name\":\"ConfirmationsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"}],\"name\":\"SetToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_typeDescription\",\"type\":\"string\"}],\"name\":\"TokenTypeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"TypeLimitsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_lastDay\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_spentToday\",\"type\":\"uint256\"}],\"name\":\"UpdateTokensTransfered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_TYPES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__Secondary_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"addTokenType\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"len\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowedTokens\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"spentToday\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastDay\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"calcMaxWithdraw\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"maxWithdraw\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"smallAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getInfoAndLimits\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"spentToday\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastDay\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.TokenInfo\",\"name\":\"info\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limit\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypeDescriptions\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"descriptions\",\"type\":\"string[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypeDescriptionsLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypesLimits\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits[]\",\"name\":\"limits\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_primary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"internalType\":\"struct IAllowTokens.TypeInfo[]\",\"name\":\"typesInfo\",\"type\":\"tuple[]\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isTokenAllowed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"largeAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mediumAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"removeAllowedToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"}],\"name\":\"setConfirmations\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.TokensAndType[]\",\"name\":\"tokensAndTypes\",\"type\":\"tuple[]\"}],\"name\":\"setMultipleTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"}],\"name\":\"setToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"setTypeLimits\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"smallAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"typeDescriptions\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"typeLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"updateTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"__Secondary_init(address)\":{\"details\":\"Sets the primary account to the one that is creating the Secondary contract.\"},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/AllowTokens/AllowTokens.sol\":\"AllowTokens\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/AllowTokens/AllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../zeppelin/math/SafeMath.sol\\\";\\r\\n// Upgradables\\r\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\\\";\\r\\n\\r\\nimport \\\"../interface/IAllowTokens.sol\\\";\\r\\n\\r\\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\\r\\n using SafeMath for uint256;\\r\\n\\r\\n address constant private NULL_ADDRESS = address(0);\\r\\n uint256 constant public MAX_TYPES = 250;\\r\\n mapping (address => TokenInfo) public allowedTokens;\\r\\n mapping (uint256 => Limits) public typeLimits;\\r\\n uint256 public smallAmountConfirmations;\\r\\n uint256 public mediumAmountConfirmations;\\r\\n uint256 public largeAmountConfirmations;\\r\\n string[] public typeDescriptions;\\r\\n\\r\\n event SetToken(address indexed _tokenAddress, uint256 _typeId);\\r\\n event AllowedTokenRemoved(address indexed _tokenAddress);\\r\\n event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\\r\\n event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\\r\\n event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\\r\\n event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\\r\\n\\r\\n\\r\\n modifier notNull(address _address) {\\r\\n require(_address != NULL_ADDRESS, \\\"AllowTokens: Null Address\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function initialize(\\r\\n address _manager,\\r\\n address _primary,\\r\\n uint256 _smallAmountConfirmations,\\r\\n uint256 _mediumAmountConfirmations,\\r\\n uint256 _largeAmountConfirmations,\\r\\n TypeInfo[] memory typesInfo) public initializer {\\r\\n UpgradableOwnable.initialize(_manager);\\r\\n UpgradableSecondary.__Secondary_init(_primary);\\r\\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\r\\n for(uint i = 0; i < typesInfo.length; i = i + 1) {\\r\\n _addTokenType(typesInfo[i].description, typesInfo[i].limits);\\r\\n }\\r\\n }\\r\\n\\r\\n function version() override external pure returns (string memory) {\\r\\n return \\\"v1\\\";\\r\\n }\\r\\n\\r\\n function getInfoAndLimits(address token) override public view\\r\\n returns (TokenInfo memory info, Limits memory limit) {\\r\\n info = allowedTokens[token];\\r\\n limit = typeLimits[info.typeId];\\r\\n return (info, limit);\\r\\n }\\r\\n function calcMaxWithdraw(address token) override public view returns (uint256 maxWithdraw) {\\r\\n (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\\r\\n return _calcMaxWithdraw(info, limits);\\r\\n }\\r\\n\\r\\n function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\\r\\n // solium-disable-next-line security/no-block-members\\r\\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\\r\\n info.spentToday = 0;\\r\\n }\\r\\n if (limits.daily <= info.spentToday)\\r\\n return 0;\\r\\n maxWithdraw = limits.daily - info.spentToday;\\r\\n if(maxWithdraw > limits.max)\\r\\n maxWithdraw = limits.max;\\r\\n return maxWithdraw;\\r\\n }\\r\\n\\r\\n // solium-disable-next-line max-len\\r\\n function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\\r\\n (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\\r\\n require(isTokenAllowed(token), \\\"AllowTokens: Not whitelisted\\\");\\r\\n require(amount >= limit.min, \\\"AllowTokens: Lower than limit\\\");\\r\\n\\r\\n // solium-disable-next-line security/no-block-members\\r\\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\\r\\n // solium-disable-next-line security/no-block-members\\r\\n info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\\r\\n info.spentToday = 0;\\r\\n }\\r\\n uint maxWithdraw = _calcMaxWithdraw(info, limit);\\r\\n require(amount <= maxWithdraw, \\\"AllowTokens: Exceeded limit\\\");\\r\\n info.spentToday = info.spentToday.add(amount);\\r\\n allowedTokens[token] = info;\\r\\n\\r\\n emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\\r\\n }\\r\\n\\r\\n function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\\r\\n require(bytes(description).length > 0, \\\"AllowTokens: Empty description\\\");\\r\\n len = typeDescriptions.length;\\r\\n require(len + 1 <= MAX_TYPES, \\\"AllowTokens: Reached MAX_TYPES\\\");\\r\\n typeDescriptions.push(description);\\r\\n _setTypeLimits(len, limits);\\r\\n emit TokenTypeAdded(len, description);\\r\\n return len;\\r\\n }\\r\\n\\r\\n function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\\r\\n return _addTokenType(description, limits);\\r\\n }\\r\\n\\r\\n function _setTypeLimits(uint256 typeId, Limits memory limits) private {\\r\\n require(typeId < typeDescriptions.length, \\\"AllowTokens: bigger than typeDescriptions\\\");\\r\\n require(limits.max >= limits.min, \\\"AllowTokens: maxTokens smaller than minTokens\\\");\\r\\n require(limits.daily >= limits.max, \\\"AllowTokens: dailyLimit smaller than maxTokens\\\");\\r\\n require(limits.mediumAmount > limits.min, \\\"AllowTokens: limits.mediumAmount smaller than min\\\");\\r\\n require(limits.largeAmount > limits.mediumAmount, \\\"AllowTokens: limits.largeAmount smaller than mediumAmount\\\");\\r\\n typeLimits[typeId] = limits;\\r\\n emit TypeLimitsChanged(typeId, limits);\\r\\n }\\r\\n\\r\\n function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\\r\\n _setTypeLimits(typeId, limits);\\r\\n }\\r\\n\\r\\n function getTypesLimits() external view override returns(Limits[] memory limits) {\\r\\n limits = new Limits[](typeDescriptions.length);\\r\\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\\r\\n limits[i] = typeLimits[i];\\r\\n }\\r\\n return limits;\\r\\n }\\r\\n\\r\\n function getTypeDescriptionsLength() external view override returns(uint256) {\\r\\n return typeDescriptions.length;\\r\\n }\\r\\n\\r\\n function getTypeDescriptions() external view override returns(string[] memory descriptions) {\\r\\n descriptions = new string[](typeDescriptions.length);\\r\\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\\r\\n descriptions[i] = typeDescriptions[i];\\r\\n }\\r\\n return descriptions;\\r\\n }\\r\\n\\r\\n function isTokenAllowed(address token) public view notNull(token) override returns (bool) {\\r\\n return allowedTokens[token].allowed;\\r\\n }\\r\\n\\r\\n function setToken(address token, uint256 typeId) override public notNull(token) {\\r\\n require(isOwner() || _msgSender() == primary(), \\\"AllowTokens: unauthorized sender\\\");\\r\\n require(typeId < typeDescriptions.length, \\\"AllowTokens: typeId does not exist\\\");\\r\\n TokenInfo memory info = allowedTokens[token];\\r\\n info.allowed = true;\\r\\n info.typeId = typeId;\\r\\n allowedTokens[token] = info;\\r\\n emit SetToken(token, typeId);\\r\\n }\\r\\n\\r\\n function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\\r\\n require(tokensAndTypes.length > 0, \\\"AllowTokens: empty tokens\\\");\\r\\n for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\\r\\n setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\\r\\n }\\r\\n }\\r\\n\\r\\n function removeAllowedToken(address token) external notNull(token) onlyOwner {\\r\\n TokenInfo memory info = allowedTokens[token];\\r\\n require(info.allowed, \\\"AllowTokens: Not Allowed\\\");\\r\\n info.allowed = false;\\r\\n allowedTokens[token] = info;\\r\\n emit AllowedTokenRemoved(token);\\r\\n }\\r\\n\\r\\n function setConfirmations(\\r\\n uint256 _smallAmountConfirmations,\\r\\n uint256 _mediumAmountConfirmations,\\r\\n uint256 _largeAmountConfirmations) external onlyOwner {\\r\\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\r\\n }\\r\\n\\r\\n function _setConfirmations(\\r\\n uint256 _smallAmountConfirmations,\\r\\n uint256 _mediumAmountConfirmations,\\r\\n uint256 _largeAmountConfirmations) private {\\r\\n require(_smallAmountConfirmations <= _mediumAmountConfirmations, \\\"AllowTokens: small bigger than medium confirmations\\\");\\r\\n require(_mediumAmountConfirmations <= _largeAmountConfirmations, \\\"AllowTokens: medium bigger than large confirmations\\\");\\r\\n smallAmountConfirmations = _smallAmountConfirmations;\\r\\n mediumAmountConfirmations = _mediumAmountConfirmations;\\r\\n largeAmountConfirmations = _largeAmountConfirmations;\\r\\n emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\r\\n }\\r\\n\\r\\n function getConfirmations() external view override\\r\\n returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount) {\\r\\n return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0xdac780e7561bcb0746bf9523707cc6158999ba1efc93fc7175f2ba798196d638\",\"license\":\"MIT\"},\"contracts/interface/IAllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IAllowTokens {\\r\\n\\r\\n struct Limits {\\r\\n uint256 min;\\r\\n uint256 max;\\r\\n uint256 daily;\\r\\n uint256 mediumAmount;\\r\\n uint256 largeAmount;\\r\\n }\\r\\n\\r\\n struct TokenInfo {\\r\\n bool allowed;\\r\\n uint256 typeId;\\r\\n uint256 spentToday;\\r\\n uint256 lastDay;\\r\\n }\\r\\n\\r\\n struct TypeInfo {\\r\\n string description;\\r\\n Limits limits;\\r\\n }\\r\\n\\r\\n struct TokensAndType {\\r\\n address token;\\r\\n uint256 typeId;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\\r\\n\\r\\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\\r\\n\\r\\n function getTypesLimits() external view returns(Limits[] memory limits);\\r\\n\\r\\n function getTypeDescriptionsLength() external view returns(uint256);\\r\\n\\r\\n function getTypeDescriptions() external view returns(string[] memory descriptions);\\r\\n\\r\\n function setToken(address token, uint256 typeId) external;\\r\\n\\r\\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\\r\\n\\r\\n function isTokenAllowed(address token) external view returns (bool);\\r\\n\\r\\n function updateTokenTransfer(address token, uint256 amount) external;\\r\\n}\",\"keccak256\":\"0xe565b0887688d1625e70316993d66adecc65890012d190a6e450ea7cb7d981b1\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\r\\n * checks.\\r\\n *\\r\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\r\\n * in bugs, because programmers usually assume that an overflow raises an\\r\\n * error, which is the standard behavior in high level programming languages.\\r\\n * `SafeMath` restores this intuition by reverting the transaction when an\\r\\n * operation overflows.\\r\\n *\\r\\n * Using this library instead of the unchecked operations eliminates an entire\\r\\n * class of bugs, so it's recommended to use it always.\\r\\n */\\r\\nlibrary SafeMath {\\r\\n /**\\r\\n * @dev Returns the addition of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `+` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Addition cannot overflow.\\r\\n */\\r\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n uint256 c = a + b;\\r\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n */\\r\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b <= a, errorMessage);\\r\\n uint256 c = a - b;\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `*` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Multiplication cannot overflow.\\r\\n */\\r\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\r\\n // benefit is lost if 'b' is also tested.\\r\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\r\\n if (a == 0) {\\r\\n return 0;\\r\\n }\\r\\n\\r\\n uint256 c = a * b;\\r\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n // Solidity only automatically asserts when dividing by 0\\r\\n require(b > 0, errorMessage);\\r\\n uint256 c = a / b;\\r\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts with custom message when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b != 0, errorMessage);\\r\\n return a % b;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x29ffa7ff59806a3add585615cc102b70b43049587dcc73649f77b427f35b009d\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @title Initializable\\r\\n *\\r\\n * @dev Helper contract to support initializer functions. To use it, replace\\r\\n * the constructor with a function that has the `initializer` modifier.\\r\\n * WARNING: Unlike constructors, initializer functions must be manually\\r\\n * invoked. This applies both to deploying an Initializable contract, as well\\r\\n * as extending an Initializable contract via inheritance.\\r\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\r\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\r\\n * because this is not dealt with automatically as with constructors.\\r\\n */\\r\\ncontract Initializable {\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract has been initialized.\\r\\n */\\r\\n bool private initialized;\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract is in the process of being initialized.\\r\\n */\\r\\n bool private initializing;\\r\\n\\r\\n /**\\r\\n * @dev Modifier to use in the initializer function of a contract.\\r\\n */\\r\\n modifier initializer() {\\r\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\r\\n\\r\\n bool isTopLevelCall = !initializing;\\r\\n if (isTopLevelCall) {\\r\\n initializing = true;\\r\\n initialized = true;\\r\\n }\\r\\n\\r\\n _;\\r\\n\\r\\n if (isTopLevelCall) {\\r\\n initializing = false;\\r\\n }\\r\\n }\\r\\n\\r\\n // Reserved storage space to allow for layout changes in the future.\\r\\n uint256[50] private ______gap;\\r\\n}\",\"keccak256\":\"0xc1f4d917648f0e17ba6a023a168173ad6163f3120e24d1c97ae294430e42eaf3\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Contract module which provides a basic access control mechanism, where\\r\\n * there is an account (an owner) that can be granted exclusive access to\\r\\n * specific functions.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the modifier\\r\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\r\\n * the owner.\\r\\n */\\r\\ncontract UpgradableOwnable is Initializable, Context {\\r\\n address private _owner;\\r\\n\\r\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract setting the deployer as the initial owner.\\r\\n */\\r\\n function initialize(address sender) public initializer {\\r\\n _owner = sender;\\r\\n emit OwnershipTransferred(address(0), _owner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the address of the current owner.\\r\\n */\\r\\n function owner() public view returns (address) {\\r\\n return _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Throws if called by any account other than the owner.\\r\\n */\\r\\n modifier onlyOwner() {\\r\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the caller is the current owner.\\r\\n */\\r\\n function isOwner() public view returns (bool) {\\r\\n return _msgSender() == _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Leaves the contract without owner. It will not be possible to call\\r\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\r\\n *\\r\\n * > Note: Renouncing ownership will leave the contract without an owner,\\r\\n * thereby removing any functionality that is only available to the owner.\\r\\n */\\r\\n function renounceOwnership() public onlyOwner {\\r\\n emit OwnershipTransferred(_owner, address(0));\\r\\n _owner = address(0);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n * Can only be called by the current owner.\\r\\n */\\r\\n function transferOwnership(address newOwner) public onlyOwner {\\r\\n _transferOwnership(newOwner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n */\\r\\n function _transferOwnership(address newOwner) internal {\\r\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\r\\n emit OwnershipTransferred(_owner, newOwner);\\r\\n _owner = newOwner;\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0xea920007e371a3300245b5885f72cecc472c4780818365f0025fae65a767273d\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\r\\n */\\r\\ncontract UpgradableSecondary is Initializable, Context {\\r\\n address private _primary;\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the primary contract changes.\\r\\n */\\r\\n event PrimaryTransferred(\\r\\n address recipient\\r\\n );\\r\\n\\r\\n /**\\r\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\r\\n */\\r\\n function __Secondary_init(address sender) public initializer {\\r\\n _primary = sender;\\r\\n emit PrimaryTransferred(_primary);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Reverts if called from any account other than the primary.\\r\\n */\\r\\n modifier onlyPrimary() {\\r\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @return the address of the primary.\\r\\n */\\r\\n function primary() public view returns (address) {\\r\\n return _primary;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers contract to a new primary.\\r\\n * @param recipient The address of new primary.\\r\\n */\\r\\n function transferPrimary(address recipient) public onlyPrimary {\\r\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\r\\n _primary = recipient;\\r\\n emit PrimaryTransferred(recipient);\\r\\n }\\r\\n\\r\\n}\",\"keccak256\":\"0xd98360c430635ed9e840b65faf7d40d1636ed49d391d889f04d9bc977d1a36aa\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50612331806100206000396000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80638f32d59b1161010f578063c4d66de8116100a2578063e4f89ae411610071578063e4f89ae4146103e3578063e744092e146103f6578063f2fde38b14610419578063f9eaee0d1461042c576101e5565b8063c4d66de8146103ad578063c6dbdf61146103c0578063d4164b5d146103c8578063d7516faa146103db576101e5565b8063adfeb5eb116100de578063adfeb5eb1461035d578063b348a29f14610370578063bb698dad14610383578063c361ce8314610396576101e5565b80638f32d59b1461030c57806390469a9d146103215780639d27d22614610334578063a81a8b1f14610355576101e5565b806354fd4d50116101875780637d496be9116101565780637d496be9146102d45780638c34bc55146102dc5780638da5cb5b146102ef5780638de52dd714610304576101e5565b806354fd4d501461029e578063601ad4c9146102a6578063715018a6146102b957806378bf2b53146102c1576101e5565b80632348238c116101c35780632348238c1461024c578063250540cf146102615780633777804f1461027457806353a8b57414610289576101e5565b806307fc9eb9146101ea5780630a9763d7146102175780631c21a08f1461022c575b600080fd5b6101fd6101f8366004611a65565b61043f565b60405161020e9594939291906122b4565b60405180910390f35b61021f61046e565b60405161020e9190612287565b61023f61023a366004611a65565b610473565b60405161020e9190611c39565b61025f61025a366004611725565b61051c565b005b61021f61026f366004611725565b6105db565b61027c610601565b60405161020e9190611bc3565b6102916106da565b60405161020e9190611b63565b61023f6107f9565b61025f6102b4366004611aa9565b610815565b61025f610849565b61025f6102cf366004611928565b6108b7565b61021f610a00565b61025f6102ea366004611928565b610a06565b6102f7610b7f565b60405161020e9190611b4f565b61021f610b8e565b610314610b94565b60405161020e9190611c11565b61025f61032f366004611725565b610bba565b610347610342366004611725565b610ce7565b60405161020e92919061224d565b61021f610d93565b61025f61036b366004611725565b610d99565b61025f61037e366004611a7d565b610e68565b61021f6103913660046119c1565b610e96565b61039e610f14565b60405161020e9392919061229e565b61025f6103bb366004611725565b610f22565b6102f7610fe6565b61025f6103d636600461173f565b610ff5565b61021f6110db565b61025f6103f1366004611951565b6110e1565b610409610404366004611725565b611175565b60405161020e9493929190611c1c565b61025f610427366004611725565b6111a0565b61031461043a366004611725565b6111d0565b603660205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b60fa81565b603a818154811061048357600080fd5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152935090918301828280156105145780601f106104e957610100808354040283529160200191610514565b820191906000526020600020905b8154815290600101906020018083116104f757829003601f168201915b505050505081565b6034546001600160a01b0316610530611219565b6001600160a01b03161461055f5760405162461bcd60e51b815260040161055690612143565b60405180910390fd5b6001600160a01b0381166105855760405162461bcd60e51b815260040161055690611f4b565b603480546001600160a01b0319166001600160a01b0383161790556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9906105d0908390611b4f565b60405180910390a150565b60008060006105e984610ce7565b915091506105f7828261121d565b925050505b919050565b603a5460609067ffffffffffffffff8111801561061d57600080fd5b5060405190808252806020026020018201604052801561065757816020015b6106446115b4565b81526020019060019003908161063c5790505b50905060005b603a548110156106d657603660008281526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250508282815181106106c357fe5b602090810291909101015260010161065d565b5090565b603a5460609067ffffffffffffffff811180156106f657600080fd5b5060405190808252806020026020018201604052801561072a57816020015b60608152602001906001900390816107155790505b50905060005b603a548110156106d657603a818154811061074757fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156107d55780601f106107aa576101008083540402835291602001916107d5565b820191906000526020600020905b8154815290600101906020018083116107b857829003601f168201915b50505050508282815181106107e657fe5b6020908102919091010152600101610730565b604080518082019091526002815261763160f01b602082015290565b61081d610b94565b6108395760405162461bcd60e51b815260040161055690611eb9565b610844838383611275565b505050565b610851610b94565b61086d5760405162461bcd60e51b815260040161055690611eb9565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b816001600160a01b0381166108de5760405162461bcd60e51b815260040161055690611e4d565b6108e6610b94565b8061091057506108f4610fe6565b6001600160a01b0316610905611219565b6001600160a01b0316145b61092c5760405162461bcd60e51b815260040161055690611e84565b603a54821061094d5760405162461bcd60e51b815260040161055690611cf1565b6001600160a01b038316600081815260356020818152604080842081516080810183528154600283018054838601908152600385018054606086019081526001808752868a018f81529b8d9052999098528451151560ff1990941693909317855597519690930195909555945190559051909155519091907f720764556647dd167f4229d6a4255ac86018e302a50fc29dd67a70edb7b314d0906109f2908690612287565b60405180910390a250505050565b60395481565b6034546001600160a01b0316610a1a611219565b6001600160a01b031614610a405760405162461bcd60e51b815260040161055690612143565b600080610a4c84610ce7565b91509150610a59846111d0565b610a755760405162461bcd60e51b8152600401610556906121d1565b8051831015610a965760405162461bcd60e51b815260040161055690612208565b81606001516201518001421115610ab557426060830152600060408301525b6000610ac1838361121d565b905080841115610ae35760405162461bcd60e51b815260040161055690611c4c565b6040830151610af29085611305565b60408481019182526001600160a01b038716600081815260356020908152908390208751815460ff191690151517815590870151600182015592516002840181905560608701516003909401849055915190927f84480cc6a063ffd72c3eddf21e3ffd30db3e2b8e386ec3abf09c98ee9e0e8d3492610b7092612290565b60405180910390a25050505050565b6033546001600160a01b031690565b60385481565b6033546000906001600160a01b0316610bab611219565b6001600160a01b031614905090565b806001600160a01b038116610be15760405162461bcd60e51b815260040161055690611e4d565b610be9610b94565b610c055760405162461bcd60e51b815260040161055690611eb9565b6001600160a01b0382166000908152603560209081526040918290208251608081018452815460ff161515808252600183015493820193909352600282015493810193909352600301546060830152610c705760405162461bcd60e51b815260040161055690612068565b60008082526001600160a01b0384168082526035602090815260408084208551815460ff191690151517815591850151600183015580850151600283015560608501516003909201919091555190917fbf996b4fd74f0c7159bb017b1db415b0d9a6f13129f46d0b93309d170b78df3191a2505050565b610cef6115e3565b610cf76115b4565b50506001600160a01b03166000908152603560209081526040808320815160808082018452825460ff1615158252600180840154838701819052600280860154858801526003958601546060808701919091529189526036885297869020865160a08101885281548152928101549783019790975296860154948101949094529184015494830194909452600490920154918101919091529091565b60375481565b600054610100900460ff1680610db2575060005460ff16155b610dce5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610df9576000805460ff1961ff0019909116610100171660011790555b603480546001600160a01b0319166001600160a01b0384811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610e4a921690611b4f565b60405180910390a18015610e64576000805461ff00191690555b5050565b610e70610b94565b610e8c5760405162461bcd60e51b815260040161055690611eb9565b610e64828261132a565b6000610ea0610b94565b610ebc5760405162461bcd60e51b815260040161055690611eb9565b610f0a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f059250505036859003850185611a4a565b61145c565b90505b9392505050565b603754603854603954909192565b600054610100900460ff1680610f3b575060005460ff16155b610f575760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610f82576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e64576000805461ff00191690555050565b6034546001600160a01b031690565b600054610100900460ff168061100e575060005460ff16155b61102a5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015611055576000805460ff1961ff0019909116610100171660011790555b61105e87610f22565b61106786610d99565b611072858585611275565b60005b82518110156110bf576110b683828151811061108d57fe5b6020026020010151600001518483815181106110a557fe5b60200260200101516020015161145c565b50600101611075565b5080156110d2576000805461ff00191690555b50505050505050565b603a5490565b6110e9610b94565b6111055760405162461bcd60e51b815260040161055690611eb9565b806111225760405162461bcd60e51b815260040161055690611dc8565b60005b818110156108445761116d83838381811061113c57fe5b6111529260206040909202019081019150611725565b84848481811061115e57fe5b905060400201602001356108b7565b600101611125565b603560205260009081526040902080546001820154600283015460039093015460ff90921692909184565b6111a8610b94565b6111c45760405162461bcd60e51b815260040161055690611eb9565b6111cd81611532565b50565b6000816001600160a01b0381166111f95760405162461bcd60e51b815260040161055690611e4d565b50506001600160a01b031660009081526035602052604090205460ff1690565b3390565b60008260600151620151800142111561123857600060408401525b826040015182604001511161124f5750600061126f565b82604001518260400151039050816020015181111561126f575060208101515b92915050565b818311156112955760405162461bcd60e51b815260040161055690611fde565b808211156112b55760405162461bcd60e51b8152600401610556906120f0565b6037839055603882905560398190556040517ffcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219906112f89085908590859061229e565b60405180910390a1505050565b600082820183811015610f0d5760405162461bcd60e51b815260040161055690611cba565b603a54821061134b5760405162461bcd60e51b815260040161055690611f95565b8051602082015110156113705760405162461bcd60e51b815260040161055690611d7b565b8060200151816040015110156113985760405162461bcd60e51b815260040161055690611dff565b80516060820151116113bc5760405162461bcd60e51b81526004016105569061209f565b80606001518160800151116113e35760405162461bcd60e51b815260040161055690611eee565b600082815260366020908152604091829020835181559083015160018201558183015160028201556060830151600382015560808301516004909101555182907f1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb9061145090849061223f565b60405180910390a25050565b60008083511161147e5760405162461bcd60e51b815260040161055690611c83565b50603a5460fa6001820111156114a65760405162461bcd60e51b815260040161055690612031565b603a805460018101825560009190915283516114e9917fa2999d817b6757290b50e8ecf3fa939673403dd35c97de392fdb343b4015ce9e0190602086019061160d565b506114f4818361132a565b807fb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0846040516115249190611c39565b60405180910390a292915050565b6001600160a01b0381166115585760405162461bcd60e51b81526004016105569061218f565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806000151581526020016000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826116435760008555611689565b82601f1061165c57805160ff1916838001178555611689565b82800160010185558215611689579182015b8281111561168957825182559160200191906001019061166e565b506106d69291505b808211156106d65760008155600101611691565b80356001600160a01b03811681146105fc57600080fd5b600060a082840312156116cd578081fd5b60405160a0810181811067ffffffffffffffff821117156116ea57fe5b806040525080915082358152602083013560208201526040830135604082015260608301356060820152608083013560808201525092915050565b600060208284031215611736578081fd5b610f0d826116a5565b60008060008060008060c08789031215611757578182fd5b611760876116a5565b955061176e602088016116a5565b945060408701359350606087013592506080870135915067ffffffffffffffff60a0880135111561179d578081fd5b60a0870135870188601f8201126117b2578182fd5b67ffffffffffffffff813511156117c557fe5b6117d4602080833502016122d7565b81358152602080820191908301845b84358110156119165760c0823586018e03601f19011215611802578586fd5b60405180604082011067ffffffffffffffff6040830111171561182157fe5b6040810160405267ffffffffffffffff60208435880101351115611843578687fd5b82358601602081013501603f018e1361185a578687fd5b67ffffffffffffffff60208435880181810135010135111561187857fe5b61189883358701602081810135909101810135601f01601f1916016122d7565b60208435880181810135019081013580835260409101018f10156118ba578788fd5b602084358801818101350180820135916040909101908301378335870160208181013582018101358301018990529082526118f9908f906040016116bc565b6020828101919091529085529384019391909101906001016117e3565b50508093505050509295509295509295565b6000806040838503121561193a578182fd5b611943836116a5565b946020939093013593505050565b60008060208385031215611963578182fd5b823567ffffffffffffffff8082111561197a578384fd5b818501915085601f83011261198d578384fd5b81358181111561199b578485fd5b8660206040830285010111156119af578485fd5b60209290920196919550909350505050565b600080600083850360c08112156119d6578384fd5b843567ffffffffffffffff808211156119ed578586fd5b818701915087601f830112611a00578586fd5b813581811115611a0e578687fd5b886020828501011115611a1f578687fd5b60209290920195509093505060a0601f1982011215611a3c578182fd5b506020840190509250925092565b600060a08284031215611a5b578081fd5b610f0d83836116bc565b600060208284031215611a76578081fd5b5035919050565b60008060c08385031215611a8f578182fd5b82359150611aa084602085016116bc565b90509250929050565b600080600060608486031215611abd578283fd5b505081359360208301359350604090920135919050565b60008151808452815b81811015611af957602081850181015186830182015201611add565b81811115611b0a5782602083870101525b50601f01601f19169290920160200192915050565b80518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b6001600160a01b0391909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611bb657603f19888603018452611ba4858351611ad4565b94509285019290850190600101611b88565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611c0557611bf2838551611b1f565b9284019260a09290920191600101611bdf565b50909695505050505050565b901515815260200190565b931515845260208401929092526040830152606082015260800190565b600060208252610f0d6020830184611ad4565b6020808252601b908201527f416c6c6f77546f6b656e733a204578636565646564206c696d69740000000000604082015260600190565b6020808252601e908201527f416c6c6f77546f6b656e733a20456d707479206465736372697074696f6e0000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526022908201527f416c6c6f77546f6b656e733a2074797065496420646f6573206e6f74206578696040820152611cdd60f21b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252602d908201527f416c6c6f77546f6b656e733a206d6178546f6b656e7320736d616c6c6572207460408201526c68616e206d696e546f6b656e7360981b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a20656d70747920746f6b656e7300000000000000604082015260600190565b6020808252602e908201527f416c6c6f77546f6b656e733a206461696c794c696d697420736d616c6c65722060408201526d7468616e206d6178546f6b656e7360901b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a204e756c6c204164647265737300000000000000604082015260600190565b6020808252818101527f416c6c6f77546f6b656e733a20756e617574686f72697a65642073656e646572604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526039908201527f416c6c6f77546f6b656e733a206c696d6974732e6c61726765416d6f756e742060408201527f736d616c6c6572207468616e206d656469756d416d6f756e7400000000000000606082015260800190565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f416c6c6f77546f6b656e733a20626967676572207468616e20747970654465736040820152686372697074696f6e7360b81b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a20736d616c6c20626967676572207468616e206d604082015272656469756d20636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252601e908201527f416c6c6f77546f6b656e733a2052656163686564204d41585f54595045530000604082015260600190565b60208082526018908201527f416c6c6f77546f6b656e733a204e6f7420416c6c6f7765640000000000000000604082015260600190565b60208082526031908201527f416c6c6f77546f6b656e733a206c696d6974732e6d656469756d416d6f756e746040820152701039b6b0b63632b9103a3430b71036b4b760791b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a206d656469756d20626967676572207468616e206040820152726c6172676520636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601c908201527f416c6c6f77546f6b656e733a204e6f742077686974656c697374656400000000604082015260600190565b6020808252601d908201527f416c6c6f77546f6b656e733a204c6f776572207468616e206c696d6974000000604082015260600190565b60a0810161126f8284611b1f565b600061012082019050835115158252602084015160208301526040840151604083015260608401516060830152610f0d6080830184611b1f565b90815260200190565b918252602082015260400190565b9283526020830191909152604082015260600190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff811182821017156122f357fe5b60405291905056fea2646970667358221220b8c803062aae1399048c52f7f09ef284f71855e36a2571b9d23d23a44a20ce7864736f6c63430007060033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101e55760003560e01c80638f32d59b1161010f578063c4d66de8116100a2578063e4f89ae411610071578063e4f89ae4146103e3578063e744092e146103f6578063f2fde38b14610419578063f9eaee0d1461042c576101e5565b8063c4d66de8146103ad578063c6dbdf61146103c0578063d4164b5d146103c8578063d7516faa146103db576101e5565b8063adfeb5eb116100de578063adfeb5eb1461035d578063b348a29f14610370578063bb698dad14610383578063c361ce8314610396576101e5565b80638f32d59b1461030c57806390469a9d146103215780639d27d22614610334578063a81a8b1f14610355576101e5565b806354fd4d50116101875780637d496be9116101565780637d496be9146102d45780638c34bc55146102dc5780638da5cb5b146102ef5780638de52dd714610304576101e5565b806354fd4d501461029e578063601ad4c9146102a6578063715018a6146102b957806378bf2b53146102c1576101e5565b80632348238c116101c35780632348238c1461024c578063250540cf146102615780633777804f1461027457806353a8b57414610289576101e5565b806307fc9eb9146101ea5780630a9763d7146102175780631c21a08f1461022c575b600080fd5b6101fd6101f8366004611a65565b61043f565b60405161020e9594939291906122b4565b60405180910390f35b61021f61046e565b60405161020e9190612287565b61023f61023a366004611a65565b610473565b60405161020e9190611c39565b61025f61025a366004611725565b61051c565b005b61021f61026f366004611725565b6105db565b61027c610601565b60405161020e9190611bc3565b6102916106da565b60405161020e9190611b63565b61023f6107f9565b61025f6102b4366004611aa9565b610815565b61025f610849565b61025f6102cf366004611928565b6108b7565b61021f610a00565b61025f6102ea366004611928565b610a06565b6102f7610b7f565b60405161020e9190611b4f565b61021f610b8e565b610314610b94565b60405161020e9190611c11565b61025f61032f366004611725565b610bba565b610347610342366004611725565b610ce7565b60405161020e92919061224d565b61021f610d93565b61025f61036b366004611725565b610d99565b61025f61037e366004611a7d565b610e68565b61021f6103913660046119c1565b610e96565b61039e610f14565b60405161020e9392919061229e565b61025f6103bb366004611725565b610f22565b6102f7610fe6565b61025f6103d636600461173f565b610ff5565b61021f6110db565b61025f6103f1366004611951565b6110e1565b610409610404366004611725565b611175565b60405161020e9493929190611c1c565b61025f610427366004611725565b6111a0565b61031461043a366004611725565b6111d0565b603660205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b60fa81565b603a818154811061048357600080fd5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152935090918301828280156105145780601f106104e957610100808354040283529160200191610514565b820191906000526020600020905b8154815290600101906020018083116104f757829003601f168201915b505050505081565b6034546001600160a01b0316610530611219565b6001600160a01b03161461055f5760405162461bcd60e51b815260040161055690612143565b60405180910390fd5b6001600160a01b0381166105855760405162461bcd60e51b815260040161055690611f4b565b603480546001600160a01b0319166001600160a01b0383161790556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9906105d0908390611b4f565b60405180910390a150565b60008060006105e984610ce7565b915091506105f7828261121d565b925050505b919050565b603a5460609067ffffffffffffffff8111801561061d57600080fd5b5060405190808252806020026020018201604052801561065757816020015b6106446115b4565b81526020019060019003908161063c5790505b50905060005b603a548110156106d657603660008281526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250508282815181106106c357fe5b602090810291909101015260010161065d565b5090565b603a5460609067ffffffffffffffff811180156106f657600080fd5b5060405190808252806020026020018201604052801561072a57816020015b60608152602001906001900390816107155790505b50905060005b603a548110156106d657603a818154811061074757fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156107d55780601f106107aa576101008083540402835291602001916107d5565b820191906000526020600020905b8154815290600101906020018083116107b857829003601f168201915b50505050508282815181106107e657fe5b6020908102919091010152600101610730565b604080518082019091526002815261763160f01b602082015290565b61081d610b94565b6108395760405162461bcd60e51b815260040161055690611eb9565b610844838383611275565b505050565b610851610b94565b61086d5760405162461bcd60e51b815260040161055690611eb9565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b816001600160a01b0381166108de5760405162461bcd60e51b815260040161055690611e4d565b6108e6610b94565b8061091057506108f4610fe6565b6001600160a01b0316610905611219565b6001600160a01b0316145b61092c5760405162461bcd60e51b815260040161055690611e84565b603a54821061094d5760405162461bcd60e51b815260040161055690611cf1565b6001600160a01b038316600081815260356020818152604080842081516080810183528154600283018054838601908152600385018054606086019081526001808752868a018f81529b8d9052999098528451151560ff1990941693909317855597519690930195909555945190559051909155519091907f720764556647dd167f4229d6a4255ac86018e302a50fc29dd67a70edb7b314d0906109f2908690612287565b60405180910390a250505050565b60395481565b6034546001600160a01b0316610a1a611219565b6001600160a01b031614610a405760405162461bcd60e51b815260040161055690612143565b600080610a4c84610ce7565b91509150610a59846111d0565b610a755760405162461bcd60e51b8152600401610556906121d1565b8051831015610a965760405162461bcd60e51b815260040161055690612208565b81606001516201518001421115610ab557426060830152600060408301525b6000610ac1838361121d565b905080841115610ae35760405162461bcd60e51b815260040161055690611c4c565b6040830151610af29085611305565b60408481019182526001600160a01b038716600081815260356020908152908390208751815460ff191690151517815590870151600182015592516002840181905560608701516003909401849055915190927f84480cc6a063ffd72c3eddf21e3ffd30db3e2b8e386ec3abf09c98ee9e0e8d3492610b7092612290565b60405180910390a25050505050565b6033546001600160a01b031690565b60385481565b6033546000906001600160a01b0316610bab611219565b6001600160a01b031614905090565b806001600160a01b038116610be15760405162461bcd60e51b815260040161055690611e4d565b610be9610b94565b610c055760405162461bcd60e51b815260040161055690611eb9565b6001600160a01b0382166000908152603560209081526040918290208251608081018452815460ff161515808252600183015493820193909352600282015493810193909352600301546060830152610c705760405162461bcd60e51b815260040161055690612068565b60008082526001600160a01b0384168082526035602090815260408084208551815460ff191690151517815591850151600183015580850151600283015560608501516003909201919091555190917fbf996b4fd74f0c7159bb017b1db415b0d9a6f13129f46d0b93309d170b78df3191a2505050565b610cef6115e3565b610cf76115b4565b50506001600160a01b03166000908152603560209081526040808320815160808082018452825460ff1615158252600180840154838701819052600280860154858801526003958601546060808701919091529189526036885297869020865160a08101885281548152928101549783019790975296860154948101949094529184015494830194909452600490920154918101919091529091565b60375481565b600054610100900460ff1680610db2575060005460ff16155b610dce5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610df9576000805460ff1961ff0019909116610100171660011790555b603480546001600160a01b0319166001600160a01b0384811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610e4a921690611b4f565b60405180910390a18015610e64576000805461ff00191690555b5050565b610e70610b94565b610e8c5760405162461bcd60e51b815260040161055690611eb9565b610e64828261132a565b6000610ea0610b94565b610ebc5760405162461bcd60e51b815260040161055690611eb9565b610f0a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f059250505036859003850185611a4a565b61145c565b90505b9392505050565b603754603854603954909192565b600054610100900460ff1680610f3b575060005460ff16155b610f575760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610f82576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e64576000805461ff00191690555050565b6034546001600160a01b031690565b600054610100900460ff168061100e575060005460ff16155b61102a5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015611055576000805460ff1961ff0019909116610100171660011790555b61105e87610f22565b61106786610d99565b611072858585611275565b60005b82518110156110bf576110b683828151811061108d57fe5b6020026020010151600001518483815181106110a557fe5b60200260200101516020015161145c565b50600101611075565b5080156110d2576000805461ff00191690555b50505050505050565b603a5490565b6110e9610b94565b6111055760405162461bcd60e51b815260040161055690611eb9565b806111225760405162461bcd60e51b815260040161055690611dc8565b60005b818110156108445761116d83838381811061113c57fe5b6111529260206040909202019081019150611725565b84848481811061115e57fe5b905060400201602001356108b7565b600101611125565b603560205260009081526040902080546001820154600283015460039093015460ff90921692909184565b6111a8610b94565b6111c45760405162461bcd60e51b815260040161055690611eb9565b6111cd81611532565b50565b6000816001600160a01b0381166111f95760405162461bcd60e51b815260040161055690611e4d565b50506001600160a01b031660009081526035602052604090205460ff1690565b3390565b60008260600151620151800142111561123857600060408401525b826040015182604001511161124f5750600061126f565b82604001518260400151039050816020015181111561126f575060208101515b92915050565b818311156112955760405162461bcd60e51b815260040161055690611fde565b808211156112b55760405162461bcd60e51b8152600401610556906120f0565b6037839055603882905560398190556040517ffcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219906112f89085908590859061229e565b60405180910390a1505050565b600082820183811015610f0d5760405162461bcd60e51b815260040161055690611cba565b603a54821061134b5760405162461bcd60e51b815260040161055690611f95565b8051602082015110156113705760405162461bcd60e51b815260040161055690611d7b565b8060200151816040015110156113985760405162461bcd60e51b815260040161055690611dff565b80516060820151116113bc5760405162461bcd60e51b81526004016105569061209f565b80606001518160800151116113e35760405162461bcd60e51b815260040161055690611eee565b600082815260366020908152604091829020835181559083015160018201558183015160028201556060830151600382015560808301516004909101555182907f1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb9061145090849061223f565b60405180910390a25050565b60008083511161147e5760405162461bcd60e51b815260040161055690611c83565b50603a5460fa6001820111156114a65760405162461bcd60e51b815260040161055690612031565b603a805460018101825560009190915283516114e9917fa2999d817b6757290b50e8ecf3fa939673403dd35c97de392fdb343b4015ce9e0190602086019061160d565b506114f4818361132a565b807fb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0846040516115249190611c39565b60405180910390a292915050565b6001600160a01b0381166115585760405162461bcd60e51b81526004016105569061218f565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806000151581526020016000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826116435760008555611689565b82601f1061165c57805160ff1916838001178555611689565b82800160010185558215611689579182015b8281111561168957825182559160200191906001019061166e565b506106d69291505b808211156106d65760008155600101611691565b80356001600160a01b03811681146105fc57600080fd5b600060a082840312156116cd578081fd5b60405160a0810181811067ffffffffffffffff821117156116ea57fe5b806040525080915082358152602083013560208201526040830135604082015260608301356060820152608083013560808201525092915050565b600060208284031215611736578081fd5b610f0d826116a5565b60008060008060008060c08789031215611757578182fd5b611760876116a5565b955061176e602088016116a5565b945060408701359350606087013592506080870135915067ffffffffffffffff60a0880135111561179d578081fd5b60a0870135870188601f8201126117b2578182fd5b67ffffffffffffffff813511156117c557fe5b6117d4602080833502016122d7565b81358152602080820191908301845b84358110156119165760c0823586018e03601f19011215611802578586fd5b60405180604082011067ffffffffffffffff6040830111171561182157fe5b6040810160405267ffffffffffffffff60208435880101351115611843578687fd5b82358601602081013501603f018e1361185a578687fd5b67ffffffffffffffff60208435880181810135010135111561187857fe5b61189883358701602081810135909101810135601f01601f1916016122d7565b60208435880181810135019081013580835260409101018f10156118ba578788fd5b602084358801818101350180820135916040909101908301378335870160208181013582018101358301018990529082526118f9908f906040016116bc565b6020828101919091529085529384019391909101906001016117e3565b50508093505050509295509295509295565b6000806040838503121561193a578182fd5b611943836116a5565b946020939093013593505050565b60008060208385031215611963578182fd5b823567ffffffffffffffff8082111561197a578384fd5b818501915085601f83011261198d578384fd5b81358181111561199b578485fd5b8660206040830285010111156119af578485fd5b60209290920196919550909350505050565b600080600083850360c08112156119d6578384fd5b843567ffffffffffffffff808211156119ed578586fd5b818701915087601f830112611a00578586fd5b813581811115611a0e578687fd5b886020828501011115611a1f578687fd5b60209290920195509093505060a0601f1982011215611a3c578182fd5b506020840190509250925092565b600060a08284031215611a5b578081fd5b610f0d83836116bc565b600060208284031215611a76578081fd5b5035919050565b60008060c08385031215611a8f578182fd5b82359150611aa084602085016116bc565b90509250929050565b600080600060608486031215611abd578283fd5b505081359360208301359350604090920135919050565b60008151808452815b81811015611af957602081850181015186830182015201611add565b81811115611b0a5782602083870101525b50601f01601f19169290920160200192915050565b80518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b6001600160a01b0391909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611bb657603f19888603018452611ba4858351611ad4565b94509285019290850190600101611b88565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611c0557611bf2838551611b1f565b9284019260a09290920191600101611bdf565b50909695505050505050565b901515815260200190565b931515845260208401929092526040830152606082015260800190565b600060208252610f0d6020830184611ad4565b6020808252601b908201527f416c6c6f77546f6b656e733a204578636565646564206c696d69740000000000604082015260600190565b6020808252601e908201527f416c6c6f77546f6b656e733a20456d707479206465736372697074696f6e0000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526022908201527f416c6c6f77546f6b656e733a2074797065496420646f6573206e6f74206578696040820152611cdd60f21b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252602d908201527f416c6c6f77546f6b656e733a206d6178546f6b656e7320736d616c6c6572207460408201526c68616e206d696e546f6b656e7360981b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a20656d70747920746f6b656e7300000000000000604082015260600190565b6020808252602e908201527f416c6c6f77546f6b656e733a206461696c794c696d697420736d616c6c65722060408201526d7468616e206d6178546f6b656e7360901b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a204e756c6c204164647265737300000000000000604082015260600190565b6020808252818101527f416c6c6f77546f6b656e733a20756e617574686f72697a65642073656e646572604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526039908201527f416c6c6f77546f6b656e733a206c696d6974732e6c61726765416d6f756e742060408201527f736d616c6c6572207468616e206d656469756d416d6f756e7400000000000000606082015260800190565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f416c6c6f77546f6b656e733a20626967676572207468616e20747970654465736040820152686372697074696f6e7360b81b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a20736d616c6c20626967676572207468616e206d604082015272656469756d20636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252601e908201527f416c6c6f77546f6b656e733a2052656163686564204d41585f54595045530000604082015260600190565b60208082526018908201527f416c6c6f77546f6b656e733a204e6f7420416c6c6f7765640000000000000000604082015260600190565b60208082526031908201527f416c6c6f77546f6b656e733a206c696d6974732e6d656469756d416d6f756e746040820152701039b6b0b63632b9103a3430b71036b4b760791b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a206d656469756d20626967676572207468616e206040820152726c6172676520636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601c908201527f416c6c6f77546f6b656e733a204e6f742077686974656c697374656400000000604082015260600190565b6020808252601d908201527f416c6c6f77546f6b656e733a204c6f776572207468616e206c696d6974000000604082015260600190565b60a0810161126f8284611b1f565b600061012082019050835115158252602084015160208301526040840151604083015260608401516060830152610f0d6080830184611b1f565b90815260200190565b918252602082015260400190565b9283526020830191909152604082015260600190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff811182821017156122f357fe5b60405291905056fea2646970667358221220b8c803062aae1399048c52f7f09ef284f71855e36a2571b9d23d23a44a20ce7864736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "__Secondary_init(address)": {
+ "details": "Sets the primary account to the one that is creating the Secondary contract."
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15789,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15792,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15832,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16076,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 16209,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_address"
+ },
+ {
+ "astId": 31,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "allowedTokens",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_mapping(t_address,t_struct(TokenInfo)7131_storage)"
+ },
+ {
+ "astId": 35,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeLimits",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_mapping(t_uint256,t_struct(Limits)7122_storage)"
+ },
+ {
+ "astId": 37,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "smallAmountConfirmations",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 39,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "mediumAmountConfirmations",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 41,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "largeAmountConfirmations",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 44,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeDescriptions",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_array(t_string_storage)dyn_storage"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "base": "t_string_storage",
+ "encoding": "dynamic_array",
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_struct(TokenInfo)7131_storage)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => struct IAllowTokens.TokenInfo)",
+ "numberOfBytes": "32",
+ "value": "t_struct(TokenInfo)7131_storage"
+ },
+ "t_mapping(t_uint256,t_struct(Limits)7122_storage)": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => struct IAllowTokens.Limits)",
+ "numberOfBytes": "32",
+ "value": "t_struct(Limits)7122_storage"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(Limits)7122_storage": {
+ "encoding": "inplace",
+ "label": "struct IAllowTokens.Limits",
+ "members": [
+ {
+ "astId": 7113,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "min",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7115,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "max",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7117,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "daily",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7119,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "mediumAmount",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7121,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "largeAmount",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "160"
+ },
+ "t_struct(TokenInfo)7131_storage": {
+ "encoding": "inplace",
+ "label": "struct IAllowTokens.TokenInfo",
+ "members": [
+ {
+ "astId": 7124,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "allowed",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 7126,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeId",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7128,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "spentToday",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7130,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "lastDay",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/AllowTokensProxy.json b/bridge/deployments/rinkeby/AllowTokensProxy.json
new file mode 100644
index 000000000..d8fdb4a08
--- /dev/null
+++ b/bridge/deployments/rinkeby/AllowTokensProxy.json
@@ -0,0 +1,426 @@
+{
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "transactionIndex": 0,
+ "gasUsed": "1682157",
+ "logsBloom": "0x04000000000000000000000000010800000400000000200000800000000000000000000000000000000000000000000000002000020400000000000000040000000012000000000000000020000000000001000100040000000000000000000008000000020000000000800000000800000000000000000000000000000000400000000400000000000000000004001000000800000000000000000000000000000000000000000000000100000004000000000000800000002000080000400000000000000004000000000000000000000008008000000000000000000060200000000080000000000200000000000000000020008000000000000000100000",
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206",
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ],
+ "data": "0x0000000000000000000000007e339118346364d7d86ab67cb0775cbb808e65f7",
+ "logIndex": 1,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0xfcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 2,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "data": "0x00000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000015af1d78b58c400000000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a0000",
+ "logIndex": 3,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034254430000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 4,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000001"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000028a857425466f800000000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000429d069189e0000",
+ "logIndex": 5,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000001"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034554480000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 6,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000002"
+ ],
+ "data": "0x00000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000878678326eac90000000000000000000000000000000000000000000000000010f0cf064dd59200000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a0000",
+ "logIndex": 7,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000002"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000083c31303030757364000000000000000000000000000000000000000000000000",
+ "logIndex": 8,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000003"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000054b40b1f852bda00000000000000000000000000000000000000000000000000a968163f0a57b4000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000008ac7230489e80000",
+ "logIndex": 9,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000003"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000073c31303075736400000000000000000000000000000000000000000000000000",
+ "logIndex": 10,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000004"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000002116545850052128000000000000000000000000000000000000000000000000422ca8b0a00a4250000000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000056bc75e2d63100000",
+ "logIndex": 11,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000004"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000053d31757364000000000000000000000000000000000000000000000000000000",
+ "logIndex": 12,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000005"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000cecb8f27f4200f3a0000000000000000000000000000000000000000000000019d971e4fe8401e740000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea00000",
+ "logIndex": 13,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000005"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000053c31757364000000000000000000000000000000000000000000000000000000",
+ "logIndex": 14,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000006"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000050c783eb9b5c85f2a80000000000000000000000000000000000000000000000a18f07d736b90be5500000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea00000",
+ "logIndex": 15,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9264199,
+ "transactionHash": "0x0f9d05da1411bab00561bbb7762e97a4158690e5bdaec43d20b819df518e1fed",
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000006"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000063c3163656e740000000000000000000000000000000000000000000000000000",
+ "logIndex": 16,
+ "blockHash": "0x87aaa649d318f20283747c526c920c0e6a5429c72fb61fe7a7d61167f0d80206"
+ }
+ ],
+ "blockNumber": 9264199,
+ "cumulativeGasUsed": "1682157",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0xBC7a3f163b2fe1d6810a942417922F09F1fe82eD",
+ "0x0b32Ea549AB1F9F7390442B5E9438b58A105cB5f",
+ "0xd4164b5d0000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b0000000000000000000000007e339118346364d7d86ab67cb0775cbb808e65f700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000015af1d78b58c400000000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000000003425443000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000028a857425466f800000000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000429d069189e00000000000000000000000000000000000000000000000000000000000000000003455448000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000878678326eac90000000000000000000000000000000000000000000000000010f0cf064dd59200000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000083c3130303075736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000054b40b1f852bda00000000000000000000000000000000000000000000000000a968163f0a57b4000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000073c3130307573640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000002116545850052128000000000000000000000000000000000000000000000000422ca8b0a00a4250000000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000053d3175736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000cecb8f27f4200f3a0000000000000000000000000000000000000000000000019d971e4fe8401e740000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000053c3175736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000050c783eb9b5c85f2a80000000000000000000000000000000000000000000000a18f07d736b90be5500000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000063c3163656e740000000000000000000000000000000000000000000000000000"
+ ],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"stateVariables\":{\"_ADMIN_SLOT\":{\"details\":\"Storage slot with the admin of the contract. This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\r\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\r\\n * be specified by overriding the virtual {_implementation} function.\\r\\n *\\r\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\r\\n * different contract through the {_delegate} function.\\r\\n *\\r\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\r\\n */\\r\\nabstract contract Proxy {\\r\\n /**\\r\\n * @dev Delegates the current call to `implementation`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _delegate(address implementation) internal virtual {\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n // Copy msg.data. We take full control of memory in this inline assembly\\r\\n // block because it will not return to Solidity code. We overwrite the\\r\\n // Solidity scratch pad at memory position 0.\\r\\n calldatacopy(0, 0, calldatasize())\\r\\n\\r\\n // Call the implementation.\\r\\n // out and outsize are 0 because we don't know the size yet.\\r\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\r\\n\\r\\n // Copy the returned data.\\r\\n returndatacopy(0, 0, returndatasize())\\r\\n\\r\\n switch result\\r\\n // delegatecall returns 0 on error.\\r\\n case 0 { revert(0, returndatasize()) }\\r\\n default { return(0, returndatasize()) }\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\r\\n * and {_fallback} should delegate.\\r\\n */\\r\\n function _implementation() internal view virtual returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _fallback() internal virtual {\\r\\n _beforeFallback();\\r\\n _delegate(_implementation());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\r\\n * function in the contract matches the call data.\\r\\n */\\r\\n fallback () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\r\\n * is empty.\\r\\n */\\r\\n receive () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\r\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\r\\n *\\r\\n * If overriden should call `super._beforeFallback()`.\\r\\n */\\r\\n function _beforeFallback() internal virtual {\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x6374180266624d2291abb230bdf0d364858fa164844f5d2d83ad5325852390c9\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./UpgradeableProxy.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\r\\n *\\r\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\r\\n * clashing], which can potentially be used in an attack, this contract uses the\\r\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\r\\n * things that go hand in hand:\\r\\n *\\r\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\r\\n * that call matches one of the admin functions exposed by the proxy itself.\\r\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\r\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\r\\n * \\\"admin cannot fallback to proxy target\\\".\\r\\n *\\r\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\r\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\r\\n * to sudden errors when trying to call a function from the proxy implementation.\\r\\n *\\r\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\r\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\r\\n */\\r\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\r\\n /**\\r\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\r\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\r\\n */\\r\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\r\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\r\\n _setAdmin(admin_);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the admin account has changed.\\r\\n */\\r\\n event AdminChanged(address previousAdmin, address newAdmin);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the admin of the contract.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\r\\n\\r\\n /**\\r\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\r\\n */\\r\\n modifier ifAdmin() {\\r\\n if (msg.sender == _admin()) {\\r\\n _;\\r\\n } else {\\r\\n _fallback();\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\r\\n */\\r\\n function admin() external ifAdmin returns (address admin_) {\\r\\n admin_ = _admin();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\r\\n */\\r\\n function implementation() external ifAdmin returns (address implementation_) {\\r\\n implementation_ = _implementation();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Changes the admin of the proxy.\\r\\n *\\r\\n * Emits an {AdminChanged} event.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\r\\n */\\r\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\r\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\r\\n emit AdminChanged(_admin(), newAdmin);\\r\\n _setAdmin(newAdmin);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\r\\n */\\r\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\r\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\r\\n * proxied contract.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\r\\n */\\r\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n Address.functionDelegateCall(newImplementation, data);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n */\\r\\n function _admin() internal view virtual returns (address adm) {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n adm := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 admin slot.\\r\\n */\\r\\n function _setAdmin(address newAdmin) private {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newAdmin)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\r\\n */\\r\\n function _beforeFallback() internal virtual override {\\r\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\r\\n super._beforeFallback();\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x7496c2c54dd8e648d6999687cf759521e6ab229d0d8ddb4db62f3b51dbe68811\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./Proxy.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\r\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\r\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\r\\n * implementation behind the proxy.\\r\\n *\\r\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\r\\n * {TransparentUpgradeableProxy}.\\r\\n */\\r\\ncontract UpgradeableProxy is Proxy {\\r\\n /**\\r\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\r\\n *\\r\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\r\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\r\\n */\\r\\n constructor(address _logic, bytes memory _data) payable {\\r\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\r\\n _setImplementation(_logic);\\r\\n if(_data.length > 0) {\\r\\n Address.functionDelegateCall(_logic, _data);\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the implementation is upgraded.\\r\\n */\\r\\n event Upgraded(address indexed implementation);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the address of the current implementation.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation address.\\r\\n */\\r\\n function _implementation() internal view virtual override returns (address impl) {\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n impl := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrades the proxy to a new implementation.\\r\\n *\\r\\n * Emits an {Upgraded} event.\\r\\n */\\r\\n function _upgradeTo(address newImplementation) internal virtual {\\r\\n _setImplementation(newImplementation);\\r\\n emit Upgraded(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 implementation slot.\\r\\n */\\r\\n function _setImplementation(address newImplementation) private {\\r\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\r\\n\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newImplementation)\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x4d3fcb8487e53abb8658817c4b90038b24d81d0a32d989f03b54d4cfab929f62\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000c9f38038062000c9f83398101604081905262000026916200022e565b8281620000338262000071565b8051156200005457620000528282620000d360201b620002ca1760201c565b505b506200005d9050565b620000688262000102565b5050506200041d565b62000087816200012660201b620002f61760201c565b620000af5760405162461bcd60e51b8152600401620000a69062000347565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6060620000fb838360405180606001604052806027815260200162000c786027913962000130565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b60606200013d8462000126565b6200015c5760405162461bcd60e51b8152600401620000a690620003a4565b600080856001600160a01b031685604051620001799190620002f4565b600060405180830381855af49150503d8060008114620001b6576040519150601f19603f3d011682016040523d82523d6000602084013e620001bb565b606091505b509092509050620001ce828286620001d8565b9695505050505050565b60608315620001e9575081620000fb565b825115620001fa5782518084602001fd5b8160405162461bcd60e51b8152600401620000a6919062000312565b80516001600160a01b03811681146200012b57600080fd5b60008060006060848603121562000243578283fd5b6200024e8462000216565b92506200025e6020850162000216565b60408501519092506001600160401b03808211156200027b578283fd5b818601915086601f8301126200028f578283fd5b8151818111156200029c57fe5b604051601f8201601f191681016020018381118282101715620002bb57fe5b604052818152838201602001891015620002d3578485fd5b620002e6826020830160208701620003ea565b809450505050509250925092565b6000825162000308818460208701620003ea565b9190910192915050565b600060208252825180602084015262000333816040850160208701620003ea565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b8381101562000407578181015183820152602001620003ed565b8381111562000417576000848401525b50505050565b61084b806200042d6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209ba77a19de177ea34b608207423a21765cca1077e9d39a414a7175e09fb147e464736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209ba77a19de177ea34b608207423a21765cca1077e9d39a414a7175e09fb147e464736f6c63430007060033",
+ "devdoc": {
+ "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.",
+ "events": {
+ "AdminChanged(address,address)": {
+ "details": "Emitted when the admin account has changed."
+ }
+ },
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "constructor": {
+ "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "stateVariables": {
+ "_ADMIN_SLOT": {
+ "details": "Storage slot with the admin of the contract. This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/Bridge.json b/bridge/deployments/rinkeby/Bridge.json
new file mode 100644
index 000000000..1d833fe6b
--- /dev/null
+++ b/bridge/deployments/rinkeby/Bridge.json
@@ -0,0 +1,1684 @@
+{
+ "address": "0x500f602F60B6d223F50aAc3750625Ec771ED3C57",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ }
+ ],
+ "name": "AcceptedCrossTransfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "AllowTokensChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_reciever",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ }
+ ],
+ "name": "Claimed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "_userData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Cross",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "FederationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "FeePercentageChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_newSideTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_newSymbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "NewSideToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Paused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "SideTokenFactoryChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Unpaused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "Upgrading",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "WrappedCurrencyChanged",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "CLAIM_TYPEHASH",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Pausable_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__PauserRol_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "acceptTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "addPauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "allowTokens",
+ "outputs": [
+ {
+ "internalType": "contract IAllowTokens",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "changeAllowTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "changeFederation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "changeSideTokenFactory",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claim",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claimFallback",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_deadline",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_v",
+ "type": "uint8"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_r",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_s",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimGasless",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_originalTokenDecimals",
+ "type": "uint8"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenName",
+ "type": "string"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "domainSeparator",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "feePercentageDivider",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFederation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFeePercentage",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "getTransactionDataHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasBeenClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasCrossed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initDomainSeparator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_federation",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_allowTokens",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_sideTokenFactory",
+ "type": "address"
+ },
+ {
+ "internalType": "string",
+ "name": "_symbolPrefix",
+ "type": "string"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isPauser",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isUpgrading",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "knownTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "mappedTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "nonces",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "originalTokenAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "originalTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "pause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "paused",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenToUse",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "receiveTokensTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renouncePauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "senderAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "setFeePercentage",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "setUpgrading",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "setWrappedCurrency",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "sideTokenFactory",
+ "outputs": [
+ {
+ "internalType": "contract ISideTokenFactory",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbolPrefix",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "userData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "tokensReceived",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionsDataHashes",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unpause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "wrappedCurrency",
+ "outputs": [
+ {
+ "internalType": "contract IWrapped",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x7111b46dbf037ef022e30d1a6cd54d8ca58737e3e950ace1a53c001ada1c2075",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0x500f602F60B6d223F50aAc3750625Ec771ED3C57",
+ "transactionIndex": 2,
+ "gasUsed": "3690987",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x87d449d1b3297e64a98ad3d67fd0ee2513a004e8d82d32e420b3400e1613a9e8",
+ "transactionHash": "0x7111b46dbf037ef022e30d1a6cd54d8ca58737e3e950ace1a53c001ada1c2075",
+ "logs": [],
+ "blockNumber": 9264194,
+ "cumulativeGasUsed": "3747451",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"}],\"name\":\"AcceptedCrossTransfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newAllowTokens\",\"type\":\"address\"}],\"name\":\"AllowTokensChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_reciever\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_relayer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"Claimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_userData\",\"type\":\"bytes\"}],\"name\":\"Cross\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newFederation\",\"type\":\"address\"}],\"name\":\"FederationChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"FeePercentageChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newSideTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_newSymbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_granularity\",\"type\":\"uint256\"}],\"name\":\"NewSideToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newSideTokenFactory\",\"type\":\"address\"}],\"name\":\"SideTokenFactoryChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"Upgrading\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_wrappedCurrency\",\"type\":\"address\"}],\"name\":\"WrappedCurrencyChanged\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"CLAIM_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__Pausable_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__PauserRol_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"}],\"name\":\"acceptTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"addPauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allowTokens\",\"outputs\":[{\"internalType\":\"contract IAllowTokens\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAllowTokens\",\"type\":\"address\"}],\"name\":\"changeAllowTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFederation\",\"type\":\"address\"}],\"name\":\"changeFederation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newSideTokenFactory\",\"type\":\"address\"}],\"name\":\"changeSideTokenFactory\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claim\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claimFallback\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"},{\"internalType\":\"address payable\",\"name\":\"_relayer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_s\",\"type\":\"bytes32\"}],\"name\":\"claimGasless\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"claimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"_originalTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"_originalTokenSymbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_originalTokenName\",\"type\":\"string\"}],\"name\":\"createSideToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"domainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePercentageDivider\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFederation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeePercentage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"}],\"name\":\"getTransactionDataHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasBeenClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasCrossed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initDomainSeparator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_federation\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_allowTokens\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_sideTokenFactory\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbolPrefix\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isPauser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUpgrading\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"knownTokens\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mappedTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"originalTokenAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"originalTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenToUse\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"receiveTokensTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renouncePauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"senderAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"setFeePercentage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"setUpgrading\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_wrappedCurrency\",\"type\":\"address\"}],\"name\":\"setWrappedCurrency\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sideTokenFactory\",\"outputs\":[{\"internalType\":\"contract ISideTokenFactory\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbolPrefix\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"userData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transactionsDataHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wrappedCurrency\",\"outputs\":[{\"internalType\":\"contract IWrapped\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"__Pausable_init(address)\":{\"details\":\"Initializes the contract in unpaused state. Assigns the Pauser role to the deployer.\"},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pause()\":{\"details\":\"Called by a pauser to pause, triggers stopped state.\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"unpause()\":{\"details\":\"Called by a pauser to unpause, returns to normal state.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"acceptTransfer(address,address,address,uint256,bytes32,bytes32,uint32)\":{\"notice\":\"Accepts the transaction from the other chain that was voted and sent by the Federation contract\"},\"claim((address,uint256,bytes32,bytes32,uint32))\":{\"notice\":\"Claims the crossed transaction using the hash, this sends the funds to the address indicated in\"},\"depositTo(address)\":{\"notice\":\"Use network currency and cross it.\"},\"receiveTokensTo(address,address,uint256)\":{\"notice\":\"ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction See https://eips.ethereum.org/EIPS/eip-777#motivation for details\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Bridge/Bridge.sol\":\"Bridge\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Bridge/Bridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n// Import base Initializable contract\\r\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\r\\n// Import interface and library from OpenZeppelin contracts\\r\\nimport \\\"../zeppelin/upgradable/utils/ReentrancyGuard.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\r\\n\\r\\nimport \\\"../zeppelin/introspection/IERC1820Registry.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC777/IERC777Recipient.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC20/IERC20.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC20/SafeERC20.sol\\\";\\r\\nimport \\\"../zeppelin/utils/Address.sol\\\";\\r\\nimport \\\"../zeppelin/math/SafeMath.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC777/IERC777.sol\\\";\\r\\n\\r\\nimport \\\"../lib/LibEIP712.sol\\\";\\r\\nimport \\\"../lib/LibUtils.sol\\\";\\r\\n\\r\\nimport \\\"../interface/IBridge.sol\\\";\\r\\nimport \\\"../interface/ISideToken.sol\\\";\\r\\nimport \\\"../interface/ISideTokenFactory.sol\\\";\\r\\nimport \\\"../interface/IAllowTokens.sol\\\";\\r\\nimport \\\"../interface/IWrapped.sol\\\";\\r\\n\\r\\n// solhint-disable-next-line max-states-count\\r\\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\\r\\n using SafeMath for uint256;\\r\\n using SafeERC20 for IERC20;\\r\\n using Address for address;\\r\\n\\r\\n address constant internal NULL_ADDRESS = address(0);\\r\\n bytes32 constant internal NULL_HASH = bytes32(0);\\r\\n IERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\r\\n\\r\\n address internal federation;\\r\\n uint256 internal feePercentage;\\r\\n string public symbolPrefix;\\r\\n // replaces uint256 internal _depprecatedLastDay;\\r\\n bytes32 public domainSeparator;\\r\\n uint256 internal _deprecatedSpentToday;\\r\\n\\r\\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\\r\\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\\r\\n mapping (address => bool) public knownTokens; // OriginalToken => true\\r\\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\\r\\n IAllowTokens public allowTokens;\\r\\n ISideTokenFactory public sideTokenFactory;\\r\\n //Bridge_v1 variables\\r\\n bool public isUpgrading;\\r\\n // Percentage with up to 2 decimals\\r\\n uint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\\r\\n //Bridge_v3 variables\\r\\n bytes32 constant internal _erc777Interface = keccak256(\\\"ERC777Token\\\"); // solhint-disable-line const-name-snakecase\\r\\n IWrapped public wrappedCurrency;\\r\\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\\r\\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\\r\\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\\r\\n\\r\\n // keccak256(\\\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\\\");\\r\\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\\r\\n mapping(address => uint) public nonces;\\r\\n\\r\\n event AllowTokensChanged(address _newAllowTokens);\\r\\n event FederationChanged(address _newFederation);\\r\\n event SideTokenFactoryChanged(address _newSideTokenFactory);\\r\\n event Upgrading(bool _isUpgrading);\\r\\n event WrappedCurrencyChanged(address _wrappedCurrency);\\r\\n\\r\\n function initialize(\\r\\n address _manager,\\r\\n address _federation,\\r\\n address _allowTokens,\\r\\n address _sideTokenFactory,\\r\\n string memory _symbolPrefix\\r\\n ) public initializer {\\r\\n UpgradableOwnable.initialize(_manager);\\r\\n UpgradablePausable.__Pausable_init(_manager);\\r\\n symbolPrefix = _symbolPrefix;\\r\\n allowTokens = IAllowTokens(_allowTokens);\\r\\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\\r\\n federation = _federation;\\r\\n //keccak256(\\\"ERC777TokensRecipient\\\")\\r\\n ERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\\r\\n initDomainSeparator();\\r\\n }\\r\\n\\r\\n receive () external payable {\\r\\n // The fallback function is needed to use WRBTC\\r\\n require(_msgSender() == address(wrappedCurrency), \\\"Bridge: not wrappedCurrency\\\");\\r\\n }\\r\\n\\r\\n function version() override external pure returns (string memory) {\\r\\n return \\\"v3\\\";\\r\\n }\\r\\n\\r\\n function initDomainSeparator() public {\\r\\n uint chainId;\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n chainId := chainid()\\r\\n }\\r\\n domainSeparator = LibEIP712.hashEIP712Domain(\\r\\n \\\"RSK Token Bridge\\\",\\r\\n \\\"1\\\",\\r\\n chainId,\\r\\n address(this)\\r\\n );\\r\\n }\\r\\n\\r\\n modifier whenNotUpgrading() {\\r\\n require(!isUpgrading, \\\"Bridge: Upgrading\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function acceptTransfer(\\r\\n address _originalTokenAddress,\\r\\n address payable _from,\\r\\n address payable _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external whenNotPaused nonReentrant override {\\r\\n require(_msgSender() == federation, \\\"Bridge: Not Federation\\\");\\r\\n require(knownTokens[_originalTokenAddress] ||\\r\\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\\r\\n \\\"Bridge: Unknown token\\\"\\r\\n );\\r\\n require(_to != NULL_ADDRESS, \\\"Bridge: Null To\\\");\\r\\n require(_amount > 0, \\\"Bridge: Amount 0\\\");\\r\\n require(_blockHash != NULL_HASH, \\\"Bridge: Null BlockHash\\\");\\r\\n require(_transactionHash != NULL_HASH, \\\"Bridge: Null TxHash\\\");\\r\\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \\\"Bridge: Already accepted\\\");\\r\\n\\r\\n bytes32 _transactionDataHash = getTransactionDataHash(\\r\\n _to,\\r\\n _amount,\\r\\n _blockHash,\\r\\n _transactionHash,\\r\\n _logIndex\\r\\n );\\r\\n // Do not remove, claimed also has the previously processed using the older bridge version\\r\\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\\r\\n require(!claimed[_transactionDataHash], \\\"Bridge: Already claimed\\\");\\r\\n\\r\\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\\r\\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\\r\\n senderAddresses[_transactionHash] = _from;\\r\\n\\r\\n emit AcceptedCrossTransfer(\\r\\n _transactionHash,\\r\\n _originalTokenAddress,\\r\\n _to,\\r\\n _from,\\r\\n _amount,\\r\\n _blockHash,\\r\\n _logIndex\\r\\n );\\r\\n }\\r\\n\\r\\n\\r\\n function createSideToken(\\r\\n uint256 _typeId,\\r\\n address _originalTokenAddress,\\r\\n uint8 _originalTokenDecimals,\\r\\n string calldata _originalTokenSymbol,\\r\\n string calldata _originalTokenName\\r\\n ) external onlyOwner {\\r\\n require(_originalTokenAddress != NULL_ADDRESS, \\\"Bridge: Null token\\\");\\r\\n address sideToken = mappedTokens[_originalTokenAddress];\\r\\n require(sideToken == NULL_ADDRESS, \\\"Bridge: Already exists\\\");\\r\\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\\r\\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\\r\\n\\r\\n // Create side token\\r\\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\\r\\n\\r\\n mappedTokens[_originalTokenAddress] = sideToken;\\r\\n originalTokens[sideToken] = _originalTokenAddress;\\r\\n allowTokens.setToken(sideToken, _typeId);\\r\\n\\r\\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\\r\\n }\\r\\n\\r\\n function claim(ClaimData calldata _claimData)\\r\\n external override returns (uint256 receivedAmount) {\\r\\n\\r\\n receivedAmount = _claim(\\r\\n _claimData,\\r\\n _claimData.to,\\r\\n payable(address(0)),\\r\\n 0\\r\\n );\\r\\n return receivedAmount;\\r\\n }\\r\\n\\r\\n function claimFallback(ClaimData calldata _claimData)\\r\\n external override returns (uint256 receivedAmount) {\\r\\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\\\"Bridge: invalid sender\\\");\\r\\n receivedAmount = _claim(\\r\\n _claimData,\\r\\n _msgSender(),\\r\\n payable(address(0)),\\r\\n 0\\r\\n );\\r\\n return receivedAmount;\\r\\n }\\r\\n\\r\\n function getDigest(\\r\\n ClaimData memory _claimData,\\r\\n address payable _relayer,\\r\\n uint256 _fee,\\r\\n uint256 _deadline\\r\\n ) internal returns (bytes32) {\\r\\n return LibEIP712.hashEIP712Message(\\r\\n domainSeparator,\\r\\n keccak256(\\r\\n abi.encode(\\r\\n CLAIM_TYPEHASH,\\r\\n _claimData.to,\\r\\n _claimData.amount,\\r\\n _claimData.transactionHash,\\r\\n _relayer,\\r\\n _fee,\\r\\n nonces[_claimData.to]++,\\r\\n _deadline\\r\\n )\\r\\n )\\r\\n );\\r\\n }\\r\\n\\r\\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\\r\\n function claimGasless(\\r\\n ClaimData calldata _claimData,\\r\\n address payable _relayer,\\r\\n uint256 _fee,\\r\\n uint256 _deadline,\\r\\n uint8 _v,\\r\\n bytes32 _r,\\r\\n bytes32 _s\\r\\n ) external override returns (uint256 receivedAmount) {\\r\\n require(_deadline >= block.timestamp, \\\"Bridge: EXPIRED\\\"); // solhint-disable-line not-rely-on-time\\r\\n\\r\\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\\r\\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\\r\\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \\\"Bridge: INVALID_SIGNATURE\\\");\\r\\n\\r\\n receivedAmount = _claim(\\r\\n _claimData,\\r\\n _claimData.to,\\r\\n _relayer,\\r\\n _fee\\r\\n );\\r\\n return receivedAmount;\\r\\n }\\r\\n\\r\\n function _claim(\\r\\n ClaimData calldata _claimData,\\r\\n address payable _reciever,\\r\\n address payable _relayer,\\r\\n uint256 _fee\\r\\n ) internal nonReentrant returns (uint256 receivedAmount) {\\r\\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\\r\\n require(originalTokenAddress != NULL_ADDRESS, \\\"Bridge: Tx not crossed\\\");\\r\\n\\r\\n bytes32 transactionDataHash = getTransactionDataHash(\\r\\n _claimData.to,\\r\\n _claimData.amount,\\r\\n _claimData.blockHash,\\r\\n _claimData.transactionHash,\\r\\n _claimData.logIndex\\r\\n );\\r\\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \\\"Bridge: Wrong transactionDataHash\\\");\\r\\n require(!claimed[transactionDataHash], \\\"Bridge: Already claimed\\\");\\r\\n\\r\\n claimed[transactionDataHash] = true;\\r\\n if (knownTokens[originalTokenAddress]) {\\r\\n receivedAmount =_claimCrossBackToToken(\\r\\n originalTokenAddress,\\r\\n _reciever,\\r\\n _claimData.amount,\\r\\n _relayer,\\r\\n _fee\\r\\n );\\r\\n } else {\\r\\n receivedAmount =_claimCrossToSideToken(\\r\\n originalTokenAddress,\\r\\n _reciever,\\r\\n _claimData.amount,\\r\\n _relayer,\\r\\n _fee\\r\\n );\\r\\n }\\r\\n emit Claimed(\\r\\n _claimData.transactionHash,\\r\\n originalTokenAddress,\\r\\n _claimData.to,\\r\\n senderAddresses[_claimData.transactionHash],\\r\\n _claimData.amount,\\r\\n _claimData.blockHash,\\r\\n _claimData.logIndex,\\r\\n _reciever,\\r\\n _relayer,\\r\\n _fee\\r\\n );\\r\\n return receivedAmount;\\r\\n }\\r\\n\\r\\n function _claimCrossToSideToken(\\r\\n address _originalTokenAddress,\\r\\n address payable _receiver,\\r\\n uint256 _amount,\\r\\n address payable _relayer,\\r\\n uint256 _fee\\r\\n ) internal returns (uint256 receivedAmount) {\\r\\n address sideToken = mappedTokens[_originalTokenAddress];\\r\\n uint256 granularity = IERC777(sideToken).granularity();\\r\\n uint256 formattedAmount = _amount.mul(granularity);\\r\\n require(_fee <= formattedAmount, \\\"Bridge: fee too high\\\");\\r\\n receivedAmount = formattedAmount - _fee;\\r\\n ISideToken(sideToken).mint(_receiver, receivedAmount, \\\"\\\", \\\"\\\");\\r\\n if(_fee > 0) {\\r\\n ISideToken(sideToken).mint(_relayer, _fee, \\\"\\\", \\\"relayer fee\\\");\\r\\n }\\r\\n return receivedAmount;\\r\\n }\\r\\n\\r\\n function _claimCrossBackToToken(\\r\\n address _originalTokenAddress,\\r\\n address payable _receiver,\\r\\n uint256 _amount,\\r\\n address payable _relayer,\\r\\n uint256 _fee\\r\\n ) internal returns (uint256 receivedAmount) {\\r\\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\\r\\n //As side tokens are ERC777 they will always have 18 decimals\\r\\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\\r\\n require(_fee <= formattedAmount, \\\"Bridge: fee too high\\\");\\r\\n receivedAmount = formattedAmount - _fee;\\r\\n if(address(wrappedCurrency) == _originalTokenAddress) {\\r\\n wrappedCurrency.withdraw(formattedAmount);\\r\\n _receiver.transfer(receivedAmount);\\r\\n if(_fee > 0) {\\r\\n _relayer.transfer(_fee);\\r\\n }\\r\\n } else {\\r\\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\\r\\n if(_fee > 0) {\\r\\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\\r\\n }\\r\\n }\\r\\n return receivedAmount;\\r\\n }\\r\\n\\r\\n /**\\r\\n * ERC-20 tokens approve and transferFrom pattern\\r\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\r\\n */\\r\\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\\r\\n address sender = _msgSender();\\r\\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\\r\\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\\r\\n crossTokens(tokenToUse, sender, to, amount, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * Use network currency and cross it.\\r\\n */\\r\\n function depositTo(address to) override external payable {\\r\\n address sender = _msgSender();\\r\\n require(address(wrappedCurrency) != NULL_ADDRESS, \\\"Bridge: wrappedCurrency empty\\\");\\r\\n wrappedCurrency.deposit{ value: msg.value }();\\r\\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\r\\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\r\\n */\\r\\n function tokensReceived (\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata\\r\\n ) external override(IBridge, IERC777Recipient){\\r\\n //Hook from ERC777address\\r\\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\\r\\n require(to == address(this), \\\"Bridge: Not to this address\\\");\\r\\n address tokenToUse = _msgSender();\\r\\n require(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \\\"Bridge: Not ERC777 token\\\");\\r\\n require(userData.length != 0 || !from.isContract(), \\\"Bridge: Specify receiver address in data\\\");\\r\\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\\r\\n crossTokens(tokenToUse, from, receiver, amount, userData);\\r\\n }\\r\\n\\r\\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\\r\\n internal whenNotUpgrading whenNotPaused nonReentrant {\\r\\n knownTokens[tokenToUse] = true;\\r\\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\\r\\n uint256 amountMinusFees = amount.sub(fee);\\r\\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\\r\\n uint formattedAmount = amount;\\r\\n if(decimals != 18) {\\r\\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\\r\\n }\\r\\n // We consider the amount before fees converted to 18 decimals to check the limits\\r\\n // updateTokenTransfer revert if token not allowed\\r\\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\\r\\n address originalTokenAddress = tokenToUse;\\r\\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\\r\\n //Side Token Crossing\\r\\n originalTokenAddress = originalTokens[tokenToUse];\\r\\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\\r\\n uint256 modulo = amountMinusFees.mod(granularity);\\r\\n fee = fee.add(modulo);\\r\\n amountMinusFees = amountMinusFees.sub(modulo);\\r\\n IERC777(tokenToUse).burn(amountMinusFees, userData);\\r\\n }\\r\\n\\r\\n emit Cross(\\r\\n originalTokenAddress,\\r\\n from,\\r\\n to,\\r\\n amountMinusFees,\\r\\n userData\\r\\n );\\r\\n\\r\\n if (fee > 0) {\\r\\n //Send the payment to the MultiSig of the Federation\\r\\n IERC20(tokenToUse).safeTransfer(owner(), fee);\\r\\n }\\r\\n }\\r\\n\\r\\n function getTransactionDataHash(\\r\\n address _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n )\\r\\n public pure override returns(bytes32)\\r\\n {\\r\\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\\r\\n }\\r\\n\\r\\n function setFeePercentage(uint amount) external onlyOwner {\\r\\n require(amount < (feePercentageDivider/10), \\\"Bridge: bigger than 10%\\\");\\r\\n feePercentage = amount;\\r\\n emit FeePercentageChanged(feePercentage);\\r\\n }\\r\\n\\r\\n function getFeePercentage() external view override returns(uint) {\\r\\n return feePercentage;\\r\\n }\\r\\n\\r\\n function changeFederation(address newFederation) external onlyOwner {\\r\\n require(newFederation != NULL_ADDRESS, \\\"Bridge: Federation is empty\\\");\\r\\n federation = newFederation;\\r\\n emit FederationChanged(federation);\\r\\n }\\r\\n\\r\\n\\r\\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\\r\\n require(newAllowTokens != NULL_ADDRESS, \\\"Bridge: AllowTokens is empty\\\");\\r\\n allowTokens = IAllowTokens(newAllowTokens);\\r\\n emit AllowTokensChanged(newAllowTokens);\\r\\n }\\r\\n\\r\\n function getFederation() external view returns(address) {\\r\\n return federation;\\r\\n }\\r\\n\\r\\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\\r\\n require(newSideTokenFactory != NULL_ADDRESS, \\\"Bridge: SideTokenFactory is empty\\\");\\r\\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\\r\\n emit SideTokenFactoryChanged(newSideTokenFactory);\\r\\n }\\r\\n\\r\\n function setUpgrading(bool _isUpgrading) external onlyOwner {\\r\\n isUpgrading = _isUpgrading;\\r\\n emit Upgrading(isUpgrading);\\r\\n }\\r\\n\\r\\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\\r\\n require(_wrappedCurrency != NULL_ADDRESS, \\\"Bridge: wrapp is empty\\\");\\r\\n wrappedCurrency = IWrapped(_wrappedCurrency);\\r\\n emit WrappedCurrencyChanged(_wrappedCurrency);\\r\\n }\\r\\n\\r\\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\\r\\n return transactionsDataHashes[transactionHash] != bytes32(0);\\r\\n }\\r\\n\\r\\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\\r\\n return claimed[transactionsDataHashes[transactionHash]];\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0x04b4af913df0dcd2c965b9550422687963b67ad588f9ba26cec50eb3c305ab7b\",\"license\":\"MIT\"},\"contracts/interface/IAllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IAllowTokens {\\r\\n\\r\\n struct Limits {\\r\\n uint256 min;\\r\\n uint256 max;\\r\\n uint256 daily;\\r\\n uint256 mediumAmount;\\r\\n uint256 largeAmount;\\r\\n }\\r\\n\\r\\n struct TokenInfo {\\r\\n bool allowed;\\r\\n uint256 typeId;\\r\\n uint256 spentToday;\\r\\n uint256 lastDay;\\r\\n }\\r\\n\\r\\n struct TypeInfo {\\r\\n string description;\\r\\n Limits limits;\\r\\n }\\r\\n\\r\\n struct TokensAndType {\\r\\n address token;\\r\\n uint256 typeId;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\\r\\n\\r\\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\\r\\n\\r\\n function getTypesLimits() external view returns(Limits[] memory limits);\\r\\n\\r\\n function getTypeDescriptionsLength() external view returns(uint256);\\r\\n\\r\\n function getTypeDescriptions() external view returns(string[] memory descriptions);\\r\\n\\r\\n function setToken(address token, uint256 typeId) external;\\r\\n\\r\\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\\r\\n\\r\\n function isTokenAllowed(address token) external view returns (bool);\\r\\n\\r\\n function updateTokenTransfer(address token, uint256 amount) external;\\r\\n}\",\"keccak256\":\"0xe565b0887688d1625e70316993d66adecc65890012d190a6e450ea7cb7d981b1\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IBridge {\\r\\n\\r\\n struct ClaimData {\\r\\n address payable to;\\r\\n uint256 amount;\\r\\n bytes32 blockHash;\\r\\n bytes32 transactionHash;\\r\\n uint32 logIndex;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getFeePercentage() external view returns(uint);\\r\\n\\r\\n /**\\r\\n * ERC-20 tokens approve and transferFrom pattern\\r\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\r\\n */\\r\\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\\r\\n\\r\\n /**\\r\\n * Use network currency and cross it.\\r\\n */\\r\\n function depositTo(address to) external payable;\\r\\n\\r\\n /**\\r\\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\r\\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\r\\n */\\r\\n function tokensReceived (\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\r\\n */\\r\\n function acceptTransfer(\\r\\n address _originalTokenAddress,\\r\\n address payable _from,\\r\\n address payable _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\r\\n */\\r\\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\r\\n\\r\\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\r\\n\\r\\n function claimGasless(\\r\\n ClaimData calldata _claimData,\\r\\n address payable _relayer,\\r\\n uint256 _fee,\\r\\n uint256 _deadline,\\r\\n uint8 _v,\\r\\n bytes32 _r,\\r\\n bytes32 _s\\r\\n ) external returns (uint256 receivedAmount);\\r\\n\\r\\n function getTransactionDataHash(\\r\\n address _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external returns(bytes32);\\r\\n\\r\\n event Cross(\\r\\n address indexed _tokenAddress,\\r\\n address indexed _from,\\r\\n address indexed _to,\\r\\n uint256 _amount,\\r\\n bytes _userData\\r\\n );\\r\\n event NewSideToken(\\r\\n address indexed _newSideTokenAddress,\\r\\n address indexed _originalTokenAddress,\\r\\n string _newSymbol,\\r\\n uint256 _granularity\\r\\n );\\r\\n event AcceptedCrossTransfer(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _from,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex\\r\\n );\\r\\n event FeePercentageChanged(uint256 _amount);\\r\\n event Claimed(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _sender,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex,\\r\\n address _reciever,\\r\\n address _relayer,\\r\\n uint256 _fee\\r\\n );\\r\\n}\",\"keccak256\":\"0x9e48ff075a1e3fd0533feec4b93f397a4678b5d267cbae021ea0faf8cc91a383\",\"license\":\"MIT\"},\"contracts/interface/ISideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideToken {\\r\\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\\r\\n}\",\"keccak256\":\"0x22b96c1de44cc83f38f93cb0bebac0d090b88e1d951373eefdceb2b4284d6ffa\",\"license\":\"MIT\"},\"contracts/interface/ISideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideTokenFactory {\\r\\n\\r\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\\r\\n\\r\\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\\r\\n}\",\"keccak256\":\"0xbac49cc8df91c7aae47037ac9b3956615399bc6fa01d2a49764a7e6e48085b14\",\"license\":\"MIT\"},\"contracts/interface/IWrapped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IWrapped {\\r\\n function balanceOf(address) external returns(uint);\\r\\n\\r\\n function deposit() external payable;\\r\\n\\r\\n function withdraw(uint wad) external;\\r\\n\\r\\n function totalSupply() external view returns (uint);\\r\\n\\r\\n function approve(address guy, uint wad) external returns (bool);\\r\\n\\r\\n function transfer(address dst, uint wad) external returns (bool);\\r\\n\\r\\n function transferFrom(address src, address dst, uint wad)\\r\\n external\\r\\n returns (bool);\\r\\n}\",\"keccak256\":\"0xb79b74797d9b4102d4ba69d452ed04bae742e34240c3aa72f654de525b29a5c7\",\"license\":\"MIT\"},\"contracts/lib/LibEIP712.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\\r\\nlibrary LibEIP712 {\\r\\n\\r\\n // Hash of the EIP712 Domain Separator Schema\\r\\n // keccak256(abi.encodePacked(\\r\\n // \\\"EIP712Domain(\\\",\\r\\n // \\\"string name,\\\",\\r\\n // \\\"string version,\\\",\\r\\n // \\\"uint256 chainId,\\\",\\r\\n // \\\"address verifyingContract\\\",\\r\\n // \\\")\\\"\\r\\n // ))\\r\\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\\r\\n\\r\\n /// @dev Calculates a EIP712 domain separator.\\r\\n /// @param name The EIP712 domain name.\\r\\n /// @param version The EIP712 domain version.\\r\\n /// @param verifyingContract The EIP712 verifying contract.\\r\\n /// @return result EIP712 domain separator.\\r\\n function hashEIP712Domain(\\r\\n string memory name,\\r\\n string memory version,\\r\\n uint256 chainId,\\r\\n address verifyingContract\\r\\n )\\r\\n internal\\r\\n pure\\r\\n returns (bytes32 result)\\r\\n {\\r\\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\\r\\n\\r\\n // Assembly for more efficient computing:\\r\\n // keccak256(abi.encodePacked(\\r\\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\\r\\n // keccak256(bytes(name)),\\r\\n // keccak256(bytes(version)),\\r\\n // chainId,\\r\\n // uint256(verifyingContract)\\r\\n // ))\\r\\n\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n // Calculate hashes of dynamic data\\r\\n let nameHash := keccak256(add(name, 32), mload(name))\\r\\n let versionHash := keccak256(add(version, 32), mload(version))\\r\\n\\r\\n // Load free memory pointer\\r\\n let memPtr := mload(64)\\r\\n\\r\\n // Store params in memory\\r\\n mstore(memPtr, schemaHash)\\r\\n mstore(add(memPtr, 32), nameHash)\\r\\n mstore(add(memPtr, 64), versionHash)\\r\\n mstore(add(memPtr, 96), chainId)\\r\\n mstore(add(memPtr, 128), verifyingContract)\\r\\n\\r\\n // Compute hash\\r\\n result := keccak256(memPtr, 160)\\r\\n }\\r\\n return result;\\r\\n }\\r\\n\\r\\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\\r\\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\\r\\n /// with getDomainHash().\\r\\n /// @param hashStruct The EIP712 hash struct.\\r\\n /// @return result EIP712 hash applied to the given EIP712 Domain.\\r\\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\\r\\n internal\\r\\n pure\\r\\n returns (bytes32 result)\\r\\n {\\r\\n // Assembly for more efficient computing:\\r\\n // keccak256(abi.encodePacked(\\r\\n // EIP191_HEADER,\\r\\n // EIP712_DOMAIN_HASH,\\r\\n // hashStruct\\r\\n // ));\\r\\n\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n // Load free memory pointer\\r\\n let memPtr := mload(64)\\r\\n\\r\\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\\r\\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\\r\\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\\r\\n\\r\\n // Compute hash\\r\\n result := keccak256(memPtr, 66)\\r\\n }\\r\\n return result;\\r\\n }\\r\\n}\",\"keccak256\":\"0xfcfcf60905df9a2644e372c9e76b8cc7a5034c5c4d6d9f44b1ffb56244551237\",\"license\":\"MIT\"},\"contracts/lib/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nlibrary LibUtils {\\r\\n\\r\\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\\r\\n require(decimals <= 18, \\\"LibUtils: Decimals not <= 18\\\");\\r\\n return uint256(10)**(18-decimals);\\r\\n }\\r\\n\\r\\n function getDecimals(address tokenToUse) internal view returns (uint8) {\\r\\n //support decimals as uint256 or uint8\\r\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"decimals()\\\"));\\r\\n require(success, \\\"LibUtils: No decimals\\\");\\r\\n // uint: enc(X) is the big-endian encoding of X,\\r\\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\\r\\n return uint8(abi.decode(data, (uint256)));\\r\\n }\\r\\n\\r\\n function getGranularity(address tokenToUse) internal view returns (uint256) {\\r\\n //support granularity if ERC777\\r\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"granularity()\\\"));\\r\\n require(success, \\\"LibUtils: No granularity\\\");\\r\\n\\r\\n return abi.decode(data, (uint256));\\r\\n }\\r\\n\\r\\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n addr := mload(add(bys,20))\\r\\n }\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0x9e289497bfdbde6ef762efab3d91e581cc83116929b69851e64da33a8d790196\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/access/Roles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @title Roles\\r\\n * @dev Library for managing addresses assigned to a Role.\\r\\n */\\r\\nlibrary Roles {\\r\\n struct Role {\\r\\n mapping (address => bool) bearer;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Give an account access to this role.\\r\\n */\\r\\n function add(Role storage role, address account) internal {\\r\\n require(!has(role, account), \\\"Roles: account already has role\\\");\\r\\n role.bearer[account] = true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Remove an account's access to this role.\\r\\n */\\r\\n function remove(Role storage role, address account) internal {\\r\\n require(has(role, account), \\\"Roles: account doesn't have role\\\");\\r\\n role.bearer[account] = false;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Check if an account has this role.\\r\\n * @return bool\\r\\n */\\r\\n function has(Role storage role, address account) internal view returns (bool) {\\r\\n require(account != address(0), \\\"Roles: account is the zero address\\\");\\r\\n return role.bearer[account];\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x51be0ac4cc78172ee6ee886a4779e6b8f289420541d28be81f3c427c5118c298\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC1820Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\r\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\r\\n * implementers for interfaces in this registry, as well as query support.\\r\\n *\\r\\n * Implementers may be shared by multiple accounts, and can also implement more\\r\\n * than a single interface for each account. Contracts can implement interfaces\\r\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\r\\n * contract.\\r\\n *\\r\\n * {IERC165} interfaces can also be queried via the registry.\\r\\n *\\r\\n * For an in-depth explanation and source code analysis, see the EIP text.\\r\\n */\\r\\ninterface IERC1820Registry {\\r\\n /**\\r\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\r\\n * account is able to set interface implementers for it.\\r\\n *\\r\\n * By default, each account is its own manager. Passing a value of `0x0` in\\r\\n * `newManager` will reset the manager to this initial state.\\r\\n *\\r\\n * Emits a {ManagerChanged} event.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the caller must be the current manager for `account`.\\r\\n */\\r\\n function setManager(address account, address newManager) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the manager for `account`.\\r\\n *\\r\\n * See {setManager}.\\r\\n */\\r\\n function getManager(address account) external view returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Sets the `implementer` contract as `account`'s implementer for\\r\\n * `interfaceHash`.\\r\\n *\\r\\n * `account` being the zero address is an alias for the caller's address.\\r\\n * The zero address can also be used in `implementer` to remove an old one.\\r\\n *\\r\\n * See {interfaceHash} to learn how these are created.\\r\\n *\\r\\n * Emits an {InterfaceImplementerSet} event.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the caller must be the current manager for `_account`.\\r\\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\r\\n * end in 28 zeroes).\\r\\n * - `_implementer` must implement {IERC1820Implementer} and return true when\\r\\n * queried for support, unless `implementer` is the caller. See\\r\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\r\\n */\\r\\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\\r\\n * implementer is registered, returns the zero address.\\r\\n *\\r\\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\r\\n * zeroes), `_account` will be queried for support of it.\\r\\n *\\r\\n * `account` being the zero address is an alias for the caller's address.\\r\\n */\\r\\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\r\\n * corresponding\\r\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\r\\n */\\r\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\r\\n\\r\\n /**\\r\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\r\\n * @param account Address of the contract for which to update the cache.\\r\\n * @param interfaceId ERC165 interface for which to update the cache.\\r\\n */\\r\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\r\\n\\r\\n /**\\r\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\r\\n * If the result is not cached a direct lookup on the contract address is performed.\\r\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\r\\n * {updateERC165Cache} with the contract address.\\r\\n * @param account Address of the contract to check.\\r\\n * @param interfaceId ERC165 interface to check.\\r\\n * @return True if `account` implements `interfaceId`, false otherwise.\\r\\n */\\r\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\\r\\n * @param account Address of the contract to check.\\r\\n * @param interfaceId ERC165 interface to check.\\r\\n * @return True if `account` implements `interfaceId`, false otherwise.\\r\\n */\\r\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\r\\n\\r\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\r\\n\\r\\n event ManagerChanged(address indexed account, address indexed newManager);\\r\\n}\\r\\n\",\"keccak256\":\"0x0c607a83a8f5ec2f214bc754ffb59428d90978e122108fcd91ba193d5fc78018\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\r\\n * checks.\\r\\n *\\r\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\r\\n * in bugs, because programmers usually assume that an overflow raises an\\r\\n * error, which is the standard behavior in high level programming languages.\\r\\n * `SafeMath` restores this intuition by reverting the transaction when an\\r\\n * operation overflows.\\r\\n *\\r\\n * Using this library instead of the unchecked operations eliminates an entire\\r\\n * class of bugs, so it's recommended to use it always.\\r\\n */\\r\\nlibrary SafeMath {\\r\\n /**\\r\\n * @dev Returns the addition of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `+` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Addition cannot overflow.\\r\\n */\\r\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n uint256 c = a + b;\\r\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n */\\r\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b <= a, errorMessage);\\r\\n uint256 c = a - b;\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `*` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Multiplication cannot overflow.\\r\\n */\\r\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\r\\n // benefit is lost if 'b' is also tested.\\r\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\r\\n if (a == 0) {\\r\\n return 0;\\r\\n }\\r\\n\\r\\n uint256 c = a * b;\\r\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n // Solidity only automatically asserts when dividing by 0\\r\\n require(b > 0, errorMessage);\\r\\n uint256 c = a / b;\\r\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts with custom message when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b != 0, errorMessage);\\r\\n return a % b;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x29ffa7ff59806a3add585615cc102b70b43049587dcc73649f77b427f35b009d\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\r\\n * the optional functions; to access them see {ERC20Detailed}.\\r\\n */\\r\\ninterface IERC20 {\\r\\n /**\\r\\n * @dev Returns the amount of tokens in existence.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens owned by `account`.\\r\\n */\\r\\n function balanceOf(address account) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transfer(address recipient, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Returns the remaining number of tokens that `spender` will be\\r\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\r\\n * zero by default.\\r\\n *\\r\\n * This value changes when {approve} or {transferFrom} are called.\\r\\n */\\r\\n function allowance(address owner, address spender) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\r\\n * that someone may use both the old and the new allowance by unfortunate\\r\\n * transaction ordering. One possible solution to mitigate this race\\r\\n * condition is to first reduce the spender's allowance to 0 and set the\\r\\n * desired value afterwards:\\r\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\r\\n *\\r\\n * Emits an {Approval} event.\\r\\n */\\r\\n function approve(address spender, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\r\\n * allowance mechanism. `amount` is then deducted from the caller's\\r\\n * allowance.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\r\\n * another (`to`).\\r\\n *\\r\\n * Note that `value` may be zero.\\r\\n */\\r\\n event Transfer(address indexed from, address indexed to, uint256 value);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\r\\n * a call to {approve}. `value` is the new allowance.\\r\\n */\\r\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\r\\n}\\r\\n\",\"keccak256\":\"0x7531f90b8a5a04fd225fb07a30e0792068438a7c82127a22db870c1849460dfc\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./IERC20.sol\\\";\\r\\nimport \\\"../../math/SafeMath.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title SafeERC20\\r\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\r\\n * contract returns false). Tokens that return no value (and instead revert or\\r\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\r\\n * successful.\\r\\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\\r\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\r\\n */\\r\\nlibrary SafeERC20 {\\r\\n using SafeMath for uint256;\\r\\n using Address for address;\\r\\n\\r\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\r\\n }\\r\\n\\r\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\r\\n }\\r\\n\\r\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\r\\n // safeApprove should only be called when setting an initial allowance,\\r\\n // or when resetting it to zero. To increase and decrease it, use\\r\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\r\\n // solhint-disable-next-line max-line-length\\r\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\r\\n \\\"SafeERC20: approve non-zero to non-zero allowance\\\"\\r\\n );\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\r\\n }\\r\\n\\r\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\r\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\r\\n }\\r\\n\\r\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\r\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\r\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\r\\n * @param token The token targeted by the call.\\r\\n * @param data The call data (encoded using abi.encode or one of its variants).\\r\\n */\\r\\n function callOptionalReturn(IERC20 token, bytes memory data) private {\\r\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\r\\n // we're implementing it ourselves.\\r\\n\\r\\n // A Solidity high level call has three parts:\\r\\n // 1. The target address is checked to verify it contains contract code\\r\\n // 2. The call itself is made, and success asserted\\r\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\r\\n // solhint-disable-next-line max-line-length\\r\\n require(address(token).isContract(), \\\"SafeERC20: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = address(token).call(data);\\r\\n require(success, \\\"SafeERC20: low-level call failed\\\");\\r\\n\\r\\n if (returndata.length > 0) { // Return data is optional\\r\\n // solhint-disable-next-line max-line-length\\r\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x393fa2aef898c565ba8c8816ac0e2d0e31865d2866e4807f39f1a8cef95f5a81\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC777Token standard as defined in the EIP.\\r\\n *\\r\\n * This contract uses the\\r\\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\\r\\n * token holders and recipients react to token movements by using setting implementers\\r\\n * for the associated interfaces in said registry. See `IERC1820Registry` and\\r\\n * `ERC1820Implementer`.\\r\\n */\\r\\ninterface IERC777 {\\r\\n /**\\r\\n * @dev Returns the name of the token.\\r\\n */\\r\\n function name() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the symbol of the token, usually a shorter version of the\\r\\n * name.\\r\\n */\\r\\n function symbol() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the smallest part of the token that is not divisible. This\\r\\n * means all token operations (creation, movement and destruction) must have\\r\\n * amounts that are a multiple of this number.\\r\\n *\\r\\n * For most token contracts, this value will equal 1.\\r\\n */\\r\\n function granularity() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens in existence.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens owned by an account (`owner`).\\r\\n */\\r\\n function balanceOf(address owner) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\r\\n *\\r\\n * If send or receive hooks are registered for the caller and `recipient`,\\r\\n * the corresponding functions will be called with `data` and empty\\r\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\r\\n *\\r\\n * Emits a `Sent` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - the caller must have at least `amount` tokens.\\r\\n * - `recipient` cannot be the zero address.\\r\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\r\\n * interface.\\r\\n */\\r\\n function send(address recipient, uint256 amount, bytes calldata data) external;\\r\\n\\r\\n /**\\r\\n * @dev Destroys `amount` tokens from the caller's account, reducing the\\r\\n * total supply.\\r\\n *\\r\\n * If a send hook is registered for the caller, the corresponding function\\r\\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\\r\\n *\\r\\n * Emits a `Burned` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - the caller must have at least `amount` tokens.\\r\\n */\\r\\n function burn(uint256 amount, bytes calldata data) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns true if an account is an operator of `tokenHolder`.\\r\\n * Operators can send and burn tokens on behalf of their owners. All\\r\\n * accounts are their own operator.\\r\\n *\\r\\n * See `operatorSend` and `operatorBurn`.\\r\\n */\\r\\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Make an account an operator of the caller.\\r\\n *\\r\\n * See `isOperatorFor`.\\r\\n *\\r\\n * Emits an `AuthorizedOperator` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `operator` cannot be calling address.\\r\\n */\\r\\n function authorizeOperator(address operator) external;\\r\\n\\r\\n /**\\r\\n * @dev Make an account an operator of the caller.\\r\\n *\\r\\n * See `isOperatorFor` and `defaultOperators`.\\r\\n *\\r\\n * Emits a `RevokedOperator` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `operator` cannot be calling address.\\r\\n */\\r\\n function revokeOperator(address operator) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the list of default operators. These accounts are operators\\r\\n * for all token holders, even if `authorizeOperator` was never called on\\r\\n * them.\\r\\n *\\r\\n * This list is immutable, but individual holders may revoke these via\\r\\n * `revokeOperator`, in which case `isOperatorFor` will return false.\\r\\n */\\r\\n function defaultOperators() external view returns (address[] memory);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\\r\\n * be an operator of `sender`.\\r\\n *\\r\\n * If send or receive hooks are registered for `sender` and `recipient`,\\r\\n * the corresponding functions will be called with `data` and\\r\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\r\\n *\\r\\n * Emits a `Sent` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `sender` cannot be the zero address.\\r\\n * - `sender` must have at least `amount` tokens.\\r\\n * - the caller must be an operator for `sender`.\\r\\n * - `recipient` cannot be the zero address.\\r\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\r\\n * interface.\\r\\n */\\r\\n function operatorSend(\\r\\n address sender,\\r\\n address recipient,\\r\\n uint256 amount,\\r\\n bytes calldata data,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\\r\\n * The caller must be an operator of `account`.\\r\\n *\\r\\n * If a send hook is registered for `account`, the corresponding function\\r\\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\\r\\n *\\r\\n * Emits a `Burned` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `account` cannot be the zero address.\\r\\n * - `account` must have at least `amount` tokens.\\r\\n * - the caller must be an operator for `account`.\\r\\n */\\r\\n function operatorBurn(\\r\\n address account,\\r\\n uint256 amount,\\r\\n bytes calldata data,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n\\r\\n event Sent(\\r\\n address indexed operator,\\r\\n address indexed from,\\r\\n address indexed to,\\r\\n uint256 amount,\\r\\n bytes data,\\r\\n bytes operatorData\\r\\n );\\r\\n\\r\\n function decimals() external returns (uint8);\\r\\n\\r\\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\\r\\n\\r\\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\\r\\n\\r\\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\\r\\n\\r\\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\\r\\n}\\r\\n\",\"keccak256\":\"0xf9947f4f7572e74766fcb4de1d58c6c26cd31379fd5d4b885cdbdf14a16dbe94\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\r\\n *\\r\\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\\r\\n * contract implement this interface (contract holders can be their own\\r\\n * implementer) and registering it on the\\r\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\r\\n *\\r\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\r\\n */\\r\\ninterface IERC777Recipient {\\r\\n /**\\r\\n * @dev Called by an `IERC777` token contract whenever tokens are being\\r\\n * moved or created into a registered account (`to`). The type of operation\\r\\n * is conveyed by `from` being the zero address or not.\\r\\n *\\r\\n * This call occurs _after_ the token contract's state is updated, so\\r\\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\\r\\n *\\r\\n * This function may revert to prevent the operation from being executed.\\r\\n */\\r\\n function tokensReceived(\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n}\\r\\n\",\"keccak256\":\"0x1f43e427174c60bacb510e63053626e5b24d825333e9921bb7c1ea673b1c6e1e\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @title Initializable\\r\\n *\\r\\n * @dev Helper contract to support initializer functions. To use it, replace\\r\\n * the constructor with a function that has the `initializer` modifier.\\r\\n * WARNING: Unlike constructors, initializer functions must be manually\\r\\n * invoked. This applies both to deploying an Initializable contract, as well\\r\\n * as extending an Initializable contract via inheritance.\\r\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\r\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\r\\n * because this is not dealt with automatically as with constructors.\\r\\n */\\r\\ncontract Initializable {\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract has been initialized.\\r\\n */\\r\\n bool private initialized;\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract is in the process of being initialized.\\r\\n */\\r\\n bool private initializing;\\r\\n\\r\\n /**\\r\\n * @dev Modifier to use in the initializer function of a contract.\\r\\n */\\r\\n modifier initializer() {\\r\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\r\\n\\r\\n bool isTopLevelCall = !initializing;\\r\\n if (isTopLevelCall) {\\r\\n initializing = true;\\r\\n initialized = true;\\r\\n }\\r\\n\\r\\n _;\\r\\n\\r\\n if (isTopLevelCall) {\\r\\n initializing = false;\\r\\n }\\r\\n }\\r\\n\\r\\n // Reserved storage space to allow for layout changes in the future.\\r\\n uint256[50] private ______gap;\\r\\n}\",\"keccak256\":\"0xc1f4d917648f0e17ba6a023a168173ad6163f3120e24d1c97ae294430e42eaf3\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../../GSN/Context.sol\\\";\\r\\nimport \\\"../../../access/Roles.sol\\\";\\r\\n\\r\\ncontract UpgradablePauserRole is Initializable, Context {\\r\\n using Roles for Roles.Role;\\r\\n\\r\\n event PauserAdded(address indexed account);\\r\\n event PauserRemoved(address indexed account);\\r\\n\\r\\n Roles.Role private _pausers;\\r\\n\\r\\n function __PauserRol_init(address sender) public initializer {\\r\\n if (!isPauser(sender)) {\\r\\n _addPauser(sender);\\r\\n }\\r\\n }\\r\\n\\r\\n modifier onlyPauser() {\\r\\n require(isPauser(_msgSender()), \\\"PauserRole: caller doesn't have the role\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function isPauser(address account) public view returns (bool) {\\r\\n return _pausers.has(account);\\r\\n }\\r\\n\\r\\n function addPauser(address account) public onlyPauser {\\r\\n _addPauser(account);\\r\\n }\\r\\n\\r\\n function renouncePauser() public {\\r\\n _removePauser(_msgSender());\\r\\n }\\r\\n\\r\\n function _addPauser(address account) internal {\\r\\n _pausers.add(account);\\r\\n emit PauserAdded(account);\\r\\n }\\r\\n\\r\\n function _removePauser(address account) internal {\\r\\n _pausers.remove(account);\\r\\n emit PauserRemoved(account);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x175465830c1ec77cab5ebdcfaeca43c79d33f3becded5332ed6136adac3f99eb\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"../access/roles/UpgradablePauserRole.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Contract module which allows children to implement an emergency stop\\r\\n * mechanism that can be triggered by an authorized account.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the\\r\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\r\\n * the functions of your contract. Note that they will not be pausable by\\r\\n * simply including this module, only once the modifiers are put in place.\\r\\n */\\r\\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\\r\\n /**\\r\\n * @dev Emitted when the pause is triggered by a pauser (`account`).\\r\\n */\\r\\n event Paused(address account);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the pause is lifted by a pauser (`account`).\\r\\n */\\r\\n event Unpaused(address account);\\r\\n\\r\\n bool private _paused;\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\\r\\n * to the deployer.\\r\\n */\\r\\n function __Pausable_init(address sender) public initializer {\\r\\n UpgradablePauserRole.__PauserRol_init(sender);\\r\\n\\r\\n _paused = false;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the contract is paused, and false otherwise.\\r\\n */\\r\\n function paused() public view returns (bool) {\\r\\n return _paused;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Modifier to make a function callable only when the contract is not paused.\\r\\n */\\r\\n modifier whenNotPaused() {\\r\\n require(!_paused, \\\"Pausable: paused\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Modifier to make a function callable only when the contract is paused.\\r\\n */\\r\\n modifier whenPaused() {\\r\\n require(_paused, \\\"Pausable: not paused\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Called by a pauser to pause, triggers stopped state.\\r\\n */\\r\\n function pause() public onlyPauser whenNotPaused {\\r\\n _paused = true;\\r\\n emit Paused(_msgSender());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Called by a pauser to unpause, returns to normal state.\\r\\n */\\r\\n function unpause() public onlyPauser whenPaused {\\r\\n _paused = false;\\r\\n emit Unpaused(_msgSender());\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x0837df4a389f73b7210b97b1b64ba8f9cc842367b473f8fc856c4e892f212ac4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Contract module which provides a basic access control mechanism, where\\r\\n * there is an account (an owner) that can be granted exclusive access to\\r\\n * specific functions.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the modifier\\r\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\r\\n * the owner.\\r\\n */\\r\\ncontract UpgradableOwnable is Initializable, Context {\\r\\n address private _owner;\\r\\n\\r\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract setting the deployer as the initial owner.\\r\\n */\\r\\n function initialize(address sender) public initializer {\\r\\n _owner = sender;\\r\\n emit OwnershipTransferred(address(0), _owner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the address of the current owner.\\r\\n */\\r\\n function owner() public view returns (address) {\\r\\n return _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Throws if called by any account other than the owner.\\r\\n */\\r\\n modifier onlyOwner() {\\r\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the caller is the current owner.\\r\\n */\\r\\n function isOwner() public view returns (bool) {\\r\\n return _msgSender() == _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Leaves the contract without owner. It will not be possible to call\\r\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\r\\n *\\r\\n * > Note: Renouncing ownership will leave the contract without an owner,\\r\\n * thereby removing any functionality that is only available to the owner.\\r\\n */\\r\\n function renounceOwnership() public onlyOwner {\\r\\n emit OwnershipTransferred(_owner, address(0));\\r\\n _owner = address(0);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n * Can only be called by the current owner.\\r\\n */\\r\\n function transferOwnership(address newOwner) public onlyOwner {\\r\\n _transferOwnership(newOwner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n */\\r\\n function _transferOwnership(address newOwner) internal {\\r\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\r\\n emit OwnershipTransferred(_owner, newOwner);\\r\\n _owner = newOwner;\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0xea920007e371a3300245b5885f72cecc472c4780818365f0025fae65a767273d\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title Helps contracts guard against reentrancy attacks.\\r\\n * @author Remco Bloemen , Eenae \\r\\n * @dev If you mark a function `nonReentrant`, you should also\\r\\n * mark it `external`.\\r\\n */\\r\\ncontract ReentrancyGuard is Initializable {\\r\\n /// @dev counter to allow mutex lock with only one SSTORE operation\\r\\n uint256 private _guardCounter;\\r\\n\\r\\n function initialize() public initializer {\\r\\n // The counter starts at one to prevent changing it from zero to a non-zero\\r\\n // value, which is a more expensive operation.\\r\\n _guardCounter = 1;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\r\\n * Calling a `nonReentrant` function from another `nonReentrant`\\r\\n * function is not supported. It is possible to prevent this from happening\\r\\n * by making the `nonReentrant` function external, and make it call a\\r\\n * `private` function that does the actual work.\\r\\n */\\r\\n modifier nonReentrant() {\\r\\n _guardCounter += 1;\\r\\n uint256 localCounter = _guardCounter;\\r\\n _;\\r\\n require(localCounter == _guardCounter, \\\"ReentrancyGuard: no reentrant allowed\\\");\\r\\n }\\r\\n}\",\"keccak256\":\"0x67a8148c8357409eac291fc0954ca7a2d023b0534294be95f34eba0b15d748a5\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b506141d0806100206000396000f3fe6080604052600436106103025760003560e01c80638456cb5911610190578063c4d66de8116100dc578063e6fc774411610095578063f2fde38b1161006f578063f2fde38b146108b0578063f698da25146108d0578063f74032f0146108e5578063fa0caa16146109055761034c565b8063e6fc774414610866578063ea2170911461087b578063eb16136f146108905761034c565b8063c4d66de8146107b1578063ca07140c146107d1578063cc3c0f06146107f1578063d12e825d14610811578063da67703714610826578063e6ede14d146108465761034c565b8063ae06c1b711610149578063b50277bb11610123578063b50277bb14610754578063b760faf914610774578063b794726214610787578063b86f60d21461079c5761034c565b8063ae06c1b7146106ff578063afad80ac1461071f578063b0e1268e1461073f5761034c565b80638456cb591461066b5780638da5cb5b146106805780638f32d59b14610695578063916dc59d146106aa578063a53d6e6e146106ca578063adc5fb64146106df5761034c565b80634beea5061161024f5780636b0509b1116102085780637813bea2116101e25780637813bea2146105f65780637ecebe00146106165780638129fc1c1461063657806382dc1ec41461064b5761034c565b80636b0509b1146105b75780636ef8d66d146105cc578063715018a6146105e15761034c565b80634beea5061461050b57806354fd4d501461052b57806359a8a8671461054d5780635c975abb146105625780635d447129146105775780636a863191146105975761034c565b80632fb3b361116102bc5780633cf3058b116102965780633cf3058b146104895780633f4ba83a146104b657806342cdb2c6146104cb57806346fbf68e146104eb5761034c565b80632fb3b3611461041c5780633500c1dc1461043c57806337e761091461045c5761034c565b806223de2914610351578063026976191461037157806307c8f7b0146103a757806311efbf61146103c757806320e3bb00146103dc5780632f3cca4e146103fc5761034c565b3661034c576041546001600160a01b031661031b610925565b6001600160a01b03161461034a5760405162461bcd60e51b815260040161034190613e39565b60405180910390fd5b005b600080fd5b34801561035d57600080fd5b5061034a61036c3660046130c0565b610929565b34801561037d57600080fd5b5061039161038c366004613237565b610b20565b60405161039e9190613693565b60405180910390f35b3480156103b357600080fd5b5061034a6103c23660046131ff565b610b32565b3480156103d357600080fd5b50610391610bb0565b3480156103e857600080fd5b5061034a6103f7366004613368565b610bb6565b34801561040857600080fd5b5061034a610417366004612f3e565b610df1565b34801561042857600080fd5b5061034a610437366004612fec565b610e7a565b34801561044857600080fd5b5061034a610457366004612f3e565b610fea565b34801561046857600080fd5b5061047c610477366004613237565b61107f565b60405161039e9190613688565b34801561049557600080fd5b506104a96104a4366004613237565b6110a4565b60405161039e919061351f565b3480156104c257600080fd5b5061034a6110bf565b3480156104d757600080fd5b5061034a6104e6366004612f3e565b611152565b3480156104f757600080fd5b5061047c610506366004612f3e565b6111e5565b34801561051757600080fd5b5061039161052636600461326a565b6111f8565b34801561053757600080fd5b50610540611312565b60405161039e919061374f565b34801561055957600080fd5b5061054061132e565b34801561056e57600080fd5b5061047c6113bc565b34801561058357600080fd5b5061047c610592366004612f3e565b6113c5565b3480156105a357600080fd5b5061034a6105b2366004612f76565b6113da565b3480156105c357600080fd5b5061039161163e565b3480156105d857600080fd5b5061034a611662565b3480156105ed57600080fd5b5061034a611674565b34801561060257600080fd5b5061034a61061136600461316e565b6116e8565b34801561062257600080fd5b50610391610631366004612f3e565b61172b565b34801561064257600080fd5b5061034a61173d565b34801561065757600080fd5b5061034a610666366004612f3e565b6117b7565b34801561067757600080fd5b5061034a6117e7565b34801561068c57600080fd5b506104a9611867565b3480156106a157600080fd5b5061047c61187b565b3480156106b657600080fd5b5061034a6106c5366004612f3e565b6118a6565b3480156106d657600080fd5b506104a961193b565b3480156106eb57600080fd5b506103916106fa36600461324f565b61194a565b34801561070b57600080fd5b5061034a61071a366004613237565b6119a9565b34801561072b57600080fd5b5061039161073a3660046131ae565b611a23565b34801561074b57600080fd5b506104a9611a5f565b34801561076057600080fd5b5061039161076f36600461324f565b611a6e565b61034a610782366004612f3e565b611a81565b34801561079357600080fd5b5061047c611b50565b3480156107a857600080fd5b506104a9611b60565b3480156107bd57600080fd5b5061034a6107cc366004612f3e565b611b6f565b3480156107dd57600080fd5b506104a96107ec366004613237565b611c3a565b3480156107fd57600080fd5b5061047c61080c366004613237565b611c55565b34801561081d57600080fd5b5061034a611c6a565b34801561083257600080fd5b5061047c610841366004613237565b611cc2565b34801561085257600080fd5b506104a9610861366004612f3e565b611cd6565b34801561087257600080fd5b50610391611cf1565b34801561088757600080fd5b506104a9611cf7565b34801561089c57600080fd5b5061034a6108ab366004612f3e565b611d06565b3480156108bc57600080fd5b5061034a6108cb366004612f3e565b611d91565b3480156108dc57600080fd5b50610391611dbe565b3480156108f157600080fd5b506104a9610900366004612f3e565b611dc4565b34801561091157600080fd5b5061034a610920366004612f3e565b611ddf565b3390565b6001600160a01b03881630141561093f57610b16565b6001600160a01b03861630146109675760405162461bcd60e51b815260040161034190613b0d565b6000610971610925565b60405163555ddc6560e11b8152909150600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906109d09085907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce217705490600401613627565b60206040518083038186803b1580156109e857600080fd5b505afa1580156109fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a209190612f5a565b6001600160a01b03161415610a475760405162461bcd60e51b815260040161034190613f0e565b83151580610a645750610a62886001600160a01b0316611e7a565b155b610a805760405162461bcd60e51b815260040161034190613b74565b60008415610acc57610ac786868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e8092505050565b610ace565b885b9050610b13828a838a8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e8792505050565b50505b5050505050505050565b60426020526000908152604090205481565b610b3a61187b565b610b565760405162461bcd60e51b815260040161034190613d8b565b6040805460ff60a01b1916600160a01b83151581029190911780835591517f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad992610ba59260ff91041690613688565b60405180910390a150565b60375490565b610bbe61187b565b610bda5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b038616610c005760405162461bcd60e51b815260040161034190613d5f565b6001600160a01b038087166000908152603b6020526040902054168015610c395760405162461bcd60e51b81526004016103419061402f565b6000610c448761213a565b9050600060388787604051602001610c5e939291906134a6565b60408051601f1981840301815282825290546326d9e96360e01b83529092506001600160a01b0316906326d9e96390610ca1908890889086908890600401613700565b602060405180830381600087803b158015610cbb57600080fd5b505af1158015610ccf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf39190612f5a565b6001600160a01b03808b166000818152603b6020908152604080832080548688166001600160a01b03199182168117909255908452603c909252918290208054909116909217909155603f5490516378bf2b5360e01b815292955016906378bf2b5390610d669086908e90600401613627565b600060405180830381600087803b158015610d8057600080fd5b505af1158015610d94573d6000803e3d6000fd5b50505050886001600160a01b0316836001600160a01b03167f2ef93c4e96a4ef0b19497ff60c9e7360a8734f3d2cd27ae5318e43851734d17f8385604051610ddd929190613762565b60405180910390a350505050505050505050565b600054610100900460ff1680610e0a575060005460ff16155b610e265760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015610e51576000805460ff1961ff0019909116610100171660011790555b610e5a82611d06565b6034805460ff191690558015610e76576000805461ff00191690555b5050565b600054610100900460ff1680610e93575060005460ff16155b610eaf5760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015610eda576000805460ff1961ff0019909116610100171660011790555b610ee386611b6f565b610eec86610df1565b8151610eff906038906020850190612e1a565b50603f80546001600160a01b038087166001600160a01b031992831617909255604080548684169083161781556036805493891693909216929092179055516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90610f969030907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b908290600401613533565b600060405180830381600087803b158015610fb057600080fd5b505af1158015610fc4573d6000803e3d6000fd5b50505050610fd0611c6a565b8015610fe2576000805461ff00191690555b505050505050565b610ff261187b565b61100e5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b0381166110345760405162461bcd60e51b815260040161034190613aae565b604180546001600160a01b0319166001600160a01b0383161790556040517f0966c958966f6fac9ff807af074f8117eb2e9ce2b76390db7a158e9bdeb2485c90610ba590839061351f565b6000818152604260209081526040808320548352603e90915290205460ff165b919050565b6044602052600090815260409020546001600160a01b031681565b6110ca610506610925565b6110e65760405162461bcd60e51b815260040161034190613a05565b60345460ff166111085760405162461bcd60e51b8152600401610341906137c9565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61113b610925565b604051611148919061351f565b60405180910390a1565b61115a61187b565b6111765760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b03811661119c5760405162461bcd60e51b815260040161034190613ca6565b604080546001600160a01b0319166001600160a01b038316178155517f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e318369252162590610ba590839061351f565b60006111f260338361216d565b92915050565b60004285101561121a5760405162461bcd60e51b815260040161034190613c7d565b600061123661122e368b90038b018b6132da565b8989896121b5565b905060006001828787876040516000815260200160405260405161125d94939291906136e2565b6020604051602081039080840390855afa15801561127f573d6000803e3d6000fd5b5050604051601f19015191506000905061129c60208c018c612f3e565b6001600160a01b0316141580156112d057506112bb60208b018b612f3e565b6001600160a01b0316816001600160a01b0316145b6112ec5760405162461bcd60e51b815260040161034190613a4d565b6113048a6112fd6020820182612f3e565b8b8b61224a565b9a9950505050505050505050565b604080518082019091526002815261763360f01b602082015290565b6038805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156113b45780601f10611389576101008083540402835291602001916113b4565b820191906000526020600020905b81548152906001019060200180831161139757829003601f168201915b505050505081565b60345460ff1690565b603d6020526000908152604090205460ff1681565b60345460ff16156113fd5760405162461bcd60e51b815260040161034190613c1c565b60358054600101908190556036546001600160a01b031661141c610925565b6001600160a01b0316146114425760405162461bcd60e51b815260040161034190613b44565b6001600160a01b0388166000908152603d602052604090205460ff168061148257506001600160a01b038881166000908152603b60205260409020541615155b61149e5760405162461bcd60e51b815260040161034190613ade565b6001600160a01b0386166114c45760405162461bcd60e51b815260040161034190613bf3565b600085116114e45760405162461bcd60e51b815260040161034190613a84565b836115015760405162461bcd60e51b815260040161034190613ea7565b8261151e5760405162461bcd60e51b815260040161034190613926565b6000838152604260205260409020541561154a5760405162461bcd60e51b815260040161034190613e70565b60006115598787878787611a23565b6000818152603e602052604090205490915060ff161561158b5760405162461bcd60e51b815260040161034190613e02565b60008481526042602090815260408083208490556043825280832080546001600160a01b03199081166001600160a01b038f811691821790935560449094529382902080549094168c821617909355519189169186907f2858b8803acb87882fd2de49ce7572ae3e741fb8073cbe772fa50ce00bdfba2290611614908d908c908c908b90613556565b60405180910390a4506035548114610b165760405162461bcd60e51b815260040161034190613784565b7ff18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd8043381565b61167261166d610925565b612463565b565b61167c61187b565b6116985760405162461bcd60e51b815260040161034190613d8b565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b60006116f2610925565b90506117096001600160a01b0385168230856124a5565b6117258482858560405180602001604052806000815250611e87565b50505050565b60456020526000908152604090205481565b600054610100900460ff1680611756575060005460ff16155b6117725760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff1615801561179d576000805460ff1961ff0019909116610100171660011790555b600160355580156117b4576000805461ff00191690555b50565b6117c2610506610925565b6117de5760405162461bcd60e51b815260040161034190613a05565b6117b4816124fd565b6117f2610506610925565b61180e5760405162461bcd60e51b815260040161034190613a05565b60345460ff16156118315760405162461bcd60e51b815260040161034190613c1c565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861113b610925565b60345461010090046001600160a01b031690565b60345460009061010090046001600160a01b0316611897610925565b6001600160a01b031614905090565b6118ae61187b565b6118ca5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b0381166118f05760405162461bcd60e51b815260040161034190613ed7565b603f80546001600160a01b0319166001600160a01b0383161790556040517f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e390610ba590839061351f565b603f546001600160a01b031681565b60608101356000908152604460205260408120546001600160a01b031661196f610925565b6001600160a01b0316146119955760405162461bcd60e51b8152600401610341906138f6565b6111f2826119a1610925565b60008061224a565b6119b161187b565b6119cd5760405162461bcd60e51b815260040161034190613d8b565b6103e881106119ee5760405162461bcd60e51b81526004016103419061405f565b60378190556040517f97e97c577f03bda90e2c9739011ec065ed5fbfb36ae217d20bb0d9be95e160cd90610ba5908390613693565b60008383878785604051602001611a3e959493929190613448565b60405160208183030381529060405280519060200120905095945050505050565b6041546001600160a01b031681565b60006111f2826119a16020820182612f3e565b6000611a8b610925565b6041549091506001600160a01b0316611ab65760405162461bcd60e51b815260040161034190613c46565b604160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611b0657600080fd5b505af1158015611b1a573d6000803e3d6000fd5b5050505050610e76604160009054906101000a90046001600160a01b031682843460405180602001604052806000815250611e87565b604054600160a01b900460ff1681565b6040546001600160a01b031681565b600054610100900460ff1680611b88575060005460ff16155b611ba45760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015611bcf576000805460ff1961ff0019909116610100171660011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e76576000805461ff00191690555050565b6043602052600090815260409020546001600160a01b031681565b603e6020526000908152604090205460ff1681565b6000469050611cbc6040518060400160405280601081526020016f52534b20546f6b656e2042726964676560801b815250604051806040016040528060018152602001603160f81b815250833061253f565b60395550565b600090815260426020526040902054151590565b603b602052600090815260409020546001600160a01b031681565b61271081565b6036546001600160a01b031690565b600054610100900460ff1680611d1f575060005460ff16155b611d3b5760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015611d66576000805460ff1961ff0019909116610100171660011790555b611d6f826111e5565b611d7c57611d7c826124fd565b8015610e76576000805461ff00191690555050565b611d9961187b565b611db55760405162461bcd60e51b815260040161034190613d8b565b6117b481612596565b60395481565b603c602052600090815260409020546001600160a01b031681565b611de761187b565b611e035760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b038116611e295760405162461bcd60e51b81526004016103419061385d565b603680546001600160a01b0319166001600160a01b0383811691909117918290556040517f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb92610ba592169061351f565b3b151590565b6014015190565b604054600160a01b900460ff1615611eb15760405162461bcd60e51b8152600401610341906138cb565b60345460ff1615611ed45760405162461bcd60e51b815260040161034190613c1c565b603580546001908101918290556001600160a01b0387166000908152603d60205260408120805460ff1916909217909155603754611f219061271090611f1b908790612623565b90612664565b90506000611f2f85836126a6565b90506000611f3c896126e8565b905085601260ff831614611f6157611f5e8760ff601285900316600a0a612623565b90505b603f54604051638c34bc5560e01b81526001600160a01b0390911690638c34bc5590611f93908d908590600401613627565b600060405180830381600087803b158015611fad57600080fd5b505af1158015611fc1573d6000803e3d6000fd5b5050506001600160a01b03808c166000908152603c60205260409020548c9250161561209b57506001600160a01b03808b166000908152603c60205260408120549091169061200f8c6127ac565b9050600061201d8683612854565b90506120298782612896565b965061203586826126a6565b60405163fe9d930360e01b81529096506001600160a01b038e169063fe9d9303906120669089908d9060040161410e565b600060405180830381600087803b15801561208057600080fd5b505af1158015612094573d6000803e3d6000fd5b5050505050505b886001600160a01b03168a6001600160a01b0316826001600160a01b03167f1e90de9ae4d02420648a650f45f089a1be18fbca324092544ea626f9833212b0878b6040516120ea92919061410e565b60405180910390a4841561211457612114612103611867565b6001600160a01b038d1690876128bb565b50505050506035548114610fe25760405162461bcd60e51b815260040161034190613784565b600060128260ff1611156121605760405162461bcd60e51b815260040161034190613ce7565b5060120360ff16600a0a90565b60006001600160a01b0382166121955760405162461bcd60e51b815260040161034190613dc0565b506001600160a01b03166000908152602091909152604090205460ff1690565b603954845160208087015160608801516001600160a01b038416600090815260458452604080822080546001810190915590519196612241969095612226957ff18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd8043395929490938d928d928d910161369c565b604051602081830303815290604052805190602001206128df565b95945050505050565b603580546001019081905560608501356000908152604360205260408120549091906001600160a01b0316806122925760405162461bcd60e51b815260040161034190613f45565b60006122c36122a460208a018a612f3e565b60208a013560408b013560608c013561073a60a08e0160808f01613402565b606089013560009081526042602052604090205490915081146122f85760405162461bcd60e51b8152600401610341906140cd565b6000818152603e602052604090205460ff16156123275760405162461bcd60e51b815260040161034190613e02565b6000818152603e60209081526040808320805460ff191660011790556001600160a01b0385168352603d90915290205460ff16156123775761237082888a6020013589896128fe565b935061238b565b61238882888a602001358989612a74565b93505b6123986020890189612f3e565b6001600160a01b0316826001600160a01b031689606001357f42b1cb6263e8da47edf0583516eda1de16f729d26282f5791dc5b7af1010e925604460008d60600135815260200190815260200160002060009054906101000a90046001600160a01b03168c602001358d604001358e60800160208101906124199190613402565b8e8e8e60405161242f9796959493929190613640565b60405180910390a45050603554811461245a5760405162461bcd60e51b815260040161034190613784565b50949350505050565b61246e603382612c0b565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b611725846323b872dd60e01b8585856040516024016124c693929190613603565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612c53565b612508603382612d37565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b6001600160a01b0381166125bc5760405162461bcd60e51b815260040161034190613fa3565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600082612632575060006111f2565b8282028284828161263f57fe5b041461265d5760405162461bcd60e51b815260040161034190613d1e565b9392505050565b600061265d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612d83565b600061265d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612dba565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b0386169161272e919061348a565b600060405180830381855afa9150503d8060008114612769576040519150601f19603f3d011682016040523d82523d6000602084013e61276e565b606091505b5091509150816127905760405162461bcd60e51b81526004016103419061382e565b808060200190518101906127a49190613350565b949350505050565b60408051600481526024810182526020810180516001600160e01b031663556f0dc760e01b1790529051600091829182916001600160a01b038616916127f2919061348a565b600060405180830381855afa9150503d806000811461282d576040519150601f19603f3d011682016040523d82523d6000602084013e612832565b606091505b5091509150816127905760405162461bcd60e51b815260040161034190613bbc565b600061265d83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250612de6565b60008282018381101561265d5760405162461bcd60e51b815260040161034190613894565b6128da8363a9059cbb60e01b84846040516024016124c6929190613627565b505050565b60405161190160f01b8152600281019290925260228201526042902090565b60008061290a876126e8565b60ff1690506000612922866012849003600a0a612664565b9050808411156129445760405162461bcd60e51b815260040161034190613f75565b60415484820393506001600160a01b0389811691161415612a3b57604154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d9061298f908490600401613693565b600060405180830381600087803b1580156129a957600080fd5b505af11580156129bd573d6000803e3d6000fd5b50506040516001600160a01b038a16925085156108fc02915085906000818181858888f193505050501580156129f7573d6000803e3d6000fd5b508315612a36576040516001600160a01b0386169085156108fc029086906000818181858888f19350505050158015612a34573d6000803e3d6000fd5b505b612a69565b612a4f6001600160a01b03891688856128bb565b8315612a6957612a696001600160a01b03891686866128bb565b505095945050505050565b6001600160a01b038086166000908152603b6020908152604080832054815163556f0dc760e01b81529151939416928492849263556f0dc79260048083019392829003018186803b158015612ac857600080fd5b505afa158015612adc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b009190613350565b90506000612b0e8783612623565b905080851115612b305760405162461bcd60e51b815260040161034190613f75565b604051630dcdc7dd60e41b815285820394506001600160a01b0384169063dcdc7dd090612b63908b9088906004016135cd565b600060405180830381600087803b158015612b7d57600080fd5b505af1158015612b91573d6000803e3d6000fd5b505050506000851115612bff57604051630dcdc7dd60e41b81526001600160a01b0384169063dcdc7dd090612bcc9089908990600401613582565b600060405180830381600087803b158015612be657600080fd5b505af1158015612bfa573d6000803e3d6000fd5b505050505b50505095945050505050565b612c15828261216d565b612c315760405162461bcd60e51b815260040161034190613953565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b612c65826001600160a01b0316611e7a565b612c815760405162461bcd60e51b815260040161034190614096565b600080836001600160a01b031683604051612c9c919061348a565b6000604051808303816000865af19150503d8060008114612cd9576040519150601f19603f3d011682016040523d82523d6000602084013e612cde565b606091505b509150915081612d005760405162461bcd60e51b815260040161034190613988565b8051156117255780806020019051810190612d1b919061321b565b6117255760405162461bcd60e51b815260040161034190613fe5565b612d41828261216d565b15612d5e5760405162461bcd60e51b8152600401610341906137f7565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60008183612da45760405162461bcd60e51b8152600401610341919061374f565b506000838581612db057fe5b0495945050505050565b60008184841115612dde5760405162461bcd60e51b8152600401610341919061374f565b505050900390565b60008183612e075760405162461bcd60e51b8152600401610341919061374f565b50828481612e1157fe5b06949350505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282612e505760008555612e96565b82601f10612e6957805160ff1916838001178555612e96565b82800160010185558215612e96579182015b82811115612e96578251825591602001919060010190612e7b565b50612ea2929150612ea6565b5090565b5b80821115612ea25760008155600101612ea7565b60008083601f840112612ecc578182fd5b50813567ffffffffffffffff811115612ee3578182fd5b602083019150836020828501011115612efb57600080fd5b9250929050565b600060a08284031215612f13578081fd5b50919050565b803563ffffffff8116811461109f57600080fd5b803560ff8116811461109f57600080fd5b600060208284031215612f4f578081fd5b813561265d81614177565b600060208284031215612f6b578081fd5b815161265d81614177565b600080600080600080600060e0888a031215612f90578283fd5b8735612f9b81614177565b96506020880135612fab81614177565b95506040880135612fbb81614177565b9450606088013593506080880135925060a08801359150612fde60c08901612f19565b905092959891949750929550565b600080600080600060a08688031215613003578081fd5b853561300e81614177565b945060208681013561301f81614177565b9450604087013561302f81614177565b9350606087013561303f81614177565b9250608087013567ffffffffffffffff8082111561305b578384fd5b818901915089601f83011261306e578384fd5b81358181111561307a57fe5b61308c601f8201601f19168501614127565b91508082528a848285010111156130a1578485fd5b8084840185840137810190920192909252949793965091945092919050565b60008060008060008060008060c0898b0312156130db578081fd5b88356130e681614177565b975060208901356130f681614177565b9650604089013561310681614177565b955060608901359450608089013567ffffffffffffffff80821115613129578283fd5b6131358c838d01612ebb565b909650945060a08b013591508082111561314d578283fd5b5061315a8b828c01612ebb565b999c989b5096995094979396929594505050565b600080600060608486031215613182578081fd5b833561318d81614177565b9250602084013561319d81614177565b929592945050506040919091013590565b600080600080600060a086880312156131c5578283fd5b85356131d081614177565b94506020860135935060408601359250606086013591506131f360808701612f19565b90509295509295909350565b600060208284031215613210578081fd5b813561265d8161418c565b60006020828403121561322c578081fd5b815161265d8161418c565b600060208284031215613248578081fd5b5035919050565b600060a08284031215613260578081fd5b61265d8383612f02565b6000806000806000806000610160888a031215613285578081fd5b61328f8989612f02565b965060a088013561329f81614177565b955060c0880135945060e088013593506132bc6101008901612f2d565b92506101208801359150610140880135905092959891949750929550565b600060a082840312156132eb578081fd5b60405160a0810181811067ffffffffffffffff8211171561330857fe5b604052823561331681614177565b8082525060208301356020820152604083013560408201526060830135606082015261334460808401612f19565b60808201529392505050565b600060208284031215613361578081fd5b5051919050565b600080600080600080600060a0888a031215613382578081fd5b87359650602088013561339481614177565b95506133a260408901612f2d565b9450606088013567ffffffffffffffff808211156133be578283fd5b6133ca8b838c01612ebb565b909650945060808a01359150808211156133e2578283fd5b506133ef8a828b01612ebb565b989b979a50959850939692959293505050565b600060208284031215613413578081fd5b61265d82612f19565b6000815180845261343481602086016020860161414b565b601f01601f19169290920160200192915050565b948552602085019390935260609190911b6bffffffffffffffffffffffff19166040840152605483015260e01b6001600160e01b031916607482015260780190565b6000825161349c81846020870161414b565b9190910192915050565b60008085546001808216600081146134c557600181146134dc5761350b565b60ff198316865260028304607f168601935061350b565b600283048986526020808720875b838110156135035781548a8201529085019082016134ea565b505050860193505b505050838582379092019182525092915050565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b6001600160a01b039490941684526020840192909252604083015263ffffffff16606082015260800190565b6001600160a01b03929092168252602082015260806040820181905260009082015260a060608201819052600b908201526a72656c617965722066656560a81b60c082015260e00190565b6001600160a01b039290921682526020820152608060408201819052600090820181905260a06060830181905282015260c00190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0397881681526020810196909652604086019490945263ffffffff9290921660608501528416608084015290921660a082015260c081019190915260e00190565b901515815260200190565b90815260200190565b9788526001600160a01b039687166020890152604088019590955260608701939093529316608085015260a084019290925260c083019190915260e08201526101000190565b93845260ff9290921660208401526040830152606082015260800190565b600060608252846060830152848660808401378060808684010152601f19601f8601168201608083820301602084015261373d608082018661341c565b91505082604083015295945050505050565b60006020825261265d602083018461341c565b600060408252613775604083018561341c565b90508260208301529392505050565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b6020808252601f908201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604082015260600190565b6020808252601590820152744c69625574696c733a204e6f20646563696d616c7360581b604082015260600190565b6020808252601b908201527f4272696467653a2046656465726174696f6e20697320656d7074790000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601190820152704272696467653a20557067726164696e6760781b604082015260600190565b602080825260169082015275213934b233b29d1034b73b30b634b21039b2b73232b960511b604082015260600190565b602080825260139082015272084e4d2c8ceca74409cead8d840a8f090c2e6d606b1b604082015260600190565b6020808252818101527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c65604082015260600190565b6020808252818101527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604082015260600190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b60208082526019908201527f4272696467653a20494e56414c49445f5349474e415455524500000000000000604082015260600190565b60208082526010908201526f04272696467653a20416d6f756e7420360841b604082015260600190565b6020808252601690820152754272696467653a20777261707020697320656d70747960501b604082015260600190565b602080825260159082015274213934b233b29d102ab735b737bbb7103a37b5b2b760591b604082015260600190565b6020808252601b908201527f4272696467653a204e6f7420746f207468697320616464726573730000000000604082015260600190565b602080825260169082015275213934b233b29d102737ba102332b232b930ba34b7b760511b604082015260600190565b60208082526028908201527f4272696467653a2053706563696679207265636569766572206164647265737360408201526720696e206461746160c01b606082015260800190565b60208082526018908201527f4c69625574696c733a204e6f206772616e756c61726974790000000000000000604082015260600190565b6020808252600f908201526e4272696467653a204e756c6c20546f60881b604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252601d908201527f4272696467653a207772617070656443757272656e637920656d707479000000604082015260600190565b6020808252600f908201526e109c9a5919d94e8811561412549151608a1b604082015260600190565b60208082526021908201527f4272696467653a2053696465546f6b656e466163746f727920697320656d70746040820152607960f81b606082015260800190565b6020808252601c908201527f4c69625574696c733a20446563696d616c73206e6f74203c3d20313800000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260129082015271213934b233b29d10273ab636103a37b5b2b760711b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526022908201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526017908201527f4272696467653a20416c726561647920636c61696d6564000000000000000000604082015260600190565b6020808252601b908201527f4272696467653a206e6f74207772617070656443757272656e63790000000000604082015260600190565b60208082526018908201527f4272696467653a20416c72656164792061636365707465640000000000000000604082015260600190565b602080825260169082015275084e4d2c8ceca74409cead8d84084d8dec6d690c2e6d60531b604082015260600190565b6020808252601c908201527f4272696467653a20416c6c6f77546f6b656e7320697320656d70747900000000604082015260600190565b60208082526018908201527f4272696467653a204e6f742045524337373720746f6b656e0000000000000000604082015260600190565b602080825260169082015275109c9a5919d94e88151e081b9bdd0818dc9bdcdcd95960521b604082015260600190565b602080825260149082015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b604082015260600190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601690820152754272696467653a20416c72656164792065786973747360501b604082015260600190565b60208082526017908201527f4272696467653a20626967676572207468616e20313025000000000000000000604082015260600190565b6020808252601f908201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604082015260600190565b60208082526021908201527f4272696467653a2057726f6e67207472616e73616374696f6e446174614861736040820152600d60fb1b606082015260800190565b6000838252604060208301526127a4604083018461341c565b60405181810167ffffffffffffffff8111828210171561414357fe5b604052919050565b60005b8381101561416657818101518382015260200161414e565b838111156117255750506000910152565b6001600160a01b03811681146117b457600080fd5b80151581146117b457600080fdfea26469706673582212204c589b204ecd046fc7fe66efcbaa8add03eceef2a33bb84785a9a9e908cd5c5664736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106103025760003560e01c80638456cb5911610190578063c4d66de8116100dc578063e6fc774411610095578063f2fde38b1161006f578063f2fde38b146108b0578063f698da25146108d0578063f74032f0146108e5578063fa0caa16146109055761034c565b8063e6fc774414610866578063ea2170911461087b578063eb16136f146108905761034c565b8063c4d66de8146107b1578063ca07140c146107d1578063cc3c0f06146107f1578063d12e825d14610811578063da67703714610826578063e6ede14d146108465761034c565b8063ae06c1b711610149578063b50277bb11610123578063b50277bb14610754578063b760faf914610774578063b794726214610787578063b86f60d21461079c5761034c565b8063ae06c1b7146106ff578063afad80ac1461071f578063b0e1268e1461073f5761034c565b80638456cb591461066b5780638da5cb5b146106805780638f32d59b14610695578063916dc59d146106aa578063a53d6e6e146106ca578063adc5fb64146106df5761034c565b80634beea5061161024f5780636b0509b1116102085780637813bea2116101e25780637813bea2146105f65780637ecebe00146106165780638129fc1c1461063657806382dc1ec41461064b5761034c565b80636b0509b1146105b75780636ef8d66d146105cc578063715018a6146105e15761034c565b80634beea5061461050b57806354fd4d501461052b57806359a8a8671461054d5780635c975abb146105625780635d447129146105775780636a863191146105975761034c565b80632fb3b361116102bc5780633cf3058b116102965780633cf3058b146104895780633f4ba83a146104b657806342cdb2c6146104cb57806346fbf68e146104eb5761034c565b80632fb3b3611461041c5780633500c1dc1461043c57806337e761091461045c5761034c565b806223de2914610351578063026976191461037157806307c8f7b0146103a757806311efbf61146103c757806320e3bb00146103dc5780632f3cca4e146103fc5761034c565b3661034c576041546001600160a01b031661031b610925565b6001600160a01b03161461034a5760405162461bcd60e51b815260040161034190613e39565b60405180910390fd5b005b600080fd5b34801561035d57600080fd5b5061034a61036c3660046130c0565b610929565b34801561037d57600080fd5b5061039161038c366004613237565b610b20565b60405161039e9190613693565b60405180910390f35b3480156103b357600080fd5b5061034a6103c23660046131ff565b610b32565b3480156103d357600080fd5b50610391610bb0565b3480156103e857600080fd5b5061034a6103f7366004613368565b610bb6565b34801561040857600080fd5b5061034a610417366004612f3e565b610df1565b34801561042857600080fd5b5061034a610437366004612fec565b610e7a565b34801561044857600080fd5b5061034a610457366004612f3e565b610fea565b34801561046857600080fd5b5061047c610477366004613237565b61107f565b60405161039e9190613688565b34801561049557600080fd5b506104a96104a4366004613237565b6110a4565b60405161039e919061351f565b3480156104c257600080fd5b5061034a6110bf565b3480156104d757600080fd5b5061034a6104e6366004612f3e565b611152565b3480156104f757600080fd5b5061047c610506366004612f3e565b6111e5565b34801561051757600080fd5b5061039161052636600461326a565b6111f8565b34801561053757600080fd5b50610540611312565b60405161039e919061374f565b34801561055957600080fd5b5061054061132e565b34801561056e57600080fd5b5061047c6113bc565b34801561058357600080fd5b5061047c610592366004612f3e565b6113c5565b3480156105a357600080fd5b5061034a6105b2366004612f76565b6113da565b3480156105c357600080fd5b5061039161163e565b3480156105d857600080fd5b5061034a611662565b3480156105ed57600080fd5b5061034a611674565b34801561060257600080fd5b5061034a61061136600461316e565b6116e8565b34801561062257600080fd5b50610391610631366004612f3e565b61172b565b34801561064257600080fd5b5061034a61173d565b34801561065757600080fd5b5061034a610666366004612f3e565b6117b7565b34801561067757600080fd5b5061034a6117e7565b34801561068c57600080fd5b506104a9611867565b3480156106a157600080fd5b5061047c61187b565b3480156106b657600080fd5b5061034a6106c5366004612f3e565b6118a6565b3480156106d657600080fd5b506104a961193b565b3480156106eb57600080fd5b506103916106fa36600461324f565b61194a565b34801561070b57600080fd5b5061034a61071a366004613237565b6119a9565b34801561072b57600080fd5b5061039161073a3660046131ae565b611a23565b34801561074b57600080fd5b506104a9611a5f565b34801561076057600080fd5b5061039161076f36600461324f565b611a6e565b61034a610782366004612f3e565b611a81565b34801561079357600080fd5b5061047c611b50565b3480156107a857600080fd5b506104a9611b60565b3480156107bd57600080fd5b5061034a6107cc366004612f3e565b611b6f565b3480156107dd57600080fd5b506104a96107ec366004613237565b611c3a565b3480156107fd57600080fd5b5061047c61080c366004613237565b611c55565b34801561081d57600080fd5b5061034a611c6a565b34801561083257600080fd5b5061047c610841366004613237565b611cc2565b34801561085257600080fd5b506104a9610861366004612f3e565b611cd6565b34801561087257600080fd5b50610391611cf1565b34801561088757600080fd5b506104a9611cf7565b34801561089c57600080fd5b5061034a6108ab366004612f3e565b611d06565b3480156108bc57600080fd5b5061034a6108cb366004612f3e565b611d91565b3480156108dc57600080fd5b50610391611dbe565b3480156108f157600080fd5b506104a9610900366004612f3e565b611dc4565b34801561091157600080fd5b5061034a610920366004612f3e565b611ddf565b3390565b6001600160a01b03881630141561093f57610b16565b6001600160a01b03861630146109675760405162461bcd60e51b815260040161034190613b0d565b6000610971610925565b60405163555ddc6560e11b8152909150600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906109d09085907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce217705490600401613627565b60206040518083038186803b1580156109e857600080fd5b505afa1580156109fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a209190612f5a565b6001600160a01b03161415610a475760405162461bcd60e51b815260040161034190613f0e565b83151580610a645750610a62886001600160a01b0316611e7a565b155b610a805760405162461bcd60e51b815260040161034190613b74565b60008415610acc57610ac786868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e8092505050565b610ace565b885b9050610b13828a838a8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e8792505050565b50505b5050505050505050565b60426020526000908152604090205481565b610b3a61187b565b610b565760405162461bcd60e51b815260040161034190613d8b565b6040805460ff60a01b1916600160a01b83151581029190911780835591517f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad992610ba59260ff91041690613688565b60405180910390a150565b60375490565b610bbe61187b565b610bda5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b038616610c005760405162461bcd60e51b815260040161034190613d5f565b6001600160a01b038087166000908152603b6020526040902054168015610c395760405162461bcd60e51b81526004016103419061402f565b6000610c448761213a565b9050600060388787604051602001610c5e939291906134a6565b60408051601f1981840301815282825290546326d9e96360e01b83529092506001600160a01b0316906326d9e96390610ca1908890889086908890600401613700565b602060405180830381600087803b158015610cbb57600080fd5b505af1158015610ccf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf39190612f5a565b6001600160a01b03808b166000818152603b6020908152604080832080548688166001600160a01b03199182168117909255908452603c909252918290208054909116909217909155603f5490516378bf2b5360e01b815292955016906378bf2b5390610d669086908e90600401613627565b600060405180830381600087803b158015610d8057600080fd5b505af1158015610d94573d6000803e3d6000fd5b50505050886001600160a01b0316836001600160a01b03167f2ef93c4e96a4ef0b19497ff60c9e7360a8734f3d2cd27ae5318e43851734d17f8385604051610ddd929190613762565b60405180910390a350505050505050505050565b600054610100900460ff1680610e0a575060005460ff16155b610e265760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015610e51576000805460ff1961ff0019909116610100171660011790555b610e5a82611d06565b6034805460ff191690558015610e76576000805461ff00191690555b5050565b600054610100900460ff1680610e93575060005460ff16155b610eaf5760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015610eda576000805460ff1961ff0019909116610100171660011790555b610ee386611b6f565b610eec86610df1565b8151610eff906038906020850190612e1a565b50603f80546001600160a01b038087166001600160a01b031992831617909255604080548684169083161781556036805493891693909216929092179055516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90610f969030907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b908290600401613533565b600060405180830381600087803b158015610fb057600080fd5b505af1158015610fc4573d6000803e3d6000fd5b50505050610fd0611c6a565b8015610fe2576000805461ff00191690555b505050505050565b610ff261187b565b61100e5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b0381166110345760405162461bcd60e51b815260040161034190613aae565b604180546001600160a01b0319166001600160a01b0383161790556040517f0966c958966f6fac9ff807af074f8117eb2e9ce2b76390db7a158e9bdeb2485c90610ba590839061351f565b6000818152604260209081526040808320548352603e90915290205460ff165b919050565b6044602052600090815260409020546001600160a01b031681565b6110ca610506610925565b6110e65760405162461bcd60e51b815260040161034190613a05565b60345460ff166111085760405162461bcd60e51b8152600401610341906137c9565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61113b610925565b604051611148919061351f565b60405180910390a1565b61115a61187b565b6111765760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b03811661119c5760405162461bcd60e51b815260040161034190613ca6565b604080546001600160a01b0319166001600160a01b038316178155517f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e318369252162590610ba590839061351f565b60006111f260338361216d565b92915050565b60004285101561121a5760405162461bcd60e51b815260040161034190613c7d565b600061123661122e368b90038b018b6132da565b8989896121b5565b905060006001828787876040516000815260200160405260405161125d94939291906136e2565b6020604051602081039080840390855afa15801561127f573d6000803e3d6000fd5b5050604051601f19015191506000905061129c60208c018c612f3e565b6001600160a01b0316141580156112d057506112bb60208b018b612f3e565b6001600160a01b0316816001600160a01b0316145b6112ec5760405162461bcd60e51b815260040161034190613a4d565b6113048a6112fd6020820182612f3e565b8b8b61224a565b9a9950505050505050505050565b604080518082019091526002815261763360f01b602082015290565b6038805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156113b45780601f10611389576101008083540402835291602001916113b4565b820191906000526020600020905b81548152906001019060200180831161139757829003601f168201915b505050505081565b60345460ff1690565b603d6020526000908152604090205460ff1681565b60345460ff16156113fd5760405162461bcd60e51b815260040161034190613c1c565b60358054600101908190556036546001600160a01b031661141c610925565b6001600160a01b0316146114425760405162461bcd60e51b815260040161034190613b44565b6001600160a01b0388166000908152603d602052604090205460ff168061148257506001600160a01b038881166000908152603b60205260409020541615155b61149e5760405162461bcd60e51b815260040161034190613ade565b6001600160a01b0386166114c45760405162461bcd60e51b815260040161034190613bf3565b600085116114e45760405162461bcd60e51b815260040161034190613a84565b836115015760405162461bcd60e51b815260040161034190613ea7565b8261151e5760405162461bcd60e51b815260040161034190613926565b6000838152604260205260409020541561154a5760405162461bcd60e51b815260040161034190613e70565b60006115598787878787611a23565b6000818152603e602052604090205490915060ff161561158b5760405162461bcd60e51b815260040161034190613e02565b60008481526042602090815260408083208490556043825280832080546001600160a01b03199081166001600160a01b038f811691821790935560449094529382902080549094168c821617909355519189169186907f2858b8803acb87882fd2de49ce7572ae3e741fb8073cbe772fa50ce00bdfba2290611614908d908c908c908b90613556565b60405180910390a4506035548114610b165760405162461bcd60e51b815260040161034190613784565b7ff18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd8043381565b61167261166d610925565b612463565b565b61167c61187b565b6116985760405162461bcd60e51b815260040161034190613d8b565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b60006116f2610925565b90506117096001600160a01b0385168230856124a5565b6117258482858560405180602001604052806000815250611e87565b50505050565b60456020526000908152604090205481565b600054610100900460ff1680611756575060005460ff16155b6117725760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff1615801561179d576000805460ff1961ff0019909116610100171660011790555b600160355580156117b4576000805461ff00191690555b50565b6117c2610506610925565b6117de5760405162461bcd60e51b815260040161034190613a05565b6117b4816124fd565b6117f2610506610925565b61180e5760405162461bcd60e51b815260040161034190613a05565b60345460ff16156118315760405162461bcd60e51b815260040161034190613c1c565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861113b610925565b60345461010090046001600160a01b031690565b60345460009061010090046001600160a01b0316611897610925565b6001600160a01b031614905090565b6118ae61187b565b6118ca5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b0381166118f05760405162461bcd60e51b815260040161034190613ed7565b603f80546001600160a01b0319166001600160a01b0383161790556040517f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e390610ba590839061351f565b603f546001600160a01b031681565b60608101356000908152604460205260408120546001600160a01b031661196f610925565b6001600160a01b0316146119955760405162461bcd60e51b8152600401610341906138f6565b6111f2826119a1610925565b60008061224a565b6119b161187b565b6119cd5760405162461bcd60e51b815260040161034190613d8b565b6103e881106119ee5760405162461bcd60e51b81526004016103419061405f565b60378190556040517f97e97c577f03bda90e2c9739011ec065ed5fbfb36ae217d20bb0d9be95e160cd90610ba5908390613693565b60008383878785604051602001611a3e959493929190613448565b60405160208183030381529060405280519060200120905095945050505050565b6041546001600160a01b031681565b60006111f2826119a16020820182612f3e565b6000611a8b610925565b6041549091506001600160a01b0316611ab65760405162461bcd60e51b815260040161034190613c46565b604160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611b0657600080fd5b505af1158015611b1a573d6000803e3d6000fd5b5050505050610e76604160009054906101000a90046001600160a01b031682843460405180602001604052806000815250611e87565b604054600160a01b900460ff1681565b6040546001600160a01b031681565b600054610100900460ff1680611b88575060005460ff16155b611ba45760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015611bcf576000805460ff1961ff0019909116610100171660011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e76576000805461ff00191690555050565b6043602052600090815260409020546001600160a01b031681565b603e6020526000908152604090205460ff1681565b6000469050611cbc6040518060400160405280601081526020016f52534b20546f6b656e2042726964676560801b815250604051806040016040528060018152602001603160f81b815250833061253f565b60395550565b600090815260426020526040902054151590565b603b602052600090815260409020546001600160a01b031681565b61271081565b6036546001600160a01b031690565b600054610100900460ff1680611d1f575060005460ff16155b611d3b5760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015611d66576000805460ff1961ff0019909116610100171660011790555b611d6f826111e5565b611d7c57611d7c826124fd565b8015610e76576000805461ff00191690555050565b611d9961187b565b611db55760405162461bcd60e51b815260040161034190613d8b565b6117b481612596565b60395481565b603c602052600090815260409020546001600160a01b031681565b611de761187b565b611e035760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b038116611e295760405162461bcd60e51b81526004016103419061385d565b603680546001600160a01b0319166001600160a01b0383811691909117918290556040517f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb92610ba592169061351f565b3b151590565b6014015190565b604054600160a01b900460ff1615611eb15760405162461bcd60e51b8152600401610341906138cb565b60345460ff1615611ed45760405162461bcd60e51b815260040161034190613c1c565b603580546001908101918290556001600160a01b0387166000908152603d60205260408120805460ff1916909217909155603754611f219061271090611f1b908790612623565b90612664565b90506000611f2f85836126a6565b90506000611f3c896126e8565b905085601260ff831614611f6157611f5e8760ff601285900316600a0a612623565b90505b603f54604051638c34bc5560e01b81526001600160a01b0390911690638c34bc5590611f93908d908590600401613627565b600060405180830381600087803b158015611fad57600080fd5b505af1158015611fc1573d6000803e3d6000fd5b5050506001600160a01b03808c166000908152603c60205260409020548c9250161561209b57506001600160a01b03808b166000908152603c60205260408120549091169061200f8c6127ac565b9050600061201d8683612854565b90506120298782612896565b965061203586826126a6565b60405163fe9d930360e01b81529096506001600160a01b038e169063fe9d9303906120669089908d9060040161410e565b600060405180830381600087803b15801561208057600080fd5b505af1158015612094573d6000803e3d6000fd5b5050505050505b886001600160a01b03168a6001600160a01b0316826001600160a01b03167f1e90de9ae4d02420648a650f45f089a1be18fbca324092544ea626f9833212b0878b6040516120ea92919061410e565b60405180910390a4841561211457612114612103611867565b6001600160a01b038d1690876128bb565b50505050506035548114610fe25760405162461bcd60e51b815260040161034190613784565b600060128260ff1611156121605760405162461bcd60e51b815260040161034190613ce7565b5060120360ff16600a0a90565b60006001600160a01b0382166121955760405162461bcd60e51b815260040161034190613dc0565b506001600160a01b03166000908152602091909152604090205460ff1690565b603954845160208087015160608801516001600160a01b038416600090815260458452604080822080546001810190915590519196612241969095612226957ff18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd8043395929490938d928d928d910161369c565b604051602081830303815290604052805190602001206128df565b95945050505050565b603580546001019081905560608501356000908152604360205260408120549091906001600160a01b0316806122925760405162461bcd60e51b815260040161034190613f45565b60006122c36122a460208a018a612f3e565b60208a013560408b013560608c013561073a60a08e0160808f01613402565b606089013560009081526042602052604090205490915081146122f85760405162461bcd60e51b8152600401610341906140cd565b6000818152603e602052604090205460ff16156123275760405162461bcd60e51b815260040161034190613e02565b6000818152603e60209081526040808320805460ff191660011790556001600160a01b0385168352603d90915290205460ff16156123775761237082888a6020013589896128fe565b935061238b565b61238882888a602001358989612a74565b93505b6123986020890189612f3e565b6001600160a01b0316826001600160a01b031689606001357f42b1cb6263e8da47edf0583516eda1de16f729d26282f5791dc5b7af1010e925604460008d60600135815260200190815260200160002060009054906101000a90046001600160a01b03168c602001358d604001358e60800160208101906124199190613402565b8e8e8e60405161242f9796959493929190613640565b60405180910390a45050603554811461245a5760405162461bcd60e51b815260040161034190613784565b50949350505050565b61246e603382612c0b565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b611725846323b872dd60e01b8585856040516024016124c693929190613603565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612c53565b612508603382612d37565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b6001600160a01b0381166125bc5760405162461bcd60e51b815260040161034190613fa3565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600082612632575060006111f2565b8282028284828161263f57fe5b041461265d5760405162461bcd60e51b815260040161034190613d1e565b9392505050565b600061265d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612d83565b600061265d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612dba565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b0386169161272e919061348a565b600060405180830381855afa9150503d8060008114612769576040519150601f19603f3d011682016040523d82523d6000602084013e61276e565b606091505b5091509150816127905760405162461bcd60e51b81526004016103419061382e565b808060200190518101906127a49190613350565b949350505050565b60408051600481526024810182526020810180516001600160e01b031663556f0dc760e01b1790529051600091829182916001600160a01b038616916127f2919061348a565b600060405180830381855afa9150503d806000811461282d576040519150601f19603f3d011682016040523d82523d6000602084013e612832565b606091505b5091509150816127905760405162461bcd60e51b815260040161034190613bbc565b600061265d83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250612de6565b60008282018381101561265d5760405162461bcd60e51b815260040161034190613894565b6128da8363a9059cbb60e01b84846040516024016124c6929190613627565b505050565b60405161190160f01b8152600281019290925260228201526042902090565b60008061290a876126e8565b60ff1690506000612922866012849003600a0a612664565b9050808411156129445760405162461bcd60e51b815260040161034190613f75565b60415484820393506001600160a01b0389811691161415612a3b57604154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d9061298f908490600401613693565b600060405180830381600087803b1580156129a957600080fd5b505af11580156129bd573d6000803e3d6000fd5b50506040516001600160a01b038a16925085156108fc02915085906000818181858888f193505050501580156129f7573d6000803e3d6000fd5b508315612a36576040516001600160a01b0386169085156108fc029086906000818181858888f19350505050158015612a34573d6000803e3d6000fd5b505b612a69565b612a4f6001600160a01b03891688856128bb565b8315612a6957612a696001600160a01b03891686866128bb565b505095945050505050565b6001600160a01b038086166000908152603b6020908152604080832054815163556f0dc760e01b81529151939416928492849263556f0dc79260048083019392829003018186803b158015612ac857600080fd5b505afa158015612adc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b009190613350565b90506000612b0e8783612623565b905080851115612b305760405162461bcd60e51b815260040161034190613f75565b604051630dcdc7dd60e41b815285820394506001600160a01b0384169063dcdc7dd090612b63908b9088906004016135cd565b600060405180830381600087803b158015612b7d57600080fd5b505af1158015612b91573d6000803e3d6000fd5b505050506000851115612bff57604051630dcdc7dd60e41b81526001600160a01b0384169063dcdc7dd090612bcc9089908990600401613582565b600060405180830381600087803b158015612be657600080fd5b505af1158015612bfa573d6000803e3d6000fd5b505050505b50505095945050505050565b612c15828261216d565b612c315760405162461bcd60e51b815260040161034190613953565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b612c65826001600160a01b0316611e7a565b612c815760405162461bcd60e51b815260040161034190614096565b600080836001600160a01b031683604051612c9c919061348a565b6000604051808303816000865af19150503d8060008114612cd9576040519150601f19603f3d011682016040523d82523d6000602084013e612cde565b606091505b509150915081612d005760405162461bcd60e51b815260040161034190613988565b8051156117255780806020019051810190612d1b919061321b565b6117255760405162461bcd60e51b815260040161034190613fe5565b612d41828261216d565b15612d5e5760405162461bcd60e51b8152600401610341906137f7565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60008183612da45760405162461bcd60e51b8152600401610341919061374f565b506000838581612db057fe5b0495945050505050565b60008184841115612dde5760405162461bcd60e51b8152600401610341919061374f565b505050900390565b60008183612e075760405162461bcd60e51b8152600401610341919061374f565b50828481612e1157fe5b06949350505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282612e505760008555612e96565b82601f10612e6957805160ff1916838001178555612e96565b82800160010185558215612e96579182015b82811115612e96578251825591602001919060010190612e7b565b50612ea2929150612ea6565b5090565b5b80821115612ea25760008155600101612ea7565b60008083601f840112612ecc578182fd5b50813567ffffffffffffffff811115612ee3578182fd5b602083019150836020828501011115612efb57600080fd5b9250929050565b600060a08284031215612f13578081fd5b50919050565b803563ffffffff8116811461109f57600080fd5b803560ff8116811461109f57600080fd5b600060208284031215612f4f578081fd5b813561265d81614177565b600060208284031215612f6b578081fd5b815161265d81614177565b600080600080600080600060e0888a031215612f90578283fd5b8735612f9b81614177565b96506020880135612fab81614177565b95506040880135612fbb81614177565b9450606088013593506080880135925060a08801359150612fde60c08901612f19565b905092959891949750929550565b600080600080600060a08688031215613003578081fd5b853561300e81614177565b945060208681013561301f81614177565b9450604087013561302f81614177565b9350606087013561303f81614177565b9250608087013567ffffffffffffffff8082111561305b578384fd5b818901915089601f83011261306e578384fd5b81358181111561307a57fe5b61308c601f8201601f19168501614127565b91508082528a848285010111156130a1578485fd5b8084840185840137810190920192909252949793965091945092919050565b60008060008060008060008060c0898b0312156130db578081fd5b88356130e681614177565b975060208901356130f681614177565b9650604089013561310681614177565b955060608901359450608089013567ffffffffffffffff80821115613129578283fd5b6131358c838d01612ebb565b909650945060a08b013591508082111561314d578283fd5b5061315a8b828c01612ebb565b999c989b5096995094979396929594505050565b600080600060608486031215613182578081fd5b833561318d81614177565b9250602084013561319d81614177565b929592945050506040919091013590565b600080600080600060a086880312156131c5578283fd5b85356131d081614177565b94506020860135935060408601359250606086013591506131f360808701612f19565b90509295509295909350565b600060208284031215613210578081fd5b813561265d8161418c565b60006020828403121561322c578081fd5b815161265d8161418c565b600060208284031215613248578081fd5b5035919050565b600060a08284031215613260578081fd5b61265d8383612f02565b6000806000806000806000610160888a031215613285578081fd5b61328f8989612f02565b965060a088013561329f81614177565b955060c0880135945060e088013593506132bc6101008901612f2d565b92506101208801359150610140880135905092959891949750929550565b600060a082840312156132eb578081fd5b60405160a0810181811067ffffffffffffffff8211171561330857fe5b604052823561331681614177565b8082525060208301356020820152604083013560408201526060830135606082015261334460808401612f19565b60808201529392505050565b600060208284031215613361578081fd5b5051919050565b600080600080600080600060a0888a031215613382578081fd5b87359650602088013561339481614177565b95506133a260408901612f2d565b9450606088013567ffffffffffffffff808211156133be578283fd5b6133ca8b838c01612ebb565b909650945060808a01359150808211156133e2578283fd5b506133ef8a828b01612ebb565b989b979a50959850939692959293505050565b600060208284031215613413578081fd5b61265d82612f19565b6000815180845261343481602086016020860161414b565b601f01601f19169290920160200192915050565b948552602085019390935260609190911b6bffffffffffffffffffffffff19166040840152605483015260e01b6001600160e01b031916607482015260780190565b6000825161349c81846020870161414b565b9190910192915050565b60008085546001808216600081146134c557600181146134dc5761350b565b60ff198316865260028304607f168601935061350b565b600283048986526020808720875b838110156135035781548a8201529085019082016134ea565b505050860193505b505050838582379092019182525092915050565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b6001600160a01b039490941684526020840192909252604083015263ffffffff16606082015260800190565b6001600160a01b03929092168252602082015260806040820181905260009082015260a060608201819052600b908201526a72656c617965722066656560a81b60c082015260e00190565b6001600160a01b039290921682526020820152608060408201819052600090820181905260a06060830181905282015260c00190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0397881681526020810196909652604086019490945263ffffffff9290921660608501528416608084015290921660a082015260c081019190915260e00190565b901515815260200190565b90815260200190565b9788526001600160a01b039687166020890152604088019590955260608701939093529316608085015260a084019290925260c083019190915260e08201526101000190565b93845260ff9290921660208401526040830152606082015260800190565b600060608252846060830152848660808401378060808684010152601f19601f8601168201608083820301602084015261373d608082018661341c565b91505082604083015295945050505050565b60006020825261265d602083018461341c565b600060408252613775604083018561341c565b90508260208301529392505050565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b6020808252601f908201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604082015260600190565b6020808252601590820152744c69625574696c733a204e6f20646563696d616c7360581b604082015260600190565b6020808252601b908201527f4272696467653a2046656465726174696f6e20697320656d7074790000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601190820152704272696467653a20557067726164696e6760781b604082015260600190565b602080825260169082015275213934b233b29d1034b73b30b634b21039b2b73232b960511b604082015260600190565b602080825260139082015272084e4d2c8ceca74409cead8d840a8f090c2e6d606b1b604082015260600190565b6020808252818101527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c65604082015260600190565b6020808252818101527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604082015260600190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b60208082526019908201527f4272696467653a20494e56414c49445f5349474e415455524500000000000000604082015260600190565b60208082526010908201526f04272696467653a20416d6f756e7420360841b604082015260600190565b6020808252601690820152754272696467653a20777261707020697320656d70747960501b604082015260600190565b602080825260159082015274213934b233b29d102ab735b737bbb7103a37b5b2b760591b604082015260600190565b6020808252601b908201527f4272696467653a204e6f7420746f207468697320616464726573730000000000604082015260600190565b602080825260169082015275213934b233b29d102737ba102332b232b930ba34b7b760511b604082015260600190565b60208082526028908201527f4272696467653a2053706563696679207265636569766572206164647265737360408201526720696e206461746160c01b606082015260800190565b60208082526018908201527f4c69625574696c733a204e6f206772616e756c61726974790000000000000000604082015260600190565b6020808252600f908201526e4272696467653a204e756c6c20546f60881b604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252601d908201527f4272696467653a207772617070656443757272656e637920656d707479000000604082015260600190565b6020808252600f908201526e109c9a5919d94e8811561412549151608a1b604082015260600190565b60208082526021908201527f4272696467653a2053696465546f6b656e466163746f727920697320656d70746040820152607960f81b606082015260800190565b6020808252601c908201527f4c69625574696c733a20446563696d616c73206e6f74203c3d20313800000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260129082015271213934b233b29d10273ab636103a37b5b2b760711b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526022908201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526017908201527f4272696467653a20416c726561647920636c61696d6564000000000000000000604082015260600190565b6020808252601b908201527f4272696467653a206e6f74207772617070656443757272656e63790000000000604082015260600190565b60208082526018908201527f4272696467653a20416c72656164792061636365707465640000000000000000604082015260600190565b602080825260169082015275084e4d2c8ceca74409cead8d84084d8dec6d690c2e6d60531b604082015260600190565b6020808252601c908201527f4272696467653a20416c6c6f77546f6b656e7320697320656d70747900000000604082015260600190565b60208082526018908201527f4272696467653a204e6f742045524337373720746f6b656e0000000000000000604082015260600190565b602080825260169082015275109c9a5919d94e88151e081b9bdd0818dc9bdcdcd95960521b604082015260600190565b602080825260149082015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b604082015260600190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601690820152754272696467653a20416c72656164792065786973747360501b604082015260600190565b60208082526017908201527f4272696467653a20626967676572207468616e20313025000000000000000000604082015260600190565b6020808252601f908201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604082015260600190565b60208082526021908201527f4272696467653a2057726f6e67207472616e73616374696f6e446174614861736040820152600d60fb1b606082015260800190565b6000838252604060208301526127a4604083018461341c565b60405181810167ffffffffffffffff8111828210171561414357fe5b604052919050565b60005b8381101561416657818101518382015260200161414e565b838111156117255750506000910152565b6001600160a01b03811681146117b457600080fd5b80151581146117b457600080fdfea26469706673582212204c589b204ecd046fc7fe66efcbaa8add03eceef2a33bb84785a9a9e908cd5c5664736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "__Pausable_init(address)": {
+ "details": "Initializes the contract in unpaused state. Assigns the Pauser role to the deployer."
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "pause()": {
+ "details": "Called by a pauser to pause, triggers stopped state."
+ },
+ "paused()": {
+ "details": "Returns true if the contract is paused, and false otherwise."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "unpause()": {
+ "details": "Called by a pauser to unpause, returns to normal state."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "acceptTransfer(address,address,address,uint256,bytes32,bytes32,uint32)": {
+ "notice": "Accepts the transaction from the other chain that was voted and sent by the Federation contract"
+ },
+ "claim((address,uint256,bytes32,bytes32,uint32))": {
+ "notice": "Claims the crossed transaction using the hash, this sends the funds to the address indicated in"
+ },
+ "depositTo(address)": {
+ "notice": "Use network currency and cross it."
+ },
+ "receiveTokensTo(address,address,uint256)": {
+ "notice": "ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom"
+ },
+ "tokensReceived(address,address,address,uint256,bytes,bytes)": {
+ "notice": "ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction See https://eips.ethereum.org/EIPS/eip-777#motivation for details"
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15789,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15792,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15832,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 15856,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_pausers",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_struct(Role)10133_storage"
+ },
+ {
+ "astId": 15978,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_paused",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16076,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_owner",
+ "offset": 1,
+ "slot": "52",
+ "type": "t_address"
+ },
+ {
+ "astId": 16790,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_guardCounter",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1282,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "federation",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_address"
+ },
+ {
+ "astId": 1284,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "feePercentage",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1286,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "symbolPrefix",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 1288,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "domainSeparator",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_bytes32"
+ },
+ {
+ "astId": 1290,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_deprecatedSpentToday",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1294,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "mappedTokens",
+ "offset": 0,
+ "slot": "59",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 1298,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originalTokens",
+ "offset": 0,
+ "slot": "60",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 1302,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "knownTokens",
+ "offset": 0,
+ "slot": "61",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 1306,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "claimed",
+ "offset": 0,
+ "slot": "62",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ },
+ {
+ "astId": 1308,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "allowTokens",
+ "offset": 0,
+ "slot": "63",
+ "type": "t_contract(IAllowTokens)7210"
+ },
+ {
+ "astId": 1310,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "sideTokenFactory",
+ "offset": 0,
+ "slot": "64",
+ "type": "t_contract(ISideTokenFactory)7607"
+ },
+ {
+ "astId": 1312,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "isUpgrading",
+ "offset": 20,
+ "slot": "64",
+ "type": "t_bool"
+ },
+ {
+ "astId": 1322,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "wrappedCurrency",
+ "offset": 0,
+ "slot": "65",
+ "type": "t_contract(IWrapped)7660"
+ },
+ {
+ "astId": 1326,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "transactionsDataHashes",
+ "offset": 0,
+ "slot": "66",
+ "type": "t_mapping(t_bytes32,t_bytes32)"
+ },
+ {
+ "astId": 1330,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originalTokenAddresses",
+ "offset": 0,
+ "slot": "67",
+ "type": "t_mapping(t_bytes32,t_address)"
+ },
+ {
+ "astId": 1334,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "senderAddresses",
+ "offset": 0,
+ "slot": "68",
+ "type": "t_mapping(t_bytes32,t_address)"
+ },
+ {
+ "astId": 1341,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "nonces",
+ "offset": 0,
+ "slot": "69",
+ "type": "t_mapping(t_address,t_uint256)"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IAllowTokens)7210": {
+ "encoding": "inplace",
+ "label": "contract IAllowTokens",
+ "numberOfBytes": "20"
+ },
+ "t_contract(ISideTokenFactory)7607": {
+ "encoding": "inplace",
+ "label": "contract ISideTokenFactory",
+ "numberOfBytes": "20"
+ },
+ "t_contract(IWrapped)7660": {
+ "encoding": "inplace",
+ "label": "contract IWrapped",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_address)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_mapping(t_bytes32,t_address)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bytes32)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bytes32)",
+ "numberOfBytes": "32",
+ "value": "t_bytes32"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)10133_storage": {
+ "encoding": "inplace",
+ "label": "struct Roles.Role",
+ "members": [
+ {
+ "astId": 10132,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "bearer",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_address,t_bool)"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/BridgeProxy.json b/bridge/deployments/rinkeby/BridgeProxy.json
new file mode 100644
index 000000000..e6b5fe846
--- /dev/null
+++ b/bridge/deployments/rinkeby/BridgeProxy.json
@@ -0,0 +1,234 @@
+{
+ "address": "0x7E339118346364d7D86AB67cb0775CBB808E65F7",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_admin",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x6e1117e9f966b6e8181d4eae41cfcf89ddc29281395dbebd4747cbd501d60c7a",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0x7E339118346364d7D86AB67cb0775CBB808E65F7",
+ "transactionIndex": 4,
+ "gasUsed": "795197",
+ "logsBloom": "0x00800000020000000000000000000000000000000000000000800000000000001000000000000000000000000000002000000000000000000000000000000000004000000080000000000000400000000001000010000000000000000000000000000000020000000000000000000800000010004020000000000000000000400000001000000000000008000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000200801000000000008000000000100000000000000000000000000000000000000000000000020000000000040000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xe6674ccab2029f73c1cc6691b90befd5c2bac674468d869abcfc3534de410ac4",
+ "transactionHash": "0x6e1117e9f966b6e8181d4eae41cfcf89ddc29281395dbebd4747cbd501d60c7a",
+ "logs": [
+ {
+ "transactionIndex": 4,
+ "blockNumber": 9264195,
+ "transactionHash": "0x6e1117e9f966b6e8181d4eae41cfcf89ddc29281395dbebd4747cbd501d60c7a",
+ "address": "0x7E339118346364d7D86AB67cb0775CBB808E65F7",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x00000000000000000000000004994d7ff4938c5953a6c8411ad30083c9097348"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0xe6674ccab2029f73c1cc6691b90befd5c2bac674468d869abcfc3534de410ac4"
+ },
+ {
+ "transactionIndex": 4,
+ "blockNumber": 9264195,
+ "transactionHash": "0x6e1117e9f966b6e8181d4eae41cfcf89ddc29281395dbebd4747cbd501d60c7a",
+ "address": "0x7E339118346364d7D86AB67cb0775CBB808E65F7",
+ "topics": [
+ "0x6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f8",
+ "0x00000000000000000000000004994d7ff4938c5953a6c8411ad30083c9097348"
+ ],
+ "data": "0x",
+ "logIndex": 1,
+ "blockHash": "0xe6674ccab2029f73c1cc6691b90befd5c2bac674468d869abcfc3534de410ac4"
+ },
+ {
+ "transactionIndex": 4,
+ "blockNumber": 9264195,
+ "transactionHash": "0x6e1117e9f966b6e8181d4eae41cfcf89ddc29281395dbebd4747cbd501d60c7a",
+ "address": "0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24",
+ "topics": [
+ "0x93baa6efbd2244243bfee6ce4cfdd1d04fc4c0e9a786abd3a41313bd352db153",
+ "0x0000000000000000000000007e339118346364d7d86ab67cb0775cbb808e65f7",
+ "0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b",
+ "0x0000000000000000000000007e339118346364d7d86ab67cb0775cbb808e65f7"
+ ],
+ "data": "0x",
+ "logIndex": 2,
+ "blockHash": "0xe6674ccab2029f73c1cc6691b90befd5c2bac674468d869abcfc3534de410ac4"
+ }
+ ],
+ "blockNumber": 9264195,
+ "cumulativeGasUsed": "913526",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0x500f602F60B6d223F50aAc3750625Ec771ED3C57",
+ "0x0b32Ea549AB1F9F7390442B5E9438b58A105cB5f",
+ "0x2fb3b36100000000000000000000000004994d7ff4938c5953a6c8411ad30083c90973480000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b0000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b0000000000000000000000001cb41dc4603612a4da692669916e8f4def2994dc00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000016500000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Proxies.sol\":\"BridgeProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Proxies.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\\\";\\r\\n\\r\\ncontract BridgeProxy is TransparentUpgradeableProxy {\\r\\n // solhint-disable-next-line no-empty-blocks\\r\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\r\\n}\\r\\n\\r\\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\\r\\n // solhint-disable-next-line no-empty-blocks\\r\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\r\\n}\\r\\n\\r\\ncontract FederationProxy is TransparentUpgradeableProxy {\\r\\n // solhint-disable-next-line no-empty-blocks\\r\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\r\\n}\",\"keccak256\":\"0x85fcee3669ce6de4bbb104f8e0878435de0f12eb5437f30933966256196f42da\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\r\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\r\\n * be specified by overriding the virtual {_implementation} function.\\r\\n *\\r\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\r\\n * different contract through the {_delegate} function.\\r\\n *\\r\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\r\\n */\\r\\nabstract contract Proxy {\\r\\n /**\\r\\n * @dev Delegates the current call to `implementation`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _delegate(address implementation) internal virtual {\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n // Copy msg.data. We take full control of memory in this inline assembly\\r\\n // block because it will not return to Solidity code. We overwrite the\\r\\n // Solidity scratch pad at memory position 0.\\r\\n calldatacopy(0, 0, calldatasize())\\r\\n\\r\\n // Call the implementation.\\r\\n // out and outsize are 0 because we don't know the size yet.\\r\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\r\\n\\r\\n // Copy the returned data.\\r\\n returndatacopy(0, 0, returndatasize())\\r\\n\\r\\n switch result\\r\\n // delegatecall returns 0 on error.\\r\\n case 0 { revert(0, returndatasize()) }\\r\\n default { return(0, returndatasize()) }\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\r\\n * and {_fallback} should delegate.\\r\\n */\\r\\n function _implementation() internal view virtual returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _fallback() internal virtual {\\r\\n _beforeFallback();\\r\\n _delegate(_implementation());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\r\\n * function in the contract matches the call data.\\r\\n */\\r\\n fallback () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\r\\n * is empty.\\r\\n */\\r\\n receive () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\r\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\r\\n *\\r\\n * If overriden should call `super._beforeFallback()`.\\r\\n */\\r\\n function _beforeFallback() internal virtual {\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x6374180266624d2291abb230bdf0d364858fa164844f5d2d83ad5325852390c9\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./UpgradeableProxy.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\r\\n *\\r\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\r\\n * clashing], which can potentially be used in an attack, this contract uses the\\r\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\r\\n * things that go hand in hand:\\r\\n *\\r\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\r\\n * that call matches one of the admin functions exposed by the proxy itself.\\r\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\r\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\r\\n * \\\"admin cannot fallback to proxy target\\\".\\r\\n *\\r\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\r\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\r\\n * to sudden errors when trying to call a function from the proxy implementation.\\r\\n *\\r\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\r\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\r\\n */\\r\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\r\\n /**\\r\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\r\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\r\\n */\\r\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\r\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\r\\n _setAdmin(admin_);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the admin account has changed.\\r\\n */\\r\\n event AdminChanged(address previousAdmin, address newAdmin);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the admin of the contract.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\r\\n\\r\\n /**\\r\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\r\\n */\\r\\n modifier ifAdmin() {\\r\\n if (msg.sender == _admin()) {\\r\\n _;\\r\\n } else {\\r\\n _fallback();\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\r\\n */\\r\\n function admin() external ifAdmin returns (address admin_) {\\r\\n admin_ = _admin();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\r\\n */\\r\\n function implementation() external ifAdmin returns (address implementation_) {\\r\\n implementation_ = _implementation();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Changes the admin of the proxy.\\r\\n *\\r\\n * Emits an {AdminChanged} event.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\r\\n */\\r\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\r\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\r\\n emit AdminChanged(_admin(), newAdmin);\\r\\n _setAdmin(newAdmin);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\r\\n */\\r\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\r\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\r\\n * proxied contract.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\r\\n */\\r\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n Address.functionDelegateCall(newImplementation, data);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n */\\r\\n function _admin() internal view virtual returns (address adm) {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n adm := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 admin slot.\\r\\n */\\r\\n function _setAdmin(address newAdmin) private {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newAdmin)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\r\\n */\\r\\n function _beforeFallback() internal virtual override {\\r\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\r\\n super._beforeFallback();\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x7496c2c54dd8e648d6999687cf759521e6ab229d0d8ddb4db62f3b51dbe68811\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./Proxy.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\r\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\r\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\r\\n * implementation behind the proxy.\\r\\n *\\r\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\r\\n * {TransparentUpgradeableProxy}.\\r\\n */\\r\\ncontract UpgradeableProxy is Proxy {\\r\\n /**\\r\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\r\\n *\\r\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\r\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\r\\n */\\r\\n constructor(address _logic, bytes memory _data) payable {\\r\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\r\\n _setImplementation(_logic);\\r\\n if(_data.length > 0) {\\r\\n Address.functionDelegateCall(_logic, _data);\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the implementation is upgraded.\\r\\n */\\r\\n event Upgraded(address indexed implementation);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the address of the current implementation.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation address.\\r\\n */\\r\\n function _implementation() internal view virtual override returns (address impl) {\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n impl := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrades the proxy to a new implementation.\\r\\n *\\r\\n * Emits an {Upgraded} event.\\r\\n */\\r\\n function _upgradeTo(address newImplementation) internal virtual {\\r\\n _setImplementation(newImplementation);\\r\\n emit Upgraded(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 implementation slot.\\r\\n */\\r\\n function _setImplementation(address newImplementation) private {\\r\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\r\\n\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newImplementation)\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x4d3fcb8487e53abb8658817c4b90038b24d81d0a32d989f03b54d4cfab929f62\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000ca538038062000ca5833981016040819052620000269162000234565b8282828281620000368262000077565b8051156200005757620000558282620000d960201b620002ca1760201c565b505b50620000609050565b6200006b8262000108565b50505050505062000423565b6200008d816200012c60201b620002f61760201c565b620000b55760405162461bcd60e51b8152600401620000ac906200034d565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606062000101838360405180606001604052806027815260200162000c7e6027913962000136565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b606062000143846200012c565b620001625760405162461bcd60e51b8152600401620000ac90620003aa565b600080856001600160a01b0316856040516200017f9190620002fa565b600060405180830381855af49150503d8060008114620001bc576040519150601f19603f3d011682016040523d82523d6000602084013e620001c1565b606091505b509092509050620001d4828286620001de565b9695505050505050565b60608315620001ef57508162000101565b825115620002005782518084602001fd5b8160405162461bcd60e51b8152600401620000ac919062000318565b80516001600160a01b03811681146200013157600080fd5b60008060006060848603121562000249578283fd5b62000254846200021c565b925062000264602085016200021c565b60408501519092506001600160401b038082111562000281578283fd5b818601915086601f83011262000295578283fd5b815181811115620002a257fe5b604051601f8201601f191681016020018381118282101715620002c157fe5b604052818152838201602001891015620002d9578485fd5b620002ec826020830160208701620003f0565b809450505050509250925092565b600082516200030e818460208701620003f0565b9190910192915050565b600060208252825180602084015262000339816040850160208701620003f0565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b838110156200040d578181015183820152602001620003f3565b838111156200041d576000848401525b50505050565b61084b80620004336000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122062766c17e94a6c40528969924f0bd026491bb737bb1305a177de6512cf341cce64736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122062766c17e94a6c40528969924f0bd026491bb737bb1305a177de6512cf341cce64736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/Federation.json b/bridge/deployments/rinkeby/Federation.json
new file mode 100644
index 000000000..8267ff490
--- /dev/null
+++ b/bridge/deployments/rinkeby/Federation.json
@@ -0,0 +1,1094 @@
+{
+ "address": "0xdc8E3000ED0aCAC926A37ead0f0B0F675182AC3b",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridge",
+ "type": "address"
+ }
+ ],
+ "name": "BridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Executed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "HeartBeat",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridgeNFT",
+ "type": "address"
+ }
+ ],
+ "name": "NFTBridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Voted",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_MEMBER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_newMember",
+ "type": "address"
+ }
+ ],
+ "name": "addMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridge",
+ "outputs": [
+ {
+ "internalType": "contract IBridge",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridgeNFT",
+ "outputs": [
+ {
+ "internalType": "contract INFTBridge",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "emitHeartbeat",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getMembers",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "getTransactionId",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_members",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridgeNFT",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isMember",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "members",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "processed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_oldMember",
+ "type": "address"
+ }
+ ],
+ "name": "removeMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ }
+ ],
+ "name": "setBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridgeNFT",
+ "type": "address"
+ }
+ ],
+ "name": "setNFTBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionWasProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "enum IFederation.TokenType",
+ "name": "tokenType",
+ "type": "uint8"
+ }
+ ],
+ "name": "voteTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "votes",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x493fb51022e5f353fd75de3e7cd5393d274011cd7a5f7843a5e47170a3ec3687",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0xdc8E3000ED0aCAC926A37ead0f0B0F675182AC3b",
+ "transactionIndex": 2,
+ "gasUsed": "1700428",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xebc2fd40d364b3616e9b02286807ca2f6e71179901f6c0d8077ccdf181f85dce",
+ "transactionHash": "0x493fb51022e5f353fd75de3e7cd5393d274011cd7a5f7843a5e47170a3ec3687",
+ "logs": [],
+ "blockNumber": 9269458,
+ "cumulativeGasUsed": "2341463",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"bridge\",\"type\":\"address\"}],\"name\":\"BridgeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"Executed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fedRskBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fedEthBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"federatorVersion\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"nodeRskInfo\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"nodeEthInfo\",\"type\":\"string\"}],\"name\":\"HeartBeat\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"bridgeNFT\",\"type\":\"address\"}],\"name\":\"NFTBridgeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"Voted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MEMBER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newMember\",\"type\":\"address\"}],\"name\":\"addMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contract IBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridgeNFT\",\"outputs\":[{\"internalType\":\"contract INFTBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fedRskBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fedEthBlock\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"federatorVersion\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nodeRskInfo\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nodeEthInfo\",\"type\":\"string\"}],\"name\":\"emitHeartbeat\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMembers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"getTransactionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"hasVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_members\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bridgeNFT\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMember\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"members\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"processed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_oldMember\",\"type\":\"address\"}],\"name\":\"removeMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"name\":\"setBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridgeNFT\",\"type\":\"address\"}],\"name\":\"setNFTBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"transactionWasProcessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"enum IFederation.TokenType\",\"name\":\"tokenType\",\"type\":\"uint8\"}],\"name\":\"voteTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"votes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addMember(address)\":{\"params\":{\"_newMember\":\"address of the new member\"}},\"changeRequirement(uint256)\":{\"details\":\"Emits the RequirementChange event\",\"params\":{\"_required\":\"the number of minimum members to approve an transaction, it has to be bigger than 1\"}},\"emitHeartbeat(uint256,uint256,string,string,string)\":{\"details\":\"Emits HeartBeat event\"},\"getMembers()\":{\"returns\":{\"_0\":\"Current members\"}},\"getTransactionCount(bytes32)\":{\"params\":{\"transactionId\":\"The transaction hashed from getTransactionId function\"}},\"getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32)\":{\"details\":\"It encodes and applies keccak256 to the parameters received in the same order\",\"params\":{\"amount\":\"Could be the amount or the tokenId\",\"blockHash\":\"The block hash in which the transaction with the cross event occurred\",\"logIndex\":\"Index of the event in the logs\",\"originalTokenAddress\":\"The address of the token in the origin (main) chain\",\"receiver\":\"Who is going to receive the token in the opposite chain\",\"sender\":\"The address who solicited the cross token\",\"transactionHash\":\"The transaction in which the cross event occurred\"},\"returns\":{\"_0\":\"The hash generated by the parameters.\"}},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"removeMember(address)\":{\"params\":{\"_oldMember\":\"address of the member to be removed from federation\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setBridge(address)\":{\"details\":\"Emits BridgeChanged event\",\"params\":{\"_bridge\":\"the new bridge contract address that should implement the IBridge interface\"}},\"setNFTBridge(address)\":{\"details\":\"Emits NFTBridgeChanged event\",\"params\":{\"_bridgeNFT\":\"the new NFT bridge contract address that should implement the INFTBridge interface\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"version()\":{\"returns\":{\"_0\":\"version in v{Number}\"}},\"voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint8)\":{\"params\":{\"blockHash\":\"The block hash in which the transaction with the cross event occurred\",\"logIndex\":\"Index of the event in the logs\",\"originalTokenAddress\":\"The address of the token in the origin (main) chain\",\"receiver\":\"Who is going to receive the token in the opposite chain\",\"sender\":\"The address who solicited the cross token\",\"tokenType\":\"Is the type of bridge to be used\",\"transactionHash\":\"The transaction in which the cross event occurred\",\"value\":\"Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\"}}},\"stateVariables\":{\"isMember\":{\"details\":\"The address should be a member to vote in transactions\"},\"required\":{\"details\":\"It should have more members than the required amount\"},\"votes\":{\"details\":\"usually the members should approve the transaction by 50% + 1\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addMember(address)\":{\"notice\":\"Add a new member to the federation\"},\"bridgeNFT()\":{\"notice\":\"Federator v3 variables \"},\"changeRequirement(uint256)\":{\"notice\":\"Changes the number of required members to vote and approve an transaction\"},\"emitHeartbeat(uint256,uint256,string,string,string)\":{\"notice\":\"It emits an HeartBeat like an health check\"},\"getMembers()\":{\"notice\":\"Return all the current members of the federation\"},\"getTransactionCount(bytes32)\":{\"notice\":\"Get the amount of approved votes for that transactionId\"},\"getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32)\":{\"notice\":\"Gets the hash of transaction from the following parameters encoded and keccaked\"},\"isMember(address)\":{\"notice\":\"All the addresses that are members of the federation\"},\"processed(bytes32)\":{\"notice\":\"(bytes32) transactionId => (bool) votedCheck if that transaction was already processed\"},\"removeMember(address)\":{\"notice\":\"Remove a member of the federation\"},\"required()\":{\"notice\":\"The minimum amount of votes to approve a transaction\"},\"setBridge(address)\":{\"notice\":\"Sets a new bridge contract\"},\"setNFTBridge(address)\":{\"notice\":\"Sets a new NFT bridge contract\"},\"version()\":{\"notice\":\"Current version of the contract\"},\"voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint8)\":{\"notice\":\"Vote in a transaction, if it has enough votes it accepts the transfer\"},\"votes(bytes32,address)\":{\"notice\":\"(bytes32) transactionId = keccak256( abi.encodePacked( originalTokenAddress, sender, receiver, amount, blockHash, transactionHash, logIndex ) ) => ( (address) members => (bool) voted )Votes by members by the transaction ID\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Federation/Federation.sol\":\"Federation\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Federation/Federation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n// Upgradables\\r\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\r\\n\\r\\nimport \\\"../nftbridge/INFTBridge.sol\\\";\\r\\nimport \\\"../interface/IBridge.sol\\\";\\r\\nimport \\\"../interface/IFederation.sol\\\";\\r\\n\\r\\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\\r\\n uint constant public MAX_MEMBER_COUNT = 50;\\r\\n address constant private NULL_ADDRESS = address(0);\\r\\n\\r\\n IBridge public bridge;\\r\\n address[] public members;\\r\\n\\r\\n /**\\r\\n @notice The minimum amount of votes to approve a transaction\\r\\n @dev It should have more members than the required amount\\r\\n */\\r\\n uint public required;\\r\\n\\r\\n /**\\r\\n @notice All the addresses that are members of the federation\\r\\n @dev The address should be a member to vote in transactions\\r\\n */\\r\\n mapping (address => bool) public isMember;\\r\\n\\r\\n /**\\r\\n (bytes32) transactionId = keccak256(\\r\\n abi.encodePacked(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n amount,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n )\\r\\n ) => (\\r\\n (address) members => (bool) voted\\r\\n )\\r\\n @notice Votes by members by the transaction ID\\r\\n @dev usually the members should approve the transaction by 50% + 1\\r\\n */\\r\\n mapping (bytes32 => mapping (address => bool)) public votes;\\r\\n\\r\\n /**\\r\\n (bytes32) transactionId => (bool) voted\\r\\n @notice Check if that transaction was already processed\\r\\n */\\r\\n mapping(bytes32 => bool) public processed;\\r\\n\\r\\n /** Federator v3 variables */\\r\\n INFTBridge public bridgeNFT;\\r\\n\\r\\n modifier onlyMember() {\\r\\n require(isMember[_msgSender()], \\\"Federation: Not Federator\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier validRequirement(uint membersCount, uint _required) {\\r\\n // solium-disable-next-line max-len\\r\\n require(_required <= membersCount && _required != 0 && membersCount != 0, \\\"Federation: Invalid requirements\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function initialize(address[] memory _members, uint _required, address _bridge, address owner, address _bridgeNFT) public\\r\\n validRequirement(_members.length, _required) initializer {\\r\\n UpgradableOwnable.initialize(owner);\\r\\n require(_members.length <= MAX_MEMBER_COUNT, \\\"Federation: Too many members\\\");\\r\\n members = _members;\\r\\n for (uint i = 0; i < _members.length; i++) {\\r\\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \\\"Federation: Invalid members\\\");\\r\\n isMember[_members[i]] = true;\\r\\n emit MemberAddition(_members[i]);\\r\\n }\\r\\n required = _required;\\r\\n emit RequirementChange(required);\\r\\n _setBridge(_bridge);\\r\\n _setNFTBridge(_bridgeNFT);\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Current version of the contract\\r\\n @return version in v{Number}\\r\\n */\\r\\n function version() external pure override returns (string memory) {\\r\\n return \\\"v3\\\";\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Sets a new bridge contract\\r\\n @dev Emits BridgeChanged event\\r\\n @param _bridge the new bridge contract address that should implement the IBridge interface\\r\\n */\\r\\n function setBridge(address _bridge) external onlyOwner override {\\r\\n _setBridge(_bridge);\\r\\n }\\r\\n\\r\\n function _setBridge(address _bridge) internal {\\r\\n require(_bridge != NULL_ADDRESS, \\\"Federation: Empty bridge\\\");\\r\\n bridge = IBridge(_bridge);\\r\\n emit BridgeChanged(_bridge);\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Sets a new NFT bridge contract\\r\\n @dev Emits NFTBridgeChanged event\\r\\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\\r\\n */\\r\\n function setNFTBridge(address _bridgeNFT) external onlyOwner override {\\r\\n _setNFTBridge(_bridgeNFT);\\r\\n }\\r\\n\\r\\n function _setNFTBridge(address _bridgeNFT) internal {\\r\\n require(_bridgeNFT != NULL_ADDRESS, \\\"Federation: Empty NFT bridge\\\");\\r\\n bridgeNFT = INFTBridge(_bridgeNFT);\\r\\n emit NFTBridgeChanged(_bridgeNFT);\\r\\n }\\r\\n\\r\\n function validateTransaction(bytes32 transactionId) internal view returns(bool) {\\r\\n uint transactionCount = getTransactionCount(transactionId);\\r\\n return transactionCount >= required && transactionCount >= members.length / 2 + 1;\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\\r\\n @param originalTokenAddress The address of the token in the origin (main) chain\\r\\n @param sender The address who solicited the cross token\\r\\n @param receiver Who is going to receive the token in the opposite chain\\r\\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\\r\\n @param blockHash The block hash in which the transaction with the cross event occurred\\r\\n @param transactionHash The transaction in which the cross event occurred\\r\\n @param logIndex Index of the event in the logs\\r\\n @param tokenType Is the type of bridge to be used\\r\\n */\\r\\n function voteTransaction(\\r\\n address originalTokenAddress,\\r\\n address payable sender,\\r\\n address payable receiver,\\r\\n uint256 value,\\r\\n bytes32 blockHash,\\r\\n bytes32 transactionHash,\\r\\n uint32 logIndex,\\r\\n TokenType tokenType\\r\\n ) external onlyMember override {\\r\\n bytes32 transactionId = getTransactionId(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n value,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n );\\r\\n if (processed[transactionId])\\r\\n return;\\r\\n\\r\\n if (votes[transactionId][_msgSender()])\\r\\n return;\\r\\n\\r\\n votes[transactionId][_msgSender()] = true;\\r\\n emit Voted(\\r\\n _msgSender(),\\r\\n transactionHash,\\r\\n transactionId,\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n value,\\r\\n blockHash,\\r\\n logIndex\\r\\n );\\r\\n\\r\\n if (validateTransaction(transactionId)) {\\r\\n processed[transactionId] = true;\\r\\n acceptTransfer(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n value,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex,\\r\\n tokenType\\r\\n );\\r\\n\\r\\n emit Executed(\\r\\n _msgSender(),\\r\\n transactionHash,\\r\\n transactionId,\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n value,\\r\\n blockHash,\\r\\n logIndex\\r\\n );\\r\\n return;\\r\\n }\\r\\n }\\r\\n\\r\\n function acceptTransfer(\\r\\n address originalTokenAddress,\\r\\n address payable sender,\\r\\n address payable receiver,\\r\\n uint256 value,\\r\\n bytes32 blockHash,\\r\\n bytes32 transactionHash,\\r\\n uint32 logIndex,\\r\\n TokenType tokenType\\r\\n ) internal {\\r\\n if (tokenType == TokenType.NFT) {\\r\\n require(address(bridgeNFT) != NULL_ADDRESS, \\\"Federation: Empty NFTBridge\\\");\\r\\n bridgeNFT.acceptTransfer(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n value,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n );\\r\\n return;\\r\\n }\\r\\n\\r\\n bridge.acceptTransfer(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n value,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n );\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Get the amount of approved votes for that transactionId\\r\\n @param transactionId The transaction hashed from getTransactionId function\\r\\n */\\r\\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\\r\\n uint count = 0;\\r\\n for (uint i = 0; i < members.length; i++) {\\r\\n if (votes[transactionId][members[i]])\\r\\n count += 1;\\r\\n }\\r\\n return count;\\r\\n }\\r\\n\\r\\n function hasVoted(bytes32 transactionId) external view returns(bool)\\r\\n {\\r\\n return votes[transactionId][_msgSender()];\\r\\n }\\r\\n\\r\\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\\r\\n {\\r\\n return processed[transactionId];\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Gets the hash of transaction from the following parameters encoded and keccaked\\r\\n @dev It encodes and applies keccak256 to the parameters received in the same order\\r\\n @param originalTokenAddress The address of the token in the origin (main) chain\\r\\n @param sender The address who solicited the cross token\\r\\n @param receiver Who is going to receive the token in the opposite chain\\r\\n @param amount Could be the amount or the tokenId\\r\\n @param blockHash The block hash in which the transaction with the cross event occurred\\r\\n @param transactionHash The transaction in which the cross event occurred\\r\\n @param logIndex Index of the event in the logs\\r\\n @return The hash generated by the parameters.\\r\\n */\\r\\n function getTransactionId(\\r\\n address originalTokenAddress,\\r\\n address sender,\\r\\n address receiver,\\r\\n uint256 amount,\\r\\n bytes32 blockHash,\\r\\n bytes32 transactionHash,\\r\\n uint32 logIndex\\r\\n ) public pure returns(bytes32) {\\r\\n return keccak256(\\r\\n abi.encodePacked(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n amount,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n )\\r\\n );\\r\\n }\\r\\n\\r\\n function addMember(address _newMember) external onlyOwner override\\r\\n {\\r\\n require(_newMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\r\\n require(!isMember[_newMember], \\\"Federation: Member already exists\\\");\\r\\n require(members.length < MAX_MEMBER_COUNT, \\\"Federation: Max members reached\\\");\\r\\n\\r\\n isMember[_newMember] = true;\\r\\n members.push(_newMember);\\r\\n emit MemberAddition(_newMember);\\r\\n }\\r\\n\\r\\n function removeMember(address _oldMember) external onlyOwner override\\r\\n {\\r\\n require(_oldMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\r\\n require(isMember[_oldMember], \\\"Federation: Member doesn't exists\\\");\\r\\n require(members.length > 1, \\\"Federation: Can't remove all the members\\\");\\r\\n require(members.length - 1 >= required, \\\"Federation: Can't have less than required members\\\");\\r\\n\\r\\n isMember[_oldMember] = false;\\r\\n for (uint i = 0; i < members.length - 1; i++) {\\r\\n if (members[i] == _oldMember) {\\r\\n members[i] = members[members.length - 1];\\r\\n break;\\r\\n }\\r\\n }\\r\\n members.pop(); // remove an element from the end of the array.\\r\\n emit MemberRemoval(_oldMember);\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Return all the current members of the federation\\r\\n @return Current members\\r\\n */\\r\\n function getMembers() external view override returns (address[] memory) {\\r\\n return members;\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Changes the number of required members to vote and approve an transaction\\r\\n @dev Emits the RequirementChange event\\r\\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\\r\\n */\\r\\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\\r\\n require(_required >= 2, \\\"Federation: Requires at least 2\\\");\\r\\n required = _required;\\r\\n emit RequirementChange(_required);\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice It emits an HeartBeat like an health check\\r\\n @dev Emits HeartBeat event\\r\\n */\\r\\n function emitHeartbeat(\\r\\n uint256 fedRskBlock,\\r\\n uint256 fedEthBlock,\\r\\n string calldata federatorVersion,\\r\\n string calldata nodeRskInfo,\\r\\n string calldata nodeEthInfo\\r\\n ) external onlyMember override {\\r\\n emit HeartBeat(\\r\\n _msgSender(),\\r\\n fedRskBlock,\\r\\n fedEthBlock,\\r\\n federatorVersion,\\r\\n nodeRskInfo,\\r\\n nodeEthInfo\\r\\n );\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xa0a2e0f2ad71ae15c4301dbccbd3a100904df70e291ddbde1f0bad759635e164\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IBridge {\\r\\n\\r\\n struct ClaimData {\\r\\n address payable to;\\r\\n uint256 amount;\\r\\n bytes32 blockHash;\\r\\n bytes32 transactionHash;\\r\\n uint32 logIndex;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getFeePercentage() external view returns(uint);\\r\\n\\r\\n /**\\r\\n * ERC-20 tokens approve and transferFrom pattern\\r\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\r\\n */\\r\\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\\r\\n\\r\\n /**\\r\\n * Use network currency and cross it.\\r\\n */\\r\\n function depositTo(address to) external payable;\\r\\n\\r\\n /**\\r\\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\r\\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\r\\n */\\r\\n function tokensReceived (\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\r\\n */\\r\\n function acceptTransfer(\\r\\n address _originalTokenAddress,\\r\\n address payable _from,\\r\\n address payable _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\r\\n */\\r\\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\r\\n\\r\\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\r\\n\\r\\n function claimGasless(\\r\\n ClaimData calldata _claimData,\\r\\n address payable _relayer,\\r\\n uint256 _fee,\\r\\n uint256 _deadline,\\r\\n uint8 _v,\\r\\n bytes32 _r,\\r\\n bytes32 _s\\r\\n ) external returns (uint256 receivedAmount);\\r\\n\\r\\n function getTransactionDataHash(\\r\\n address _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external returns(bytes32);\\r\\n\\r\\n event Cross(\\r\\n address indexed _tokenAddress,\\r\\n address indexed _from,\\r\\n address indexed _to,\\r\\n uint256 _amount,\\r\\n bytes _userData\\r\\n );\\r\\n event NewSideToken(\\r\\n address indexed _newSideTokenAddress,\\r\\n address indexed _originalTokenAddress,\\r\\n string _newSymbol,\\r\\n uint256 _granularity\\r\\n );\\r\\n event AcceptedCrossTransfer(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _from,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex\\r\\n );\\r\\n event FeePercentageChanged(uint256 _amount);\\r\\n event Claimed(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _sender,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex,\\r\\n address _reciever,\\r\\n address _relayer,\\r\\n uint256 _fee\\r\\n );\\r\\n}\",\"keccak256\":\"0x9e48ff075a1e3fd0533feec4b93f397a4678b5d267cbae021ea0faf8cc91a383\",\"license\":\"MIT\"},\"contracts/interface/IFederation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface IFederation {\\r\\n enum TokenType{ COIN, NFT }\\r\\n\\r\\n /**\\r\\n @notice Current version of the contract\\r\\n @return version in v{Number}\\r\\n */\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n /**\\r\\n @notice Sets a new bridge contract\\r\\n @param _bridge the new bridge contract address that should implement the IBridge interface\\r\\n */\\r\\n function setBridge(address _bridge) external;\\r\\n\\r\\n /**\\r\\n @notice Sets a new NFT bridge contract\\r\\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\\r\\n */\\r\\n function setNFTBridge(address _bridgeNFT) external;\\r\\n\\r\\n /**\\r\\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\\r\\n @param originalTokenAddress The address of the token in the origin (main) chain\\r\\n @param sender The address who solicited the cross token\\r\\n @param receiver Who is going to receive the token in the opposite chain\\r\\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\\r\\n @param blockHash The block hash in which the transaction with the cross event occurred\\r\\n @param transactionHash The transaction in which the cross event occurred\\r\\n @param logIndex Index of the event in the logs\\r\\n @param tokenType Is the type of bridge to be used\\r\\n */\\r\\n function voteTransaction(\\r\\n address originalTokenAddress,\\r\\n address payable sender,\\r\\n address payable receiver,\\r\\n uint256 value,\\r\\n bytes32 blockHash,\\r\\n bytes32 transactionHash,\\r\\n uint32 logIndex,\\r\\n TokenType tokenType\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n @notice Add a new member to the federation\\r\\n @param _newMember address of the new member\\r\\n */\\r\\n function addMember(address _newMember) external;\\r\\n\\r\\n /**\\r\\n @notice Remove a member of the federation\\r\\n @param _oldMember address of the member to be removed from federation\\r\\n */\\r\\n function removeMember(address _oldMember) external;\\r\\n\\r\\n /**\\r\\n @notice Return all the current members of the federation\\r\\n @return Current members\\r\\n */\\r\\n function getMembers() external view returns (address[] memory);\\r\\n\\r\\n /**\\r\\n @notice Changes the number of required members to vote and approve an transaction\\r\\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\\r\\n */\\r\\n function changeRequirement(uint _required) external;\\r\\n\\r\\n /**\\r\\n @notice It emmits an HeartBeat like an healthy check\\r\\n */\\r\\n function emitHeartbeat(\\r\\n uint256 fedRskBlock,\\r\\n uint256 fedEthBlock,\\r\\n string calldata federatorVersion,\\r\\n string calldata nodeRskInfo,\\r\\n string calldata nodeEthInfo\\r\\n ) external;\\r\\n\\r\\n event Executed(\\r\\n address indexed federator,\\r\\n bytes32 indexed transactionHash,\\r\\n bytes32 indexed transactionId,\\r\\n address originalTokenAddress,\\r\\n address sender,\\r\\n address receiver,\\r\\n uint256 amount,\\r\\n bytes32 blockHash,\\r\\n uint32 logIndex\\r\\n );\\r\\n event MemberAddition(address indexed member);\\r\\n event MemberRemoval(address indexed member);\\r\\n event RequirementChange(uint required);\\r\\n event BridgeChanged(address bridge);\\r\\n event NFTBridgeChanged(address bridgeNFT);\\r\\n event Voted(\\r\\n address indexed federator,\\r\\n bytes32 indexed transactionHash,\\r\\n bytes32 indexed transactionId,\\r\\n address originalTokenAddress,\\r\\n address sender,\\r\\n address receiver,\\r\\n uint256 amount,\\r\\n bytes32 blockHash,\\r\\n uint32 logIndex\\r\\n );\\r\\n event HeartBeat(\\r\\n address indexed sender,\\r\\n uint256 fedRskBlock,\\r\\n uint256 fedEthBlock,\\r\\n string federatorVersion,\\r\\n string nodeRskInfo,\\r\\n string nodeEthInfo\\r\\n );\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0x209134d6fd63a3f442a9cf086716baf7ac8639650c295e308a73a351ba077a21\",\"license\":\"MIT\"},\"contracts/nftbridge/INFTBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface INFTBridge {\\r\\n struct NFTClaimData {\\r\\n address payable to;\\r\\n address from;\\r\\n uint256 tokenId;\\r\\n address tokenAddress;\\r\\n bytes32 blockHash;\\r\\n bytes32 transactionHash;\\r\\n uint32 logIndex;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getFixedFee() external view returns (uint256);\\r\\n\\r\\n function receiveTokensTo(\\r\\n address tokenAddress,\\r\\n address to,\\r\\n uint256 tokenId\\r\\n ) external payable;\\r\\n\\r\\n /**\\r\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\r\\n */\\r\\n function acceptTransfer(\\r\\n address _originalTokenAddress,\\r\\n address payable _from,\\r\\n address payable _to,\\r\\n uint256 _tokenId,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\\r\\n */\\r\\n function claim(NFTClaimData calldata _claimData) external;\\r\\n\\r\\n function claimFallback(NFTClaimData calldata _claimData) external;\\r\\n\\r\\n function getTransactionDataHash(\\r\\n address _to,\\r\\n address _from,\\r\\n uint256 _tokenId,\\r\\n address _tokenAddress,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external returns (bytes32);\\r\\n\\r\\n event Cross(\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _from,\\r\\n address indexed _to,\\r\\n address _tokenCreator,\\r\\n bytes _userData,\\r\\n uint256 _totalSupply,\\r\\n uint256 _tokenId,\\r\\n string _tokenURI\\r\\n );\\r\\n event NewSideNFTToken(\\r\\n address indexed _newSideNFTTokenAddress,\\r\\n address indexed _originalTokenAddress,\\r\\n string _newSymbol\\r\\n );\\r\\n event AcceptedNFTCrossTransfer(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _from,\\r\\n uint256 _tokenId,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex\\r\\n );\\r\\n event FixedFeeNFTChanged(uint256 _amount);\\r\\n event ClaimedNFTToken(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _sender,\\r\\n uint256 _tokenId,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex,\\r\\n address _receiver\\r\\n );\\r\\n}\\r\\n\",\"keccak256\":\"0x2ae628c2bf573e402f83c817bb3bcf80a9f38aa82e328141f4cd9da1deadc88d\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @title Initializable\\r\\n *\\r\\n * @dev Helper contract to support initializer functions. To use it, replace\\r\\n * the constructor with a function that has the `initializer` modifier.\\r\\n * WARNING: Unlike constructors, initializer functions must be manually\\r\\n * invoked. This applies both to deploying an Initializable contract, as well\\r\\n * as extending an Initializable contract via inheritance.\\r\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\r\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\r\\n * because this is not dealt with automatically as with constructors.\\r\\n */\\r\\ncontract Initializable {\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract has been initialized.\\r\\n */\\r\\n bool private initialized;\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract is in the process of being initialized.\\r\\n */\\r\\n bool private initializing;\\r\\n\\r\\n /**\\r\\n * @dev Modifier to use in the initializer function of a contract.\\r\\n */\\r\\n modifier initializer() {\\r\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\r\\n\\r\\n bool isTopLevelCall = !initializing;\\r\\n if (isTopLevelCall) {\\r\\n initializing = true;\\r\\n initialized = true;\\r\\n }\\r\\n\\r\\n _;\\r\\n\\r\\n if (isTopLevelCall) {\\r\\n initializing = false;\\r\\n }\\r\\n }\\r\\n\\r\\n // Reserved storage space to allow for layout changes in the future.\\r\\n uint256[50] private ______gap;\\r\\n}\",\"keccak256\":\"0xc1f4d917648f0e17ba6a023a168173ad6163f3120e24d1c97ae294430e42eaf3\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Contract module which provides a basic access control mechanism, where\\r\\n * there is an account (an owner) that can be granted exclusive access to\\r\\n * specific functions.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the modifier\\r\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\r\\n * the owner.\\r\\n */\\r\\ncontract UpgradableOwnable is Initializable, Context {\\r\\n address private _owner;\\r\\n\\r\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract setting the deployer as the initial owner.\\r\\n */\\r\\n function initialize(address sender) public initializer {\\r\\n _owner = sender;\\r\\n emit OwnershipTransferred(address(0), _owner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the address of the current owner.\\r\\n */\\r\\n function owner() public view returns (address) {\\r\\n return _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Throws if called by any account other than the owner.\\r\\n */\\r\\n modifier onlyOwner() {\\r\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the caller is the current owner.\\r\\n */\\r\\n function isOwner() public view returns (bool) {\\r\\n return _msgSender() == _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Leaves the contract without owner. It will not be possible to call\\r\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\r\\n *\\r\\n * > Note: Renouncing ownership will leave the contract without an owner,\\r\\n * thereby removing any functionality that is only available to the owner.\\r\\n */\\r\\n function renounceOwnership() public onlyOwner {\\r\\n emit OwnershipTransferred(_owner, address(0));\\r\\n _owner = address(0);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n * Can only be called by the current owner.\\r\\n */\\r\\n function transferOwnership(address newOwner) public onlyOwner {\\r\\n _transferOwnership(newOwner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n */\\r\\n function _transferOwnership(address newOwner) internal {\\r\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\r\\n emit OwnershipTransferred(_owner, newOwner);\\r\\n _owner = newOwner;\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0xea920007e371a3300245b5885f72cecc472c4780818365f0025fae65a767273d\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50611dcb806100206000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c8063a481d59b116100f9578063ca6d56dc11610097578063ef1093a711610071578063ef1093a714610357578063f2fde38b1461035f578063f697aa2414610372578063fa6297ba14610385576101a9565b8063ca6d56dc14610334578063dc8452cd14610347578063e78cea921461034f576101a9565b8063b9a3b9dc116100d3578063b9a3b9dc146102e8578063ba51a6df146102fb578063c1f0808a1461030e578063c4d66de814610321576101a9565b8063a481d59b146102af578063a8e12e4c146102c2578063a93585f0146102d5576101a9565b80638da5cb5b116101665780639386775a116101405780639386775a146102615780639eab525314610274578063a1fb4acb14610289578063a230c5241461029c576101a9565b80638da5cb5b1461023e5780638dd14802146102465780638f32d59b14610259576101a9565b80630b1ca49a146101ae5780631b4613cb146101c357806354fd4d50146101ec5780635daf08ca14610201578063681fc92114610221578063715018a614610236575b600080fd5b6101c16101bc366004611456565b610398565b005b6101d66101d1366004611667565b6105a6565b6040516101e391906118c4565b60405180910390f35b6101f46105e2565b6040516101e391906118d8565b61021461020f366004611667565b6105fe565b6040516101e391906117df565b610229610628565b6040516101e391906118cf565b6101c161062d565b61021461069b565b6101c1610254366004611456565b6106aa565b6101d66106da565b6101d661026f36600461167f565b610700565b61027c610720565b6040516101e39190611877565b610229610297366004611667565b610782565b6101d66102aa366004611456565b6107f3565b6101c16102bd366004611456565b610808565b6101c16102d0366004611576565b610835565b6101d66102e3366004611667565b610aad565b6101c16102f63660046116ae565b610ac2565b6101c1610309366004611667565b610b67565b6101d661031c366004611667565b610c28565b6101c161032f366004611456565b610c3d565b6101c1610342366004611456565b610d02565b610229610e33565b610214610e39565b610214610e48565b6101c161036d366004611456565b610e57565b6101c1610380366004611472565b610e84565b610229610393366004611500565b61106a565b6103a06106da565b6103c55760405162461bcd60e51b81526004016103bc90611b8e565b60405180910390fd5b6001600160a01b0381166103eb5760405162461bcd60e51b81526004016103bc90611bfa565b6001600160a01b03811660009081526037602052604090205460ff166104235760405162461bcd60e51b81526004016103bc906119ce565b6035546001106104455760405162461bcd60e51b81526004016103bc90611c68565b60365460355460001901101561046d5760405162461bcd60e51b81526004016103bc90611b3d565b6001600160a01b0381166000908152603760205260408120805460ff191690555b6035546000190181101561054157816001600160a01b0316603582815481106104b357fe5b6000918252602090912001546001600160a01b03161415610539576035805460001981019081106104e057fe5b600091825260209091200154603580546001600160a01b03909216918390811061050657fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610541565b60010161048e565b50603580548061054d57fe5b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b6000818152603860205260408120816105bd6110ac565b6001600160a01b0316815260208101919091526040016000205460ff1690505b919050565b604080518082019091526002815261763360f01b602082015290565b6035818154811061060e57600080fd5b6000918252602090912001546001600160a01b0316905081565b603281565b6106356106da565b6106515760405162461bcd60e51b81526004016103bc90611b8e565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6106b26106da565b6106ce5760405162461bcd60e51b81526004016103bc90611b8e565b6106d7816110b0565b50565b6033546000906001600160a01b03166106f16110ac565b6001600160a01b031614905090565b603860209081526000928352604080842090915290825290205460ff1681565b6060603580548060200260200160405190810160405280929190818152602001828054801561077857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161075a575b5050505050905090565b600080805b6035548110156107ec57600084815260386020526040812060358054919291849081106107b057fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156107e4576001820191505b600101610787565b5092915050565b60376020526000908152604090205460ff1681565b6108106106da565b61082c5760405162461bcd60e51b81526004016103bc90611b8e565b6106d78161112c565b84518481811115801561084757508015155b801561085257508115155b61086e5760405162461bcd60e51b81526004016103bc9061192b565b600054610100900460ff1680610887575060005460ff16155b6108a35760405162461bcd60e51b81526004016103bc90611a0f565b600054610100900460ff161580156108ce576000805460ff1961ff0019909116610100171660011790555b6108d785610c3d565b6032885111156108f95760405162461bcd60e51b81526004016103bc90611997565b875161090c9060359060208b0190611376565b5060005b8851811015610a4157603760008a838151811061092957fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015610983575060006001600160a01b031689828151811061096f57fe5b60200260200101516001600160a01b031614155b61099f5760405162461bcd60e51b81526004016103bc90611a57565b6001603760008b84815181106109b157fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055508881815181106109fc57fe5b60200260200101516001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a2600101610910565b5060368790556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610a779089906118cf565b60405180910390a1610a88866110b0565b610a918461112c565b8015610aa3576000805461ff00191690555b5050505050505050565b60009081526039602052604090205460ff1690565b60376000610ace6110ac565b6001600160a01b0316815260208101919091526040016000205460ff16610b075760405162461bcd60e51b81526004016103bc90611cf2565b610b0f6110ac565b6001600160a01b03167fbb00e6cbdccbb5b7549e189335249187223d88583604555326aa1d7ccbcad4428989898989898989604051610b55989796959493929190611d29565b60405180910390a25050505050505050565b610b6f6106da565b610b8b5760405162461bcd60e51b81526004016103bc90611b8e565b60355481818111801590610b9e57508015155b8015610ba957508115155b610bc55760405162461bcd60e51b81526004016103bc9061192b565b6002831015610be65760405162461bcd60e51b81526004016103bc90611bc3565b60368390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610c1b9085906118cf565b60405180910390a1505050565b60396020526000908152604090205460ff1681565b600054610100900460ff1680610c56575060005460ff16155b610c725760405162461bcd60e51b81526004016103bc90611a0f565b600054610100900460ff16158015610c9d576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610cfe576000805461ff00191690555b5050565b610d0a6106da565b610d265760405162461bcd60e51b81526004016103bc90611b8e565b6001600160a01b038116610d4c5760405162461bcd60e51b81526004016103bc90611bfa565b6001600160a01b03811660009081526037602052604090205460ff1615610d855760405162461bcd60e51b81526004016103bc90611a8e565b603554603211610da75760405162461bcd60e51b81526004016103bc90611960565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b60365481565b6034546001600160a01b031681565b603a546001600160a01b031681565b610e5f6106da565b610e7b5760405162461bcd60e51b81526004016103bc90611b8e565b6106d78161119d565b60376000610e906110ac565b6001600160a01b0316815260208101919091526040016000205460ff16610ec95760405162461bcd60e51b81526004016103bc90611cf2565b6000610eda8989898989898961106a565b60008181526039602052604090205490915060ff1615610efa5750610aa3565b600081815260386020526040812090610f116110ac565b6001600160a01b0316815260208101919091526040016000205460ff1615610f395750610aa3565b6000818152603860205260408120600191610f526110ac565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558084610f846110ac565b6001600160a01b03167fd22894491aaa5bb67855bcff4b9730bdf7768be1e25f66ced9a7d7ad623bf2918c8c8c8c8c8b604051610fc696959493929190611839565b60405180910390a4610fd78161121f565b1561105f576000818152603960205260409020805460ff19166001179055611005898989898989898961124f565b808461100f6110ac565b6001600160a01b03167fe21e4d3d66ef78424137270e65cfafe938736bb770702ab4fd630383e7820b738c8c8c8c8c8b60405161105196959493929190611839565b60405180910390a450610aa3565b505050505050505050565b6000878787878787876040516020016110899796959493929190611781565b604051602081830303815290604052805190602001209050979650505050505050565b3390565b6001600160a01b0381166110d65760405162461bcd60e51b81526004016103bc90611acf565b603480546001600160a01b0319166001600160a01b0383161790556040517f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b92551782794497906111219083906117df565b60405180910390a150565b6001600160a01b0381166111525760405162461bcd60e51b81526004016103bc90611b06565b603a80546001600160a01b0319166001600160a01b0383161790556040517f41d363b5ede55d38b1fa8f7ba6188f9c20e353bc71e4a93de8938a20b27b6bc2906111219083906117df565b6001600160a01b0381166111c35760405162461bcd60e51b81526004016103bc90611cb0565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b60008061122b83610782565b905060365481101580156112485750603554600290046001018110155b9392505050565b600181600181111561125d57fe5b14156112fe57603a546001600160a01b031661128b5760405162461bcd60e51b81526004016103bc90611c31565b603a54604051636a86319160e01b81526001600160a01b0390911690636a863191906112c7908b908b908b908b908b908b908b906004016117f3565b600060405180830381600087803b1580156112e157600080fd5b505af11580156112f5573d6000803e3d6000fd5b50505050610aa3565b603454604051636a86319160e01b81526001600160a01b0390911690636a8631919061133a908b908b908b908b908b908b908b906004016117f3565b600060405180830381600087803b15801561135457600080fd5b505af1158015611368573d6000803e3d6000fd5b505050505050505050505050565b8280548282559060005260206000209081019282156113cb579160200282015b828111156113cb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190611396565b506113d79291506113db565b5090565b5b808211156113d757600081556001016113dc565b80356105dd81611d80565b60008083601f84011261140c578182fd5b50813567ffffffffffffffff811115611423578182fd5b60208301915083602082850101111561143b57600080fd5b9250929050565b803563ffffffff811681146105dd57600080fd5b600060208284031215611467578081fd5b813561124881611d80565b600080600080600080600080610100898b03121561148e578384fd5b883561149981611d80565b975060208901356114a981611d80565b965060408901356114b981611d80565b9550606089013594506080890135935060a089013592506114dc60c08a01611442565b915060e0890135600281106114ef578182fd5b809150509295985092959890939650565b600080600080600080600060e0888a03121561151a578283fd5b873561152581611d80565b9650602088013561153581611d80565b9550604088013561154581611d80565b9450606088013593506080880135925060a0880135915061156860c08901611442565b905092959891949750929550565b600080600080600060a0868803121561158d578081fd5b853567ffffffffffffffff808211156115a4578283fd5b818801915088601f8301126115b7578283fd5b81356020828211156115c557fe5b808202604051828282010181811086821117156115de57fe5b604052838152828101945085830182870184018e10156115fc578788fd5b8796505b8487101561162557611611816113f0565b865260019690960195948301948301611600565b50995050890135965061163f9250506040880190506113f0565b925061164d606087016113f0565b915061165b608087016113f0565b90509295509295909350565b600060208284031215611678578081fd5b5035919050565b60008060408385031215611691578182fd5b8235915060208301356116a381611d80565b809150509250929050565b60008060008060008060008060a0898b0312156116c9578384fd5b8835975060208901359650604089013567ffffffffffffffff808211156116ee578586fd5b6116fa8c838d016113fb565b909850965060608b0135915080821115611712578586fd5b61171e8c838d016113fb565b909650945060808b0135915080821115611736578384fd5b506117438b828c016113fb565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b606097881b6bffffffffffffffffffffffff19908116825296881b871660148201529490961b9094166028840152603c830191909152605c820152607c81019190915260e09190911b6001600160e01b031916609c82015260a00190565b6001600160a01b0391909116815260200190565b6001600160a01b03978816815295871660208701529390951660408501526060840191909152608083015260a082019290925263ffffffff90911660c082015260e00190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925263ffffffff90911660a082015260c00190565b6020808252825182820181905260009190848201906040850190845b818110156118b85783516001600160a01b031683529284019291840191600101611893565b50909695505050505050565b901515815260200190565b90815260200190565b6000602080835283518082850152825b81811015611904578581018301518582016040015282016118e8565b818111156119155783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f46656465726174696f6e3a20496e76616c696420726571756972656d656e7473604082015260600190565b6020808252601f908201527f46656465726174696f6e3a204d6178206d656d62657273207265616368656400604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20546f6f206d616e79206d656d6265727300000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746040820152607360f81b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252601b908201527f46656465726174696f6e3a20496e76616c6964206d656d626572730000000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746040820152607360f81b606082015260800190565b60208082526018908201527f46656465726174696f6e3a20456d707479206272696467650000000000000000604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20456d707479204e46542062726964676500000000604082015260600190565b60208082526031908201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604082015270207265717569726564206d656d6265727360781b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f46656465726174696f6e3a205265717569726573206174206c65617374203200604082015260600190565b60208082526018908201527f46656465726174696f6e3a20456d707479206d656d6265720000000000000000604082015260600190565b6020808252601b908201527f46656465726174696f6e3a20456d707479204e46544272696467650000000000604082015260600190565b60208082526028908201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604082015267206d656d6265727360c01b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526019908201527f46656465726174696f6e3a204e6f7420466564657261746f7200000000000000604082015260600190565b600089825288602083015260a06040830152611d4960a08301888a611757565b8281036060840152611d5c818789611757565b90508281036080840152611d71818587611757565b9b9a5050505050505050505050565b6001600160a01b03811681146106d757600080fdfea26469706673582212208aa1d2dd4590c44473c5e505bfb4d78ecb4c655a2f568f5eef1510b1514c437e64736f6c63430007060033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a95760003560e01c8063a481d59b116100f9578063ca6d56dc11610097578063ef1093a711610071578063ef1093a714610357578063f2fde38b1461035f578063f697aa2414610372578063fa6297ba14610385576101a9565b8063ca6d56dc14610334578063dc8452cd14610347578063e78cea921461034f576101a9565b8063b9a3b9dc116100d3578063b9a3b9dc146102e8578063ba51a6df146102fb578063c1f0808a1461030e578063c4d66de814610321576101a9565b8063a481d59b146102af578063a8e12e4c146102c2578063a93585f0146102d5576101a9565b80638da5cb5b116101665780639386775a116101405780639386775a146102615780639eab525314610274578063a1fb4acb14610289578063a230c5241461029c576101a9565b80638da5cb5b1461023e5780638dd14802146102465780638f32d59b14610259576101a9565b80630b1ca49a146101ae5780631b4613cb146101c357806354fd4d50146101ec5780635daf08ca14610201578063681fc92114610221578063715018a614610236575b600080fd5b6101c16101bc366004611456565b610398565b005b6101d66101d1366004611667565b6105a6565b6040516101e391906118c4565b60405180910390f35b6101f46105e2565b6040516101e391906118d8565b61021461020f366004611667565b6105fe565b6040516101e391906117df565b610229610628565b6040516101e391906118cf565b6101c161062d565b61021461069b565b6101c1610254366004611456565b6106aa565b6101d66106da565b6101d661026f36600461167f565b610700565b61027c610720565b6040516101e39190611877565b610229610297366004611667565b610782565b6101d66102aa366004611456565b6107f3565b6101c16102bd366004611456565b610808565b6101c16102d0366004611576565b610835565b6101d66102e3366004611667565b610aad565b6101c16102f63660046116ae565b610ac2565b6101c1610309366004611667565b610b67565b6101d661031c366004611667565b610c28565b6101c161032f366004611456565b610c3d565b6101c1610342366004611456565b610d02565b610229610e33565b610214610e39565b610214610e48565b6101c161036d366004611456565b610e57565b6101c1610380366004611472565b610e84565b610229610393366004611500565b61106a565b6103a06106da565b6103c55760405162461bcd60e51b81526004016103bc90611b8e565b60405180910390fd5b6001600160a01b0381166103eb5760405162461bcd60e51b81526004016103bc90611bfa565b6001600160a01b03811660009081526037602052604090205460ff166104235760405162461bcd60e51b81526004016103bc906119ce565b6035546001106104455760405162461bcd60e51b81526004016103bc90611c68565b60365460355460001901101561046d5760405162461bcd60e51b81526004016103bc90611b3d565b6001600160a01b0381166000908152603760205260408120805460ff191690555b6035546000190181101561054157816001600160a01b0316603582815481106104b357fe5b6000918252602090912001546001600160a01b03161415610539576035805460001981019081106104e057fe5b600091825260209091200154603580546001600160a01b03909216918390811061050657fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610541565b60010161048e565b50603580548061054d57fe5b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b6000818152603860205260408120816105bd6110ac565b6001600160a01b0316815260208101919091526040016000205460ff1690505b919050565b604080518082019091526002815261763360f01b602082015290565b6035818154811061060e57600080fd5b6000918252602090912001546001600160a01b0316905081565b603281565b6106356106da565b6106515760405162461bcd60e51b81526004016103bc90611b8e565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6106b26106da565b6106ce5760405162461bcd60e51b81526004016103bc90611b8e565b6106d7816110b0565b50565b6033546000906001600160a01b03166106f16110ac565b6001600160a01b031614905090565b603860209081526000928352604080842090915290825290205460ff1681565b6060603580548060200260200160405190810160405280929190818152602001828054801561077857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161075a575b5050505050905090565b600080805b6035548110156107ec57600084815260386020526040812060358054919291849081106107b057fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156107e4576001820191505b600101610787565b5092915050565b60376020526000908152604090205460ff1681565b6108106106da565b61082c5760405162461bcd60e51b81526004016103bc90611b8e565b6106d78161112c565b84518481811115801561084757508015155b801561085257508115155b61086e5760405162461bcd60e51b81526004016103bc9061192b565b600054610100900460ff1680610887575060005460ff16155b6108a35760405162461bcd60e51b81526004016103bc90611a0f565b600054610100900460ff161580156108ce576000805460ff1961ff0019909116610100171660011790555b6108d785610c3d565b6032885111156108f95760405162461bcd60e51b81526004016103bc90611997565b875161090c9060359060208b0190611376565b5060005b8851811015610a4157603760008a838151811061092957fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015610983575060006001600160a01b031689828151811061096f57fe5b60200260200101516001600160a01b031614155b61099f5760405162461bcd60e51b81526004016103bc90611a57565b6001603760008b84815181106109b157fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055508881815181106109fc57fe5b60200260200101516001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a2600101610910565b5060368790556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610a779089906118cf565b60405180910390a1610a88866110b0565b610a918461112c565b8015610aa3576000805461ff00191690555b5050505050505050565b60009081526039602052604090205460ff1690565b60376000610ace6110ac565b6001600160a01b0316815260208101919091526040016000205460ff16610b075760405162461bcd60e51b81526004016103bc90611cf2565b610b0f6110ac565b6001600160a01b03167fbb00e6cbdccbb5b7549e189335249187223d88583604555326aa1d7ccbcad4428989898989898989604051610b55989796959493929190611d29565b60405180910390a25050505050505050565b610b6f6106da565b610b8b5760405162461bcd60e51b81526004016103bc90611b8e565b60355481818111801590610b9e57508015155b8015610ba957508115155b610bc55760405162461bcd60e51b81526004016103bc9061192b565b6002831015610be65760405162461bcd60e51b81526004016103bc90611bc3565b60368390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610c1b9085906118cf565b60405180910390a1505050565b60396020526000908152604090205460ff1681565b600054610100900460ff1680610c56575060005460ff16155b610c725760405162461bcd60e51b81526004016103bc90611a0f565b600054610100900460ff16158015610c9d576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610cfe576000805461ff00191690555b5050565b610d0a6106da565b610d265760405162461bcd60e51b81526004016103bc90611b8e565b6001600160a01b038116610d4c5760405162461bcd60e51b81526004016103bc90611bfa565b6001600160a01b03811660009081526037602052604090205460ff1615610d855760405162461bcd60e51b81526004016103bc90611a8e565b603554603211610da75760405162461bcd60e51b81526004016103bc90611960565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b60365481565b6034546001600160a01b031681565b603a546001600160a01b031681565b610e5f6106da565b610e7b5760405162461bcd60e51b81526004016103bc90611b8e565b6106d78161119d565b60376000610e906110ac565b6001600160a01b0316815260208101919091526040016000205460ff16610ec95760405162461bcd60e51b81526004016103bc90611cf2565b6000610eda8989898989898961106a565b60008181526039602052604090205490915060ff1615610efa5750610aa3565b600081815260386020526040812090610f116110ac565b6001600160a01b0316815260208101919091526040016000205460ff1615610f395750610aa3565b6000818152603860205260408120600191610f526110ac565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558084610f846110ac565b6001600160a01b03167fd22894491aaa5bb67855bcff4b9730bdf7768be1e25f66ced9a7d7ad623bf2918c8c8c8c8c8b604051610fc696959493929190611839565b60405180910390a4610fd78161121f565b1561105f576000818152603960205260409020805460ff19166001179055611005898989898989898961124f565b808461100f6110ac565b6001600160a01b03167fe21e4d3d66ef78424137270e65cfafe938736bb770702ab4fd630383e7820b738c8c8c8c8c8b60405161105196959493929190611839565b60405180910390a450610aa3565b505050505050505050565b6000878787878787876040516020016110899796959493929190611781565b604051602081830303815290604052805190602001209050979650505050505050565b3390565b6001600160a01b0381166110d65760405162461bcd60e51b81526004016103bc90611acf565b603480546001600160a01b0319166001600160a01b0383161790556040517f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b92551782794497906111219083906117df565b60405180910390a150565b6001600160a01b0381166111525760405162461bcd60e51b81526004016103bc90611b06565b603a80546001600160a01b0319166001600160a01b0383161790556040517f41d363b5ede55d38b1fa8f7ba6188f9c20e353bc71e4a93de8938a20b27b6bc2906111219083906117df565b6001600160a01b0381166111c35760405162461bcd60e51b81526004016103bc90611cb0565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b60008061122b83610782565b905060365481101580156112485750603554600290046001018110155b9392505050565b600181600181111561125d57fe5b14156112fe57603a546001600160a01b031661128b5760405162461bcd60e51b81526004016103bc90611c31565b603a54604051636a86319160e01b81526001600160a01b0390911690636a863191906112c7908b908b908b908b908b908b908b906004016117f3565b600060405180830381600087803b1580156112e157600080fd5b505af11580156112f5573d6000803e3d6000fd5b50505050610aa3565b603454604051636a86319160e01b81526001600160a01b0390911690636a8631919061133a908b908b908b908b908b908b908b906004016117f3565b600060405180830381600087803b15801561135457600080fd5b505af1158015611368573d6000803e3d6000fd5b505050505050505050505050565b8280548282559060005260206000209081019282156113cb579160200282015b828111156113cb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190611396565b506113d79291506113db565b5090565b5b808211156113d757600081556001016113dc565b80356105dd81611d80565b60008083601f84011261140c578182fd5b50813567ffffffffffffffff811115611423578182fd5b60208301915083602082850101111561143b57600080fd5b9250929050565b803563ffffffff811681146105dd57600080fd5b600060208284031215611467578081fd5b813561124881611d80565b600080600080600080600080610100898b03121561148e578384fd5b883561149981611d80565b975060208901356114a981611d80565b965060408901356114b981611d80565b9550606089013594506080890135935060a089013592506114dc60c08a01611442565b915060e0890135600281106114ef578182fd5b809150509295985092959890939650565b600080600080600080600060e0888a03121561151a578283fd5b873561152581611d80565b9650602088013561153581611d80565b9550604088013561154581611d80565b9450606088013593506080880135925060a0880135915061156860c08901611442565b905092959891949750929550565b600080600080600060a0868803121561158d578081fd5b853567ffffffffffffffff808211156115a4578283fd5b818801915088601f8301126115b7578283fd5b81356020828211156115c557fe5b808202604051828282010181811086821117156115de57fe5b604052838152828101945085830182870184018e10156115fc578788fd5b8796505b8487101561162557611611816113f0565b865260019690960195948301948301611600565b50995050890135965061163f9250506040880190506113f0565b925061164d606087016113f0565b915061165b608087016113f0565b90509295509295909350565b600060208284031215611678578081fd5b5035919050565b60008060408385031215611691578182fd5b8235915060208301356116a381611d80565b809150509250929050565b60008060008060008060008060a0898b0312156116c9578384fd5b8835975060208901359650604089013567ffffffffffffffff808211156116ee578586fd5b6116fa8c838d016113fb565b909850965060608b0135915080821115611712578586fd5b61171e8c838d016113fb565b909650945060808b0135915080821115611736578384fd5b506117438b828c016113fb565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b606097881b6bffffffffffffffffffffffff19908116825296881b871660148201529490961b9094166028840152603c830191909152605c820152607c81019190915260e09190911b6001600160e01b031916609c82015260a00190565b6001600160a01b0391909116815260200190565b6001600160a01b03978816815295871660208701529390951660408501526060840191909152608083015260a082019290925263ffffffff90911660c082015260e00190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925263ffffffff90911660a082015260c00190565b6020808252825182820181905260009190848201906040850190845b818110156118b85783516001600160a01b031683529284019291840191600101611893565b50909695505050505050565b901515815260200190565b90815260200190565b6000602080835283518082850152825b81811015611904578581018301518582016040015282016118e8565b818111156119155783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f46656465726174696f6e3a20496e76616c696420726571756972656d656e7473604082015260600190565b6020808252601f908201527f46656465726174696f6e3a204d6178206d656d62657273207265616368656400604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20546f6f206d616e79206d656d6265727300000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746040820152607360f81b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252601b908201527f46656465726174696f6e3a20496e76616c6964206d656d626572730000000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746040820152607360f81b606082015260800190565b60208082526018908201527f46656465726174696f6e3a20456d707479206272696467650000000000000000604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20456d707479204e46542062726964676500000000604082015260600190565b60208082526031908201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604082015270207265717569726564206d656d6265727360781b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f46656465726174696f6e3a205265717569726573206174206c65617374203200604082015260600190565b60208082526018908201527f46656465726174696f6e3a20456d707479206d656d6265720000000000000000604082015260600190565b6020808252601b908201527f46656465726174696f6e3a20456d707479204e46544272696467650000000000604082015260600190565b60208082526028908201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604082015267206d656d6265727360c01b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526019908201527f46656465726174696f6e3a204e6f7420466564657261746f7200000000000000604082015260600190565b600089825288602083015260a06040830152611d4960a08301888a611757565b8281036060840152611d5c818789611757565b90508281036080840152611d71818587611757565b9b9a5050505050505050505050565b6001600160a01b03811681146106d757600080fdfea26469706673582212208aa1d2dd4590c44473c5e505bfb4d78ecb4c655a2f568f5eef1510b1514c437e64736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "addMember(address)": {
+ "params": {
+ "_newMember": "address of the new member"
+ }
+ },
+ "changeRequirement(uint256)": {
+ "details": "Emits the RequirementChange event",
+ "params": {
+ "_required": "the number of minimum members to approve an transaction, it has to be bigger than 1"
+ }
+ },
+ "emitHeartbeat(uint256,uint256,string,string,string)": {
+ "details": "Emits HeartBeat event"
+ },
+ "getMembers()": {
+ "returns": {
+ "_0": "Current members"
+ }
+ },
+ "getTransactionCount(bytes32)": {
+ "params": {
+ "transactionId": "The transaction hashed from getTransactionId function"
+ }
+ },
+ "getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32)": {
+ "details": "It encodes and applies keccak256 to the parameters received in the same order",
+ "params": {
+ "amount": "Could be the amount or the tokenId",
+ "blockHash": "The block hash in which the transaction with the cross event occurred",
+ "logIndex": "Index of the event in the logs",
+ "originalTokenAddress": "The address of the token in the origin (main) chain",
+ "receiver": "Who is going to receive the token in the opposite chain",
+ "sender": "The address who solicited the cross token",
+ "transactionHash": "The transaction in which the cross event occurred"
+ },
+ "returns": {
+ "_0": "The hash generated by the parameters."
+ }
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "removeMember(address)": {
+ "params": {
+ "_oldMember": "address of the member to be removed from federation"
+ }
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "setBridge(address)": {
+ "details": "Emits BridgeChanged event",
+ "params": {
+ "_bridge": "the new bridge contract address that should implement the IBridge interface"
+ }
+ },
+ "setNFTBridge(address)": {
+ "details": "Emits NFTBridgeChanged event",
+ "params": {
+ "_bridgeNFT": "the new NFT bridge contract address that should implement the INFTBridge interface"
+ }
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "version()": {
+ "returns": {
+ "_0": "version in v{Number}"
+ }
+ },
+ "voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint8)": {
+ "params": {
+ "blockHash": "The block hash in which the transaction with the cross event occurred",
+ "logIndex": "Index of the event in the logs",
+ "originalTokenAddress": "The address of the token in the origin (main) chain",
+ "receiver": "Who is going to receive the token in the opposite chain",
+ "sender": "The address who solicited the cross token",
+ "tokenType": "Is the type of bridge to be used",
+ "transactionHash": "The transaction in which the cross event occurred",
+ "value": "Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT"
+ }
+ }
+ },
+ "stateVariables": {
+ "isMember": {
+ "details": "The address should be a member to vote in transactions"
+ },
+ "required": {
+ "details": "It should have more members than the required amount"
+ },
+ "votes": {
+ "details": "usually the members should approve the transaction by 50% + 1"
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "addMember(address)": {
+ "notice": "Add a new member to the federation"
+ },
+ "bridgeNFT()": {
+ "notice": "Federator v3 variables "
+ },
+ "changeRequirement(uint256)": {
+ "notice": "Changes the number of required members to vote and approve an transaction"
+ },
+ "emitHeartbeat(uint256,uint256,string,string,string)": {
+ "notice": "It emits an HeartBeat like an health check"
+ },
+ "getMembers()": {
+ "notice": "Return all the current members of the federation"
+ },
+ "getTransactionCount(bytes32)": {
+ "notice": "Get the amount of approved votes for that transactionId"
+ },
+ "getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32)": {
+ "notice": "Gets the hash of transaction from the following parameters encoded and keccaked"
+ },
+ "isMember(address)": {
+ "notice": "All the addresses that are members of the federation"
+ },
+ "processed(bytes32)": {
+ "notice": "(bytes32) transactionId => (bool) votedCheck if that transaction was already processed"
+ },
+ "removeMember(address)": {
+ "notice": "Remove a member of the federation"
+ },
+ "required()": {
+ "notice": "The minimum amount of votes to approve a transaction"
+ },
+ "setBridge(address)": {
+ "notice": "Sets a new bridge contract"
+ },
+ "setNFTBridge(address)": {
+ "notice": "Sets a new NFT bridge contract"
+ },
+ "version()": {
+ "notice": "Current version of the contract"
+ },
+ "voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint8)": {
+ "notice": "Vote in a transaction, if it has enough votes it accepts the transfer"
+ },
+ "votes(bytes32,address)": {
+ "notice": "(bytes32) transactionId = keccak256( abi.encodePacked( originalTokenAddress, sender, receiver, amount, blockHash, transactionHash, logIndex ) ) => ( (address) members => (bool) voted )Votes by members by the transaction ID"
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15789,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15792,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15832,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16076,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 4016,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "bridge",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_contract(IBridge)7398"
+ },
+ {
+ "astId": 4019,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "members",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 4022,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "required",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 4027,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "isMember",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 4034,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "votes",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_mapping(t_bytes32,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 4039,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "processed",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ },
+ {
+ "astId": 4042,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "bridgeNFT",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_contract(INFTBridge)7960"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IBridge)7398": {
+ "encoding": "inplace",
+ "label": "contract IBridge",
+ "numberOfBytes": "20"
+ },
+ "t_contract(INFTBridge)7960": {
+ "encoding": "inplace",
+ "label": "contract INFTBridge",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/FederationProxy.json b/bridge/deployments/rinkeby/FederationProxy.json
new file mode 100644
index 000000000..dc3d8f76f
--- /dev/null
+++ b/bridge/deployments/rinkeby/FederationProxy.json
@@ -0,0 +1,257 @@
+{
+ "address": "0xBC383764ceBc13b66c04E1abeb36804a0Caaa5C6",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x8f61ef1e5d6545ff89d65a825d3eb9233c8933682f68dfaad441caa9fd06f352",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0xBC383764ceBc13b66c04E1abeb36804a0Caaa5C6",
+ "transactionIndex": 2,
+ "gasUsed": "743242",
+ "logsBloom": "0x00000000000000000001000000000800000100000000000000800000000000000000000000000000000000000000008000000000000000000080000000000000004000800000000000000020000000000001000000000000000400000000100000000000020000000000000000000800000000000000000000000000000000400000000000000000000000008000000010000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000008000000000000000000000000000000000000000000000000000000000020000010000000000000000000000000000100000020000000000800000000000000",
+ "blockHash": "0xe15b829adff6c0661f632f3c4088ea031761bd6810a4c0ee9b756858cfde1e13",
+ "transactionHash": "0x8f61ef1e5d6545ff89d65a825d3eb9233c8933682f68dfaad441caa9fd06f352",
+ "logs": [
+ {
+ "transactionIndex": 2,
+ "blockNumber": 9264197,
+ "transactionHash": "0x8f61ef1e5d6545ff89d65a825d3eb9233c8933682f68dfaad441caa9fd06f352",
+ "address": "0xBC383764ceBc13b66c04E1abeb36804a0Caaa5C6",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x00000000000000000000000004994d7ff4938c5953a6c8411ad30083c9097348"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0xe15b829adff6c0661f632f3c4088ea031761bd6810a4c0ee9b756858cfde1e13"
+ },
+ {
+ "transactionIndex": 2,
+ "blockNumber": 9264197,
+ "transactionHash": "0x8f61ef1e5d6545ff89d65a825d3eb9233c8933682f68dfaad441caa9fd06f352",
+ "address": "0xBC383764ceBc13b66c04E1abeb36804a0Caaa5C6",
+ "topics": [
+ "0x72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c7",
+ "0x0000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b"
+ ],
+ "data": "0x",
+ "logIndex": 1,
+ "blockHash": "0xe15b829adff6c0661f632f3c4088ea031761bd6810a4c0ee9b756858cfde1e13"
+ },
+ {
+ "transactionIndex": 2,
+ "blockNumber": 9264197,
+ "transactionHash": "0x8f61ef1e5d6545ff89d65a825d3eb9233c8933682f68dfaad441caa9fd06f352",
+ "address": "0xBC383764ceBc13b66c04E1abeb36804a0Caaa5C6",
+ "topics": [
+ "0xa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "logIndex": 2,
+ "blockHash": "0xe15b829adff6c0661f632f3c4088ea031761bd6810a4c0ee9b756858cfde1e13"
+ },
+ {
+ "transactionIndex": 2,
+ "blockNumber": 9264197,
+ "transactionHash": "0x8f61ef1e5d6545ff89d65a825d3eb9233c8933682f68dfaad441caa9fd06f352",
+ "address": "0xBC383764ceBc13b66c04E1abeb36804a0Caaa5C6",
+ "topics": [
+ "0x9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b92551782794497"
+ ],
+ "data": "0x0000000000000000000000007e339118346364d7d86ab67cb0775cbb808e65f7",
+ "logIndex": 3,
+ "blockHash": "0xe15b829adff6c0661f632f3c4088ea031761bd6810a4c0ee9b756858cfde1e13"
+ }
+ ],
+ "blockNumber": 9264197,
+ "cumulativeGasUsed": "799706",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0x8c8A34Fe13400169a8da50908dffDe4985237D19",
+ "0x0b32Ea549AB1F9F7390442B5E9438b58A105cB5f",
+ "0xc1b4a1e3000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000007e339118346364d7d86ab67cb0775cbb808e65f700000000000000000000000004994d7ff4938c5953a6c8411ad30083c909734800000000000000000000000000000000000000000000000000000000000000010000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b"
+ ],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"stateVariables\":{\"_ADMIN_SLOT\":{\"details\":\"Storage slot with the admin of the contract. This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\r\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\r\\n * be specified by overriding the virtual {_implementation} function.\\r\\n *\\r\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\r\\n * different contract through the {_delegate} function.\\r\\n *\\r\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\r\\n */\\r\\nabstract contract Proxy {\\r\\n /**\\r\\n * @dev Delegates the current call to `implementation`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _delegate(address implementation) internal virtual {\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n // Copy msg.data. We take full control of memory in this inline assembly\\r\\n // block because it will not return to Solidity code. We overwrite the\\r\\n // Solidity scratch pad at memory position 0.\\r\\n calldatacopy(0, 0, calldatasize())\\r\\n\\r\\n // Call the implementation.\\r\\n // out and outsize are 0 because we don't know the size yet.\\r\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\r\\n\\r\\n // Copy the returned data.\\r\\n returndatacopy(0, 0, returndatasize())\\r\\n\\r\\n switch result\\r\\n // delegatecall returns 0 on error.\\r\\n case 0 { revert(0, returndatasize()) }\\r\\n default { return(0, returndatasize()) }\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\r\\n * and {_fallback} should delegate.\\r\\n */\\r\\n function _implementation() internal view virtual returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _fallback() internal virtual {\\r\\n _beforeFallback();\\r\\n _delegate(_implementation());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\r\\n * function in the contract matches the call data.\\r\\n */\\r\\n fallback () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\r\\n * is empty.\\r\\n */\\r\\n receive () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\r\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\r\\n *\\r\\n * If overriden should call `super._beforeFallback()`.\\r\\n */\\r\\n function _beforeFallback() internal virtual {\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x6374180266624d2291abb230bdf0d364858fa164844f5d2d83ad5325852390c9\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./UpgradeableProxy.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\r\\n *\\r\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\r\\n * clashing], which can potentially be used in an attack, this contract uses the\\r\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\r\\n * things that go hand in hand:\\r\\n *\\r\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\r\\n * that call matches one of the admin functions exposed by the proxy itself.\\r\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\r\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\r\\n * \\\"admin cannot fallback to proxy target\\\".\\r\\n *\\r\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\r\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\r\\n * to sudden errors when trying to call a function from the proxy implementation.\\r\\n *\\r\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\r\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\r\\n */\\r\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\r\\n /**\\r\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\r\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\r\\n */\\r\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\r\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\r\\n _setAdmin(admin_);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the admin account has changed.\\r\\n */\\r\\n event AdminChanged(address previousAdmin, address newAdmin);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the admin of the contract.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\r\\n\\r\\n /**\\r\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\r\\n */\\r\\n modifier ifAdmin() {\\r\\n if (msg.sender == _admin()) {\\r\\n _;\\r\\n } else {\\r\\n _fallback();\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\r\\n */\\r\\n function admin() external ifAdmin returns (address admin_) {\\r\\n admin_ = _admin();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\r\\n */\\r\\n function implementation() external ifAdmin returns (address implementation_) {\\r\\n implementation_ = _implementation();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Changes the admin of the proxy.\\r\\n *\\r\\n * Emits an {AdminChanged} event.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\r\\n */\\r\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\r\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\r\\n emit AdminChanged(_admin(), newAdmin);\\r\\n _setAdmin(newAdmin);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\r\\n */\\r\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\r\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\r\\n * proxied contract.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\r\\n */\\r\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n Address.functionDelegateCall(newImplementation, data);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n */\\r\\n function _admin() internal view virtual returns (address adm) {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n adm := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 admin slot.\\r\\n */\\r\\n function _setAdmin(address newAdmin) private {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newAdmin)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\r\\n */\\r\\n function _beforeFallback() internal virtual override {\\r\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\r\\n super._beforeFallback();\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x7496c2c54dd8e648d6999687cf759521e6ab229d0d8ddb4db62f3b51dbe68811\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./Proxy.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\r\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\r\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\r\\n * implementation behind the proxy.\\r\\n *\\r\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\r\\n * {TransparentUpgradeableProxy}.\\r\\n */\\r\\ncontract UpgradeableProxy is Proxy {\\r\\n /**\\r\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\r\\n *\\r\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\r\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\r\\n */\\r\\n constructor(address _logic, bytes memory _data) payable {\\r\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\r\\n _setImplementation(_logic);\\r\\n if(_data.length > 0) {\\r\\n Address.functionDelegateCall(_logic, _data);\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the implementation is upgraded.\\r\\n */\\r\\n event Upgraded(address indexed implementation);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the address of the current implementation.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation address.\\r\\n */\\r\\n function _implementation() internal view virtual override returns (address impl) {\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n impl := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrades the proxy to a new implementation.\\r\\n *\\r\\n * Emits an {Upgraded} event.\\r\\n */\\r\\n function _upgradeTo(address newImplementation) internal virtual {\\r\\n _setImplementation(newImplementation);\\r\\n emit Upgraded(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 implementation slot.\\r\\n */\\r\\n function _setImplementation(address newImplementation) private {\\r\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\r\\n\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newImplementation)\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x4d3fcb8487e53abb8658817c4b90038b24d81d0a32d989f03b54d4cfab929f62\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000c9f38038062000c9f83398101604081905262000026916200022e565b8281620000338262000071565b8051156200005457620000528282620000d360201b620002ca1760201c565b505b506200005d9050565b620000688262000102565b5050506200041d565b62000087816200012660201b620002f61760201c565b620000af5760405162461bcd60e51b8152600401620000a69062000347565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6060620000fb838360405180606001604052806027815260200162000c786027913962000130565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b60606200013d8462000126565b6200015c5760405162461bcd60e51b8152600401620000a690620003a4565b600080856001600160a01b031685604051620001799190620002f4565b600060405180830381855af49150503d8060008114620001b6576040519150601f19603f3d011682016040523d82523d6000602084013e620001bb565b606091505b509092509050620001ce828286620001d8565b9695505050505050565b60608315620001e9575081620000fb565b825115620001fa5782518084602001fd5b8160405162461bcd60e51b8152600401620000a6919062000312565b80516001600160a01b03811681146200012b57600080fd5b60008060006060848603121562000243578283fd5b6200024e8462000216565b92506200025e6020850162000216565b60408501519092506001600160401b03808211156200027b578283fd5b818601915086601f8301126200028f578283fd5b8151818111156200029c57fe5b604051601f8201601f191681016020018381118282101715620002bb57fe5b604052818152838201602001891015620002d3578485fd5b620002e6826020830160208701620003ea565b809450505050509250925092565b6000825162000308818460208701620003ea565b9190910192915050565b600060208252825180602084015262000333816040850160208701620003ea565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b8381101562000407578181015183820152602001620003ed565b8381111562000417576000848401525b50505050565b61084b806200042d6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209ba77a19de177ea34b608207423a21765cca1077e9d39a414a7175e09fb147e464736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209ba77a19de177ea34b608207423a21765cca1077e9d39a414a7175e09fb147e464736f6c63430007060033",
+ "devdoc": {
+ "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.",
+ "events": {
+ "AdminChanged(address,address)": {
+ "details": "Emitted when the admin account has changed."
+ }
+ },
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "constructor": {
+ "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "stateVariables": {
+ "_ADMIN_SLOT": {
+ "details": "Storage slot with the admin of the contract. This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/FederationV2.json b/bridge/deployments/rinkeby/FederationV2.json
new file mode 100644
index 000000000..80f7f1774
--- /dev/null
+++ b/bridge/deployments/rinkeby/FederationV2.json
@@ -0,0 +1,905 @@
+{
+ "address": "0x8c8A34Fe13400169a8da50908dffDe4985237D19",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridge",
+ "type": "address"
+ }
+ ],
+ "name": "BridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Executed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "HeartBeat",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Voted",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_MEMBER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_newMember",
+ "type": "address"
+ }
+ ],
+ "name": "addMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridge",
+ "outputs": [
+ {
+ "internalType": "contract IBridge",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "emitHeartbeat",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getMembers",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "getTransactionId",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_members",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isMember",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "members",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "processed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_oldMember",
+ "type": "address"
+ }
+ ],
+ "name": "removeMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ }
+ ],
+ "name": "setBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionWasProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "voteTransaction",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "votes",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xe5ac51b9967f55d4e9f32bcd3d8988c262a084a63fd8f528b728f25e969b5de8",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0x8c8A34Fe13400169a8da50908dffDe4985237D19",
+ "transactionIndex": 4,
+ "gasUsed": "1544714",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x75104a75ae08593cd7e19f4baa8e4e5e462fe699b18ac9602f0ed6f54832f855",
+ "transactionHash": "0xe5ac51b9967f55d4e9f32bcd3d8988c262a084a63fd8f528b728f25e969b5de8",
+ "logs": [],
+ "blockNumber": 9264196,
+ "cumulativeGasUsed": "1663055",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"bridge\",\"type\":\"address\"}],\"name\":\"BridgeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"Executed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fedRskBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fedEthBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"federatorVersion\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"nodeRskInfo\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"nodeEthInfo\",\"type\":\"string\"}],\"name\":\"HeartBeat\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"Voted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MEMBER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newMember\",\"type\":\"address\"}],\"name\":\"addMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contract IBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fedRskBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fedEthBlock\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"federatorVersion\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nodeRskInfo\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nodeEthInfo\",\"type\":\"string\"}],\"name\":\"emitHeartbeat\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMembers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"getTransactionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"hasVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_members\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMember\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"members\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"processed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_oldMember\",\"type\":\"address\"}],\"name\":\"removeMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"name\":\"setBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"transactionWasProcessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"voteTransaction\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"votes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Federation/FederationV2.sol\":\"FederationV2\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Federation/FederationV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n// Upgradables\\r\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\r\\n\\r\\nimport \\\"../interface/IBridge.sol\\\";\\r\\n\\r\\ncontract FederationV2 is Initializable, UpgradableOwnable {\\r\\n uint constant public MAX_MEMBER_COUNT = 50;\\r\\n address constant private NULL_ADDRESS = address(0);\\r\\n\\r\\n IBridge public bridge;\\r\\n address[] public members;\\r\\n uint public required;\\r\\n\\r\\n mapping (address => bool) public isMember;\\r\\n mapping (bytes32 => mapping (address => bool)) public votes;\\r\\n mapping(bytes32 => bool) public processed;\\r\\n\\r\\n event Executed(\\r\\n address indexed federator,\\r\\n bytes32 indexed transactionHash,\\r\\n bytes32 indexed transactionId,\\r\\n address originalTokenAddress,\\r\\n address sender,\\r\\n address receiver,\\r\\n uint256 amount,\\r\\n bytes32 blockHash,\\r\\n uint32 logIndex\\r\\n );\\r\\n event MemberAddition(address indexed member);\\r\\n event MemberRemoval(address indexed member);\\r\\n event RequirementChange(uint required);\\r\\n event BridgeChanged(address bridge);\\r\\n event Voted(\\r\\n address indexed federator,\\r\\n bytes32 indexed transactionHash,\\r\\n bytes32 indexed transactionId,\\r\\n address originalTokenAddress,\\r\\n address sender,\\r\\n address receiver,\\r\\n uint256 amount,\\r\\n bytes32 blockHash,\\r\\n uint32 logIndex\\r\\n );\\r\\n event HeartBeat(\\r\\n address indexed sender,\\r\\n uint256 fedRskBlock,\\r\\n uint256 fedEthBlock,\\r\\n string federatorVersion,\\r\\n string nodeRskInfo,\\r\\n string nodeEthInfo\\r\\n );\\r\\n\\r\\n modifier onlyMember() {\\r\\n require(isMember[_msgSender()], \\\"Federation: Not Federator\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier validRequirement(uint membersCount, uint _required) {\\r\\n // solium-disable-next-line max-len\\r\\n require(_required <= membersCount && _required != 0 && membersCount != 0, \\\"Federation: Invalid requirements\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\\r\\n public validRequirement(_members.length, _required) initializer {\\r\\n UpgradableOwnable.initialize(owner);\\r\\n require(_members.length <= MAX_MEMBER_COUNT, \\\"Federation: Too many members\\\");\\r\\n members = _members;\\r\\n for (uint i = 0; i < _members.length; i++) {\\r\\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \\\"Federation: Invalid members\\\");\\r\\n isMember[_members[i]] = true;\\r\\n emit MemberAddition(_members[i]);\\r\\n }\\r\\n required = _required;\\r\\n emit RequirementChange(required);\\r\\n _setBridge(_bridge);\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory) {\\r\\n return \\\"v2\\\";\\r\\n }\\r\\n\\r\\n function setBridge(address _bridge) external onlyOwner {\\r\\n _setBridge(_bridge);\\r\\n }\\r\\n\\r\\n function _setBridge(address _bridge) internal {\\r\\n require(_bridge != NULL_ADDRESS, \\\"Federation: Empty bridge\\\");\\r\\n bridge = IBridge(_bridge);\\r\\n emit BridgeChanged(_bridge);\\r\\n }\\r\\n\\r\\n function voteTransaction(\\r\\n address originalTokenAddress,\\r\\n address payable sender,\\r\\n address payable receiver,\\r\\n uint256 amount,\\r\\n bytes32 blockHash,\\r\\n bytes32 transactionHash,\\r\\n uint32 logIndex\\r\\n )\\r\\n public onlyMember returns(bool)\\r\\n {\\r\\n bytes32 transactionId = getTransactionId(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n amount,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n );\\r\\n if (processed[transactionId])\\r\\n return true;\\r\\n\\r\\n if (votes[transactionId][_msgSender()])\\r\\n return true;\\r\\n\\r\\n votes[transactionId][_msgSender()] = true;\\r\\n emit Voted(\\r\\n _msgSender(),\\r\\n transactionHash,\\r\\n transactionId,\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n amount,\\r\\n blockHash,\\r\\n logIndex\\r\\n );\\r\\n\\r\\n uint transactionCount = getTransactionCount(transactionId);\\r\\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\\r\\n processed[transactionId] = true;\\r\\n bridge.acceptTransfer(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n amount,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n );\\r\\n emit Executed(\\r\\n _msgSender(),\\r\\n transactionHash,\\r\\n transactionId,\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n amount,\\r\\n blockHash,\\r\\n logIndex\\r\\n );\\r\\n return true;\\r\\n }\\r\\n\\r\\n return true;\\r\\n }\\r\\n\\r\\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\\r\\n uint count = 0;\\r\\n for (uint i = 0; i < members.length; i++) {\\r\\n if (votes[transactionId][members[i]])\\r\\n count += 1;\\r\\n }\\r\\n return count;\\r\\n }\\r\\n\\r\\n function hasVoted(bytes32 transactionId) external view returns(bool)\\r\\n {\\r\\n return votes[transactionId][_msgSender()];\\r\\n }\\r\\n\\r\\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\\r\\n {\\r\\n return processed[transactionId];\\r\\n }\\r\\n\\r\\n function getTransactionId(\\r\\n address originalTokenAddress,\\r\\n address sender,\\r\\n address receiver,\\r\\n uint256 amount,\\r\\n bytes32 blockHash,\\r\\n bytes32 transactionHash,\\r\\n uint32 logIndex\\r\\n ) public pure returns(bytes32)\\r\\n {\\r\\n return keccak256(\\r\\n abi.encodePacked(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n amount,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n )\\r\\n );\\r\\n }\\r\\n\\r\\n function addMember(address _newMember) external onlyOwner\\r\\n {\\r\\n require(_newMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\r\\n require(!isMember[_newMember], \\\"Federation: Member already exists\\\");\\r\\n require(members.length < MAX_MEMBER_COUNT, \\\"Federation: Max members reached\\\");\\r\\n\\r\\n isMember[_newMember] = true;\\r\\n members.push(_newMember);\\r\\n emit MemberAddition(_newMember);\\r\\n }\\r\\n\\r\\n function removeMember(address _oldMember) external onlyOwner\\r\\n {\\r\\n require(_oldMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\r\\n require(isMember[_oldMember], \\\"Federation: Member doesn't exists\\\");\\r\\n require(members.length > 1, \\\"Federation: Can't remove all the members\\\");\\r\\n require(members.length - 1 >= required, \\\"Federation: Can't have less than required members\\\");\\r\\n\\r\\n isMember[_oldMember] = false;\\r\\n for (uint i = 0; i < members.length - 1; i++) {\\r\\n if (members[i] == _oldMember) {\\r\\n members[i] = members[members.length - 1];\\r\\n break;\\r\\n }\\r\\n }\\r\\n members.pop(); // remove an element from the end of the array.\\r\\n emit MemberRemoval(_oldMember);\\r\\n }\\r\\n\\r\\n function getMembers() external view returns (address[] memory)\\r\\n {\\r\\n return members;\\r\\n }\\r\\n\\r\\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\\r\\n {\\r\\n require(_required >= 2, \\\"Federation: Requires at least 2\\\");\\r\\n required = _required;\\r\\n emit RequirementChange(_required);\\r\\n }\\r\\n\\r\\n function emitHeartbeat(\\r\\n uint256 fedRskBlock,\\r\\n uint256 fedEthBlock,\\r\\n string calldata federatorVersion,\\r\\n string calldata nodeRskInfo,\\r\\n string calldata nodeEthInfo\\r\\n ) external onlyMember {\\r\\n emit HeartBeat(\\r\\n _msgSender(),\\r\\n fedRskBlock,\\r\\n fedEthBlock,\\r\\n federatorVersion,\\r\\n nodeRskInfo,\\r\\n nodeEthInfo\\r\\n );\\r\\n }\\r\\n}\",\"keccak256\":\"0xaf2beb2559b7db4dc06994cc8b3518aa78b74ee6db87ea30df64597fd5aa3a7d\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IBridge {\\r\\n\\r\\n struct ClaimData {\\r\\n address payable to;\\r\\n uint256 amount;\\r\\n bytes32 blockHash;\\r\\n bytes32 transactionHash;\\r\\n uint32 logIndex;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getFeePercentage() external view returns(uint);\\r\\n\\r\\n /**\\r\\n * ERC-20 tokens approve and transferFrom pattern\\r\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\r\\n */\\r\\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\\r\\n\\r\\n /**\\r\\n * Use network currency and cross it.\\r\\n */\\r\\n function depositTo(address to) external payable;\\r\\n\\r\\n /**\\r\\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\r\\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\r\\n */\\r\\n function tokensReceived (\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\r\\n */\\r\\n function acceptTransfer(\\r\\n address _originalTokenAddress,\\r\\n address payable _from,\\r\\n address payable _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\r\\n */\\r\\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\r\\n\\r\\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\r\\n\\r\\n function claimGasless(\\r\\n ClaimData calldata _claimData,\\r\\n address payable _relayer,\\r\\n uint256 _fee,\\r\\n uint256 _deadline,\\r\\n uint8 _v,\\r\\n bytes32 _r,\\r\\n bytes32 _s\\r\\n ) external returns (uint256 receivedAmount);\\r\\n\\r\\n function getTransactionDataHash(\\r\\n address _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external returns(bytes32);\\r\\n\\r\\n event Cross(\\r\\n address indexed _tokenAddress,\\r\\n address indexed _from,\\r\\n address indexed _to,\\r\\n uint256 _amount,\\r\\n bytes _userData\\r\\n );\\r\\n event NewSideToken(\\r\\n address indexed _newSideTokenAddress,\\r\\n address indexed _originalTokenAddress,\\r\\n string _newSymbol,\\r\\n uint256 _granularity\\r\\n );\\r\\n event AcceptedCrossTransfer(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _from,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex\\r\\n );\\r\\n event FeePercentageChanged(uint256 _amount);\\r\\n event Claimed(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _sender,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex,\\r\\n address _reciever,\\r\\n address _relayer,\\r\\n uint256 _fee\\r\\n );\\r\\n}\",\"keccak256\":\"0x9e48ff075a1e3fd0533feec4b93f397a4678b5d267cbae021ea0faf8cc91a383\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @title Initializable\\r\\n *\\r\\n * @dev Helper contract to support initializer functions. To use it, replace\\r\\n * the constructor with a function that has the `initializer` modifier.\\r\\n * WARNING: Unlike constructors, initializer functions must be manually\\r\\n * invoked. This applies both to deploying an Initializable contract, as well\\r\\n * as extending an Initializable contract via inheritance.\\r\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\r\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\r\\n * because this is not dealt with automatically as with constructors.\\r\\n */\\r\\ncontract Initializable {\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract has been initialized.\\r\\n */\\r\\n bool private initialized;\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract is in the process of being initialized.\\r\\n */\\r\\n bool private initializing;\\r\\n\\r\\n /**\\r\\n * @dev Modifier to use in the initializer function of a contract.\\r\\n */\\r\\n modifier initializer() {\\r\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\r\\n\\r\\n bool isTopLevelCall = !initializing;\\r\\n if (isTopLevelCall) {\\r\\n initializing = true;\\r\\n initialized = true;\\r\\n }\\r\\n\\r\\n _;\\r\\n\\r\\n if (isTopLevelCall) {\\r\\n initializing = false;\\r\\n }\\r\\n }\\r\\n\\r\\n // Reserved storage space to allow for layout changes in the future.\\r\\n uint256[50] private ______gap;\\r\\n}\",\"keccak256\":\"0xc1f4d917648f0e17ba6a023a168173ad6163f3120e24d1c97ae294430e42eaf3\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Contract module which provides a basic access control mechanism, where\\r\\n * there is an account (an owner) that can be granted exclusive access to\\r\\n * specific functions.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the modifier\\r\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\r\\n * the owner.\\r\\n */\\r\\ncontract UpgradableOwnable is Initializable, Context {\\r\\n address private _owner;\\r\\n\\r\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract setting the deployer as the initial owner.\\r\\n */\\r\\n function initialize(address sender) public initializer {\\r\\n _owner = sender;\\r\\n emit OwnershipTransferred(address(0), _owner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the address of the current owner.\\r\\n */\\r\\n function owner() public view returns (address) {\\r\\n return _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Throws if called by any account other than the owner.\\r\\n */\\r\\n modifier onlyOwner() {\\r\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the caller is the current owner.\\r\\n */\\r\\n function isOwner() public view returns (bool) {\\r\\n return _msgSender() == _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Leaves the contract without owner. It will not be possible to call\\r\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\r\\n *\\r\\n * > Note: Renouncing ownership will leave the contract without an owner,\\r\\n * thereby removing any functionality that is only available to the owner.\\r\\n */\\r\\n function renounceOwnership() public onlyOwner {\\r\\n emit OwnershipTransferred(_owner, address(0));\\r\\n _owner = address(0);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n * Can only be called by the current owner.\\r\\n */\\r\\n function transferOwnership(address newOwner) public onlyOwner {\\r\\n _transferOwnership(newOwner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n */\\r\\n function _transferOwnership(address newOwner) internal {\\r\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\r\\n emit OwnershipTransferred(_owner, newOwner);\\r\\n _owner = newOwner;\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0xea920007e371a3300245b5885f72cecc472c4780818365f0025fae65a767273d\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50611afa806100206000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063a1fb4acb116100de578063c1f0808a11610097578063dc8452cd11610071578063dc8452cd14610311578063e78cea9214610319578063f2fde38b14610321578063fa6297ba1461033457610173565b8063c1f0808a146102d8578063c4d66de8146102eb578063ca6d56dc146102fe57610173565b8063a1fb4acb14610266578063a230c52414610279578063a93585f01461028c578063b9a3b9dc1461029f578063ba51a6df146102b2578063c1b4a1e3146102c557610173565b8063715018a611610130578063715018a6146102135780638da5cb5b1461021b5780638dd14802146102235780638f32d59b146102365780639386775a1461023e5780639eab52531461025157610173565b80630b1ca49a146101785780631b4613cb1461018d57806335d4aa9e146101b657806354fd4d50146101c95780635daf08ca146101de578063681fc921146101fe575b600080fd5b61018b61018636600461128b565b610347565b005b6101a061019b366004611404565b610555565b6040516101ad9190611661565b60405180910390f35b6101a06101c43660046112ae565b610591565b6101d161080b565b6040516101ad9190611675565b6101f16101ec366004611404565b610827565b6040516101ad919061157c565b610206610851565b6040516101ad919061166c565b61018b610856565b6101f16108c4565b61018b61023136600461128b565b6108d3565b6101a0610903565b6101a061024c36600461141c565b610929565b610259610949565b6040516101ad9190611614565b610206610274366004611404565b6109ab565b6101a061028736600461128b565b610a1c565b6101a061029a366004611404565b610a31565b61018b6102ad36600461144b565b610a46565b61018b6102c0366004611404565b610aeb565b61018b6102d3366004611324565b610bac565b6101a06102e6366004611404565b610e1a565b61018b6102f936600461128b565b610e2f565b61018b61030c36600461128b565b610ef4565b610206611025565b6101f161102b565b61018b61032f36600461128b565b61103a565b6102066103423660046112ae565b611067565b61034f610903565b6103745760405162461bcd60e51b815260040161036b906118f4565b60405180910390fd5b6001600160a01b03811661039a5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff166103d25760405162461bcd60e51b815260040161036b9061176b565b6035546001106103f45760405162461bcd60e51b815260040161036b90611997565b60365460355460001901101561041c5760405162461bcd60e51b815260040161036b906118a3565b6001600160a01b0381166000908152603760205260408120805460ff191690555b603554600019018110156104f057816001600160a01b03166035828154811061046257fe5b6000918252602090912001546001600160a01b031614156104e85760358054600019810190811061048f57fe5b600091825260209091200154603580546001600160a01b0390921691839081106104b557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506104f0565b60010161043d565b5060358054806104fc57fe5b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b60008181526038602052604081208161056c6110a9565b6001600160a01b0316815260208101919091526040016000205460ff1690505b919050565b60006037600061059f6110a9565b6001600160a01b0316815260208101919091526040016000205460ff166105d85760405162461bcd60e51b815260040161036b90611a21565b60006105e989898989898989611067565b60008181526039602052604090205490915060ff161561060d576001915050610800565b6000818152603860205260408120906106246110a9565b6001600160a01b0316815260208101919091526040016000205460ff1615610650576001915050610800565b60008181526038602052604081206001916106696110a9565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055808461069b6110a9565b6001600160a01b03167fd22894491aaa5bb67855bcff4b9730bdf7768be1e25f66ced9a7d7ad623bf2918c8c8c8c8c8b6040516106dd969594939291906115d6565b60405180910390a460006106f0826109ab565b9050603654811015801561070d5750603554600290046001018110155b156107f95760008281526039602052604090819020805460ff191660011790556034549051636a86319160e01b81526001600160a01b0390911690636a86319190610768908d908d908d908d908d908d908d90600401611590565b600060405180830381600087803b15801561078257600080fd5b505af1158015610796573d6000803e3d6000fd5b5050505081856107a46110a9565b6001600160a01b03167fe21e4d3d66ef78424137270e65cfafe938736bb770702ab4fd630383e7820b738d8d8d8d8d8c6040516107e6969594939291906115d6565b60405180910390a4600192505050610800565b6001925050505b979650505050505050565b6040805180820190915260028152613b1960f11b602082015290565b6035818154811061083757600080fd5b6000918252602090912001546001600160a01b0316905081565b603281565b61085e610903565b61087a5760405162461bcd60e51b815260040161036b906118f4565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6108db610903565b6108f75760405162461bcd60e51b815260040161036b906118f4565b610900816110ad565b50565b6033546000906001600160a01b031661091a6110a9565b6001600160a01b031614905090565b603860209081526000928352604080842090915290825290205460ff1681565b606060358054806020026020016040519081016040528092919081815260200182805480156109a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610983575b5050505050905090565b600080805b603554811015610a1557600084815260386020526040812060358054919291849081106109d957fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0d576001820191505b6001016109b0565b5092915050565b60376020526000908152604090205460ff1681565b60009081526039602052604090205460ff1690565b60376000610a526110a9565b6001600160a01b0316815260208101919091526040016000205460ff16610a8b5760405162461bcd60e51b815260040161036b90611a21565b610a936110a9565b6001600160a01b03167fbb00e6cbdccbb5b7549e189335249187223d88583604555326aa1d7ccbcad4428989898989898989604051610ad9989796959493929190611a58565b60405180910390a25050505050505050565b610af3610903565b610b0f5760405162461bcd60e51b815260040161036b906118f4565b60355481818111801590610b2257508015155b8015610b2d57508115155b610b495760405162461bcd60e51b815260040161036b906116c8565b6002831015610b6a5760405162461bcd60e51b815260040161036b90611929565b60368390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610b9f90859061166c565b60405180910390a1505050565b835183818111158015610bbe57508015155b8015610bc957508115155b610be55760405162461bcd60e51b815260040161036b906116c8565b600054610100900460ff1680610bfe575060005460ff16155b610c1a5760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610c45576000805460ff1961ff0019909116610100171660011790555b610c4e84610e2f565b603287511115610c705760405162461bcd60e51b815260040161036b90611734565b8651610c839060359060208a01906111ab565b5060005b8751811015610db85760376000898381518110610ca057fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015610cfa575060006001600160a01b0316888281518110610ce657fe5b60200260200101516001600160a01b031614155b610d165760405162461bcd60e51b815260040161036b906117f4565b6001603760008a8481518110610d2857fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550878181518110610d7357fe5b60200260200101516001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a2600101610c87565b5060368690556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610dee90889061166c565b60405180910390a1610dff856110ad565b8015610e11576000805461ff00191690555b50505050505050565b60396020526000908152604090205460ff1681565b600054610100900460ff1680610e48575060005460ff16155b610e645760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610e8f576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610ef0576000805461ff00191690555b5050565b610efc610903565b610f185760405162461bcd60e51b815260040161036b906118f4565b6001600160a01b038116610f3e5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff1615610f775760405162461bcd60e51b815260040161036b9061182b565b603554603211610f995760405162461bcd60e51b815260040161036b906116fd565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b60365481565b6034546001600160a01b031681565b611042610903565b61105e5760405162461bcd60e51b815260040161036b906118f4565b61090081611129565b600087878787878787604051602001611086979695949392919061151e565b604051602081830303815290604052805190602001209050979650505050505050565b3390565b6001600160a01b0381166110d35760405162461bcd60e51b815260040161036b9061186c565b603480546001600160a01b0319166001600160a01b0383161790556040517f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b925517827944979061111e90839061157c565b60405180910390a150565b6001600160a01b03811661114f5760405162461bcd60e51b815260040161036b906119df565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b828054828255906000526020600020908101928215611200579160200282015b8281111561120057825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906111cb565b5061120c929150611210565b5090565b5b8082111561120c5760008155600101611211565b803561058c81611aaf565b60008083601f840112611241578182fd5b50813567ffffffffffffffff811115611258578182fd5b60208301915083602082850101111561127057600080fd5b9250929050565b803563ffffffff8116811461058c57600080fd5b60006020828403121561129c578081fd5b81356112a781611aaf565b9392505050565b600080600080600080600060e0888a0312156112c8578283fd5b87356112d381611aaf565b965060208801356112e381611aaf565b955060408801356112f381611aaf565b9450606088013593506080880135925060a0880135915061131660c08901611277565b905092959891949750929550565b60008060008060808587031215611339578384fd5b843567ffffffffffffffff80821115611350578586fd5b818701915087601f830112611363578586fd5b813560208282111561137157fe5b8082026040518282820101818110868211171561138a57fe5b604052838152828101945085830182870184018d10156113a8578a8bfd5b8a96505b848710156113d1576113bd81611225565b8652600196909601959483019483016113ac565b5098505088013595506113eb925050604087019050611225565b91506113f960608601611225565b905092959194509250565b600060208284031215611415578081fd5b5035919050565b6000806040838503121561142e578182fd5b82359150602083013561144081611aaf565b809150509250929050565b60008060008060008060008060a0898b031215611466578081fd5b8835975060208901359650604089013567ffffffffffffffff8082111561148b578283fd5b6114978c838d01611230565b909850965060608b01359150808211156114af578283fd5b6114bb8c838d01611230565b909650945060808b01359150808211156114d3578283fd5b506114e08b828c01611230565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b606097881b6bffffffffffffffffffffffff19908116825296881b871660148201529490961b9094166028840152603c830191909152605c820152607c81019190915260e09190911b6001600160e01b031916609c82015260a00190565b6001600160a01b0391909116815260200190565b6001600160a01b03978816815295871660208701529390951660408501526060840191909152608083015260a082019290925263ffffffff90911660c082015260e00190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925263ffffffff90911660a082015260c00190565b6020808252825182820181905260009190848201906040850190845b818110156116555783516001600160a01b031683529284019291840191600101611630565b50909695505050505050565b901515815260200190565b90815260200190565b6000602080835283518082850152825b818110156116a157858101830151858201604001528201611685565b818111156116b25783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f46656465726174696f6e3a20496e76616c696420726571756972656d656e7473604082015260600190565b6020808252601f908201527f46656465726174696f6e3a204d6178206d656d62657273207265616368656400604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20546f6f206d616e79206d656d6265727300000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746040820152607360f81b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252601b908201527f46656465726174696f6e3a20496e76616c6964206d656d626572730000000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746040820152607360f81b606082015260800190565b60208082526018908201527f46656465726174696f6e3a20456d707479206272696467650000000000000000604082015260600190565b60208082526031908201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604082015270207265717569726564206d656d6265727360781b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f46656465726174696f6e3a205265717569726573206174206c65617374203200604082015260600190565b60208082526018908201527f46656465726174696f6e3a20456d707479206d656d6265720000000000000000604082015260600190565b60208082526028908201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604082015267206d656d6265727360c01b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526019908201527f46656465726174696f6e3a204e6f7420466564657261746f7200000000000000604082015260600190565b600089825288602083015260a06040830152611a7860a08301888a6114f4565b8281036060840152611a8b8187896114f4565b90508281036080840152611aa08185876114f4565b9b9a5050505050505050505050565b6001600160a01b038116811461090057600080fdfea26469706673582212201ed28c73ed4ae70ef955780ff1194179b97395123f029d2daf12887f3e16603c64736f6c63430007060033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101735760003560e01c8063a1fb4acb116100de578063c1f0808a11610097578063dc8452cd11610071578063dc8452cd14610311578063e78cea9214610319578063f2fde38b14610321578063fa6297ba1461033457610173565b8063c1f0808a146102d8578063c4d66de8146102eb578063ca6d56dc146102fe57610173565b8063a1fb4acb14610266578063a230c52414610279578063a93585f01461028c578063b9a3b9dc1461029f578063ba51a6df146102b2578063c1b4a1e3146102c557610173565b8063715018a611610130578063715018a6146102135780638da5cb5b1461021b5780638dd14802146102235780638f32d59b146102365780639386775a1461023e5780639eab52531461025157610173565b80630b1ca49a146101785780631b4613cb1461018d57806335d4aa9e146101b657806354fd4d50146101c95780635daf08ca146101de578063681fc921146101fe575b600080fd5b61018b61018636600461128b565b610347565b005b6101a061019b366004611404565b610555565b6040516101ad9190611661565b60405180910390f35b6101a06101c43660046112ae565b610591565b6101d161080b565b6040516101ad9190611675565b6101f16101ec366004611404565b610827565b6040516101ad919061157c565b610206610851565b6040516101ad919061166c565b61018b610856565b6101f16108c4565b61018b61023136600461128b565b6108d3565b6101a0610903565b6101a061024c36600461141c565b610929565b610259610949565b6040516101ad9190611614565b610206610274366004611404565b6109ab565b6101a061028736600461128b565b610a1c565b6101a061029a366004611404565b610a31565b61018b6102ad36600461144b565b610a46565b61018b6102c0366004611404565b610aeb565b61018b6102d3366004611324565b610bac565b6101a06102e6366004611404565b610e1a565b61018b6102f936600461128b565b610e2f565b61018b61030c36600461128b565b610ef4565b610206611025565b6101f161102b565b61018b61032f36600461128b565b61103a565b6102066103423660046112ae565b611067565b61034f610903565b6103745760405162461bcd60e51b815260040161036b906118f4565b60405180910390fd5b6001600160a01b03811661039a5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff166103d25760405162461bcd60e51b815260040161036b9061176b565b6035546001106103f45760405162461bcd60e51b815260040161036b90611997565b60365460355460001901101561041c5760405162461bcd60e51b815260040161036b906118a3565b6001600160a01b0381166000908152603760205260408120805460ff191690555b603554600019018110156104f057816001600160a01b03166035828154811061046257fe5b6000918252602090912001546001600160a01b031614156104e85760358054600019810190811061048f57fe5b600091825260209091200154603580546001600160a01b0390921691839081106104b557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506104f0565b60010161043d565b5060358054806104fc57fe5b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b60008181526038602052604081208161056c6110a9565b6001600160a01b0316815260208101919091526040016000205460ff1690505b919050565b60006037600061059f6110a9565b6001600160a01b0316815260208101919091526040016000205460ff166105d85760405162461bcd60e51b815260040161036b90611a21565b60006105e989898989898989611067565b60008181526039602052604090205490915060ff161561060d576001915050610800565b6000818152603860205260408120906106246110a9565b6001600160a01b0316815260208101919091526040016000205460ff1615610650576001915050610800565b60008181526038602052604081206001916106696110a9565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055808461069b6110a9565b6001600160a01b03167fd22894491aaa5bb67855bcff4b9730bdf7768be1e25f66ced9a7d7ad623bf2918c8c8c8c8c8b6040516106dd969594939291906115d6565b60405180910390a460006106f0826109ab565b9050603654811015801561070d5750603554600290046001018110155b156107f95760008281526039602052604090819020805460ff191660011790556034549051636a86319160e01b81526001600160a01b0390911690636a86319190610768908d908d908d908d908d908d908d90600401611590565b600060405180830381600087803b15801561078257600080fd5b505af1158015610796573d6000803e3d6000fd5b5050505081856107a46110a9565b6001600160a01b03167fe21e4d3d66ef78424137270e65cfafe938736bb770702ab4fd630383e7820b738d8d8d8d8d8c6040516107e6969594939291906115d6565b60405180910390a4600192505050610800565b6001925050505b979650505050505050565b6040805180820190915260028152613b1960f11b602082015290565b6035818154811061083757600080fd5b6000918252602090912001546001600160a01b0316905081565b603281565b61085e610903565b61087a5760405162461bcd60e51b815260040161036b906118f4565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6108db610903565b6108f75760405162461bcd60e51b815260040161036b906118f4565b610900816110ad565b50565b6033546000906001600160a01b031661091a6110a9565b6001600160a01b031614905090565b603860209081526000928352604080842090915290825290205460ff1681565b606060358054806020026020016040519081016040528092919081815260200182805480156109a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610983575b5050505050905090565b600080805b603554811015610a1557600084815260386020526040812060358054919291849081106109d957fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0d576001820191505b6001016109b0565b5092915050565b60376020526000908152604090205460ff1681565b60009081526039602052604090205460ff1690565b60376000610a526110a9565b6001600160a01b0316815260208101919091526040016000205460ff16610a8b5760405162461bcd60e51b815260040161036b90611a21565b610a936110a9565b6001600160a01b03167fbb00e6cbdccbb5b7549e189335249187223d88583604555326aa1d7ccbcad4428989898989898989604051610ad9989796959493929190611a58565b60405180910390a25050505050505050565b610af3610903565b610b0f5760405162461bcd60e51b815260040161036b906118f4565b60355481818111801590610b2257508015155b8015610b2d57508115155b610b495760405162461bcd60e51b815260040161036b906116c8565b6002831015610b6a5760405162461bcd60e51b815260040161036b90611929565b60368390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610b9f90859061166c565b60405180910390a1505050565b835183818111158015610bbe57508015155b8015610bc957508115155b610be55760405162461bcd60e51b815260040161036b906116c8565b600054610100900460ff1680610bfe575060005460ff16155b610c1a5760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610c45576000805460ff1961ff0019909116610100171660011790555b610c4e84610e2f565b603287511115610c705760405162461bcd60e51b815260040161036b90611734565b8651610c839060359060208a01906111ab565b5060005b8751811015610db85760376000898381518110610ca057fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015610cfa575060006001600160a01b0316888281518110610ce657fe5b60200260200101516001600160a01b031614155b610d165760405162461bcd60e51b815260040161036b906117f4565b6001603760008a8481518110610d2857fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550878181518110610d7357fe5b60200260200101516001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a2600101610c87565b5060368690556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610dee90889061166c565b60405180910390a1610dff856110ad565b8015610e11576000805461ff00191690555b50505050505050565b60396020526000908152604090205460ff1681565b600054610100900460ff1680610e48575060005460ff16155b610e645760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610e8f576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610ef0576000805461ff00191690555b5050565b610efc610903565b610f185760405162461bcd60e51b815260040161036b906118f4565b6001600160a01b038116610f3e5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff1615610f775760405162461bcd60e51b815260040161036b9061182b565b603554603211610f995760405162461bcd60e51b815260040161036b906116fd565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b60365481565b6034546001600160a01b031681565b611042610903565b61105e5760405162461bcd60e51b815260040161036b906118f4565b61090081611129565b600087878787878787604051602001611086979695949392919061151e565b604051602081830303815290604052805190602001209050979650505050505050565b3390565b6001600160a01b0381166110d35760405162461bcd60e51b815260040161036b9061186c565b603480546001600160a01b0319166001600160a01b0383161790556040517f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b925517827944979061111e90839061157c565b60405180910390a150565b6001600160a01b03811661114f5760405162461bcd60e51b815260040161036b906119df565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b828054828255906000526020600020908101928215611200579160200282015b8281111561120057825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906111cb565b5061120c929150611210565b5090565b5b8082111561120c5760008155600101611211565b803561058c81611aaf565b60008083601f840112611241578182fd5b50813567ffffffffffffffff811115611258578182fd5b60208301915083602082850101111561127057600080fd5b9250929050565b803563ffffffff8116811461058c57600080fd5b60006020828403121561129c578081fd5b81356112a781611aaf565b9392505050565b600080600080600080600060e0888a0312156112c8578283fd5b87356112d381611aaf565b965060208801356112e381611aaf565b955060408801356112f381611aaf565b9450606088013593506080880135925060a0880135915061131660c08901611277565b905092959891949750929550565b60008060008060808587031215611339578384fd5b843567ffffffffffffffff80821115611350578586fd5b818701915087601f830112611363578586fd5b813560208282111561137157fe5b8082026040518282820101818110868211171561138a57fe5b604052838152828101945085830182870184018d10156113a8578a8bfd5b8a96505b848710156113d1576113bd81611225565b8652600196909601959483019483016113ac565b5098505088013595506113eb925050604087019050611225565b91506113f960608601611225565b905092959194509250565b600060208284031215611415578081fd5b5035919050565b6000806040838503121561142e578182fd5b82359150602083013561144081611aaf565b809150509250929050565b60008060008060008060008060a0898b031215611466578081fd5b8835975060208901359650604089013567ffffffffffffffff8082111561148b578283fd5b6114978c838d01611230565b909850965060608b01359150808211156114af578283fd5b6114bb8c838d01611230565b909650945060808b01359150808211156114d3578283fd5b506114e08b828c01611230565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b606097881b6bffffffffffffffffffffffff19908116825296881b871660148201529490961b9094166028840152603c830191909152605c820152607c81019190915260e09190911b6001600160e01b031916609c82015260a00190565b6001600160a01b0391909116815260200190565b6001600160a01b03978816815295871660208701529390951660408501526060840191909152608083015260a082019290925263ffffffff90911660c082015260e00190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925263ffffffff90911660a082015260c00190565b6020808252825182820181905260009190848201906040850190845b818110156116555783516001600160a01b031683529284019291840191600101611630565b50909695505050505050565b901515815260200190565b90815260200190565b6000602080835283518082850152825b818110156116a157858101830151858201604001528201611685565b818111156116b25783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f46656465726174696f6e3a20496e76616c696420726571756972656d656e7473604082015260600190565b6020808252601f908201527f46656465726174696f6e3a204d6178206d656d62657273207265616368656400604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20546f6f206d616e79206d656d6265727300000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746040820152607360f81b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252601b908201527f46656465726174696f6e3a20496e76616c6964206d656d626572730000000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746040820152607360f81b606082015260800190565b60208082526018908201527f46656465726174696f6e3a20456d707479206272696467650000000000000000604082015260600190565b60208082526031908201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604082015270207265717569726564206d656d6265727360781b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f46656465726174696f6e3a205265717569726573206174206c65617374203200604082015260600190565b60208082526018908201527f46656465726174696f6e3a20456d707479206d656d6265720000000000000000604082015260600190565b60208082526028908201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604082015267206d656d6265727360c01b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526019908201527f46656465726174696f6e3a204e6f7420466564657261746f7200000000000000604082015260600190565b600089825288602083015260a06040830152611a7860a08301888a6114f4565b8281036060840152611a8b8187896114f4565b90508281036080840152611aa08185876114f4565b9b9a5050505050505050505050565b6001600160a01b038116811461090057600080fdfea26469706673582212201ed28c73ed4ae70ef955780ff1194179b97395123f029d2daf12887f3e16603c64736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15789,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15792,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15832,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16076,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 5414,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "bridge",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_contract(IBridge)7398"
+ },
+ {
+ "astId": 5417,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "members",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 5419,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "required",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 5423,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "isMember",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 5429,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "votes",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_mapping(t_bytes32,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 5433,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "processed",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IBridge)7398": {
+ "encoding": "inplace",
+ "label": "contract IBridge",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/MainToken.json b/bridge/deployments/rinkeby/MainToken.json
new file mode 100644
index 000000000..b36eb47d5
--- /dev/null
+++ b/bridge/deployments/rinkeby/MainToken.json
@@ -0,0 +1,507 @@
+{
+ "address": "0xC511a79E359F5313feca3c51879DECBb63A9A1a9",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "uint8",
+ "name": "decimals",
+ "type": "uint8"
+ },
+ {
+ "internalType": "uint256",
+ "name": "totalSupply",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "subtractedValue",
+ "type": "uint256"
+ }
+ ],
+ "name": "decreaseAllowance",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "addedValue",
+ "type": "uint256"
+ }
+ ],
+ "name": "increaseAllowance",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "name": "transferAndCall",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x0f672d407a67c367c94faa764f7e6f37dadbb1b61675888536e9f92844b10643",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0xC511a79E359F5313feca3c51879DECBb63A9A1a9",
+ "transactionIndex": 0,
+ "gasUsed": "822325",
+ "logsBloom": "0x00000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000400000000000000000000000000000000000020000000000000000000800000000000000000000000010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000020000000800000000000000000000000000000000020000000000000000000000000",
+ "blockHash": "0x6831e7735169f014e289bb804f2bbaa181e26681e9acc374214952000e2dd8b1",
+ "transactionHash": "0x0f672d407a67c367c94faa764f7e6f37dadbb1b61675888536e9f92844b10643",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9269448,
+ "transactionHash": "0x0f672d407a67c367c94faa764f7e6f37dadbb1b61675888536e9f92844b10643",
+ "address": "0xC511a79E359F5313feca3c51879DECBb63A9A1a9",
+ "topics": [
+ "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b"
+ ],
+ "data": "0x00000000000000000000000000000000000000000000003635c9adc5dea00000",
+ "logIndex": 0,
+ "blockHash": "0x6831e7735169f014e289bb804f2bbaa181e26681e9acc374214952000e2dd8b1"
+ }
+ ],
+ "blockNumber": 9269448,
+ "cumulativeGasUsed": "822325",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "MAIN",
+ "MAIN",
+ 18,
+ "1000000000000000000000"
+ ],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"transferAndCall\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5,05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}; Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for `sender`'s tokens of at least `amount`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"transferAndCall(address,uint256,bytes)\":{\"notice\":\"ERC-677's only method implementation See https://github.com/ethereum/EIPs/issues/677 for details\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/test/MainToken.sol\":\"MainToken\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/test/MainToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../zeppelin/token/ERC20/ERC20Detailed.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC20/ERC20.sol\\\";\\r\\n\\r\\ncontract MainToken is ERC20Detailed, ERC20 {\\r\\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\\r\\n ERC20Detailed(name, symbol, decimals)\\r\\n {\\r\\n _mint(msg.sender, totalSupply);\\r\\n }\\r\\n\\r\\n /**\\r\\n * ERC-677's only method implementation\\r\\n * See https://github.com/ethereum/EIPs/issues/677 for details\\r\\n */\\r\\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\\r\\n bool result = transfer(_to, _value);\\r\\n if (!result) return false;\\r\\n\\r\\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\\r\\n receiver.tokenFallback(msg.sender, _value, _data);\\r\\n\\r\\n // IMPORTANT: the ERC-677 specification does not say\\r\\n // anything about the use of the receiver contract's\\r\\n // tokenFallback method return value. Given\\r\\n // its return type matches with this method's return\\r\\n // type, returning it could be a possibility.\\r\\n // We here take the more conservative approach and\\r\\n // ignore the return value, returning true\\r\\n // to signal a succesful transfer despite tokenFallback's\\r\\n // return value -- fact being tokens are transferred\\r\\n // in any case.\\r\\n return true;\\r\\n }\\r\\n}\\r\\n\\r\\ninterface ERC677TransferReceiver {\\r\\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\\r\\n}\",\"keccak256\":\"0xfef6affbdfdbc9ac0344b2e6349fb021efdccc30d5fe7ce4b40f19ddc2265bd1\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\r\\n * checks.\\r\\n *\\r\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\r\\n * in bugs, because programmers usually assume that an overflow raises an\\r\\n * error, which is the standard behavior in high level programming languages.\\r\\n * `SafeMath` restores this intuition by reverting the transaction when an\\r\\n * operation overflows.\\r\\n *\\r\\n * Using this library instead of the unchecked operations eliminates an entire\\r\\n * class of bugs, so it's recommended to use it always.\\r\\n */\\r\\nlibrary SafeMath {\\r\\n /**\\r\\n * @dev Returns the addition of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `+` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Addition cannot overflow.\\r\\n */\\r\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n uint256 c = a + b;\\r\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n */\\r\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b <= a, errorMessage);\\r\\n uint256 c = a - b;\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `*` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Multiplication cannot overflow.\\r\\n */\\r\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\r\\n // benefit is lost if 'b' is also tested.\\r\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\r\\n if (a == 0) {\\r\\n return 0;\\r\\n }\\r\\n\\r\\n uint256 c = a * b;\\r\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n // Solidity only automatically asserts when dividing by 0\\r\\n require(b > 0, errorMessage);\\r\\n uint256 c = a / b;\\r\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts with custom message when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b != 0, errorMessage);\\r\\n return a % b;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x29ffa7ff59806a3add585615cc102b70b43049587dcc73649f77b427f35b009d\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"./IERC20.sol\\\";\\r\\nimport \\\"../../math/SafeMath.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Implementation of the {IERC20} interface.\\r\\n *\\r\\n * This implementation is agnostic to the way tokens are created. This means\\r\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\r\\n * For a generic mechanism see {ERC20Mintable}.\\r\\n *\\r\\n * TIP: For a detailed writeup see our guide\\r\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\r\\n * to implement supply mechanisms].\\r\\n *\\r\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\r\\n * of returning `false` on failure. This behavior is nonetheless conventional\\r\\n * and does not conflict with the expectations of ERC20 applications.\\r\\n *\\r\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\r\\n * This allows applications to reconstruct the allowance for all accounts just\\r\\n * by listening to said events. Other implementations of the EIP may not emit\\r\\n * these events, as it isn't required by the specification.\\r\\n *\\r\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\r\\n * functions have been added to mitigate the well-known issues around setting\\r\\n * allowances. See {IERC20-approve}.\\r\\n */\\r\\ncontract ERC20 is Context, IERC20 {\\r\\n using SafeMath for uint256;\\r\\n\\r\\n mapping (address => uint256) private _balances;\\r\\n\\r\\n mapping (address => mapping (address => uint256)) private _allowances;\\r\\n\\r\\n uint256 private _totalSupply;\\r\\n\\r\\n /**\\r\\n * @dev See {IERC20-totalSupply}.\\r\\n */\\r\\n function totalSupply() override public view returns (uint256) {\\r\\n return _totalSupply;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC20-balanceOf}.\\r\\n */\\r\\n function balanceOf(address account) override public view returns (uint256) {\\r\\n return _balances[account];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC20-transfer}.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `recipient` cannot be the zero address.\\r\\n * - the caller must have a balance of at least `amount`.\\r\\n */\\r\\n function transfer(address recipient, uint256 amount) override public returns (bool) {\\r\\n _transfer(_msgSender(), recipient, amount);\\r\\n return true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC20-allowance}.\\r\\n */\\r\\n function allowance(address owner, address spender) override public view returns (uint256) {\\r\\n return _allowances[owner][spender];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC20-approve}.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `spender` cannot be the zero address.\\r\\n */\\r\\n function approve(address spender, uint256 amount) override public returns (bool) {\\r\\n _approve(_msgSender(), spender, amount);\\r\\n return true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC20-transferFrom}.\\r\\n *\\r\\n * Emits an {Approval} event indicating the updated allowance. This is not\\r\\n * required by the EIP. See the note at the beginning of {ERC20};\\r\\n *\\r\\n * Requirements:\\r\\n * - `sender` and `recipient` cannot be the zero address.\\r\\n * - `sender` must have a balance of at least `amount`.\\r\\n * - the caller must have allowance for `sender`'s tokens of at least\\r\\n * `amount`.\\r\\n */\\r\\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\\r\\n _transfer(sender, recipient, amount);\\r\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\r\\n return true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\r\\n *\\r\\n * This is an alternative to {approve} that can be used as a mitigation for\\r\\n * problems described in {IERC20-approve}.\\r\\n *\\r\\n * Emits an {Approval} event indicating the updated allowance.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `spender` cannot be the zero address.\\r\\n */\\r\\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\\r\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\r\\n return true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\r\\n *\\r\\n * This is an alternative to {approve} that can be used as a mitigation for\\r\\n * problems described in {IERC20-approve}.\\r\\n *\\r\\n * Emits an {Approval} event indicating the updated allowance.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `spender` cannot be the zero address.\\r\\n * - `spender` must have allowance for the caller of at least\\r\\n * `subtractedValue`.\\r\\n */\\r\\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\\r\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\r\\n return true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\r\\n *\\r\\n * This is internal function is equivalent to {transfer}, and can be used to\\r\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `sender` cannot be the zero address.\\r\\n * - `recipient` cannot be the zero address.\\r\\n * - `sender` must have a balance of at least `amount`.\\r\\n */\\r\\n function _transfer(address sender, address recipient, uint256 amount) internal {\\r\\n require(sender != address(0), \\\"ERC20: transfer from zero address\\\");\\r\\n require(recipient != address(0), \\\"ERC20: transfer to zero address\\\");\\r\\n\\r\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\r\\n _balances[recipient] = _balances[recipient].add(amount);\\r\\n emit Transfer(sender, recipient, amount);\\r\\n }\\r\\n\\r\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\r\\n * the total supply.\\r\\n *\\r\\n * Emits a {Transfer} event with `from` set to the zero address.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `to` cannot be the zero address.\\r\\n */\\r\\n function _mint(address account, uint256 amount) internal {\\r\\n require(account != address(0), \\\"ERC20: mint to zero address\\\");\\r\\n\\r\\n _totalSupply = _totalSupply.add(amount);\\r\\n _balances[account] = _balances[account].add(amount);\\r\\n emit Transfer(address(0), account, amount);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Destroys `amount` tokens from `account`, reducing the\\r\\n * total supply.\\r\\n *\\r\\n * Emits a {Transfer} event with `to` set to the zero address.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `account` cannot be the zero address.\\r\\n * - `account` must have at least `amount` tokens.\\r\\n */\\r\\n function _burn(address account, uint256 amount) internal {\\r\\n require(account != address(0), \\\"ERC20: burn from zero address\\\");\\r\\n\\r\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\r\\n _totalSupply = _totalSupply.sub(amount);\\r\\n emit Transfer(account, address(0), amount);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\\r\\n *\\r\\n * This is internal function is equivalent to `approve`, and can be used to\\r\\n * e.g. set automatic allowances for certain subsystems, etc.\\r\\n *\\r\\n * Emits an {Approval} event.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `owner` cannot be the zero address.\\r\\n * - `spender` cannot be the zero address.\\r\\n */\\r\\n function _approve(address owner, address spender, uint256 amount) internal {\\r\\n require(owner != address(0), \\\"ERC20: approve from zero address\\\");\\r\\n require(spender != address(0), \\\"ERC20: approve to zero address\\\");\\r\\n\\r\\n _allowances[owner][spender] = amount;\\r\\n emit Approval(owner, spender, amount);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\\r\\n * from the caller's allowance.\\r\\n *\\r\\n * See {_burn} and {_approve}.\\r\\n */\\r\\n function _burnFrom(address account, uint256 amount) internal {\\r\\n _burn(account, amount);\\r\\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \\\"ERC20: burn amount exceeds allowance\\\"));\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xc3236d3e5ff8c9e76dafc824352fba2e4c360148ca8296291e0b8226a15ca8c0\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/ERC20Detailed.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./IERC20.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Optional functions from the ERC20 standard.\\r\\n */\\r\\nabstract contract ERC20Detailed is IERC20 {\\r\\n string private _name;\\r\\n string private _symbol;\\r\\n uint8 private _decimals;\\r\\n\\r\\n /**\\r\\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\\r\\n * these values are immutable: they can only be set once during\\r\\n * construction.\\r\\n */\\r\\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\\r\\n _name = aName;\\r\\n _symbol = aSymbol;\\r\\n _decimals = theDecimals;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the name of the token.\\r\\n */\\r\\n function name() public view returns (string memory) {\\r\\n return _name;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the symbol of the token, usually a shorter version of the\\r\\n * name.\\r\\n */\\r\\n function symbol() public view returns (string memory) {\\r\\n return _symbol;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of decimals used to get its user representation.\\r\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\r\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\r\\n *\\r\\n * Tokens usually opt for a value of 18, imitating the relationship between\\r\\n * Ether and Wei.\\r\\n *\\r\\n * NOTE: This information is only used for _display_ purposes: it in\\r\\n * no way affects any of the arithmetic of the contract, including\\r\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\r\\n */\\r\\n function decimals() public view returns (uint8) {\\r\\n return _decimals;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x561486a93c8d2dc68a79a2f79d64d33b9d7a8f1957b34cc2d80c63f9dee0516a\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\r\\n * the optional functions; to access them see {ERC20Detailed}.\\r\\n */\\r\\ninterface IERC20 {\\r\\n /**\\r\\n * @dev Returns the amount of tokens in existence.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens owned by `account`.\\r\\n */\\r\\n function balanceOf(address account) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transfer(address recipient, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Returns the remaining number of tokens that `spender` will be\\r\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\r\\n * zero by default.\\r\\n *\\r\\n * This value changes when {approve} or {transferFrom} are called.\\r\\n */\\r\\n function allowance(address owner, address spender) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\r\\n * that someone may use both the old and the new allowance by unfortunate\\r\\n * transaction ordering. One possible solution to mitigate this race\\r\\n * condition is to first reduce the spender's allowance to 0 and set the\\r\\n * desired value afterwards:\\r\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\r\\n *\\r\\n * Emits an {Approval} event.\\r\\n */\\r\\n function approve(address spender, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\r\\n * allowance mechanism. `amount` is then deducted from the caller's\\r\\n * allowance.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\r\\n * another (`to`).\\r\\n *\\r\\n * Note that `value` may be zero.\\r\\n */\\r\\n event Transfer(address indexed from, address indexed to, uint256 value);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\r\\n * a call to {approve}. `value` is the new allowance.\\r\\n */\\r\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\r\\n}\\r\\n\",\"keccak256\":\"0x7531f90b8a5a04fd225fb07a30e0792068438a7c82127a22db870c1849460dfc\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x60806040523480156200001157600080fd5b5060405162000fd538038062000fd5833981810160405260808110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b506040908152602082810151929091015186519294509250859185918591620001c891600091908601906200031b565b508151620001de9060019060208501906200031b565b506002805460ff191660ff929092169190911790555062000202905033826200020c565b505050506200043e565b6001600160a01b0382166200023e5760405162461bcd60e51b81526004016200023590620003fe565b60405180910390fd5b6200025a81600554620002ec60201b6200074b1790919060201c565b6005556001600160a01b0382166000908152600360209081526040909120546200028f9183906200074b620002ec821b17901c565b6001600160a01b0383166000818152600360205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90620002e090859062000435565b60405180910390a35050565b600082820183811015620003145760405162461bcd60e51b81526004016200023590620003c7565b9392505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200035357600085556200039e565b82601f106200036e57805160ff19168380011785556200039e565b828001600101855582156200039e579182015b828111156200039e57825182559160200191906001019062000381565b50620003ac929150620003b0565b5090565b5b80821115620003ac5760008155600101620003b1565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601b908201527f45524332303a206d696e7420746f207a65726f20616464726573730000000000604082015260600190565b90815260200190565b610b87806200044e6000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80634000aea0116100715780634000aea01461021057806370a08231146102cb57806395d89b41146102f1578063a457c2d7146102f9578063a9059cbb14610325578063dd62ed3e14610351576100b4565b806306fdde03146100b9578063095ea7b31461013657806318160ddd1461017657806323b872dd14610190578063313ce567146101c657806339509351146101e4575b600080fd5b6100c161037f565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100fb5781810151838201526020016100e3565b50505050905090810190601f1680156101285780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101626004803603604081101561014c57600080fd5b506001600160a01b038135169060200135610415565b604080519115158252519081900360200190f35b61017e610432565b60408051918252519081900360200190f35b610162600480360360608110156101a657600080fd5b506001600160a01b03813581169160208101359091169060400135610438565b6101ce6104c0565b6040805160ff9092168252519081900360200190f35b610162600480360360408110156101fa57600080fd5b506001600160a01b0381351690602001356104c9565b6101626004803603606081101561022657600080fd5b6001600160a01b038235169160208101359181019060608101604082013564010000000081111561025657600080fd5b82018360208201111561026857600080fd5b8035906020019184600183028401116401000000008311171561028a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610517945050505050565b61017e600480360360208110156102e157600080fd5b50356001600160a01b0316610629565b6100c1610644565b6101626004803603604081101561030f57600080fd5b506001600160a01b0381351690602001356106a4565b6101626004803603604081101561033b57600080fd5b506001600160a01b03813516906020013561070c565b61017e6004803603604081101561036757600080fd5b506001600160a01b0381358116916020013516610720565b60008054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561040b5780601f106103e05761010080835404028352916020019161040b565b820191906000526020600020905b8154815290600101906020018083116103ee57829003601f168201915b5050505050905090565b6000610429610422610779565b848461077d565b50600192915050565b60055490565b6000610445848484610831565b6104b584610451610779565b6104b085604051806060016040528060288152602001610b05602891396001600160a01b038a1660009081526004602052604081209061048f610779565b6001600160a01b03168152602081019190915260400160002054919061093b565b61077d565b5060015b9392505050565b60025460ff1690565b60006104296104d6610779565b846104b085600460006104e7610779565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549061074b565b600080610524858561070c565b9050806105355760009150506104b9565b60405163607705c560e11b815233600482018181526024830187905260606044840190815286516064850152865189946001600160a01b0386169463c0ee0b8a9490938b938b9360840190602085019080838360005b838110156105a357818101518382015260200161058b565b50505050905090810190601f1680156105d05780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156105f157600080fd5b505af1158015610605573d6000803e3d6000fd5b505050506040513d602081101561061b57600080fd5b506001979650505050505050565b6001600160a01b031660009081526003602052604090205490565b60018054604080516020601f6002600019610100878916150201909516949094049384018190048102820181019092528281526060939092909183018282801561040b5780601f106103e05761010080835404028352916020019161040b565b60006104296106b1610779565b846104b085604051806060016040528060258152602001610b2d60259139600460006106db610779565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919061093b565b6000610429610719610779565b8484610831565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205490565b6000828201838110156104b95760405162461bcd60e51b8152600401610770906109f1565b60405180910390fd5b3390565b6001600160a01b0383166107a35760405162461bcd60e51b815260040161077090610aa0565b6001600160a01b0382166107c95760405162461bcd60e51b8152600401610770906109ba565b6001600160a01b0380841660008181526004602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610824908590610ad5565b60405180910390a3505050565b6001600160a01b0383166108575760405162461bcd60e51b815260040161077090610a28565b6001600160a01b03821661087d5760405162461bcd60e51b815260040161077090610a69565b6108ba81604051806060016040528060268152602001610adf602691396001600160a01b038616600090815260036020526040902054919061093b565b6001600160a01b0380851660009081526003602052604080822093909355908416815220546108e9908261074b565b6001600160a01b0380841660008181526003602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610824908590610ad5565b6000818484111561095f5760405162461bcd60e51b81526004016107709190610967565b505050900390565b6000602080835283518082850152825b8181101561099357858101830151858201604001528201610977565b818111156109a45783604083870101525b50601f01601f1916929092016040019392505050565b6020808252601e908201527f45524332303a20617070726f766520746f207a65726f20616464726573730000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526021908201527f45524332303a207472616e736665722066726f6d207a65726f206164647265736040820152607360f81b606082015260800190565b6020808252601f908201527f45524332303a207472616e7366657220746f207a65726f206164647265737300604082015260600190565b6020808252818101527f45524332303a20617070726f76652066726f6d207a65726f2061646472657373604082015260600190565b9081526020019056fe45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220792dad2b78601a73f2210ef3e4423eb800f843c4cfab545116ac70c02bee3b9264736f6c63430007060033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100b45760003560e01c80634000aea0116100715780634000aea01461021057806370a08231146102cb57806395d89b41146102f1578063a457c2d7146102f9578063a9059cbb14610325578063dd62ed3e14610351576100b4565b806306fdde03146100b9578063095ea7b31461013657806318160ddd1461017657806323b872dd14610190578063313ce567146101c657806339509351146101e4575b600080fd5b6100c161037f565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100fb5781810151838201526020016100e3565b50505050905090810190601f1680156101285780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101626004803603604081101561014c57600080fd5b506001600160a01b038135169060200135610415565b604080519115158252519081900360200190f35b61017e610432565b60408051918252519081900360200190f35b610162600480360360608110156101a657600080fd5b506001600160a01b03813581169160208101359091169060400135610438565b6101ce6104c0565b6040805160ff9092168252519081900360200190f35b610162600480360360408110156101fa57600080fd5b506001600160a01b0381351690602001356104c9565b6101626004803603606081101561022657600080fd5b6001600160a01b038235169160208101359181019060608101604082013564010000000081111561025657600080fd5b82018360208201111561026857600080fd5b8035906020019184600183028401116401000000008311171561028a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610517945050505050565b61017e600480360360208110156102e157600080fd5b50356001600160a01b0316610629565b6100c1610644565b6101626004803603604081101561030f57600080fd5b506001600160a01b0381351690602001356106a4565b6101626004803603604081101561033b57600080fd5b506001600160a01b03813516906020013561070c565b61017e6004803603604081101561036757600080fd5b506001600160a01b0381358116916020013516610720565b60008054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561040b5780601f106103e05761010080835404028352916020019161040b565b820191906000526020600020905b8154815290600101906020018083116103ee57829003601f168201915b5050505050905090565b6000610429610422610779565b848461077d565b50600192915050565b60055490565b6000610445848484610831565b6104b584610451610779565b6104b085604051806060016040528060288152602001610b05602891396001600160a01b038a1660009081526004602052604081209061048f610779565b6001600160a01b03168152602081019190915260400160002054919061093b565b61077d565b5060015b9392505050565b60025460ff1690565b60006104296104d6610779565b846104b085600460006104e7610779565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549061074b565b600080610524858561070c565b9050806105355760009150506104b9565b60405163607705c560e11b815233600482018181526024830187905260606044840190815286516064850152865189946001600160a01b0386169463c0ee0b8a9490938b938b9360840190602085019080838360005b838110156105a357818101518382015260200161058b565b50505050905090810190601f1680156105d05780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156105f157600080fd5b505af1158015610605573d6000803e3d6000fd5b505050506040513d602081101561061b57600080fd5b506001979650505050505050565b6001600160a01b031660009081526003602052604090205490565b60018054604080516020601f6002600019610100878916150201909516949094049384018190048102820181019092528281526060939092909183018282801561040b5780601f106103e05761010080835404028352916020019161040b565b60006104296106b1610779565b846104b085604051806060016040528060258152602001610b2d60259139600460006106db610779565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919061093b565b6000610429610719610779565b8484610831565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205490565b6000828201838110156104b95760405162461bcd60e51b8152600401610770906109f1565b60405180910390fd5b3390565b6001600160a01b0383166107a35760405162461bcd60e51b815260040161077090610aa0565b6001600160a01b0382166107c95760405162461bcd60e51b8152600401610770906109ba565b6001600160a01b0380841660008181526004602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610824908590610ad5565b60405180910390a3505050565b6001600160a01b0383166108575760405162461bcd60e51b815260040161077090610a28565b6001600160a01b03821661087d5760405162461bcd60e51b815260040161077090610a69565b6108ba81604051806060016040528060268152602001610adf602691396001600160a01b038616600090815260036020526040902054919061093b565b6001600160a01b0380851660009081526003602052604080822093909355908416815220546108e9908261074b565b6001600160a01b0380841660008181526003602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610824908590610ad5565b6000818484111561095f5760405162461bcd60e51b81526004016107709190610967565b505050900390565b6000602080835283518082850152825b8181101561099357858101830151858201604001528201610977565b818111156109a45783604083870101525b50601f01601f1916929092016040019392505050565b6020808252601e908201527f45524332303a20617070726f766520746f207a65726f20616464726573730000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526021908201527f45524332303a207472616e736665722066726f6d207a65726f206164647265736040820152607360f81b606082015260800190565b6020808252601f908201527f45524332303a207472616e7366657220746f207a65726f206164647265737300604082015260600190565b6020808252818101527f45524332303a20617070726f76652066726f6d207a65726f2061646472657373604082015260600190565b9081526020019056fe45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220792dad2b78601a73f2210ef3e4423eb800f843c4cfab545116ac70c02bee3b9264736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "allowance(address,address)": {
+ "details": "See {IERC20-allowance}."
+ },
+ "approve(address,uint256)": {
+ "details": "See {IERC20-approve}. Requirements: - `spender` cannot be the zero address."
+ },
+ "balanceOf(address)": {
+ "details": "See {IERC20-balanceOf}."
+ },
+ "decimals()": {
+ "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5,05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}."
+ },
+ "decreaseAllowance(address,uint256)": {
+ "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`."
+ },
+ "increaseAllowance(address,uint256)": {
+ "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address."
+ },
+ "name()": {
+ "details": "Returns the name of the token."
+ },
+ "symbol()": {
+ "details": "Returns the symbol of the token, usually a shorter version of the name."
+ },
+ "totalSupply()": {
+ "details": "See {IERC20-totalSupply}."
+ },
+ "transfer(address,uint256)": {
+ "details": "See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`."
+ },
+ "transferFrom(address,address,uint256)": {
+ "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}; Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for `sender`'s tokens of at least `amount`."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "transferAndCall(address,uint256,bytes)": {
+ "notice": "ERC-677's only method implementation See https://github.com/ethereum/EIPs/issues/677 for details"
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 12918,
+ "contract": "contracts/test/MainToken.sol:MainToken",
+ "label": "_name",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 12920,
+ "contract": "contracts/test/MainToken.sol:MainToken",
+ "label": "_symbol",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 12922,
+ "contract": "contracts/test/MainToken.sol:MainToken",
+ "label": "_decimals",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint8"
+ },
+ {
+ "astId": 12493,
+ "contract": "contracts/test/MainToken.sol:MainToken",
+ "label": "_balances",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_mapping(t_address,t_uint256)"
+ },
+ {
+ "astId": 12499,
+ "contract": "contracts/test/MainToken.sol:MainToken",
+ "label": "_allowances",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))"
+ },
+ {
+ "astId": 12501,
+ "contract": "contracts/test/MainToken.sol:MainToken",
+ "label": "_totalSupply",
+ "offset": 0,
+ "slot": "5",
+ "type": "t_uint256"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_uint256))": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_uint256)"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "encoding": "inplace",
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/MultiSigWallet.json b/bridge/deployments/rinkeby/MultiSigWallet.json
new file mode 100644
index 000000000..0a5255d5a
--- /dev/null
+++ b/bridge/deployments/rinkeby/MultiSigWallet.json
@@ -0,0 +1,843 @@
+{
+ "address": "0x04994d7fF4938c5953A6C8411ad30083C9097348",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_owners",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Confirmation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposit",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Execution",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "ExecutionFailure",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnerAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnerRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Revocation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Submission",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_OWNER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "addOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "confirmTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "confirmations",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "executeTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getConfirmationCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "count",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getConfirmations",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "_confirmations",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getOwners",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "pending",
+ "type": "bool"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "count",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "from",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "to",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "pending",
+ "type": "bool"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "name": "getTransactionIds",
+ "outputs": [
+ {
+ "internalType": "uint256[]",
+ "name": "_transactionIds",
+ "type": "uint256[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "isConfirmed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "owners",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "removeOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "replaceOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "revokeConfirmation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "destination",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "submitTransaction",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "transactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "transactions",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "destination",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x216386b246f132046869d755619ca6fcf06a5ec2f63514e610690c5a1de61a9e",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0x04994d7fF4938c5953A6C8411ad30083C9097348",
+ "transactionIndex": 2,
+ "gasUsed": "1635718",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x51c834c105c3181d2eae902ec20c251506af253d6c7b3b6e421ca059a902b655",
+ "transactionHash": "0x216386b246f132046869d755619ca6fcf06a5ec2f63514e610690c5a1de61a9e",
+ "logs": [],
+ "blockNumber": 9264190,
+ "cumulativeGasUsed": "1692564",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ [
+ "0x2b3058eAb56FB80b53f3137422189E940EeFe31b"
+ ],
+ 1
+ ],
+ "solcInputHash": "ac84b9a231dc57cb70373cf629ffea6c",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_owners\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Confirmation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Execution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"ExecutionFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnerAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnerRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Revocation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Submission\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_OWNER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"addOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"confirmTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"confirmations\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"executeTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"getConfirmationCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"getConfirmations\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_confirmations\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pending\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"from\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"to\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"pending\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"name\":\"getTransactionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_transactionIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"isConfirmed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"owners\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"removeOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"replaceOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"revokeConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"submitTransaction\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"transactions\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"author\":\"Stefan George - \",\"kind\":\"dev\",\"methods\":{\"addOwner(address)\":{\"details\":\"Allows to add a new owner. Transaction has to be sent by wallet.\",\"params\":{\"owner\":\"Address of new owner.\"}},\"changeRequirement(uint256)\":{\"details\":\"Allows to change the number of required confirmations. Transaction has to be sent by wallet.\",\"params\":{\"_required\":\"Number of required confirmations.\"}},\"confirmTransaction(uint256)\":{\"details\":\"Allows an owner to confirm a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"constructor\":{\"details\":\"Contract constructor sets initial owners and required number of confirmations.\",\"params\":{\"_owners\":\"List of initial owners.\",\"_required\":\"Number of required confirmations.\"}},\"executeTransaction(uint256)\":{\"details\":\"Allows anyone to execute a confirmed transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"getConfirmationCount(uint256)\":{\"details\":\"Returns number of confirmations of a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"count\":\"Number of confirmations.\"}},\"getConfirmations(uint256)\":{\"details\":\"Returns array with owner addresses, which confirmed transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"_confirmations\":\"Returns array of owner addresses.\"}},\"getOwners()\":{\"details\":\"Returns list of owners.\",\"returns\":{\"_0\":\"List of owner addresses.\"}},\"getTransactionCount(bool,bool)\":{\"details\":\"Returns total number of transactions after filers are applied.\",\"params\":{\"executed\":\"Include executed transactions.\",\"pending\":\"Include pending transactions.\"},\"returns\":{\"count\":\"Total number of transactions after filters are applied.\"}},\"getTransactionIds(uint256,uint256,bool,bool)\":{\"details\":\"Returns list of transaction IDs in defined range.\",\"params\":{\"executed\":\"Include executed transactions.\",\"from\":\"Index start position of transaction array.\",\"pending\":\"Include pending transactions.\",\"to\":\"Index end position of transaction array.\"},\"returns\":{\"_transactionIds\":\"Returns array of transaction IDs.\"}},\"isConfirmed(uint256)\":{\"details\":\"Returns the confirmation status of a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"_0\":\"Confirmation status.\"}},\"removeOwner(address)\":{\"details\":\"Allows to remove an owner. Transaction has to be sent by wallet.\",\"params\":{\"owner\":\"Address of owner.\"}},\"replaceOwner(address,address)\":{\"details\":\"Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\",\"params\":{\"newOwner\":\"Address of new owner.\",\"owner\":\"Address of owner to be replaced.\"}},\"revokeConfirmation(uint256)\":{\"details\":\"Allows an owner to revoke a confirmation for a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"submitTransaction(address,uint256,bytes)\":{\"details\":\"Allows an owner to submit and confirm a transaction.\",\"params\":{\"data\":\"Transaction data payload.\",\"destination\":\"Transaction target address.\",\"value\":\"Transaction ether value.\"},\"returns\":{\"transactionId\":\"Returns transaction ID.\"}}},\"title\":\"Multisignature wallet - Allows multiple parties to agree on transactions before execution.\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/MultiSigWallet.sol\":\"MultiSigWallet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/MultiSigWallet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.\\r\\n/// @author Stefan George - \\r\\ncontract MultiSigWallet {\\r\\n\\r\\n /*\\r\\n * Events\\r\\n */\\r\\n event Confirmation(address indexed sender, uint indexed transactionId);\\r\\n event Revocation(address indexed sender, uint indexed transactionId);\\r\\n event Submission(uint indexed transactionId);\\r\\n event Execution(uint indexed transactionId);\\r\\n event ExecutionFailure(uint indexed transactionId);\\r\\n event Deposit(address indexed sender, uint value);\\r\\n event OwnerAddition(address indexed owner);\\r\\n event OwnerRemoval(address indexed owner);\\r\\n event RequirementChange(uint required);\\r\\n\\r\\n /*\\r\\n * views\\r\\n */\\r\\n uint constant public MAX_OWNER_COUNT = 50;\\r\\n\\r\\n /*\\r\\n * Storage\\r\\n */\\r\\n mapping (uint => Transaction) public transactions;\\r\\n mapping (uint => mapping (address => bool)) public confirmations;\\r\\n mapping (address => bool) public isOwner;\\r\\n address[] public owners;\\r\\n uint public required;\\r\\n uint public transactionCount;\\r\\n\\r\\n struct Transaction {\\r\\n address destination;\\r\\n uint value;\\r\\n bytes data;\\r\\n bool executed;\\r\\n }\\r\\n\\r\\n /*\\r\\n * Modifiers\\r\\n */\\r\\n modifier onlyWallet() {\\r\\n require(msg.sender == address(this), \\\"Only wallet allowed\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier ownerDoesNotExist(address owner) {\\r\\n require(!isOwner[owner], \\\"The owner already exists\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier ownerExists(address owner) {\\r\\n require(isOwner[owner], \\\"The owner does not exist\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier transactionExists(uint transactionId) {\\r\\n require(transactions[transactionId].destination != address(0), \\\"Transaction does not exist\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier confirmed(uint transactionId, address owner) {\\r\\n require(confirmations[transactionId][owner], \\\"Transaction is not confirmed by owner\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier notConfirmed(uint transactionId, address owner) {\\r\\n require(!confirmations[transactionId][owner], \\\"Transaction is already confirmed by owner\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier notExecuted(uint transactionId) {\\r\\n require(!transactions[transactionId].executed, \\\"Transaction was already executed\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier notNull(address _address) {\\r\\n require(_address != address(0), \\\"Address cannot be empty\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier validRequirement(uint ownerCount, uint _required) {\\r\\n // solium-disable-next-line max-len\\r\\n require(ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && _required != 0 && ownerCount != 0, \\\"Required value is invalid for the current owners count\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /// @dev Fallback function allows to deposit ether.\\r\\n receive ()\\r\\n external\\r\\n payable\\r\\n {\\r\\n if (msg.value > 0)\\r\\n emit Deposit(msg.sender, msg.value);\\r\\n }\\r\\n\\r\\n /*\\r\\n * Public functions\\r\\n */\\r\\n /// @dev Contract constructor sets initial owners and required number of confirmations.\\r\\n /// @param _owners List of initial owners.\\r\\n /// @param _required Number of required confirmations.\\r\\n constructor(address[] memory _owners, uint _required)\\r\\n validRequirement(_owners.length, _required)\\r\\n {\\r\\n for (uint i = 0; i < _owners.length; i++) {\\r\\n require(!isOwner[_owners[i]] && _owners[i] != address(0), \\\"Owners addresses are invalid\\\");\\r\\n isOwner[_owners[i]] = true;\\r\\n }\\r\\n owners = _owners;\\r\\n required = _required;\\r\\n }\\r\\n\\r\\n /// @dev Allows to add a new owner. Transaction has to be sent by wallet.\\r\\n /// @param owner Address of new owner.\\r\\n function addOwner(address owner)\\r\\n public\\r\\n onlyWallet\\r\\n ownerDoesNotExist(owner)\\r\\n notNull(owner)\\r\\n validRequirement(owners.length + 1, required)\\r\\n {\\r\\n isOwner[owner] = true;\\r\\n owners.push(owner);\\r\\n emit OwnerAddition(owner);\\r\\n }\\r\\n\\r\\n /// @dev Allows to remove an owner. Transaction has to be sent by wallet.\\r\\n /// @param owner Address of owner.\\r\\n function removeOwner(address owner)\\r\\n public\\r\\n onlyWallet\\r\\n ownerExists(owner)\\r\\n {\\r\\n isOwner[owner] = false;\\r\\n for (uint i = 0; i < owners.length - 1; i++)\\r\\n if (owners[i] == owner) {\\r\\n owners[i] = owners[owners.length - 1];\\r\\n break;\\r\\n }\\r\\n owners.pop(); // remove an element from the end of the array.\\r\\n if (required > owners.length)\\r\\n changeRequirement(owners.length);\\r\\n emit OwnerRemoval(owner);\\r\\n }\\r\\n\\r\\n /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\\r\\n /// @param owner Address of owner to be replaced.\\r\\n /// @param newOwner Address of new owner.\\r\\n function replaceOwner(address owner, address newOwner)\\r\\n public\\r\\n onlyWallet\\r\\n ownerExists(owner)\\r\\n ownerDoesNotExist(newOwner)\\r\\n {\\r\\n for (uint i = 0; i < owners.length; i++)\\r\\n if (owners[i] == owner) {\\r\\n owners[i] = newOwner;\\r\\n break;\\r\\n }\\r\\n isOwner[owner] = false;\\r\\n isOwner[newOwner] = true;\\r\\n emit OwnerRemoval(owner);\\r\\n emit OwnerAddition(newOwner);\\r\\n }\\r\\n\\r\\n /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.\\r\\n /// @param _required Number of required confirmations.\\r\\n function changeRequirement(uint _required)\\r\\n public\\r\\n onlyWallet\\r\\n validRequirement(owners.length, _required)\\r\\n {\\r\\n required = _required;\\r\\n emit RequirementChange(_required);\\r\\n }\\r\\n\\r\\n /// @dev Allows an owner to submit and confirm a transaction.\\r\\n /// @param destination Transaction target address.\\r\\n /// @param value Transaction ether value.\\r\\n /// @param data Transaction data payload.\\r\\n /// @return transactionId Returns transaction ID.\\r\\n function submitTransaction(address destination, uint value, bytes memory data)\\r\\n public\\r\\n returns (uint transactionId)\\r\\n {\\r\\n transactionId = addTransaction(destination, value, data);\\r\\n confirmTransaction(transactionId);\\r\\n }\\r\\n\\r\\n /// @dev Allows an owner to confirm a transaction.\\r\\n /// @param transactionId Transaction ID.\\r\\n function confirmTransaction(uint transactionId)\\r\\n public\\r\\n ownerExists(msg.sender)\\r\\n transactionExists(transactionId)\\r\\n notConfirmed(transactionId, msg.sender)\\r\\n {\\r\\n confirmations[transactionId][msg.sender] = true;\\r\\n emit Confirmation(msg.sender, transactionId);\\r\\n executeTransaction(transactionId);\\r\\n }\\r\\n\\r\\n /// @dev Allows an owner to revoke a confirmation for a transaction.\\r\\n /// @param transactionId Transaction ID.\\r\\n function revokeConfirmation(uint transactionId)\\r\\n public\\r\\n ownerExists(msg.sender)\\r\\n confirmed(transactionId, msg.sender)\\r\\n notExecuted(transactionId)\\r\\n {\\r\\n confirmations[transactionId][msg.sender] = false;\\r\\n emit Revocation(msg.sender, transactionId);\\r\\n }\\r\\n\\r\\n /// @dev Allows anyone to execute a confirmed transaction.\\r\\n /// @param transactionId Transaction ID.\\r\\n function executeTransaction(uint transactionId)\\r\\n public\\r\\n ownerExists(msg.sender)\\r\\n confirmed(transactionId, msg.sender)\\r\\n notExecuted(transactionId)\\r\\n {\\r\\n if (isConfirmed(transactionId)) {\\r\\n Transaction storage txn = transactions[transactionId];\\r\\n txn.executed = true;\\r\\n if (external_call(txn.destination, txn.value, txn.data.length, txn.data))\\r\\n emit Execution(transactionId);\\r\\n else {\\r\\n emit ExecutionFailure(transactionId);\\r\\n txn.executed = false;\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n // call has been separated into its own function in order to take advantage\\r\\n // of the Solidity's code generator to produce a loop that copies tx.data into memory.\\r\\n function external_call(address destination, uint value, uint dataLength, bytes memory data) internal returns (bool) {\\r\\n bool result;\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n let x := mload(0x40) // \\\"Allocate\\\" memory for output (0x40 is where \\\"free memory\\\" pointer is stored by convention)\\r\\n let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that\\r\\n result := call(\\r\\n sub(gas(), 34710), // 34710 is the value that solidity is currently emitting\\r\\n // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +\\r\\n // callNewAccountGas (25000, in case the destination address does not exist and needs creating)\\r\\n destination,\\r\\n value,\\r\\n d,\\r\\n dataLength, // Size of the input (in bytes) - this is what fixes the padding problem\\r\\n x,\\r\\n 0 // Output is ignored, therefore the output size is zero\\r\\n )\\r\\n }\\r\\n return result;\\r\\n }\\r\\n\\r\\n /// @dev Returns the confirmation status of a transaction.\\r\\n /// @param transactionId Transaction ID.\\r\\n /// @return Confirmation status.\\r\\n function isConfirmed(uint transactionId)\\r\\n public\\r\\n view\\r\\n returns (bool)\\r\\n {\\r\\n uint count = 0;\\r\\n for (uint i = 0; i < owners.length; i++) {\\r\\n if (confirmations[transactionId][owners[i]])\\r\\n count += 1;\\r\\n if (count == required)\\r\\n return true;\\r\\n }\\r\\n return false;\\r\\n }\\r\\n\\r\\n /*\\r\\n * Internal functions\\r\\n */\\r\\n /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.\\r\\n /// @param destination Transaction target address.\\r\\n /// @param value Transaction ether value.\\r\\n /// @param data Transaction data payload.\\r\\n /// @return transactionId Returns transaction ID.\\r\\n function addTransaction(address destination, uint value, bytes memory data)\\r\\n internal\\r\\n notNull(destination)\\r\\n returns (uint transactionId)\\r\\n {\\r\\n transactionId = transactionCount;\\r\\n transactions[transactionId] = Transaction({\\r\\n destination: destination,\\r\\n value: value,\\r\\n data: data,\\r\\n executed: false\\r\\n });\\r\\n transactionCount += 1;\\r\\n emit Submission(transactionId);\\r\\n }\\r\\n\\r\\n /*\\r\\n * Web3 call functions\\r\\n */\\r\\n /// @dev Returns number of confirmations of a transaction.\\r\\n /// @param transactionId Transaction ID.\\r\\n /// @return count Number of confirmations.\\r\\n function getConfirmationCount(uint transactionId)\\r\\n public\\r\\n view\\r\\n returns (uint count)\\r\\n {\\r\\n for (uint i = 0; i < owners.length; i++) {\\r\\n if (confirmations[transactionId][owners[i]]) {\\r\\n count += 1;\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n /// @dev Returns total number of transactions after filers are applied.\\r\\n /// @param pending Include pending transactions.\\r\\n /// @param executed Include executed transactions.\\r\\n /// @return count Total number of transactions after filters are applied.\\r\\n function getTransactionCount(bool pending, bool executed)\\r\\n public\\r\\n view\\r\\n returns (uint count)\\r\\n {\\r\\n for (uint i = 0; i < transactionCount; i++) {\\r\\n if ( pending && !transactions[i].executed || executed && transactions[i].executed) {\\r\\n count += 1;\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n /// @dev Returns list of owners.\\r\\n /// @return List of owner addresses.\\r\\n function getOwners()\\r\\n public\\r\\n view\\r\\n returns (address[] memory)\\r\\n {\\r\\n return owners;\\r\\n }\\r\\n\\r\\n /// @dev Returns array with owner addresses, which confirmed transaction.\\r\\n /// @param transactionId Transaction ID.\\r\\n /// @return _confirmations Returns array of owner addresses.\\r\\n function getConfirmations(uint transactionId)\\r\\n public\\r\\n view\\r\\n returns (address[] memory _confirmations)\\r\\n {\\r\\n address[] memory confirmationsTemp = new address[](owners.length);\\r\\n uint count = 0;\\r\\n uint i;\\r\\n for (i = 0; i < owners.length; i++)\\r\\n if (confirmations[transactionId][owners[i]]) {\\r\\n confirmationsTemp[count] = owners[i];\\r\\n count += 1;\\r\\n }\\r\\n _confirmations = new address[](count);\\r\\n for (i = 0; i < count; i++)\\r\\n _confirmations[i] = confirmationsTemp[i];\\r\\n }\\r\\n\\r\\n /// @dev Returns list of transaction IDs in defined range.\\r\\n /// @param from Index start position of transaction array.\\r\\n /// @param to Index end position of transaction array.\\r\\n /// @param pending Include pending transactions.\\r\\n /// @param executed Include executed transactions.\\r\\n /// @return _transactionIds Returns array of transaction IDs.\\r\\n function getTransactionIds(uint from, uint to, bool pending, bool executed)\\r\\n public\\r\\n view\\r\\n returns (uint[] memory _transactionIds)\\r\\n {\\r\\n uint[] memory transactionIdsTemp = new uint[](transactionCount);\\r\\n uint count = 0;\\r\\n uint i;\\r\\n for (i = 0; i < transactionCount; i++)\\r\\n if ( pending && !transactions[i].executed || executed && transactions[i].executed)\\r\\n {\\r\\n transactionIdsTemp[count] = i;\\r\\n count += 1;\\r\\n }\\r\\n _transactionIds = new uint[](to - from);\\r\\n for (i = from; i < to; i++)\\r\\n _transactionIds[i - from] = transactionIdsTemp[i];\\r\\n }\\r\\n}\",\"keccak256\":\"0x792f88ed02deed2ebe9ad69cf1ec730f945c349f995b0c84de4f574d7a39365d\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x60806040523480156200001157600080fd5b5060405162001e5838038062001e58833981016040819052620000349162000231565b81518160328211158015620000495750818111155b80156200005557508015155b80156200006157508115155b620000895760405162461bcd60e51b81526004016200008090620002f7565b60405180910390fd5b60005b8451811015620001705760026000868381518110620000a757fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1615801562000103575060006001600160a01b0316858281518110620000ef57fe5b60200260200101516001600160a01b031614155b620001225760405162461bcd60e51b8152600401620000809062000354565b6001600260008784815181106200013557fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff19169115159190911790556001016200008c565b5083516200018690600390602087019062000193565b505050600455506200038b565b828054828255906000526020600020908101928215620001eb579160200282015b82811115620001eb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620001b4565b50620001f9929150620001fd565b5090565b5b80821115620001f95760008155600101620001fe565b80516001600160a01b03811681146200022c57600080fd5b919050565b6000806040838503121562000244578182fd5b82516001600160401b03808211156200025b578384fd5b818501915085601f8301126200026f578384fd5b81516020828211156200027e57fe5b808202604051828282010181811086821117156200029857fe5b604052838152828101945085830182870184018b1015620002b7578889fd5b8896505b84871015620002e457620002cf8162000214565b865260019690960195948301948301620002bb565b5097909101519698969750505050505050565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f7220746860408201527f652063757272656e74206f776e65727320636f756e7400000000000000000000606082015260800190565b6020808252601c908201527f4f776e657273206164647265737365732061726520696e76616c696400000000604082015260600190565b611abd806200039b6000396000f3fe60806040526004361061012e5760003560e01c8063a0e67e2b116100ab578063c01a8c841161006f578063c01a8c84146103a6578063c6427474146103c6578063d74f8edd146103e6578063dc8452cd146103fb578063e20056e614610410578063ee22610b146104305761017d565b8063a0e67e2b14610302578063a8abe69a14610324578063b5dc40c314610351578063b77bf60014610371578063ba51a6df146103865761017d565b806354741525116100f257806354741525146102455780637065cb4814610272578063784547a7146102925780638b51d13f146102b25780639ace38c2146102d25761017d565b8063025e7c2714610182578063173825d9146101b857806320ea8d86146101d85780632f54bf6e146101f85780633411c81c146102255761017d565b3661017d57341561017b57336001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040516101729190611a7e565b60405180910390a25b005b600080fd5b34801561018e57600080fd5b506101a261019d3660046116ba565b610450565b6040516101af919061173f565b60405180910390f35b3480156101c457600080fd5b5061017b6101d3366004611594565b61047a565b3480156101e457600080fd5b5061017b6101f33660046116ba565b61062e565b34801561020457600080fd5b50610218610213366004611594565b61071d565b6040516101af9190611851565b34801561023157600080fd5b506102186102403660046116d2565b610732565b34801561025157600080fd5b50610265610260366004611691565b610752565b6040516101af9190611a7e565b34801561027e57600080fd5b5061017b61028d366004611594565b6107be565b34801561029e57600080fd5b506102186102ad3660046116ba565b61091e565b3480156102be57600080fd5b506102656102cd3660046116ba565b6109a9565b3480156102de57600080fd5b506102f26102ed3660046116ba565b610a18565b6040516101af9493929190611753565b34801561030e57600080fd5b50610317610ad6565b6040516101af91906117cc565b34801561033057600080fd5b5061034461033f3660046116f4565b610b38565b6040516101af9190611819565b34801561035d57600080fd5b5061031761036c3660046116ba565b610c92565b34801561037d57600080fd5b50610265610e37565b34801561039257600080fd5b5061017b6103a13660046116ba565b610e3d565b3480156103b257600080fd5b5061017b6103c13660046116ba565b610ee5565b3480156103d257600080fd5b506102656103e13660046115e0565b610fe5565b3480156103f257600080fd5b50610265611004565b34801561040757600080fd5b50610265611009565b34801561041c57600080fd5b5061017b61042b3660046115ae565b61100f565b34801561043c57600080fd5b5061017b61044b3660046116ba565b6111c5565b6003818154811061046057600080fd5b6000918252602090912001546001600160a01b0316905081565b3330146104a25760405162461bcd60e51b815260040161049990611977565b60405180910390fd5b6001600160a01b038116600090815260026020526040902054819060ff166104dc5760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b0382166000908152600260205260408120805460ff191690555b600354600019018110156105b057826001600160a01b03166003828154811061052257fe5b6000918252602090912001546001600160a01b031614156105a85760038054600019810190811061054f57fe5b600091825260209091200154600380546001600160a01b03909216918390811061057557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506105b0565b6001016104fd565b5060038054806105bc57fe5b600082815260209020810160001990810180546001600160a01b031916905501905560035460045411156105f6576003546105f690610e3d565b6040516001600160a01b038316907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a25050565b3360008181526002602052604090205460ff1661065d5760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff1661069a5760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156106ce5760405162461bcd60e51b815260040161049990611a49565b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b6005548110156107b75783801561077f575060008181526020819052604090206003015460ff16155b806107a357508280156107a3575060008181526020819052604090206003015460ff165b156107af576001820191505b600101610756565b5092915050565b3330146107dd5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038116600090815260026020526040902054819060ff16156108185760405162461bcd60e51b815260040161049990611a12565b816001600160a01b03811661083f5760405162461bcd60e51b815260040161049990611940565b6003805490506001016004546032821115801561085c5750818111155b801561086757508015155b801561087257508115155b61088e5760405162461bcd60e51b8152600401610499906118a5565b6001600160a01b038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b60035481101561099d576000848152600160205260408120600380549192918490811061094c57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610980576001820191505b600454821415610995576001925050506109a4565b600101610923565b5060009150505b919050565b6000805b600354811015610a1257600083815260016020526040812060038054919291849081106109d657fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0a576001820191505b6001016109ad565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f81018890048802840188019096528583526001600160a01b0390931695909491929190830182828015610ac35780601f10610a9857610100808354040283529160200191610ac3565b820191906000526020600020905b815481529060010190602001808311610aa657829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610b2e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b10575b5050505050905090565b6060600060055467ffffffffffffffff81118015610b5557600080fd5b50604051908082528060200260200182016040528015610b7f578160200160208202803683370190505b5090506000805b600554811015610c0057858015610baf575060008181526020819052604090206003015460ff16155b80610bd35750848015610bd3575060008181526020819052604090206003015460ff165b15610bf85780838381518110610be557fe5b6020026020010181815250506001820191505b600101610b86565b87870367ffffffffffffffff81118015610c1957600080fd5b50604051908082528060200260200182016040528015610c43578160200160208202803683370190505b5093508790505b86811015610c8757828181518110610c5e57fe5b60200260200101518489830381518110610c7457fe5b6020908102919091010152600101610c4a565b505050949350505050565b60035460609060009067ffffffffffffffff81118015610cb157600080fd5b50604051908082528060200260200182016040528015610cdb578160200160208202803683370190505b5090506000805b600354811015610d9e5760008581526001602052604081206003805491929184908110610d0b57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610d965760038181548110610d4557fe5b9060005260206000200160009054906101000a90046001600160a01b0316838381518110610d6f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001820191505b600101610ce2565b8167ffffffffffffffff81118015610db557600080fd5b50604051908082528060200260200182016040528015610ddf578160200160208202803683370190505b509350600090505b81811015610e2f57828181518110610dfb57fe5b6020026020010151848281518110610e0f57fe5b6001600160a01b0390921660209283029190910190910152600101610de7565b505050919050565b60055481565b333014610e5c5760405162461bcd60e51b815260040161049990611977565b6003548160328211801590610e715750818111155b8015610e7c57508015155b8015610e8757508115155b610ea35760405162461bcd60e51b8152600401610499906118a5565b60048390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610ed8908590611a7e565b60405180910390a1505050565b3360008181526002602052604090205460ff16610f145760405162461bcd60e51b8152600401610499906119a4565b60008281526020819052604090205482906001600160a01b0316610f4a5760405162461bcd60e51b8152600401610499906119db565b60008381526001602090815260408083203380855292529091205484919060ff1615610f885760405162461bcd60e51b81526004016104999061185c565b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3610fde856111c5565b5050505050565b6000610ff28484846113b5565b9050610ffd81610ee5565b9392505050565b603281565b60045481565b33301461102e5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038216600090815260026020526040902054829060ff166110685760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b038216600090815260026020526040902054829060ff16156110a35760405162461bcd60e51b815260040161049990611a12565b60005b60035481101561112b57846001600160a01b0316600382815481106110c757fe5b6000918252602090912001546001600160a01b031614156111235783600382815481106110f057fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061112b565b6001016110a6565b506001600160a01b03808516600081815260026020526040808220805460ff1990811690915593871682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a26040516001600160a01b038416907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a250505050565b3360008181526002602052604090205460ff166111f45760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff166112315760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156112655760405162461bcd60e51b815260040161049990611a49565b61126e8561091e565b15610fde576000858152602081815260409182902060038101805460ff19166001908117909155815481830154600280850180548851601f600019978316156101000297909701909116929092049485018790048702820187019097528381529395611340956001600160a01b039093169491939283908301828280156113365780601f1061130b57610100808354040283529160200191611336565b820191906000526020600020905b81548152906001019060200180831161131957829003601f168201915b50505050506114a9565b156113755760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26113ad565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038101805460ff191690555b505050505050565b6000836001600160a01b0381166113de5760405162461bcd60e51b815260040161049990611940565b600554604080516080810182526001600160a01b038881168252602080830189815283850189815260006060860181905287815280845295909520845181546001600160a01b031916941693909317835551600183015592518051949650919390926114519260028501929101906114cc565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b6000806040516020840160008287838a8c6187965a03f198975050505050505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826115025760008555611548565b82601f1061151b57805160ff1916838001178555611548565b82800160010185558215611548579182015b8281111561154857825182559160200191906001019061152d565b50611554929150611558565b5090565b5b808211156115545760008155600101611559565b80356001600160a01b03811681146109a457600080fd5b803580151581146109a457600080fd5b6000602082840312156115a5578081fd5b610ffd8261156d565b600080604083850312156115c0578081fd5b6115c98361156d565b91506115d76020840161156d565b90509250929050565b6000806000606084860312156115f4578081fd5b6115fd8461156d565b92506020808501359250604085013567ffffffffffffffff80821115611621578384fd5b818701915087601f830112611634578384fd5b81358181111561164057fe5b604051601f8201601f191681018501838111828210171561165d57fe5b60405281815283820185018a1015611673578586fd5b81858501868301378585838301015280955050505050509250925092565b600080604083850312156116a3578182fd5b6116ac83611584565b91506115d760208401611584565b6000602082840312156116cb578081fd5b5035919050565b600080604083850312156116e4578182fd5b823591506115d76020840161156d565b60008060008060808587031215611709578081fd5b843593506020850135925061172060408601611584565b915061172e60608601611584565b905092959194509250565b15159052565b6001600160a01b0391909116815260200190565b600060018060a01b038616825260208581840152608060408401528451806080850152825b818110156117945786810183015185820160a001528201611778565b818111156117a5578360a083870101525b50601f01601f1916830160a00191506117c390506060830184611739565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d5783516001600160a01b0316835292840192918401916001016117e8565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d57835183529284019291840191600101611835565b901515815260200190565b60208082526029908201527f5472616e73616374696f6e20697320616c726561647920636f6e6669726d656460408201526810313c9037bbb732b960b91b606082015260800190565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f72207468604082015275194818dd5c9c995b9d081bdddb995c9cc818dbdd5b9d60521b606082015260800190565b60208082526025908201527f5472616e73616374696f6e206973206e6f7420636f6e6669726d65642062792060408201526437bbb732b960d91b606082015260800190565b60208082526017908201527f416464726573732063616e6e6f7420626520656d707479000000000000000000604082015260600190565b60208082526013908201527213db9b1e481dd85b1b195d08185b1b1bddd959606a1b604082015260600190565b60208082526018908201527f546865206f776e657220646f6573206e6f742065786973740000000000000000604082015260600190565b6020808252601a908201527f5472616e73616374696f6e20646f6573206e6f74206578697374000000000000604082015260600190565b60208082526018908201527f546865206f776e657220616c7265616479206578697374730000000000000000604082015260600190565b6020808252818101527f5472616e73616374696f6e2077617320616c7265616479206578656375746564604082015260600190565b9081526020019056fea26469706673582212208e92b4f9d48fc5437b15ca73ef2f130bce58b998b5d726836438d13f68b237e464736f6c63430007060033",
+ "deployedBytecode": "0x60806040526004361061012e5760003560e01c8063a0e67e2b116100ab578063c01a8c841161006f578063c01a8c84146103a6578063c6427474146103c6578063d74f8edd146103e6578063dc8452cd146103fb578063e20056e614610410578063ee22610b146104305761017d565b8063a0e67e2b14610302578063a8abe69a14610324578063b5dc40c314610351578063b77bf60014610371578063ba51a6df146103865761017d565b806354741525116100f257806354741525146102455780637065cb4814610272578063784547a7146102925780638b51d13f146102b25780639ace38c2146102d25761017d565b8063025e7c2714610182578063173825d9146101b857806320ea8d86146101d85780632f54bf6e146101f85780633411c81c146102255761017d565b3661017d57341561017b57336001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040516101729190611a7e565b60405180910390a25b005b600080fd5b34801561018e57600080fd5b506101a261019d3660046116ba565b610450565b6040516101af919061173f565b60405180910390f35b3480156101c457600080fd5b5061017b6101d3366004611594565b61047a565b3480156101e457600080fd5b5061017b6101f33660046116ba565b61062e565b34801561020457600080fd5b50610218610213366004611594565b61071d565b6040516101af9190611851565b34801561023157600080fd5b506102186102403660046116d2565b610732565b34801561025157600080fd5b50610265610260366004611691565b610752565b6040516101af9190611a7e565b34801561027e57600080fd5b5061017b61028d366004611594565b6107be565b34801561029e57600080fd5b506102186102ad3660046116ba565b61091e565b3480156102be57600080fd5b506102656102cd3660046116ba565b6109a9565b3480156102de57600080fd5b506102f26102ed3660046116ba565b610a18565b6040516101af9493929190611753565b34801561030e57600080fd5b50610317610ad6565b6040516101af91906117cc565b34801561033057600080fd5b5061034461033f3660046116f4565b610b38565b6040516101af9190611819565b34801561035d57600080fd5b5061031761036c3660046116ba565b610c92565b34801561037d57600080fd5b50610265610e37565b34801561039257600080fd5b5061017b6103a13660046116ba565b610e3d565b3480156103b257600080fd5b5061017b6103c13660046116ba565b610ee5565b3480156103d257600080fd5b506102656103e13660046115e0565b610fe5565b3480156103f257600080fd5b50610265611004565b34801561040757600080fd5b50610265611009565b34801561041c57600080fd5b5061017b61042b3660046115ae565b61100f565b34801561043c57600080fd5b5061017b61044b3660046116ba565b6111c5565b6003818154811061046057600080fd5b6000918252602090912001546001600160a01b0316905081565b3330146104a25760405162461bcd60e51b815260040161049990611977565b60405180910390fd5b6001600160a01b038116600090815260026020526040902054819060ff166104dc5760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b0382166000908152600260205260408120805460ff191690555b600354600019018110156105b057826001600160a01b03166003828154811061052257fe5b6000918252602090912001546001600160a01b031614156105a85760038054600019810190811061054f57fe5b600091825260209091200154600380546001600160a01b03909216918390811061057557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506105b0565b6001016104fd565b5060038054806105bc57fe5b600082815260209020810160001990810180546001600160a01b031916905501905560035460045411156105f6576003546105f690610e3d565b6040516001600160a01b038316907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a25050565b3360008181526002602052604090205460ff1661065d5760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff1661069a5760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156106ce5760405162461bcd60e51b815260040161049990611a49565b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b6005548110156107b75783801561077f575060008181526020819052604090206003015460ff16155b806107a357508280156107a3575060008181526020819052604090206003015460ff165b156107af576001820191505b600101610756565b5092915050565b3330146107dd5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038116600090815260026020526040902054819060ff16156108185760405162461bcd60e51b815260040161049990611a12565b816001600160a01b03811661083f5760405162461bcd60e51b815260040161049990611940565b6003805490506001016004546032821115801561085c5750818111155b801561086757508015155b801561087257508115155b61088e5760405162461bcd60e51b8152600401610499906118a5565b6001600160a01b038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b60035481101561099d576000848152600160205260408120600380549192918490811061094c57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610980576001820191505b600454821415610995576001925050506109a4565b600101610923565b5060009150505b919050565b6000805b600354811015610a1257600083815260016020526040812060038054919291849081106109d657fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0a576001820191505b6001016109ad565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f81018890048802840188019096528583526001600160a01b0390931695909491929190830182828015610ac35780601f10610a9857610100808354040283529160200191610ac3565b820191906000526020600020905b815481529060010190602001808311610aa657829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610b2e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b10575b5050505050905090565b6060600060055467ffffffffffffffff81118015610b5557600080fd5b50604051908082528060200260200182016040528015610b7f578160200160208202803683370190505b5090506000805b600554811015610c0057858015610baf575060008181526020819052604090206003015460ff16155b80610bd35750848015610bd3575060008181526020819052604090206003015460ff165b15610bf85780838381518110610be557fe5b6020026020010181815250506001820191505b600101610b86565b87870367ffffffffffffffff81118015610c1957600080fd5b50604051908082528060200260200182016040528015610c43578160200160208202803683370190505b5093508790505b86811015610c8757828181518110610c5e57fe5b60200260200101518489830381518110610c7457fe5b6020908102919091010152600101610c4a565b505050949350505050565b60035460609060009067ffffffffffffffff81118015610cb157600080fd5b50604051908082528060200260200182016040528015610cdb578160200160208202803683370190505b5090506000805b600354811015610d9e5760008581526001602052604081206003805491929184908110610d0b57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610d965760038181548110610d4557fe5b9060005260206000200160009054906101000a90046001600160a01b0316838381518110610d6f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001820191505b600101610ce2565b8167ffffffffffffffff81118015610db557600080fd5b50604051908082528060200260200182016040528015610ddf578160200160208202803683370190505b509350600090505b81811015610e2f57828181518110610dfb57fe5b6020026020010151848281518110610e0f57fe5b6001600160a01b0390921660209283029190910190910152600101610de7565b505050919050565b60055481565b333014610e5c5760405162461bcd60e51b815260040161049990611977565b6003548160328211801590610e715750818111155b8015610e7c57508015155b8015610e8757508115155b610ea35760405162461bcd60e51b8152600401610499906118a5565b60048390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610ed8908590611a7e565b60405180910390a1505050565b3360008181526002602052604090205460ff16610f145760405162461bcd60e51b8152600401610499906119a4565b60008281526020819052604090205482906001600160a01b0316610f4a5760405162461bcd60e51b8152600401610499906119db565b60008381526001602090815260408083203380855292529091205484919060ff1615610f885760405162461bcd60e51b81526004016104999061185c565b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3610fde856111c5565b5050505050565b6000610ff28484846113b5565b9050610ffd81610ee5565b9392505050565b603281565b60045481565b33301461102e5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038216600090815260026020526040902054829060ff166110685760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b038216600090815260026020526040902054829060ff16156110a35760405162461bcd60e51b815260040161049990611a12565b60005b60035481101561112b57846001600160a01b0316600382815481106110c757fe5b6000918252602090912001546001600160a01b031614156111235783600382815481106110f057fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061112b565b6001016110a6565b506001600160a01b03808516600081815260026020526040808220805460ff1990811690915593871682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a26040516001600160a01b038416907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a250505050565b3360008181526002602052604090205460ff166111f45760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff166112315760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156112655760405162461bcd60e51b815260040161049990611a49565b61126e8561091e565b15610fde576000858152602081815260409182902060038101805460ff19166001908117909155815481830154600280850180548851601f600019978316156101000297909701909116929092049485018790048702820187019097528381529395611340956001600160a01b039093169491939283908301828280156113365780601f1061130b57610100808354040283529160200191611336565b820191906000526020600020905b81548152906001019060200180831161131957829003601f168201915b50505050506114a9565b156113755760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26113ad565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038101805460ff191690555b505050505050565b6000836001600160a01b0381166113de5760405162461bcd60e51b815260040161049990611940565b600554604080516080810182526001600160a01b038881168252602080830189815283850189815260006060860181905287815280845295909520845181546001600160a01b031916941693909317835551600183015592518051949650919390926114519260028501929101906114cc565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b6000806040516020840160008287838a8c6187965a03f198975050505050505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826115025760008555611548565b82601f1061151b57805160ff1916838001178555611548565b82800160010185558215611548579182015b8281111561154857825182559160200191906001019061152d565b50611554929150611558565b5090565b5b808211156115545760008155600101611559565b80356001600160a01b03811681146109a457600080fd5b803580151581146109a457600080fd5b6000602082840312156115a5578081fd5b610ffd8261156d565b600080604083850312156115c0578081fd5b6115c98361156d565b91506115d76020840161156d565b90509250929050565b6000806000606084860312156115f4578081fd5b6115fd8461156d565b92506020808501359250604085013567ffffffffffffffff80821115611621578384fd5b818701915087601f830112611634578384fd5b81358181111561164057fe5b604051601f8201601f191681018501838111828210171561165d57fe5b60405281815283820185018a1015611673578586fd5b81858501868301378585838301015280955050505050509250925092565b600080604083850312156116a3578182fd5b6116ac83611584565b91506115d760208401611584565b6000602082840312156116cb578081fd5b5035919050565b600080604083850312156116e4578182fd5b823591506115d76020840161156d565b60008060008060808587031215611709578081fd5b843593506020850135925061172060408601611584565b915061172e60608601611584565b905092959194509250565b15159052565b6001600160a01b0391909116815260200190565b600060018060a01b038616825260208581840152608060408401528451806080850152825b818110156117945786810183015185820160a001528201611778565b818111156117a5578360a083870101525b50601f01601f1916830160a00191506117c390506060830184611739565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d5783516001600160a01b0316835292840192918401916001016117e8565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d57835183529284019291840191600101611835565b901515815260200190565b60208082526029908201527f5472616e73616374696f6e20697320616c726561647920636f6e6669726d656460408201526810313c9037bbb732b960b91b606082015260800190565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f72207468604082015275194818dd5c9c995b9d081bdddb995c9cc818dbdd5b9d60521b606082015260800190565b60208082526025908201527f5472616e73616374696f6e206973206e6f7420636f6e6669726d65642062792060408201526437bbb732b960d91b606082015260800190565b60208082526017908201527f416464726573732063616e6e6f7420626520656d707479000000000000000000604082015260600190565b60208082526013908201527213db9b1e481dd85b1b195d08185b1b1bddd959606a1b604082015260600190565b60208082526018908201527f546865206f776e657220646f6573206e6f742065786973740000000000000000604082015260600190565b6020808252601a908201527f5472616e73616374696f6e20646f6573206e6f74206578697374000000000000604082015260600190565b60208082526018908201527f546865206f776e657220616c7265616479206578697374730000000000000000604082015260600190565b6020808252818101527f5472616e73616374696f6e2077617320616c7265616479206578656375746564604082015260600190565b9081526020019056fea26469706673582212208e92b4f9d48fc5437b15ca73ef2f130bce58b998b5d726836438d13f68b237e464736f6c63430007060033",
+ "devdoc": {
+ "author": "Stefan George - ",
+ "kind": "dev",
+ "methods": {
+ "addOwner(address)": {
+ "details": "Allows to add a new owner. Transaction has to be sent by wallet.",
+ "params": {
+ "owner": "Address of new owner."
+ }
+ },
+ "changeRequirement(uint256)": {
+ "details": "Allows to change the number of required confirmations. Transaction has to be sent by wallet.",
+ "params": {
+ "_required": "Number of required confirmations."
+ }
+ },
+ "confirmTransaction(uint256)": {
+ "details": "Allows an owner to confirm a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "constructor": {
+ "details": "Contract constructor sets initial owners and required number of confirmations.",
+ "params": {
+ "_owners": "List of initial owners.",
+ "_required": "Number of required confirmations."
+ }
+ },
+ "executeTransaction(uint256)": {
+ "details": "Allows anyone to execute a confirmed transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "getConfirmationCount(uint256)": {
+ "details": "Returns number of confirmations of a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "count": "Number of confirmations."
+ }
+ },
+ "getConfirmations(uint256)": {
+ "details": "Returns array with owner addresses, which confirmed transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "_confirmations": "Returns array of owner addresses."
+ }
+ },
+ "getOwners()": {
+ "details": "Returns list of owners.",
+ "returns": {
+ "_0": "List of owner addresses."
+ }
+ },
+ "getTransactionCount(bool,bool)": {
+ "details": "Returns total number of transactions after filers are applied.",
+ "params": {
+ "executed": "Include executed transactions.",
+ "pending": "Include pending transactions."
+ },
+ "returns": {
+ "count": "Total number of transactions after filters are applied."
+ }
+ },
+ "getTransactionIds(uint256,uint256,bool,bool)": {
+ "details": "Returns list of transaction IDs in defined range.",
+ "params": {
+ "executed": "Include executed transactions.",
+ "from": "Index start position of transaction array.",
+ "pending": "Include pending transactions.",
+ "to": "Index end position of transaction array."
+ },
+ "returns": {
+ "_transactionIds": "Returns array of transaction IDs."
+ }
+ },
+ "isConfirmed(uint256)": {
+ "details": "Returns the confirmation status of a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "_0": "Confirmation status."
+ }
+ },
+ "removeOwner(address)": {
+ "details": "Allows to remove an owner. Transaction has to be sent by wallet.",
+ "params": {
+ "owner": "Address of owner."
+ }
+ },
+ "replaceOwner(address,address)": {
+ "details": "Allows to replace an owner with a new owner. Transaction has to be sent by wallet.",
+ "params": {
+ "newOwner": "Address of new owner.",
+ "owner": "Address of owner to be replaced."
+ }
+ },
+ "revokeConfirmation(uint256)": {
+ "details": "Allows an owner to revoke a confirmation for a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "submitTransaction(address,uint256,bytes)": {
+ "details": "Allows an owner to submit and confirm a transaction.",
+ "params": {
+ "data": "Transaction data payload.",
+ "destination": "Transaction target address.",
+ "value": "Transaction ether value."
+ },
+ "returns": {
+ "transactionId": "Returns transaction ID."
+ }
+ }
+ },
+ "title": "Multisignature wallet - Allows multiple parties to agree on transactions before execution.",
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 52,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "transactions",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_uint256,t_struct(Transaction)78_storage)"
+ },
+ {
+ "astId": 58,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "confirmations",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_mapping(t_uint256,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 62,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "isOwner",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 65,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "owners",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 67,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "required",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 69,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "transactionCount",
+ "offset": 0,
+ "slot": "5",
+ "type": "t_uint256"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes_storage": {
+ "encoding": "bytes",
+ "label": "bytes",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_uint256,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_mapping(t_uint256,t_struct(Transaction)78_storage)": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => struct MultiSigWallet.Transaction)",
+ "numberOfBytes": "32",
+ "value": "t_struct(Transaction)78_storage"
+ },
+ "t_struct(Transaction)78_storage": {
+ "encoding": "inplace",
+ "label": "struct MultiSigWallet.Transaction",
+ "members": [
+ {
+ "astId": 71,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "destination",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ },
+ {
+ "astId": 73,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "value",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 75,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "data",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_bytes_storage"
+ },
+ {
+ "astId": 77,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "executed",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_bool"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/NFTBridge.json b/bridge/deployments/rinkeby/NFTBridge.json
new file mode 100644
index 000000000..fef13f806
--- /dev/null
+++ b/bridge/deployments/rinkeby/NFTBridge.json
@@ -0,0 +1,1419 @@
+{
+ "address": "0xebD27fD00Eb737D91c1a66B750a45361D234Eb74",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_tokenId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ }
+ ],
+ "name": "AcceptedNFTCrossTransfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "AllowTokensChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_tokenId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_receiver",
+ "type": "address"
+ }
+ ],
+ "name": "ClaimedNFTToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_tokenCreator",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "_userData",
+ "type": "bytes"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_totalSupply",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_tokenId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_tokenURI",
+ "type": "string"
+ }
+ ],
+ "name": "Cross",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "FederationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "FixedFeeNFTChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_newSideNFTTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_newSymbol",
+ "type": "string"
+ }
+ ],
+ "name": "NewSideNFTToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Paused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newSideNFTTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "SideTokenFactoryChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Unpaused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "Upgrading",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Pausable_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__PauserRol_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_tokenId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "acceptTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "addPauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "allowTokens",
+ "outputs": [
+ {
+ "internalType": "contract IAllowTokens",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "changeAllowTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "changeFederation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newSideNFTTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "changeSideTokenFactory",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct INFTBridge.NFTClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claim",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct INFTBridge.NFTClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claimFallback",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenName",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_baseURI",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_contractURI",
+ "type": "string"
+ }
+ ],
+ "name": "createSideNFTToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFederation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFixedFee",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getTokenCreator",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_tokenId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "getTransactionDataHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasBeenClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasCrossed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_federation",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_allowTokens",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_sideTokenFactory",
+ "type": "address"
+ },
+ {
+ "internalType": "string",
+ "name": "_symbolPrefix",
+ "type": "string"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isAddressFromCrossedOriginalToken",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isPauser",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isUpgrading",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "onERC721Received",
+ "outputs": [
+ {
+ "internalType": "bytes4",
+ "name": "",
+ "type": "bytes4"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "originalTokenAddressBySideTokenAddress",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "pause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "paused",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "receiveTokensTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renouncePauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "setFixedFee",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "setUpgrading",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "sideTokenAddressByOriginalTokenAddress",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "sideTokenFactory",
+ "outputs": [
+ {
+ "internalType": "contract ISideNFTTokenFactory",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbolPrefix",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionDataHashes",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unpause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xfa20c7187d9322927281b4bd46784e56890f4d6e0efd72ee45b4277b4a0d8f29",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0xebD27fD00Eb737D91c1a66B750a45361D234Eb74",
+ "transactionIndex": 0,
+ "gasUsed": "2682548",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xf2770da5cbbcc0472ec4a5684515e2bf16eb69c63862b0db2442bc15eb895c44",
+ "transactionHash": "0xfa20c7187d9322927281b4bd46784e56890f4d6e0efd72ee45b4277b4a0d8f29",
+ "logs": [],
+ "blockNumber": 9269455,
+ "cumulativeGasUsed": "2682548",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"}],\"name\":\"AcceptedNFTCrossTransfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newAllowTokens\",\"type\":\"address\"}],\"name\":\"AllowTokensChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"ClaimedNFTToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_tokenCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_userData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_totalSupply\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_tokenURI\",\"type\":\"string\"}],\"name\":\"Cross\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newFederation\",\"type\":\"address\"}],\"name\":\"FederationChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"FixedFeeNFTChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newSideNFTTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_newSymbol\",\"type\":\"string\"}],\"name\":\"NewSideNFTToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newSideNFTTokenFactory\",\"type\":\"address\"}],\"name\":\"SideTokenFactoryChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"Upgrading\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__Pausable_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__PauserRol_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"}],\"name\":\"acceptTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"addPauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allowTokens\",\"outputs\":[{\"internalType\":\"contract IAllowTokens\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAllowTokens\",\"type\":\"address\"}],\"name\":\"changeAllowTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"newFederation\",\"type\":\"address\"}],\"name\":\"changeFederation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newSideNFTTokenFactory\",\"type\":\"address\"}],\"name\":\"changeSideTokenFactory\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct INFTBridge.NFTClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct INFTBridge.NFTClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claimFallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"claimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_originalTokenSymbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_originalTokenName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_baseURI\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_contractURI\",\"type\":\"string\"}],\"name\":\"createSideNFTToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFederation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFixedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getTokenCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"}],\"name\":\"getTransactionDataHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasBeenClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasCrossed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_federation\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_allowTokens\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_sideTokenFactory\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbolPrefix\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isAddressFromCrossedOriginalToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isPauser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUpgrading\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"originalTokenAddressBySideTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"receiveTokensTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renouncePauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"setFixedFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"setUpgrading\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"sideTokenAddressByOriginalTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sideTokenFactory\",\"outputs\":[{\"internalType\":\"contract ISideNFTTokenFactory\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbolPrefix\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transactionDataHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"__Pausable_init(address)\":{\"details\":\"Initializes the contract in unpaused state. Assigns the Pauser role to the deployer.\"},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pause()\":{\"details\":\"Called by a pauser to pause, triggers stopped state.\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"unpause()\":{\"details\":\"Called by a pauser to unpause, returns to normal state.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"claim((address,address,uint256,address,bytes32,bytes32,uint32))\":{\"notice\":\"Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Always returns `IERC721Receiver.onERC721Received.selector`.\"},\"receiveTokensTo(address,address,uint256)\":{\"notice\":\"ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/nftbridge/NFTBridge.sol\":\"NFTBridge\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interface/IAllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IAllowTokens {\\r\\n\\r\\n struct Limits {\\r\\n uint256 min;\\r\\n uint256 max;\\r\\n uint256 daily;\\r\\n uint256 mediumAmount;\\r\\n uint256 largeAmount;\\r\\n }\\r\\n\\r\\n struct TokenInfo {\\r\\n bool allowed;\\r\\n uint256 typeId;\\r\\n uint256 spentToday;\\r\\n uint256 lastDay;\\r\\n }\\r\\n\\r\\n struct TypeInfo {\\r\\n string description;\\r\\n Limits limits;\\r\\n }\\r\\n\\r\\n struct TokensAndType {\\r\\n address token;\\r\\n uint256 typeId;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\\r\\n\\r\\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\\r\\n\\r\\n function getTypesLimits() external view returns(Limits[] memory limits);\\r\\n\\r\\n function getTypeDescriptionsLength() external view returns(uint256);\\r\\n\\r\\n function getTypeDescriptions() external view returns(string[] memory descriptions);\\r\\n\\r\\n function setToken(address token, uint256 typeId) external;\\r\\n\\r\\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\\r\\n\\r\\n function isTokenAllowed(address token) external view returns (bool);\\r\\n\\r\\n function updateTokenTransfer(address token, uint256 amount) external;\\r\\n}\",\"keccak256\":\"0xe565b0887688d1625e70316993d66adecc65890012d190a6e450ea7cb7d981b1\",\"license\":\"MIT\"},\"contracts/interface/IWrapped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IWrapped {\\r\\n function balanceOf(address) external returns(uint);\\r\\n\\r\\n function deposit() external payable;\\r\\n\\r\\n function withdraw(uint wad) external;\\r\\n\\r\\n function totalSupply() external view returns (uint);\\r\\n\\r\\n function approve(address guy, uint wad) external returns (bool);\\r\\n\\r\\n function transfer(address dst, uint wad) external returns (bool);\\r\\n\\r\\n function transferFrom(address src, address dst, uint wad)\\r\\n external\\r\\n returns (bool);\\r\\n}\",\"keccak256\":\"0xb79b74797d9b4102d4ba69d452ed04bae742e34240c3aa72f654de525b29a5c7\",\"license\":\"MIT\"},\"contracts/lib/LibEIP712.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\\r\\nlibrary LibEIP712 {\\r\\n\\r\\n // Hash of the EIP712 Domain Separator Schema\\r\\n // keccak256(abi.encodePacked(\\r\\n // \\\"EIP712Domain(\\\",\\r\\n // \\\"string name,\\\",\\r\\n // \\\"string version,\\\",\\r\\n // \\\"uint256 chainId,\\\",\\r\\n // \\\"address verifyingContract\\\",\\r\\n // \\\")\\\"\\r\\n // ))\\r\\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\\r\\n\\r\\n /// @dev Calculates a EIP712 domain separator.\\r\\n /// @param name The EIP712 domain name.\\r\\n /// @param version The EIP712 domain version.\\r\\n /// @param verifyingContract The EIP712 verifying contract.\\r\\n /// @return result EIP712 domain separator.\\r\\n function hashEIP712Domain(\\r\\n string memory name,\\r\\n string memory version,\\r\\n uint256 chainId,\\r\\n address verifyingContract\\r\\n )\\r\\n internal\\r\\n pure\\r\\n returns (bytes32 result)\\r\\n {\\r\\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\\r\\n\\r\\n // Assembly for more efficient computing:\\r\\n // keccak256(abi.encodePacked(\\r\\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\\r\\n // keccak256(bytes(name)),\\r\\n // keccak256(bytes(version)),\\r\\n // chainId,\\r\\n // uint256(verifyingContract)\\r\\n // ))\\r\\n\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n // Calculate hashes of dynamic data\\r\\n let nameHash := keccak256(add(name, 32), mload(name))\\r\\n let versionHash := keccak256(add(version, 32), mload(version))\\r\\n\\r\\n // Load free memory pointer\\r\\n let memPtr := mload(64)\\r\\n\\r\\n // Store params in memory\\r\\n mstore(memPtr, schemaHash)\\r\\n mstore(add(memPtr, 32), nameHash)\\r\\n mstore(add(memPtr, 64), versionHash)\\r\\n mstore(add(memPtr, 96), chainId)\\r\\n mstore(add(memPtr, 128), verifyingContract)\\r\\n\\r\\n // Compute hash\\r\\n result := keccak256(memPtr, 160)\\r\\n }\\r\\n return result;\\r\\n }\\r\\n\\r\\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\\r\\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\\r\\n /// with getDomainHash().\\r\\n /// @param hashStruct The EIP712 hash struct.\\r\\n /// @return result EIP712 hash applied to the given EIP712 Domain.\\r\\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\\r\\n internal\\r\\n pure\\r\\n returns (bytes32 result)\\r\\n {\\r\\n // Assembly for more efficient computing:\\r\\n // keccak256(abi.encodePacked(\\r\\n // EIP191_HEADER,\\r\\n // EIP712_DOMAIN_HASH,\\r\\n // hashStruct\\r\\n // ));\\r\\n\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n // Load free memory pointer\\r\\n let memPtr := mload(64)\\r\\n\\r\\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\\r\\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\\r\\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\\r\\n\\r\\n // Compute hash\\r\\n result := keccak256(memPtr, 66)\\r\\n }\\r\\n return result;\\r\\n }\\r\\n}\",\"keccak256\":\"0xfcfcf60905df9a2644e372c9e76b8cc7a5034c5c4d6d9f44b1ffb56244551237\",\"license\":\"MIT\"},\"contracts/lib/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nlibrary LibUtils {\\r\\n\\r\\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\\r\\n require(decimals <= 18, \\\"LibUtils: Decimals not <= 18\\\");\\r\\n return uint256(10)**(18-decimals);\\r\\n }\\r\\n\\r\\n function getDecimals(address tokenToUse) internal view returns (uint8) {\\r\\n //support decimals as uint256 or uint8\\r\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"decimals()\\\"));\\r\\n require(success, \\\"LibUtils: No decimals\\\");\\r\\n // uint: enc(X) is the big-endian encoding of X,\\r\\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\\r\\n return uint8(abi.decode(data, (uint256)));\\r\\n }\\r\\n\\r\\n function getGranularity(address tokenToUse) internal view returns (uint256) {\\r\\n //support granularity if ERC777\\r\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"granularity()\\\"));\\r\\n require(success, \\\"LibUtils: No granularity\\\");\\r\\n\\r\\n return abi.decode(data, (uint256));\\r\\n }\\r\\n\\r\\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n addr := mload(add(bys,20))\\r\\n }\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0x9e289497bfdbde6ef762efab3d91e581cc83116929b69851e64da33a8d790196\",\"license\":\"MIT\"},\"contracts/nftbridge/INFTBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface INFTBridge {\\r\\n struct NFTClaimData {\\r\\n address payable to;\\r\\n address from;\\r\\n uint256 tokenId;\\r\\n address tokenAddress;\\r\\n bytes32 blockHash;\\r\\n bytes32 transactionHash;\\r\\n uint32 logIndex;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getFixedFee() external view returns (uint256);\\r\\n\\r\\n function receiveTokensTo(\\r\\n address tokenAddress,\\r\\n address to,\\r\\n uint256 tokenId\\r\\n ) external payable;\\r\\n\\r\\n /**\\r\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\r\\n */\\r\\n function acceptTransfer(\\r\\n address _originalTokenAddress,\\r\\n address payable _from,\\r\\n address payable _to,\\r\\n uint256 _tokenId,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\\r\\n */\\r\\n function claim(NFTClaimData calldata _claimData) external;\\r\\n\\r\\n function claimFallback(NFTClaimData calldata _claimData) external;\\r\\n\\r\\n function getTransactionDataHash(\\r\\n address _to,\\r\\n address _from,\\r\\n uint256 _tokenId,\\r\\n address _tokenAddress,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external returns (bytes32);\\r\\n\\r\\n event Cross(\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _from,\\r\\n address indexed _to,\\r\\n address _tokenCreator,\\r\\n bytes _userData,\\r\\n uint256 _totalSupply,\\r\\n uint256 _tokenId,\\r\\n string _tokenURI\\r\\n );\\r\\n event NewSideNFTToken(\\r\\n address indexed _newSideNFTTokenAddress,\\r\\n address indexed _originalTokenAddress,\\r\\n string _newSymbol\\r\\n );\\r\\n event AcceptedNFTCrossTransfer(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _from,\\r\\n uint256 _tokenId,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex\\r\\n );\\r\\n event FixedFeeNFTChanged(uint256 _amount);\\r\\n event ClaimedNFTToken(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _sender,\\r\\n uint256 _tokenId,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex,\\r\\n address _receiver\\r\\n );\\r\\n}\\r\\n\",\"keccak256\":\"0x2ae628c2bf573e402f83c817bb3bcf80a9f38aa82e328141f4cd9da1deadc88d\",\"license\":\"MIT\"},\"contracts/nftbridge/ISideNFTToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideNFTToken {\\r\\n function mint(address account, uint256 tokenId) external;\\r\\n}\",\"keccak256\":\"0xcedb55e825518cb74679fa8a249cc36f5621d3787075cfaf483729e44cd605d3\",\"license\":\"MIT\"},\"contracts/nftbridge/ISideNFTTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideNFTTokenFactory {\\r\\n\\r\\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\\r\\n string calldata contractURI) external returns(address);\\r\\n\\r\\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\\r\\n}\",\"keccak256\":\"0x94993f1c48d9cc1e806d04fc5468566c5314f992705729024c4f9bcdd1eeb99f\",\"license\":\"MIT\"},\"contracts/nftbridge/NFTBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n// Import base Initializable contract\\r\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\r\\n// Import interface and library from OpenZeppelin contracts\\r\\nimport \\\"../zeppelin/upgradable/utils/ReentrancyGuard.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\r\\n\\r\\nimport \\\"../zeppelin/introspection/IERC1820Registry.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC20/IERC20.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC20/SafeERC20.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC721/IERC721.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC721/IERC721Metadata.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC721/IERC721Enumerable.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC721/IERC721Receiver.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC721/ERC721Burnable.sol\\\";\\r\\nimport \\\"../zeppelin/utils/Address.sol\\\";\\r\\nimport \\\"../zeppelin/math/SafeMath.sol\\\";\\r\\n\\r\\nimport \\\"../lib/LibEIP712.sol\\\";\\r\\nimport \\\"../lib/LibUtils.sol\\\";\\r\\n\\r\\nimport \\\"./INFTBridge.sol\\\";\\r\\nimport \\\"./ISideNFTToken.sol\\\";\\r\\nimport \\\"./ISideNFTTokenFactory.sol\\\";\\r\\nimport \\\"../interface/IAllowTokens.sol\\\";\\r\\nimport \\\"../interface/IWrapped.sol\\\";\\r\\n\\r\\n// solhint-disable-next-line max-states-count\\r\\ncontract NFTBridge is\\r\\n Initializable,\\r\\n INFTBridge,\\r\\n UpgradablePausable,\\r\\n UpgradableOwnable,\\r\\n ReentrancyGuard,\\r\\n IERC721Receiver {\\r\\n using SafeMath for uint256;\\r\\n using SafeERC20 for IERC20;\\r\\n using Address for address;\\r\\n\\r\\n address internal constant NULL_ADDRESS = address(0);\\r\\n bytes32 internal constant NULL_HASH = bytes32(0);\\r\\n IERC1820Registry internal constant ERC1820 =\\r\\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\r\\n\\r\\n address payable internal federation;\\r\\n uint256 internal fixedFee;\\r\\n string public symbolPrefix;\\r\\n\\r\\n mapping(address => address) public sideTokenAddressByOriginalTokenAddress;\\r\\n mapping(address => address) public originalTokenAddressBySideTokenAddress;\\r\\n mapping(address => bool) public isAddressFromCrossedOriginalToken; // address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\\r\\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\\r\\n IAllowTokens public allowTokens;\\r\\n ISideNFTTokenFactory public sideTokenFactory;\\r\\n bool public isUpgrading;\\r\\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\\r\\n\\r\\n event AllowTokensChanged(address _newAllowTokens);\\r\\n event FederationChanged(address _newFederation);\\r\\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\\r\\n event Upgrading(bool _isUpgrading);\\r\\n\\r\\n function initialize(\\r\\n address _manager,\\r\\n address payable _federation,\\r\\n address _allowTokens,\\r\\n address _sideTokenFactory,\\r\\n string memory _symbolPrefix\\r\\n ) public initializer {\\r\\n UpgradableOwnable.initialize(_manager);\\r\\n UpgradablePausable.__Pausable_init(_manager);\\r\\n symbolPrefix = _symbolPrefix;\\r\\n allowTokens = IAllowTokens(_allowTokens);\\r\\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\\r\\n federation = _federation;\\r\\n ERC1820.setInterfaceImplementer(\\r\\n address(this),\\r\\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\\r\\n address(this)\\r\\n );\\r\\n }\\r\\n\\r\\n function version() external pure override returns (string memory) {\\r\\n return \\\"v1\\\";\\r\\n }\\r\\n\\r\\n modifier whenNotUpgrading() {\\r\\n require(!isUpgrading, \\\"Bridge: Upgrading\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function acceptTransfer(\\r\\n address _tokenAddress,\\r\\n address payable _from,\\r\\n address payable _to,\\r\\n uint256 _tokenId,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external whenNotPaused nonReentrant override {\\r\\n require(_msgSender() == federation, \\\"NFTBridge: Not Federation\\\");\\r\\n require(\\r\\n isAddressFromCrossedOriginalToken[_tokenAddress] ||\\r\\n sideTokenAddressByOriginalTokenAddress[_tokenAddress] != NULL_ADDRESS,\\r\\n \\\"NFTBridge: Unknown token\\\"\\r\\n );\\r\\n require(_to != NULL_ADDRESS, \\\"NFTBridge: Null To\\\");\\r\\n require(_from != NULL_ADDRESS, \\\"NFTBridge: Null From\\\");\\r\\n require(_blockHash != NULL_HASH, \\\"NFTBridge: Null BlockHash\\\");\\r\\n require(_transactionHash != NULL_HASH, \\\"NFTBridge: Null TxHash\\\");\\r\\n require(\\r\\n transactionDataHashes[_transactionHash] == bytes32(0),\\r\\n \\\"NFTBridge: Already accepted\\\"\\r\\n );\\r\\n\\r\\n bytes32 _transactionDataHash = getTransactionDataHash(\\r\\n _to,\\r\\n _from,\\r\\n _tokenId,\\r\\n _tokenAddress,\\r\\n _blockHash,\\r\\n _transactionHash,\\r\\n _logIndex\\r\\n );\\r\\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\\r\\n require(!claimed[_transactionDataHash], \\\"NFTBridge: Already claimed\\\");\\r\\n\\r\\n transactionDataHashes[_transactionHash] = _transactionDataHash;\\r\\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\\r\\n// senderAddresses[_transactionHash] = _from;\\r\\n\\r\\n emit AcceptedNFTCrossTransfer(\\r\\n _transactionHash,\\r\\n _tokenAddress,\\r\\n _to,\\r\\n _from,\\r\\n _tokenId,\\r\\n _blockHash,\\r\\n _logIndex\\r\\n );\\r\\n }\\r\\n\\r\\n function createSideNFTToken(\\r\\n address _originalTokenAddress,\\r\\n string calldata _originalTokenSymbol,\\r\\n string calldata _originalTokenName,\\r\\n string calldata _baseURI,\\r\\n string calldata _contractURI\\r\\n ) external onlyOwner {\\r\\n require(_originalTokenAddress != NULL_ADDRESS, \\\"NFTBridge: Null original token address\\\");\\r\\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[_originalTokenAddress];\\r\\n require(sideTokenAddress == NULL_ADDRESS, \\\"NFTBridge: Side token already exists\\\");\\r\\n string memory sideTokenSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\\r\\n\\r\\n // Create side token\\r\\n sideTokenAddress = sideTokenFactory.createSideNFTToken(_originalTokenName, sideTokenSymbol, _baseURI, _contractURI);\\r\\n\\r\\n sideTokenAddressByOriginalTokenAddress[_originalTokenAddress] = sideTokenAddress;\\r\\n originalTokenAddressBySideTokenAddress[sideTokenAddress] = _originalTokenAddress;\\r\\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, sideTokenSymbol);\\r\\n }\\r\\n\\r\\n function claim(NFTClaimData calldata _claimData) external override {\\r\\n _claim(_claimData, _claimData.to);\\r\\n }\\r\\n\\r\\n function claimFallback(NFTClaimData calldata _claimData) external override {\\r\\n require(_msgSender() == _claimData.from, \\\"NFTBridge: invalid sender\\\");\\r\\n _claim(_claimData, _msgSender());\\r\\n }\\r\\n\\r\\n function _claim(\\r\\n NFTClaimData calldata _claimData,\\r\\n address payable _receiver\\r\\n ) internal {\\r\\n address tokenAddress = _claimData.tokenAddress;\\r\\n uint256 tokenId = _claimData.tokenId;\\r\\n\\r\\n bytes32 transactionDataHash = getTransactionDataHash(\\r\\n _claimData.to,\\r\\n _claimData.from,\\r\\n tokenId,\\r\\n tokenAddress,\\r\\n _claimData.blockHash,\\r\\n _claimData.transactionHash,\\r\\n _claimData.logIndex\\r\\n );\\r\\n require(\\r\\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\\r\\n \\\"NFTBridge: Wrong txDataHash\\\"\\r\\n );\\r\\n require(!claimed[transactionDataHash], \\\"NFTBridge: Already claimed\\\");\\r\\n\\r\\n claimed[transactionDataHash] = true;\\r\\n bool isClaimBeingRequestedInMainChain = isAddressFromCrossedOriginalToken[tokenAddress];\\r\\n if (isClaimBeingRequestedInMainChain) {\\r\\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\\r\\n } else {\\r\\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[tokenAddress];\\r\\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\\r\\n }\\r\\n\\r\\n emit ClaimedNFTToken(\\r\\n _claimData.transactionHash,\\r\\n tokenAddress,\\r\\n _claimData.to,\\r\\n _claimData.from,\\r\\n _claimData.tokenId,\\r\\n _claimData.blockHash,\\r\\n _claimData.logIndex,\\r\\n _receiver\\r\\n );\\r\\n }\\r\\n\\r\\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\\r\\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\\\"creator()\\\"));\\r\\n if (success) {\\r\\n return abi.decode(data, (address));\\r\\n }\\r\\n\\r\\n return IERC721(tokenAddress).ownerOf(tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * ERC-20 tokens approve and transferFrom pattern\\r\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\r\\n */\\r\\n function receiveTokensTo(\\r\\n address tokenAddress,\\r\\n address to,\\r\\n uint256 tokenId\\r\\n ) public payable override {\\r\\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\\r\\n\\r\\n address payable sender = _msgSender();\\r\\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\\r\\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\\r\\n\\r\\n crossTokens(tokenAddress, to, tokenCreator, \\\"\\\", tokenId);\\r\\n\\r\\n if (fixedFee > 0) {\\r\\n require(msg.value >= fixedFee, \\\"NFTBridge: value is smaller than fixed fee\\\");\\r\\n\\r\\n // Send the payment to the MultiSig of the Federation\\r\\n federation.transfer(fixedFee);\\r\\n if (msg.value > fixedFee) { // refund of unused value\\r\\n sender.transfer(msg.value.sub(fixedFee));\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n function crossTokens(\\r\\n address tokenAddress,\\r\\n address to,\\r\\n address tokenCreator,\\r\\n bytes memory userData,\\r\\n uint256 tokenId\\r\\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\\r\\n isAddressFromCrossedOriginalToken[tokenAddress] = true;\\r\\n\\r\\n IERC721Enumerable enumerable = IERC721Enumerable(tokenAddress);\\r\\n IERC721Metadata metadataIERC = IERC721Metadata(tokenAddress);\\r\\n string memory tokenURI = metadataIERC.tokenURI(tokenId);\\r\\n\\r\\n address originalTokenAddress = tokenAddress;\\r\\n if (originalTokenAddressBySideTokenAddress[tokenAddress] != NULL_ADDRESS) {\\r\\n originalTokenAddress = originalTokenAddressBySideTokenAddress[tokenAddress];\\r\\n ERC721Burnable(tokenAddress).burn(tokenId);\\r\\n }\\r\\n\\r\\n emit Cross(\\r\\n originalTokenAddress,\\r\\n _msgSender(),\\r\\n to,\\r\\n tokenCreator,\\r\\n userData,\\r\\n enumerable.totalSupply(),\\r\\n tokenId,\\r\\n tokenURI\\r\\n );\\r\\n }\\r\\n\\r\\n function getTransactionDataHash(\\r\\n address _to,\\r\\n address _from,\\r\\n uint256 _tokenId,\\r\\n address _tokenAddress,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) public pure override returns (bytes32) {\\r\\n return keccak256(\\r\\n abi.encodePacked(\\r\\n _blockHash,\\r\\n _transactionHash,\\r\\n _to,\\r\\n _from,\\r\\n _tokenId,\\r\\n _tokenAddress,\\r\\n _logIndex\\r\\n )\\r\\n );\\r\\n }\\r\\n\\r\\n function setFixedFee(uint256 amount) external onlyOwner {\\r\\n fixedFee = amount;\\r\\n emit FixedFeeNFTChanged(fixedFee);\\r\\n }\\r\\n\\r\\n function getFixedFee() external view override returns (uint256) {\\r\\n return fixedFee;\\r\\n }\\r\\n\\r\\n function changeFederation(address payable newFederation) external onlyOwner {\\r\\n require(newFederation != NULL_ADDRESS, \\\"NFTBridge: Federation is empty\\\");\\r\\n federation = newFederation;\\r\\n emit FederationChanged(federation);\\r\\n }\\r\\n\\r\\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\\r\\n require(newAllowTokens != NULL_ADDRESS, \\\"NFTBridge: AllowTokens is empty\\\");\\r\\n allowTokens = IAllowTokens(newAllowTokens);\\r\\n emit AllowTokensChanged(newAllowTokens);\\r\\n }\\r\\n\\r\\n function getFederation() external view returns (address) {\\r\\n return federation;\\r\\n }\\r\\n\\r\\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\\r\\n require(\\r\\n newSideNFTTokenFactory != NULL_ADDRESS,\\r\\n \\\"NFTBridge: empty SideTokenFactory\\\"\\r\\n );\\r\\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\\r\\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\\r\\n }\\r\\n\\r\\n function setUpgrading(bool _isUpgrading) external onlyOwner {\\r\\n isUpgrading = _isUpgrading;\\r\\n emit Upgrading(isUpgrading);\\r\\n }\\r\\n\\r\\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\\r\\n return transactionDataHashes[transactionHash] != bytes32(0);\\r\\n }\\r\\n\\r\\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\\r\\n return claimed[transactionDataHashes[transactionHash]];\\r\\n }\\r\\n\\r\\n /**\\r\\n * Always returns `IERC721Receiver.onERC721Received.selector`.\\r\\n */\\r\\n function onERC721Received(\\r\\n address,\\r\\n address,\\r\\n uint256,\\r\\n bytes memory\\r\\n ) public virtual override returns (bytes4) {\\r\\n return this.onERC721Received.selector;\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0x1d5e192990a4660c02e48e52be750cbca20966baa95cb036f0d6c7512da0eacf\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/access/Roles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @title Roles\\r\\n * @dev Library for managing addresses assigned to a Role.\\r\\n */\\r\\nlibrary Roles {\\r\\n struct Role {\\r\\n mapping (address => bool) bearer;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Give an account access to this role.\\r\\n */\\r\\n function add(Role storage role, address account) internal {\\r\\n require(!has(role, account), \\\"Roles: account already has role\\\");\\r\\n role.bearer[account] = true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Remove an account's access to this role.\\r\\n */\\r\\n function remove(Role storage role, address account) internal {\\r\\n require(has(role, account), \\\"Roles: account doesn't have role\\\");\\r\\n role.bearer[account] = false;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Check if an account has this role.\\r\\n * @return bool\\r\\n */\\r\\n function has(Role storage role, address account) internal view returns (bool) {\\r\\n require(account != address(0), \\\"Roles: account is the zero address\\\");\\r\\n return role.bearer[account];\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x51be0ac4cc78172ee6ee886a4779e6b8f289420541d28be81f3c427c5118c298\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC165.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Implementation of the {IERC165} interface.\\r\\n *\\r\\n * Contracts may inherit from this and call {_registerInterface} to declare\\r\\n * their support of an interface.\\r\\n */\\r\\nabstract contract ERC165 is IERC165 {\\r\\n /*\\r\\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\\r\\n\\r\\n /**\\r\\n * @dev Mapping of interface ids to whether or not it's supported.\\r\\n */\\r\\n mapping(bytes4 => bool) private _supportedInterfaces;\\r\\n\\r\\n constructor () {\\r\\n // Derived contracts need only register support for their own interfaces,\\r\\n // we register support for ERC165 itself here\\r\\n _registerInterface(_INTERFACE_ID_ERC165);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC165-supportsInterface}.\\r\\n *\\r\\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\\r\\n */\\r\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\r\\n return _supportedInterfaces[interfaceId];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Registers the contract as an implementer of the interface defined by\\r\\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\\r\\n * registering its interface id is not required.\\r\\n *\\r\\n * See {IERC165-supportsInterface}.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\\r\\n */\\r\\n function _registerInterface(bytes4 interfaceId) internal virtual {\\r\\n require(interfaceId != 0xffffffff, \\\"ERC165: invalid interface id\\\");\\r\\n _supportedInterfaces[interfaceId] = true;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x5415f8c63658ee08e6284e6f270b2490331aea0c375b6451c4c9ed14a805a336\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC165 standard, as defined in the\\r\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\r\\n *\\r\\n * Implementers can declare support of contract interfaces, which can then be\\r\\n * queried by others ({ERC165Checker}).\\r\\n *\\r\\n * For an implementation, see {ERC165}.\\r\\n */\\r\\ninterface IERC165 {\\r\\n /**\\r\\n * @dev Returns true if this contract implements the interface defined by\\r\\n * `interfaceId`. See the corresponding\\r\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\r\\n * to learn more about how these ids are created.\\r\\n *\\r\\n * This function call must use less than 30 000 gas.\\r\\n */\\r\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\r\\n}\\r\\n\",\"keccak256\":\"0xd5da4ccf6a22475f021130a32aaad92daf6eecce9258cb7a8a5c48d109607767\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC1820Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\r\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\r\\n * implementers for interfaces in this registry, as well as query support.\\r\\n *\\r\\n * Implementers may be shared by multiple accounts, and can also implement more\\r\\n * than a single interface for each account. Contracts can implement interfaces\\r\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\r\\n * contract.\\r\\n *\\r\\n * {IERC165} interfaces can also be queried via the registry.\\r\\n *\\r\\n * For an in-depth explanation and source code analysis, see the EIP text.\\r\\n */\\r\\ninterface IERC1820Registry {\\r\\n /**\\r\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\r\\n * account is able to set interface implementers for it.\\r\\n *\\r\\n * By default, each account is its own manager. Passing a value of `0x0` in\\r\\n * `newManager` will reset the manager to this initial state.\\r\\n *\\r\\n * Emits a {ManagerChanged} event.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the caller must be the current manager for `account`.\\r\\n */\\r\\n function setManager(address account, address newManager) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the manager for `account`.\\r\\n *\\r\\n * See {setManager}.\\r\\n */\\r\\n function getManager(address account) external view returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Sets the `implementer` contract as `account`'s implementer for\\r\\n * `interfaceHash`.\\r\\n *\\r\\n * `account` being the zero address is an alias for the caller's address.\\r\\n * The zero address can also be used in `implementer` to remove an old one.\\r\\n *\\r\\n * See {interfaceHash} to learn how these are created.\\r\\n *\\r\\n * Emits an {InterfaceImplementerSet} event.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the caller must be the current manager for `_account`.\\r\\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\r\\n * end in 28 zeroes).\\r\\n * - `_implementer` must implement {IERC1820Implementer} and return true when\\r\\n * queried for support, unless `implementer` is the caller. See\\r\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\r\\n */\\r\\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\\r\\n * implementer is registered, returns the zero address.\\r\\n *\\r\\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\r\\n * zeroes), `_account` will be queried for support of it.\\r\\n *\\r\\n * `account` being the zero address is an alias for the caller's address.\\r\\n */\\r\\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\r\\n * corresponding\\r\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\r\\n */\\r\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\r\\n\\r\\n /**\\r\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\r\\n * @param account Address of the contract for which to update the cache.\\r\\n * @param interfaceId ERC165 interface for which to update the cache.\\r\\n */\\r\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\r\\n\\r\\n /**\\r\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\r\\n * If the result is not cached a direct lookup on the contract address is performed.\\r\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\r\\n * {updateERC165Cache} with the contract address.\\r\\n * @param account Address of the contract to check.\\r\\n * @param interfaceId ERC165 interface to check.\\r\\n * @return True if `account` implements `interfaceId`, false otherwise.\\r\\n */\\r\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\\r\\n * @param account Address of the contract to check.\\r\\n * @param interfaceId ERC165 interface to check.\\r\\n * @return True if `account` implements `interfaceId`, false otherwise.\\r\\n */\\r\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\r\\n\\r\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\r\\n\\r\\n event ManagerChanged(address indexed account, address indexed newManager);\\r\\n}\\r\\n\",\"keccak256\":\"0x0c607a83a8f5ec2f214bc754ffb59428d90978e122108fcd91ba193d5fc78018\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\r\\n * checks.\\r\\n *\\r\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\r\\n * in bugs, because programmers usually assume that an overflow raises an\\r\\n * error, which is the standard behavior in high level programming languages.\\r\\n * `SafeMath` restores this intuition by reverting the transaction when an\\r\\n * operation overflows.\\r\\n *\\r\\n * Using this library instead of the unchecked operations eliminates an entire\\r\\n * class of bugs, so it's recommended to use it always.\\r\\n */\\r\\nlibrary SafeMath {\\r\\n /**\\r\\n * @dev Returns the addition of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `+` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Addition cannot overflow.\\r\\n */\\r\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n uint256 c = a + b;\\r\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n */\\r\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b <= a, errorMessage);\\r\\n uint256 c = a - b;\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `*` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Multiplication cannot overflow.\\r\\n */\\r\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\r\\n // benefit is lost if 'b' is also tested.\\r\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\r\\n if (a == 0) {\\r\\n return 0;\\r\\n }\\r\\n\\r\\n uint256 c = a * b;\\r\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n // Solidity only automatically asserts when dividing by 0\\r\\n require(b > 0, errorMessage);\\r\\n uint256 c = a / b;\\r\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts with custom message when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b != 0, errorMessage);\\r\\n return a % b;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x29ffa7ff59806a3add585615cc102b70b43049587dcc73649f77b427f35b009d\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\r\\n * the optional functions; to access them see {ERC20Detailed}.\\r\\n */\\r\\ninterface IERC20 {\\r\\n /**\\r\\n * @dev Returns the amount of tokens in existence.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens owned by `account`.\\r\\n */\\r\\n function balanceOf(address account) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transfer(address recipient, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Returns the remaining number of tokens that `spender` will be\\r\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\r\\n * zero by default.\\r\\n *\\r\\n * This value changes when {approve} or {transferFrom} are called.\\r\\n */\\r\\n function allowance(address owner, address spender) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\r\\n * that someone may use both the old and the new allowance by unfortunate\\r\\n * transaction ordering. One possible solution to mitigate this race\\r\\n * condition is to first reduce the spender's allowance to 0 and set the\\r\\n * desired value afterwards:\\r\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\r\\n *\\r\\n * Emits an {Approval} event.\\r\\n */\\r\\n function approve(address spender, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\r\\n * allowance mechanism. `amount` is then deducted from the caller's\\r\\n * allowance.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\r\\n * another (`to`).\\r\\n *\\r\\n * Note that `value` may be zero.\\r\\n */\\r\\n event Transfer(address indexed from, address indexed to, uint256 value);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\r\\n * a call to {approve}. `value` is the new allowance.\\r\\n */\\r\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\r\\n}\\r\\n\",\"keccak256\":\"0x7531f90b8a5a04fd225fb07a30e0792068438a7c82127a22db870c1849460dfc\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./IERC20.sol\\\";\\r\\nimport \\\"../../math/SafeMath.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title SafeERC20\\r\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\r\\n * contract returns false). Tokens that return no value (and instead revert or\\r\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\r\\n * successful.\\r\\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\\r\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\r\\n */\\r\\nlibrary SafeERC20 {\\r\\n using SafeMath for uint256;\\r\\n using Address for address;\\r\\n\\r\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\r\\n }\\r\\n\\r\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\r\\n }\\r\\n\\r\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\r\\n // safeApprove should only be called when setting an initial allowance,\\r\\n // or when resetting it to zero. To increase and decrease it, use\\r\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\r\\n // solhint-disable-next-line max-line-length\\r\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\r\\n \\\"SafeERC20: approve non-zero to non-zero allowance\\\"\\r\\n );\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\r\\n }\\r\\n\\r\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\r\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\r\\n }\\r\\n\\r\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\r\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\r\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\r\\n * @param token The token targeted by the call.\\r\\n * @param data The call data (encoded using abi.encode or one of its variants).\\r\\n */\\r\\n function callOptionalReturn(IERC20 token, bytes memory data) private {\\r\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\r\\n // we're implementing it ourselves.\\r\\n\\r\\n // A Solidity high level call has three parts:\\r\\n // 1. The target address is checked to verify it contains contract code\\r\\n // 2. The call itself is made, and success asserted\\r\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\r\\n // solhint-disable-next-line max-line-length\\r\\n require(address(token).isContract(), \\\"SafeERC20: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = address(token).call(data);\\r\\n require(success, \\\"SafeERC20: low-level call failed\\\");\\r\\n\\r\\n if (returndata.length > 0) { // Return data is optional\\r\\n // solhint-disable-next-line max-line-length\\r\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x393fa2aef898c565ba8c8816ac0e2d0e31865d2866e4807f39f1a8cef95f5a81\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"./IERC721.sol\\\";\\r\\nimport \\\"./IERC721Metadata.sol\\\";\\r\\nimport \\\"./IERC721Enumerable.sol\\\";\\r\\nimport \\\"./IERC721Receiver.sol\\\";\\r\\nimport \\\"../../introspection/ERC165.sol\\\";\\r\\nimport \\\"../../math/SafeMath.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\nimport \\\"../../utils/EnumerableSet.sol\\\";\\r\\nimport \\\"../../utils/EnumerableMap.sol\\\";\\r\\nimport \\\"../../utils/Strings.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC721 Non-Fungible Token Standard basic implementation\\r\\n * @dev see https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\\r\\n using SafeMath for uint256;\\r\\n using Address for address;\\r\\n using EnumerableSet for EnumerableSet.UintSet;\\r\\n using EnumerableMap for EnumerableMap.UintToAddressMap;\\r\\n using Strings for uint256;\\r\\n\\r\\n // Equals to `bytes4(keccak256(\\\"onERC721Received(address,address,uint256,bytes)\\\"))`\\r\\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\\r\\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\\r\\n\\r\\n // Mapping from holder address to their (enumerable) set of owned tokens\\r\\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\\r\\n\\r\\n // Enumerable mapping from token ids to their owners\\r\\n EnumerableMap.UintToAddressMap private _tokenOwners;\\r\\n\\r\\n // Mapping from token ID to approved address\\r\\n mapping (uint256 => address) private _tokenApprovals;\\r\\n\\r\\n // Mapping from owner to operator approvals\\r\\n mapping (address => mapping (address => bool)) private _operatorApprovals;\\r\\n\\r\\n // Token name\\r\\n string private _name;\\r\\n\\r\\n // Token symbol\\r\\n string private _symbol;\\r\\n\\r\\n // Optional mapping for token URIs\\r\\n mapping (uint256 => string) private _tokenURIs;\\r\\n\\r\\n // Base URI\\r\\n string private _baseURI;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\\r\\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\\r\\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\\r\\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\\r\\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\\r\\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\\r\\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\\r\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\\r\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\\r\\n *\\r\\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\\r\\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('name()')) == 0x06fdde03\\r\\n * bytes4(keccak256('symbol()')) == 0x95d89b41\\r\\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\\r\\n *\\r\\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\\r\\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\\r\\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\\r\\n *\\r\\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\r\\n */\\r\\n constructor (string memory name_, string memory symbol_) {\\r\\n _name = name_;\\r\\n _symbol = symbol_;\\r\\n\\r\\n // register the supported interfaces to conform to ERC721 via ERC165\\r\\n _registerInterface(_INTERFACE_ID_ERC721);\\r\\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\\r\\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-balanceOf}.\\r\\n */\\r\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\r\\n require(owner != address(0), \\\"ERC721: balance query for the zero address\\\");\\r\\n return _holderTokens[owner].length();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-ownerOf}.\\r\\n */\\r\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\r\\n return _tokenOwners.get(tokenId, \\\"ERC721: owner query for nonexistent token\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-name}.\\r\\n */\\r\\n function name() public view virtual override returns (string memory) {\\r\\n return _name;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-symbol}.\\r\\n */\\r\\n function symbol() public view virtual override returns (string memory) {\\r\\n return _symbol;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-tokenURI}.\\r\\n */\\r\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\r\\n require(_exists(tokenId), \\\"ERC721Metadata: URI query for nonexistent token\\\");\\r\\n\\r\\n string memory _tokenURI = _tokenURIs[tokenId];\\r\\n string memory base = baseURI();\\r\\n\\r\\n // If there is no base URI, return the token URI.\\r\\n if (bytes(base).length == 0) {\\r\\n return _tokenURI;\\r\\n }\\r\\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\\r\\n if (bytes(_tokenURI).length > 0) {\\r\\n return string(abi.encodePacked(base, _tokenURI));\\r\\n }\\r\\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\\r\\n return string(abi.encodePacked(base, tokenId.toString()));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the base URI set via {_setBaseURI}. This will be\\r\\n * automatically added as a prefix in {tokenURI} to each token's URI, or\\r\\n * to the token ID if no specific URI is set for that token ID.\\r\\n */\\r\\n function baseURI() public view virtual returns (string memory) {\\r\\n return _baseURI;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\r\\n */\\r\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\r\\n return _holderTokens[owner].at(index);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-totalSupply}.\\r\\n */\\r\\n function totalSupply() public view virtual override returns (uint256) {\\r\\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\\r\\n return _tokenOwners.length();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\r\\n */\\r\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\r\\n (uint256 tokenId, ) = _tokenOwners.at(index);\\r\\n return tokenId;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-approve}.\\r\\n */\\r\\n function approve(address to, uint256 tokenId) public virtual override {\\r\\n address owner = ERC721.ownerOf(tokenId);\\r\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\r\\n\\r\\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\\r\\n \\\"ERC721: approve caller is not owner nor approved for all\\\"\\r\\n );\\r\\n\\r\\n _approve(to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-getApproved}.\\r\\n */\\r\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\r\\n require(_exists(tokenId), \\\"ERC721: approved query for nonexistent token\\\");\\r\\n\\r\\n return _tokenApprovals[tokenId];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-setApprovalForAll}.\\r\\n */\\r\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\r\\n require(operator != _msgSender(), \\\"ERC721: approve to caller\\\");\\r\\n\\r\\n _operatorApprovals[_msgSender()][operator] = approved;\\r\\n emit ApprovalForAll(_msgSender(), operator, approved);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-isApprovedForAll}.\\r\\n */\\r\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\r\\n return _operatorApprovals[owner][operator];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-transferFrom}.\\r\\n */\\r\\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\\r\\n //solhint-disable-next-line max-line-length\\r\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\r\\n\\r\\n _transfer(from, to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-safeTransferFrom}.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\\r\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-safeTransferFrom}.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\\r\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\r\\n _safeTransfer(from, to, tokenId, _data);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\r\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\r\\n *\\r\\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\\r\\n *\\r\\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\r\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\\r\\n _transfer(from, to, tokenId);\\r\\n require(_checkOnERC721Received(from, to, tokenId, _data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns whether `tokenId` exists.\\r\\n *\\r\\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\r\\n *\\r\\n * Tokens start existing when they are minted (`_mint`),\\r\\n * and stop existing when they are burned (`_burn`).\\r\\n */\\r\\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\\r\\n return _tokenOwners.contains(tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\r\\n require(_exists(tokenId), \\\"ERC721: operator query for nonexistent token\\\");\\r\\n address owner = ERC721.ownerOf(tokenId);\\r\\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\r\\n *\\r\\n * Requirements:\\r\\n d*\\r\\n * - `tokenId` must not exist.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\r\\n _safeMint(to, tokenId, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\r\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\r\\n */\\r\\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\\r\\n _mint(to, tokenId);\\r\\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Mints `tokenId` and transfers it to `to`.\\r\\n *\\r\\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must not exist.\\r\\n * - `to` cannot be the zero address.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _mint(address to, uint256 tokenId) internal virtual {\\r\\n require(to != address(0), \\\"ERC721: mint to the zero address\\\");\\r\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\r\\n\\r\\n _beforeTokenTransfer(address(0), to, tokenId);\\r\\n\\r\\n _holderTokens[to].add(tokenId);\\r\\n\\r\\n _tokenOwners.set(tokenId, to);\\r\\n\\r\\n emit Transfer(address(0), to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Destroys `tokenId`.\\r\\n * The approval is cleared when the token is burned.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _burn(uint256 tokenId) internal virtual {\\r\\n address owner = ERC721.ownerOf(tokenId); // internal owner\\r\\n\\r\\n _beforeTokenTransfer(owner, address(0), tokenId);\\r\\n\\r\\n // Clear approvals\\r\\n _approve(address(0), tokenId);\\r\\n\\r\\n // Clear metadata (if any)\\r\\n if (bytes(_tokenURIs[tokenId]).length != 0) {\\r\\n delete _tokenURIs[tokenId];\\r\\n }\\r\\n\\r\\n _holderTokens[owner].remove(tokenId);\\r\\n\\r\\n _tokenOwners.remove(tokenId);\\r\\n\\r\\n emit Transfer(owner, address(0), tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers `tokenId` from `from` to `to`.\\r\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must be owned by `from`.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\\r\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer of token that is not own\\\"); // internal owner\\r\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\r\\n\\r\\n _beforeTokenTransfer(from, to, tokenId);\\r\\n\\r\\n // Clear approvals from the previous owner\\r\\n _approve(address(0), tokenId);\\r\\n\\r\\n _holderTokens[from].remove(tokenId);\\r\\n _holderTokens[to].add(tokenId);\\r\\n\\r\\n _tokenOwners.set(tokenId, to);\\r\\n\\r\\n emit Transfer(from, to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\\r\\n require(_exists(tokenId), \\\"ERC721Metadata: URI set of nonexistent token\\\");\\r\\n _tokenURIs[tokenId] = _tokenURI;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Internal function to set the base URI for all token IDs. It is\\r\\n * automatically added as a prefix to the value returned in {tokenURI},\\r\\n * or to the token ID if {tokenURI} is empty.\\r\\n */\\r\\n function _setBaseURI(string memory baseURI_) internal virtual {\\r\\n _baseURI = baseURI_;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\r\\n * The call is not executed if the target address is not a contract.\\r\\n *\\r\\n * @param from address representing the previous owner of the given token ID\\r\\n * @param to target address that will receive the tokens\\r\\n * @param tokenId uint256 ID of the token to be transferred\\r\\n * @param _data bytes optional data to send along with the call\\r\\n * @return bool whether the call correctly returned the expected magic value\\r\\n */\\r\\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\\r\\n private returns (bool)\\r\\n {\\r\\n if (!to.isContract()) {\\r\\n return true;\\r\\n }\\r\\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\\r\\n IERC721Receiver(to).onERC721Received.selector,\\r\\n _msgSender(),\\r\\n from,\\r\\n tokenId,\\r\\n _data\\r\\n ), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n bytes4 retval = abi.decode(returndata, (bytes4));\\r\\n return (retval == _ERC721_RECEIVED);\\r\\n }\\r\\n\\r\\n function _approve(address to, uint256 tokenId) private {\\r\\n _tokenApprovals[tokenId] = to;\\r\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Hook that is called before any token transfer. This includes minting\\r\\n * and burning.\\r\\n *\\r\\n * Calling conditions:\\r\\n *\\r\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\r\\n * transferred to `to`.\\r\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\r\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n *\\r\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\r\\n */\\r\\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\\r\\n}\\r\\n\",\"keccak256\":\"0x4180eedc31f632ef146dd07583840a9688de44bdb9e7fe2425c448fd57496004\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"./ERC721.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC721 Burnable Token\\r\\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\\r\\n */\\r\\nabstract contract ERC721Burnable is Context, ERC721 {\\r\\n /**\\r\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - The caller must own `tokenId` or be an approved operator.\\r\\n */\\r\\n function burn(uint256 tokenId) public virtual {\\r\\n //solhint-disable-next-line max-line-length\\r\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721Burnable: caller is not owner nor approved\\\");\\r\\n _burn(tokenId);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x699ce4b0903e16b958d6a008703c24be7d11a7d3223e5e9ab9523a8f81687f13\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../../introspection/IERC165.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Required interface of an ERC721 compliant contract.\\r\\n */\\r\\ninterface IERC721 is IERC165 {\\r\\n /**\\r\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\r\\n */\\r\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\r\\n */\\r\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\r\\n */\\r\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of tokens in ``owner``'s account.\\r\\n */\\r\\n function balanceOf(address owner) external view returns (uint256 balance);\\r\\n\\r\\n /**\\r\\n * @dev Returns the owner of the `tokenId` token.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\r\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Transfers `tokenId` token from `from` to `to`.\\r\\n *\\r\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must be owned by `from`.\\r\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transferFrom(address from, address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\r\\n * The approval is cleared when the token is transferred.\\r\\n *\\r\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - The caller must own the token or be an approved operator.\\r\\n * - `tokenId` must exist.\\r\\n *\\r\\n * Emits an {Approval} event.\\r\\n */\\r\\n function approve(address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the account approved for `tokenId` token.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function getApproved(uint256 tokenId) external view returns (address operator);\\r\\n\\r\\n /**\\r\\n * @dev Approve or remove `operator` as an operator for the caller.\\r\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - The `operator` cannot be the caller.\\r\\n *\\r\\n * Emits an {ApprovalForAll} event.\\r\\n */\\r\\n function setApprovalForAll(address operator, bool _approved) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\r\\n *\\r\\n * See {setApprovalForAll}\\r\\n */\\r\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\r\\n}\\r\\n\",\"keccak256\":\"0xd3c22060e78ce52f5cb41b3ab9b29bb5582aa4a58015e878116251cba658324c\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC721.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\r\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ninterface IERC721Enumerable is IERC721 {\\r\\n\\r\\n /**\\r\\n * @dev Returns the total amount of tokens stored by the contract.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\r\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\r\\n */\\r\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\r\\n * Use along with {totalSupply} to enumerate all tokens.\\r\\n */\\r\\n function tokenByIndex(uint256 index) external view returns (uint256);\\r\\n}\\r\\n\",\"keccak256\":\"0x5539b1567797a57e7a135dcc446fdbb02b1ae2b450799274db88a47dea81e6fa\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC721.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\r\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ninterface IERC721Metadata is IERC721 {\\r\\n\\r\\n /**\\r\\n * @dev Returns the token collection name.\\r\\n */\\r\\n function name() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the token collection symbol.\\r\\n */\\r\\n function symbol() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\r\\n */\\r\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\r\\n}\\r\\n\",\"keccak256\":\"0xe92ae6f0b94fce8480d16a24faa8835926cd5fc074a4d418de94aaddbdecf49d\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @title ERC721 token receiver interface\\r\\n * @dev Interface for any contract that wants to support safeTransfers\\r\\n * from ERC721 asset contracts.\\r\\n */\\r\\ninterface IERC721Receiver {\\r\\n /**\\r\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\r\\n * by `operator` from `from`, this function is called.\\r\\n *\\r\\n * It must return its Solidity selector to confirm the token transfer.\\r\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\r\\n *\\r\\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\\r\\n */\\r\\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\\r\\n}\\r\\n\",\"keccak256\":\"0x515410f905897b0d658f1746064cc2a94d52a1bc625fab215dccb7fb5ead50f7\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @title Initializable\\r\\n *\\r\\n * @dev Helper contract to support initializer functions. To use it, replace\\r\\n * the constructor with a function that has the `initializer` modifier.\\r\\n * WARNING: Unlike constructors, initializer functions must be manually\\r\\n * invoked. This applies both to deploying an Initializable contract, as well\\r\\n * as extending an Initializable contract via inheritance.\\r\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\r\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\r\\n * because this is not dealt with automatically as with constructors.\\r\\n */\\r\\ncontract Initializable {\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract has been initialized.\\r\\n */\\r\\n bool private initialized;\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract is in the process of being initialized.\\r\\n */\\r\\n bool private initializing;\\r\\n\\r\\n /**\\r\\n * @dev Modifier to use in the initializer function of a contract.\\r\\n */\\r\\n modifier initializer() {\\r\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\r\\n\\r\\n bool isTopLevelCall = !initializing;\\r\\n if (isTopLevelCall) {\\r\\n initializing = true;\\r\\n initialized = true;\\r\\n }\\r\\n\\r\\n _;\\r\\n\\r\\n if (isTopLevelCall) {\\r\\n initializing = false;\\r\\n }\\r\\n }\\r\\n\\r\\n // Reserved storage space to allow for layout changes in the future.\\r\\n uint256[50] private ______gap;\\r\\n}\",\"keccak256\":\"0xc1f4d917648f0e17ba6a023a168173ad6163f3120e24d1c97ae294430e42eaf3\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../../GSN/Context.sol\\\";\\r\\nimport \\\"../../../access/Roles.sol\\\";\\r\\n\\r\\ncontract UpgradablePauserRole is Initializable, Context {\\r\\n using Roles for Roles.Role;\\r\\n\\r\\n event PauserAdded(address indexed account);\\r\\n event PauserRemoved(address indexed account);\\r\\n\\r\\n Roles.Role private _pausers;\\r\\n\\r\\n function __PauserRol_init(address sender) public initializer {\\r\\n if (!isPauser(sender)) {\\r\\n _addPauser(sender);\\r\\n }\\r\\n }\\r\\n\\r\\n modifier onlyPauser() {\\r\\n require(isPauser(_msgSender()), \\\"PauserRole: caller doesn't have the role\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function isPauser(address account) public view returns (bool) {\\r\\n return _pausers.has(account);\\r\\n }\\r\\n\\r\\n function addPauser(address account) public onlyPauser {\\r\\n _addPauser(account);\\r\\n }\\r\\n\\r\\n function renouncePauser() public {\\r\\n _removePauser(_msgSender());\\r\\n }\\r\\n\\r\\n function _addPauser(address account) internal {\\r\\n _pausers.add(account);\\r\\n emit PauserAdded(account);\\r\\n }\\r\\n\\r\\n function _removePauser(address account) internal {\\r\\n _pausers.remove(account);\\r\\n emit PauserRemoved(account);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x175465830c1ec77cab5ebdcfaeca43c79d33f3becded5332ed6136adac3f99eb\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"../access/roles/UpgradablePauserRole.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Contract module which allows children to implement an emergency stop\\r\\n * mechanism that can be triggered by an authorized account.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the\\r\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\r\\n * the functions of your contract. Note that they will not be pausable by\\r\\n * simply including this module, only once the modifiers are put in place.\\r\\n */\\r\\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\\r\\n /**\\r\\n * @dev Emitted when the pause is triggered by a pauser (`account`).\\r\\n */\\r\\n event Paused(address account);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the pause is lifted by a pauser (`account`).\\r\\n */\\r\\n event Unpaused(address account);\\r\\n\\r\\n bool private _paused;\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\\r\\n * to the deployer.\\r\\n */\\r\\n function __Pausable_init(address sender) public initializer {\\r\\n UpgradablePauserRole.__PauserRol_init(sender);\\r\\n\\r\\n _paused = false;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the contract is paused, and false otherwise.\\r\\n */\\r\\n function paused() public view returns (bool) {\\r\\n return _paused;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Modifier to make a function callable only when the contract is not paused.\\r\\n */\\r\\n modifier whenNotPaused() {\\r\\n require(!_paused, \\\"Pausable: paused\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Modifier to make a function callable only when the contract is paused.\\r\\n */\\r\\n modifier whenPaused() {\\r\\n require(_paused, \\\"Pausable: not paused\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Called by a pauser to pause, triggers stopped state.\\r\\n */\\r\\n function pause() public onlyPauser whenNotPaused {\\r\\n _paused = true;\\r\\n emit Paused(_msgSender());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Called by a pauser to unpause, returns to normal state.\\r\\n */\\r\\n function unpause() public onlyPauser whenPaused {\\r\\n _paused = false;\\r\\n emit Unpaused(_msgSender());\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x0837df4a389f73b7210b97b1b64ba8f9cc842367b473f8fc856c4e892f212ac4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Contract module which provides a basic access control mechanism, where\\r\\n * there is an account (an owner) that can be granted exclusive access to\\r\\n * specific functions.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the modifier\\r\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\r\\n * the owner.\\r\\n */\\r\\ncontract UpgradableOwnable is Initializable, Context {\\r\\n address private _owner;\\r\\n\\r\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract setting the deployer as the initial owner.\\r\\n */\\r\\n function initialize(address sender) public initializer {\\r\\n _owner = sender;\\r\\n emit OwnershipTransferred(address(0), _owner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the address of the current owner.\\r\\n */\\r\\n function owner() public view returns (address) {\\r\\n return _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Throws if called by any account other than the owner.\\r\\n */\\r\\n modifier onlyOwner() {\\r\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the caller is the current owner.\\r\\n */\\r\\n function isOwner() public view returns (bool) {\\r\\n return _msgSender() == _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Leaves the contract without owner. It will not be possible to call\\r\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\r\\n *\\r\\n * > Note: Renouncing ownership will leave the contract without an owner,\\r\\n * thereby removing any functionality that is only available to the owner.\\r\\n */\\r\\n function renounceOwnership() public onlyOwner {\\r\\n emit OwnershipTransferred(_owner, address(0));\\r\\n _owner = address(0);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n * Can only be called by the current owner.\\r\\n */\\r\\n function transferOwnership(address newOwner) public onlyOwner {\\r\\n _transferOwnership(newOwner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n */\\r\\n function _transferOwnership(address newOwner) internal {\\r\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\r\\n emit OwnershipTransferred(_owner, newOwner);\\r\\n _owner = newOwner;\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0xea920007e371a3300245b5885f72cecc472c4780818365f0025fae65a767273d\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title Helps contracts guard against reentrancy attacks.\\r\\n * @author Remco Bloemen , Eenae \\r\\n * @dev If you mark a function `nonReentrant`, you should also\\r\\n * mark it `external`.\\r\\n */\\r\\ncontract ReentrancyGuard is Initializable {\\r\\n /// @dev counter to allow mutex lock with only one SSTORE operation\\r\\n uint256 private _guardCounter;\\r\\n\\r\\n function initialize() public initializer {\\r\\n // The counter starts at one to prevent changing it from zero to a non-zero\\r\\n // value, which is a more expensive operation.\\r\\n _guardCounter = 1;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\r\\n * Calling a `nonReentrant` function from another `nonReentrant`\\r\\n * function is not supported. It is possible to prevent this from happening\\r\\n * by making the `nonReentrant` function external, and make it call a\\r\\n * `private` function that does the actual work.\\r\\n */\\r\\n modifier nonReentrant() {\\r\\n _guardCounter += 1;\\r\\n uint256 localCounter = _guardCounter;\\r\\n _;\\r\\n require(localCounter == _guardCounter, \\\"ReentrancyGuard: no reentrant allowed\\\");\\r\\n }\\r\\n}\",\"keccak256\":\"0x67a8148c8357409eac291fc0954ca7a2d023b0534294be95f34eba0b15d748a5\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/EnumerableMap.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Library for managing an enumerable variant of Solidity's\\r\\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\\r\\n * type.\\r\\n *\\r\\n * Maps have the following properties:\\r\\n *\\r\\n * - Entries are added, removed, and checked for existence in constant time\\r\\n * (O(1)).\\r\\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\\r\\n *\\r\\n * ```\\r\\n * contract Example {\\r\\n * // Add the library methods\\r\\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\\r\\n *\\r\\n * // Declare a set state variable\\r\\n * EnumerableMap.UintToAddressMap private myMap;\\r\\n * }\\r\\n * ```\\r\\n *\\r\\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\\r\\n * supported.\\r\\n */\\r\\nlibrary EnumerableMap {\\r\\n // To implement this library for multiple types with as little code\\r\\n // repetition as possible, we write it in terms of a generic Map type with\\r\\n // bytes32 keys and values.\\r\\n // The Map implementation uses private functions, and user-facing\\r\\n // implementations (such as Uint256ToAddressMap) are just wrappers around\\r\\n // the underlying Map.\\r\\n // This means that we can only create new EnumerableMaps for types that fit\\r\\n // in bytes32.\\r\\n\\r\\n struct MapEntry {\\r\\n bytes32 _key;\\r\\n bytes32 _value;\\r\\n }\\r\\n\\r\\n struct Map {\\r\\n // Storage of map keys and values\\r\\n MapEntry[] _entries;\\r\\n\\r\\n // Position of the entry defined by a key in the `entries` array, plus 1\\r\\n // because index 0 means a key is not in the map.\\r\\n mapping (bytes32 => uint256) _indexes;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Adds a key-value pair to a map, or updates the value for an existing\\r\\n * key. O(1).\\r\\n *\\r\\n * Returns true if the key was added to the map, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\\r\\n // We read and store the key's index to prevent multiple reads from the same storage slot\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n\\r\\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\\r\\n map._entries.push(MapEntry({ _key: key, _value: value }));\\r\\n // The entry is stored at length-1, but we add 1 to all indexes\\r\\n // and use 0 as a sentinel value\\r\\n map._indexes[key] = map._entries.length;\\r\\n return true;\\r\\n } else {\\r\\n map._entries[keyIndex - 1]._value = value;\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a key-value pair from a map. O(1).\\r\\n *\\r\\n * Returns true if the key was removed from the map, that is if it was present.\\r\\n */\\r\\n function _remove(Map storage map, bytes32 key) private returns (bool) {\\r\\n // We read and store the key's index to prevent multiple reads from the same storage slot\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n\\r\\n if (keyIndex != 0) { // Equivalent to contains(map, key)\\r\\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\\r\\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\\r\\n // This modifies the order of the array, as noted in {at}.\\r\\n\\r\\n uint256 toDeleteIndex = keyIndex - 1;\\r\\n uint256 lastIndex = map._entries.length - 1;\\r\\n\\r\\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\\r\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\r\\n\\r\\n MapEntry storage lastEntry = map._entries[lastIndex];\\r\\n\\r\\n // Move the last entry to the index where the entry to delete is\\r\\n map._entries[toDeleteIndex] = lastEntry;\\r\\n // Update the index for the moved entry\\r\\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\\r\\n\\r\\n // Delete the slot where the moved entry was stored\\r\\n map._entries.pop();\\r\\n\\r\\n // Delete the index for the deleted slot\\r\\n delete map._indexes[key];\\r\\n\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the key is in the map. O(1).\\r\\n */\\r\\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\\r\\n return map._indexes[key] != 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of key-value pairs in the map. O(1).\\r\\n */\\r\\n function _length(Map storage map) private view returns (uint256) {\\r\\n return map._entries.length;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of entries inside the\\r\\n * array, and it may change when more entries are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\\r\\n require(map._entries.length > index, \\\"EnumerableMap: index out of bounds\\\");\\r\\n\\r\\n MapEntry storage entry = map._entries[index];\\r\\n return (entry._key, entry._value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Tries to returns the value associated with `key`. O(1).\\r\\n * Does not revert if `key` is not in the map.\\r\\n */\\r\\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\\r\\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value associated with `key`. O(1).\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `key` must be in the map.\\r\\n */\\r\\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n require(keyIndex != 0, \\\"EnumerableMap: nonexistent key\\\"); // Equivalent to contains(map, key)\\r\\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\\r\\n *\\r\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\r\\n * message unnecessarily. For custom revert reasons use {_tryGet}.\\r\\n */\\r\\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\\r\\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\\r\\n }\\r\\n\\r\\n // UintToAddressMap\\r\\n\\r\\n struct UintToAddressMap {\\r\\n Map _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Adds a key-value pair to a map, or updates the value for an existing\\r\\n * key. O(1).\\r\\n *\\r\\n * Returns true if the key was added to the map, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\\r\\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the key was removed from the map, that is if it was present.\\r\\n */\\r\\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\\r\\n return _remove(map._inner, bytes32(key));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the key is in the map. O(1).\\r\\n */\\r\\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\\r\\n return _contains(map._inner, bytes32(key));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of elements in the map. O(1).\\r\\n */\\r\\n function length(UintToAddressMap storage map) internal view returns (uint256) {\\r\\n return _length(map._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the element stored at position `index` in the set. O(1).\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\\r\\n (bytes32 key, bytes32 value) = _at(map._inner, index);\\r\\n return (uint256(key), address(uint160(uint256(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Tries to returns the value associated with `key`. O(1).\\r\\n * Does not revert if `key` is not in the map.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\\r\\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\\r\\n return (success, address(uint160(uint256(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value associated with `key`. O(1).\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `key` must be in the map.\\r\\n */\\r\\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\\r\\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\\r\\n *\\r\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\r\\n * message unnecessarily. For custom revert reasons use {tryGet}.\\r\\n */\\r\\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\\r\\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x5538ae23826bfaa205dc16a24a50f18feaae576a1c46ddea7086bbbd4c13d84e\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Library for managing\\r\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\r\\n * types.\\r\\n *\\r\\n * Sets have the following properties:\\r\\n *\\r\\n * - Elements are added, removed, and checked for existence in constant time\\r\\n * (O(1)).\\r\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\r\\n *\\r\\n * ```\\r\\n * contract Example {\\r\\n * // Add the library methods\\r\\n * using EnumerableSet for EnumerableSet.AddressSet;\\r\\n *\\r\\n * // Declare a set state variable\\r\\n * EnumerableSet.AddressSet private mySet;\\r\\n * }\\r\\n * ```\\r\\n *\\r\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\r\\n * and `uint256` (`UintSet`) are supported.\\r\\n */\\r\\nlibrary EnumerableSet {\\r\\n // To implement this library for multiple types with as little code\\r\\n // repetition as possible, we write it in terms of a generic Set type with\\r\\n // bytes32 values.\\r\\n // The Set implementation uses private functions, and user-facing\\r\\n // implementations (such as AddressSet) are just wrappers around the\\r\\n // underlying Set.\\r\\n // This means that we can only create new EnumerableSets for types that fit\\r\\n // in bytes32.\\r\\n\\r\\n struct Set {\\r\\n // Storage of set values\\r\\n bytes32[] _values;\\r\\n\\r\\n // Position of the value in the `values` array, plus 1 because index 0\\r\\n // means a value is not in the set.\\r\\n mapping (bytes32 => uint256) _indexes;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\r\\n if (!_contains(set, value)) {\\r\\n set._values.push(value);\\r\\n // The value is stored at length-1, but we add 1 to all indexes\\r\\n // and use 0 as a sentinel value\\r\\n set._indexes[value] = set._values.length;\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\r\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\r\\n uint256 valueIndex = set._indexes[value];\\r\\n\\r\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\r\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\r\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\r\\n // This modifies the order of the array, as noted in {at}.\\r\\n\\r\\n uint256 toDeleteIndex = valueIndex - 1;\\r\\n uint256 lastIndex = set._values.length - 1;\\r\\n\\r\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\r\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\r\\n\\r\\n bytes32 lastvalue = set._values[lastIndex];\\r\\n\\r\\n // Move the last value to the index where the value to delete is\\r\\n set._values[toDeleteIndex] = lastvalue;\\r\\n // Update the index for the moved value\\r\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\r\\n\\r\\n // Delete the slot where the moved value was stored\\r\\n set._values.pop();\\r\\n\\r\\n // Delete the index for the deleted slot\\r\\n delete set._indexes[value];\\r\\n\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\r\\n return set._indexes[value] != 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values on the set. O(1).\\r\\n */\\r\\n function _length(Set storage set) private view returns (uint256) {\\r\\n return set._values.length;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\r\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\r\\n return set._values[index];\\r\\n }\\r\\n\\r\\n // Bytes32Set\\r\\n\\r\\n struct Bytes32Set {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\r\\n return _add(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\r\\n return _remove(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\r\\n return _contains(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values in the set. O(1).\\r\\n */\\r\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\r\\n return _at(set._inner, index);\\r\\n }\\r\\n\\r\\n // AddressSet\\r\\n\\r\\n struct AddressSet {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(AddressSet storage set, address value) internal returns (bool) {\\r\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\r\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\r\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values in the set. O(1).\\r\\n */\\r\\n function length(AddressSet storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\r\\n return address(uint160(uint256(_at(set._inner, index))));\\r\\n }\\r\\n\\r\\n\\r\\n // UintSet\\r\\n\\r\\n struct UintSet {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\r\\n return _add(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\r\\n return _remove(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\r\\n return _contains(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values on the set. O(1).\\r\\n */\\r\\n function length(UintSet storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\r\\n return uint256(_at(set._inner, index));\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x4c3f4a13b8f0c2b911044b85d3db13396e772cb9b79f7fb16ec8d41ca5fc7321\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev String operations.\\r\\n */\\r\\nlibrary Strings {\\r\\n /**\\r\\n * @dev Converts a `uint256` to its ASCII `string` representation.\\r\\n */\\r\\n function toString(uint256 value) internal pure returns (string memory) {\\r\\n // Inspired by OraclizeAPI's implementation - MIT licence\\r\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\r\\n\\r\\n if (value == 0) {\\r\\n return \\\"0\\\";\\r\\n }\\r\\n uint256 temp = value;\\r\\n uint256 digits;\\r\\n while (temp != 0) {\\r\\n digits++;\\r\\n temp /= 10;\\r\\n }\\r\\n bytes memory buffer = new bytes(digits);\\r\\n uint256 index = digits - 1;\\r\\n temp = value;\\r\\n while (temp != 0) {\\r\\n buffer[index--] = bytes1(uint8(48 + temp % 10));\\r\\n temp /= 10;\\r\\n }\\r\\n return string(buffer);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x0f1313d4fbca3b365d39200fc056b6db57b957b53dabb06d6fff3566fb8caa29\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50612f91806100206000396000f3fe6080604052600436106102515760003560e01c806382dc1ec411610139578063c4d66de8116100b6578063ea2170911161007a578063ea21709114610686578063eb16136f1461069b578063ed99f4c6146106bb578063f1409028146106d0578063f2fde38b146106f0578063fa0caa161461071057610251565b8063c4d66de8146105e6578063cc3c0f0614610606578063ce5f8bf214610626578063d220d30a14610646578063da6770371461066657610251565b8063a53d6e6e116100fd578063a53d6e6e14610567578063a9e4eff21461057c578063b79472621461059c578063b86f60d2146105b1578063c33c8c61146105c657610251565b806382dc1ec4146104db5780638456cb59146104fb5780638da5cb5b146105105780638f32d59b14610532578063916dc59d1461054757610251565b806342cdb2c6116101d2578063664761091161019657806366476109146104495780636a863191146104695780636ef8d66d14610489578063715018a61461049e5780637813bea2146104b35780638129fc1c146104c657610251565b806342cdb2c6146103bd57806346fbf68e146103dd57806354fd4d50146103fd57806359a8a8671461041f5780635c975abb1461043457610251565b80632f3cca4e116102195780632f3cca4e146103285780632fb3b3611461034857806337de81061461036857806337e76109146103885780633f4ba83a146103a857610251565b806307c8f7b0146102565780630b2292a614610278578063150b7a02146102ae5780631b68e6e6146102db5780631c7e6efb146102fb575b600080fd5b34801561026257600080fd5b506102766102713660046124d8565b610730565b005b34801561028457600080fd5b506102986102933660046124f8565b6107b9565b6040516102a59190612836565b60405180910390f35b3480156102ba57600080fd5b506102ce6102c936600461235c565b6107cb565b6040516102a5919061283f565b3480156102e757600080fd5b506102766102f636600461257a565b6107db565b34801561030757600080fd5b5061031b61031636600461216d565b610836565b6040516102a5919061282b565b34801561033457600080fd5b5061027661034336600461216d565b61084b565b34801561035457600080fd5b5061027661036336600461221b565b6108d4565b34801561037457600080fd5b506102766103833660046124f8565b610a3e565b34801561039457600080fd5b5061031b6103a33660046124f8565b610a97565b3480156103b457600080fd5b50610276610abc565b3480156103c957600080fd5b506102766103d836600461216d565b610b4f565b3480156103e957600080fd5b5061031b6103f836600461216d565b610be4565b34801561040957600080fd5b50610412610bf7565b6040516102a591906128b2565b34801561042b57600080fd5b50610412610c13565b34801561044057600080fd5b5061031b610ca1565b34801561045557600080fd5b5061027661046436600461257a565b610caa565b34801561047557600080fd5b506102766104843660046121a5565b610cbb565b34801561049557600080fd5b50610276610f0a565b3480156104aa57600080fd5b50610276610f1c565b6102766104c13660046122b4565b610f90565b3480156104d257600080fd5b506102766110eb565b3480156104e757600080fd5b506102766104f636600461216d565b611164565b34801561050757600080fd5b50610276611194565b34801561051c57600080fd5b50610525611214565b6040516102a59190612707565b34801561053e57600080fd5b5061031b611228565b34801561055357600080fd5b5061027661056236600461216d565b611253565b34801561057357600080fd5b506105256112e8565b34801561058857600080fd5b506102986105973660046122f4565b6112f7565b3480156105a857600080fd5b5061031b611339565b3480156105bd57600080fd5b50610525611349565b3480156105d257600080fd5b506102766105e13660046123d9565b611358565b3480156105f257600080fd5b5061027661060136600461216d565b61151f565b34801561061257600080fd5b5061031b6106213660046124f8565b6115ea565b34801561063257600080fd5b5061052561064136600461216d565b6115ff565b34801561065257600080fd5b506105256106613660046124ad565b61161a565b34801561067257600080fd5b5061031b6106813660046124f8565b61174d565b34801561069257600080fd5b50610525611761565b3480156106a757600080fd5b506102766106b636600461216d565b611770565b3480156106c757600080fd5b506102986117fb565b3480156106dc57600080fd5b506105256106eb36600461216d565b611801565b3480156106fc57600080fd5b5061027661070b36600461216d565b61181c565b34801561071c57600080fd5b5061027661072b36600461216d565b611849565b610738611228565b61075d5760405162461bcd60e51b815260040161075490612c16565b60405180910390fd5b603e805460ff60a01b1916600160a01b831515810291909117918290556040517f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad9926107ae9260ff9104169061282b565b60405180910390a150565b603f6020526000908152604090205481565b630a85bd0160e11b949350505050565b6107eb604082016020830161216d565b6001600160a01b03166107fc6118e4565b6001600160a01b0316146108225760405162461bcd60e51b81526004016107549061296f565b6108338161082e6118e4565b6118e8565b50565b603b6020526000908152604090205460ff1681565b600054610100900460ff1680610864575060005460ff16155b6108805760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff161580156108ab576000805460ff1961ff0019909116610100171660011790555b6108b482611770565b6034805460ff1916905580156108d0576000805461ff00191690555b5050565b600054610100900460ff16806108ed575060005460ff16155b6109095760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff16158015610934576000805460ff1961ff0019909116610100171660011790555b61093d8661151f565b6109468661084b565b8151610959906038906020850190612033565b50603d80546001600160a01b038087166001600160a01b031992831617909255603e805486841690831617905560368054928816929091169190911790556040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d906109f29030907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b9082906004016127d2565b600060405180830381600087803b158015610a0c57600080fd5b505af1158015610a20573d6000803e3d6000fd5b505050508015610a36576000805461ff00191690555b505050505050565b610a46611228565b610a625760405162461bcd60e51b815260040161075490612c16565b60378190556040517f5eebc59df2662862db7d6ef529ff1a264721bd7c26550f39c89a685382668f4e906107ae908390612836565b6000818152603f60209081526040808320548352603c90915290205460ff165b919050565b610ac76103f86118e4565b610ae35760405162461bcd60e51b815260040161075490612acb565b60345460ff16610b055760405162461bcd60e51b81526004016107549061290a565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610b386118e4565b604051610b459190612707565b60405180910390a1565b610b57611228565b610b735760405162461bcd60e51b815260040161075490612c16565b6001600160a01b038116610b995760405162461bcd60e51b815260040161075490612e8f565b603e80546001600160a01b0319166001600160a01b0383161790556040517f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e3183692521625906107ae908390612707565b6000610bf1603383611b47565b92915050565b604080518082019091526002815261763160f01b602082015290565b6038805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610c995780601f10610c6e57610100808354040283529160200191610c99565b820191906000526020600020905b815481529060010190602001808311610c7c57829003601f168201915b505050505081565b60345460ff1690565b6108338161082e602082018261216d565b60345460ff1615610cde5760405162461bcd60e51b815260040161075490612b57565b60358054600101908190556036546001600160a01b0316610cfd6118e4565b6001600160a01b031614610d235760405162461bcd60e51b815260040161075490612bdf565b6001600160a01b0388166000908152603b602052604090205460ff1680610d6357506001600160a01b038881166000908152603960205260409020541615155b610d7f5760405162461bcd60e51b815260040161075490612cfb565b6001600160a01b038616610da55760405162461bcd60e51b815260040161075490612db3565b6001600160a01b038716610dcb5760405162461bcd60e51b815260040161075490612b81565b83610de85760405162461bcd60e51b815260040161075490612e16565b82610e055760405162461bcd60e51b815260040161075490612baf565b6000838152603f602052604090205415610e315760405162461bcd60e51b815260040161075490612d32565b6000610e428789888c8989896112f7565b6000818152603c602052604090205490915060ff1615610e745760405162461bcd60e51b815260040161075490612cc4565b80603f600086815260200190815260200160002081905550866001600160a01b0316896001600160a01b0316857f68c55835fbe7c27942e2ff7632542cf70ee33ba41b292bff9cb6183e3db7e63b8b8a8a89604051610ed69493929190612758565b60405180910390a4506035548114610f005760405162461bcd60e51b8152600401610754906128c5565b5050505050505050565b610f1a610f156118e4565b611b8f565b565b610f24611228565b610f405760405162461bcd60e51b815260040161075490612c16565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b6000610f9c848361161a565b90506000610fa86118e4565b6040516323b872dd60e01b81529091506001600160a01b038616906323b872dd90610fdb9084903090889060040161271b565b600060405180830381600087803b158015610ff557600080fd5b505af1158015611009573d6000803e3d6000fd5b505050506110298585846040518060200160405280600081525087611bd1565b603754156110e4576037543410156110535760405162461bcd60e51b815260040161075490612d69565b6036546037546040516001600160a01b039092169181156108fc0291906000818181858888f1935050505015801561108f573d6000803e3d6000fd5b506037543411156110e457806001600160a01b03166108fc6110bc60375434611e5b90919063ffffffff16565b6040518115909202916000818181858888f19350505050158015610a36573d6000803e3d6000fd5b5050505050565b600054610100900460ff1680611104575060005460ff16155b6111205760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff1615801561114b576000805460ff1961ff0019909116610100171660011790555b60016035558015610833576000805461ff001916905550565b61116f6103f86118e4565b61118b5760405162461bcd60e51b815260040161075490612acb565b61083381611ea4565b61119f6103f86118e4565b6111bb5760405162461bcd60e51b815260040161075490612acb565b60345460ff16156111de5760405162461bcd60e51b815260040161075490612b57565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610b386118e4565b60345461010090046001600160a01b031690565b60345460009061010090046001600160a01b03166112446118e4565b6001600160a01b031614905090565b61125b611228565b6112775760405162461bcd60e51b815260040161075490612c16565b6001600160a01b03811661129d5760405162461bcd60e51b815260040161075490612ddf565b603d80546001600160a01b0319166001600160a01b0383161790556040517f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e3906107ae908390612707565b603d546001600160a01b031681565b6000838389898989876040516020016113169796959493929190612619565b604051602081830303815290604052805190602001209050979650505050505050565b603e54600160a01b900460ff1681565b603e546001600160a01b031681565b611360611228565b61137c5760405162461bcd60e51b815260040161075490612c16565b6001600160a01b0389166113a25760405162461bcd60e51b8152600401610754906129a6565b6001600160a01b03808a166000908152603960205260409020541680156113db5760405162461bcd60e51b815260040161075490612b13565b600060388a8a6040516020016113f39392919061268e565b60408051601f1981840301815290829052603e54634423ac3360e11b83529092506001600160a01b03169063884758669061143e908b908b9086908c908c908c908c90600401612854565b602060405180830381600087803b15801561145857600080fd5b505af115801561146c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114909190612189565b6001600160a01b03808d16600081815260396020908152604080832080549587166001600160a01b03199687168117909155808452603a909252918290208054909416831790935551929450917f622ea91961d2c1c42b6f59a73d152d990066165d59f27d922ce6d1f59650638c9061150a9085906128b2565b60405180910390a35050505050505050505050565b600054610100900460ff1680611538575060005460ff16155b6115545760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff1615801561157f576000805460ff1961ff0019909116610100171660011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a380156108d0576000805461ff00191690555050565b603c6020526000908152604090205460ff1681565b603a602052600090815260409020546001600160a01b031681565b60408051600481526024810182526020810180516001600160e01b03166302d05d3f60e01b1790529051600091829182916001600160a01b038716916116609190612672565b600060405180830381855afa9150503d806000811461169b576040519150601f19603f3d011682016040523d82523d6000602084013e6116a0565b606091505b509150915081156116c857808060200190518101906116bf9190612189565b92505050610bf1565b6040516331a9108f60e11b81526001600160a01b03861690636352211e906116f4908790600401612836565b60206040518083038186803b15801561170c57600080fd5b505afa158015611720573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117449190612189565b95945050505050565b6000908152603f6020526040902054151590565b6036546001600160a01b031690565b600054610100900460ff1680611789575060005460ff16155b6117a55760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff161580156117d0576000805460ff1961ff0019909116610100171660011790555b6117d982610be4565b6117e6576117e682611ea4565b80156108d0576000805461ff00191690555050565b60375490565b6039602052600090815260409020546001600160a01b031681565b611824611228565b6118405760405162461bcd60e51b815260040161075490612c16565b61083381611ee6565b611851611228565b61186d5760405162461bcd60e51b815260040161075490612c16565b6001600160a01b0381166118935760405162461bcd60e51b815260040161075490612c8d565b603680546001600160a01b0319166001600160a01b0383811691909117918290556040517f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb926107ae921690612707565b3390565b60006118fa608084016060850161216d565b90506040830135600061193f611913602087018761216d565b611923604088016020890161216d565b848660808a013560a08b013561059760e08d0160c08e016125a9565b60a08601356000908152603f602052604090205490915081146119745760405162461bcd60e51b8152600401610754906129ec565b6000818152603c602052604090205460ff16156119a35760405162461bcd60e51b815260040161075490612cc4565b6000818152603c60209081526040808320805460ff191660011790556001600160a01b0386168352603b90915290205460ff168015611a4357604051632142170760e11b81526001600160a01b038516906342842e0e90611a0c9030908990889060040161271b565b600060405180830381600087803b158015611a2657600080fd5b505af1158015611a3a573d6000803e3d6000fd5b50505050611aba565b6001600160a01b03808516600090815260396020526040908190205490516340c10f1960e01b815291169081906340c10f1990611a86908990889060040161273f565b600060405180830381600087803b158015611aa057600080fd5b505af1158015611ab4573d6000803e3d6000fd5b50505050505b611ac7602087018761216d565b6001600160a01b0390811690851660a08801357f8738727192721a6f1909e42e987fa3faf27386067521caf12f11c5dc4013c2ac611b0b60408b0160208c0161216d565b60408b013560808c0135611b2560e08e0160c08f016125a9565b8c604051611b379594939291906127f5565b60405180910390a4505050505050565b60006001600160a01b038216611b6f5760405162461bcd60e51b815260040161075490612c4b565b506001600160a01b03166000908152602091909152604090205460ff1690565b611b9a603382611f73565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b603e54600160a01b900460ff1615611bfb5760405162461bcd60e51b815260040161075490612a23565b60345460ff1615611c1e5760405162461bcd60e51b815260040161075490612b57565b603580546001908101918290556001600160a01b0387166000818152603b6020526040808220805460ff1916909417909355915163c87b56dd60e01b815288928392909163c87b56dd90611c76908890600401612836565b60006040518083038186803b158015611c8e57600080fd5b505afa158015611ca2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611cca9190810190612510565b6001600160a01b03808b166000908152603a60205260409020549192508a911615611d6257506001600160a01b03808a166000818152603a602052604090819020549051630852cd8d60e31b81529216916342966c6890611d2f908990600401612836565b600060405180830381600087803b158015611d4957600080fd5b505af1158015611d5d573d6000803e3d6000fd5b505050505b886001600160a01b0316611d746118e4565b6001600160a01b0316826001600160a01b03167f8586062302f52eda0114687cd36998f16298ea820e0a6f8878bbbfefebc09e9f8b8b896001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611de357600080fd5b505afa158015611df7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1b9190612591565b8c89604051611e2e959493929190612784565b60405180910390a4505050506035548114610a365760405162461bcd60e51b8152600401610754906128c5565b6000611e9d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611fbb565b9392505050565b611eaf603382611fe7565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6001600160a01b038116611f0c5760405162461bcd60e51b815260040161075490612e4d565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b611f7d8282611b47565b611f995760405162461bcd60e51b815260040161075490612a4e565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b60008184841115611fdf5760405162461bcd60e51b815260040161075491906128b2565b505050900390565b611ff18282611b47565b1561200e5760405162461bcd60e51b815260040161075490612938565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261206957600085556120af565b82601f1061208257805160ff19168380011785556120af565b828001600101855582156120af579182015b828111156120af578251825591602001919060010190612094565b506120bb9291506120bf565b5090565b5b808211156120bb57600081556001016120c0565b60006120e76120e284612ef4565b612ed0565b90508281528383830111156120fb57600080fd5b828260208301376000602084830101529392505050565b60008083601f840112612123578182fd5b50813567ffffffffffffffff81111561213a578182fd5b60208301915083602082850101111561215257600080fd5b9250929050565b803563ffffffff81168114610ab757600080fd5b60006020828403121561217e578081fd5b8135611e9d81612f46565b60006020828403121561219a578081fd5b8151611e9d81612f46565b600080600080600080600060e0888a0312156121bf578283fd5b87356121ca81612f46565b965060208801356121da81612f46565b955060408801356121ea81612f46565b9450606088013593506080880135925060a0880135915061220d60c08901612159565b905092959891949750929550565b600080600080600060a08688031215612232578081fd5b853561223d81612f46565b9450602086013561224d81612f46565b9350604086013561225d81612f46565b9250606086013561226d81612f46565b9150608086013567ffffffffffffffff811115612288578182fd5b8601601f81018813612298578182fd5b6122a7888235602084016120d4565b9150509295509295909350565b6000806000606084860312156122c8578283fd5b83356122d381612f46565b925060208401356122e381612f46565b929592945050506040919091013590565b600080600080600080600060e0888a03121561230e578081fd5b873561231981612f46565b9650602088013561232981612f46565b955060408801359450606088013561234081612f46565b93506080880135925060a0880135915061220d60c08901612159565b60008060008060808587031215612371578182fd5b843561237c81612f46565b9350602085013561238c81612f46565b925060408501359150606085013567ffffffffffffffff8111156123ae578182fd5b8501601f810187136123be578182fd5b6123cd878235602084016120d4565b91505092959194509250565b600080600080600080600080600060a08a8c0312156123f6578283fd5b893561240181612f46565b985060208a013567ffffffffffffffff8082111561241d578485fd5b6124298d838e01612112565b909a50985060408c0135915080821115612441578485fd5b61244d8d838e01612112565b909850965060608c0135915080821115612465578485fd5b6124718d838e01612112565b909650945060808c0135915080821115612489578384fd5b506124968c828d01612112565b915080935050809150509295985092959850929598565b600080604083850312156124bf578182fd5b82356124ca81612f46565b946020939093013593505050565b6000602082840312156124e9578081fd5b81358015158114611e9d578182fd5b600060208284031215612509578081fd5b5035919050565b600060208284031215612521578081fd5b815167ffffffffffffffff811115612537578182fd5b8201601f81018413612547578182fd5b80516125556120e282612ef4565b818152856020838501011115612569578384fd5b611744826020830160208601612f16565b600060e0828403121561258b578081fd5b50919050565b6000602082840312156125a2578081fd5b5051919050565b6000602082840312156125ba578081fd5b611e9d82612159565b600081518084526125db816020860160208601612f16565b601f01601f19169290920160200192915050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b9687526020870195909552606093841b6bffffffffffffffffffffffff19908116604088015292841b83166054870152606886019190915290911b16608883015260e01b6001600160e01b031916609c82015260a00190565b60008251612684818460208701612f16565b9190910192915050565b60008085546001808216600081146126ad57600181146126c4576126f3565b60ff198316865260028304607f16860193506126f3565b600283048986526020808720875b838110156126eb5781548a8201529085019082016126d2565b505050860193505b505050838582379092019182525092915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039490941684526020840192909252604083015263ffffffff16606082015260800190565b6001600160a01b038616815260a0602082018190526000906127a8908301876125c3565b85604084015284606084015282810360808401526127c681856125c3565b98975050505050505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b6001600160a01b0395861681526020810194909452604084019290925263ffffffff166060830152909116608082015260a00190565b901515815260200190565b90815260200190565b6001600160e01b031991909116815260200190565b60006080825261286860808301898b6125ef565b828103602084015261287a81896125c3565b9050828103604084015261288f8187896125ef565b905082810360608401526128a48185876125ef565b9a9950505050505050505050565b600060208252611e9d60208301846125c3565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b6020808252601f908201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604082015260600190565b60208082526019908201527f4e46544272696467653a20696e76616c69642073656e64657200000000000000604082015260600190565b60208082526026908201527f4e46544272696467653a204e756c6c206f726967696e616c20746f6b656e206160408201526564647265737360d01b606082015260800190565b6020808252601b908201527f4e46544272696467653a2057726f6e6720747844617461486173680000000000604082015260600190565b6020808252601190820152704272696467653a20557067726164696e6760781b604082015260600190565b6020808252818101527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c65604082015260600190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b60208082526024908201527f4e46544272696467653a205369646520746f6b656e20616c72656164792065786040820152636973747360e01b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252601490820152734e46544272696467653a204e756c6c2046726f6d60601b604082015260600190565b60208082526016908201527509c8ca884e4d2c8ceca74409cead8d840a8f090c2e6d60531b604082015260600190565b60208082526019908201527f4e46544272696467653a204e6f742046656465726174696f6e00000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526022908201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601e908201527f4e46544272696467653a2046656465726174696f6e20697320656d7074790000604082015260600190565b6020808252601a908201527f4e46544272696467653a20416c726561647920636c61696d6564000000000000604082015260600190565b60208082526018908201527f4e46544272696467653a20556e6b6e6f776e20746f6b656e0000000000000000604082015260600190565b6020808252601b908201527f4e46544272696467653a20416c72656164792061636365707465640000000000604082015260600190565b6020808252602a908201527f4e46544272696467653a2076616c756520697320736d616c6c6572207468616e6040820152692066697865642066656560b01b606082015260800190565b6020808252601290820152714e46544272696467653a204e756c6c20546f60701b604082015260600190565b6020808252601f908201527f4e46544272696467653a20416c6c6f77546f6b656e7320697320656d70747900604082015260600190565b60208082526019908201527f4e46544272696467653a204e756c6c20426c6f636b4861736800000000000000604082015260600190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526021908201527f4e46544272696467653a20656d7074792053696465546f6b656e466163746f726040820152607960f81b606082015260800190565b60405181810167ffffffffffffffff81118282101715612eec57fe5b604052919050565b600067ffffffffffffffff821115612f0857fe5b50601f01601f191660200190565b60005b83811015612f31578181015183820152602001612f19565b83811115612f40576000848401525b50505050565b6001600160a01b038116811461083357600080fdfea2646970667358221220c2db86366b65f97c4730018c60c95ed2c68e7f2ccd8332c152047ef6d532db2764736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106102515760003560e01c806382dc1ec411610139578063c4d66de8116100b6578063ea2170911161007a578063ea21709114610686578063eb16136f1461069b578063ed99f4c6146106bb578063f1409028146106d0578063f2fde38b146106f0578063fa0caa161461071057610251565b8063c4d66de8146105e6578063cc3c0f0614610606578063ce5f8bf214610626578063d220d30a14610646578063da6770371461066657610251565b8063a53d6e6e116100fd578063a53d6e6e14610567578063a9e4eff21461057c578063b79472621461059c578063b86f60d2146105b1578063c33c8c61146105c657610251565b806382dc1ec4146104db5780638456cb59146104fb5780638da5cb5b146105105780638f32d59b14610532578063916dc59d1461054757610251565b806342cdb2c6116101d2578063664761091161019657806366476109146104495780636a863191146104695780636ef8d66d14610489578063715018a61461049e5780637813bea2146104b35780638129fc1c146104c657610251565b806342cdb2c6146103bd57806346fbf68e146103dd57806354fd4d50146103fd57806359a8a8671461041f5780635c975abb1461043457610251565b80632f3cca4e116102195780632f3cca4e146103285780632fb3b3611461034857806337de81061461036857806337e76109146103885780633f4ba83a146103a857610251565b806307c8f7b0146102565780630b2292a614610278578063150b7a02146102ae5780631b68e6e6146102db5780631c7e6efb146102fb575b600080fd5b34801561026257600080fd5b506102766102713660046124d8565b610730565b005b34801561028457600080fd5b506102986102933660046124f8565b6107b9565b6040516102a59190612836565b60405180910390f35b3480156102ba57600080fd5b506102ce6102c936600461235c565b6107cb565b6040516102a5919061283f565b3480156102e757600080fd5b506102766102f636600461257a565b6107db565b34801561030757600080fd5b5061031b61031636600461216d565b610836565b6040516102a5919061282b565b34801561033457600080fd5b5061027661034336600461216d565b61084b565b34801561035457600080fd5b5061027661036336600461221b565b6108d4565b34801561037457600080fd5b506102766103833660046124f8565b610a3e565b34801561039457600080fd5b5061031b6103a33660046124f8565b610a97565b3480156103b457600080fd5b50610276610abc565b3480156103c957600080fd5b506102766103d836600461216d565b610b4f565b3480156103e957600080fd5b5061031b6103f836600461216d565b610be4565b34801561040957600080fd5b50610412610bf7565b6040516102a591906128b2565b34801561042b57600080fd5b50610412610c13565b34801561044057600080fd5b5061031b610ca1565b34801561045557600080fd5b5061027661046436600461257a565b610caa565b34801561047557600080fd5b506102766104843660046121a5565b610cbb565b34801561049557600080fd5b50610276610f0a565b3480156104aa57600080fd5b50610276610f1c565b6102766104c13660046122b4565b610f90565b3480156104d257600080fd5b506102766110eb565b3480156104e757600080fd5b506102766104f636600461216d565b611164565b34801561050757600080fd5b50610276611194565b34801561051c57600080fd5b50610525611214565b6040516102a59190612707565b34801561053e57600080fd5b5061031b611228565b34801561055357600080fd5b5061027661056236600461216d565b611253565b34801561057357600080fd5b506105256112e8565b34801561058857600080fd5b506102986105973660046122f4565b6112f7565b3480156105a857600080fd5b5061031b611339565b3480156105bd57600080fd5b50610525611349565b3480156105d257600080fd5b506102766105e13660046123d9565b611358565b3480156105f257600080fd5b5061027661060136600461216d565b61151f565b34801561061257600080fd5b5061031b6106213660046124f8565b6115ea565b34801561063257600080fd5b5061052561064136600461216d565b6115ff565b34801561065257600080fd5b506105256106613660046124ad565b61161a565b34801561067257600080fd5b5061031b6106813660046124f8565b61174d565b34801561069257600080fd5b50610525611761565b3480156106a757600080fd5b506102766106b636600461216d565b611770565b3480156106c757600080fd5b506102986117fb565b3480156106dc57600080fd5b506105256106eb36600461216d565b611801565b3480156106fc57600080fd5b5061027661070b36600461216d565b61181c565b34801561071c57600080fd5b5061027661072b36600461216d565b611849565b610738611228565b61075d5760405162461bcd60e51b815260040161075490612c16565b60405180910390fd5b603e805460ff60a01b1916600160a01b831515810291909117918290556040517f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad9926107ae9260ff9104169061282b565b60405180910390a150565b603f6020526000908152604090205481565b630a85bd0160e11b949350505050565b6107eb604082016020830161216d565b6001600160a01b03166107fc6118e4565b6001600160a01b0316146108225760405162461bcd60e51b81526004016107549061296f565b6108338161082e6118e4565b6118e8565b50565b603b6020526000908152604090205460ff1681565b600054610100900460ff1680610864575060005460ff16155b6108805760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff161580156108ab576000805460ff1961ff0019909116610100171660011790555b6108b482611770565b6034805460ff1916905580156108d0576000805461ff00191690555b5050565b600054610100900460ff16806108ed575060005460ff16155b6109095760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff16158015610934576000805460ff1961ff0019909116610100171660011790555b61093d8661151f565b6109468661084b565b8151610959906038906020850190612033565b50603d80546001600160a01b038087166001600160a01b031992831617909255603e805486841690831617905560368054928816929091169190911790556040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d906109f29030907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b9082906004016127d2565b600060405180830381600087803b158015610a0c57600080fd5b505af1158015610a20573d6000803e3d6000fd5b505050508015610a36576000805461ff00191690555b505050505050565b610a46611228565b610a625760405162461bcd60e51b815260040161075490612c16565b60378190556040517f5eebc59df2662862db7d6ef529ff1a264721bd7c26550f39c89a685382668f4e906107ae908390612836565b6000818152603f60209081526040808320548352603c90915290205460ff165b919050565b610ac76103f86118e4565b610ae35760405162461bcd60e51b815260040161075490612acb565b60345460ff16610b055760405162461bcd60e51b81526004016107549061290a565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610b386118e4565b604051610b459190612707565b60405180910390a1565b610b57611228565b610b735760405162461bcd60e51b815260040161075490612c16565b6001600160a01b038116610b995760405162461bcd60e51b815260040161075490612e8f565b603e80546001600160a01b0319166001600160a01b0383161790556040517f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e3183692521625906107ae908390612707565b6000610bf1603383611b47565b92915050565b604080518082019091526002815261763160f01b602082015290565b6038805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610c995780601f10610c6e57610100808354040283529160200191610c99565b820191906000526020600020905b815481529060010190602001808311610c7c57829003601f168201915b505050505081565b60345460ff1690565b6108338161082e602082018261216d565b60345460ff1615610cde5760405162461bcd60e51b815260040161075490612b57565b60358054600101908190556036546001600160a01b0316610cfd6118e4565b6001600160a01b031614610d235760405162461bcd60e51b815260040161075490612bdf565b6001600160a01b0388166000908152603b602052604090205460ff1680610d6357506001600160a01b038881166000908152603960205260409020541615155b610d7f5760405162461bcd60e51b815260040161075490612cfb565b6001600160a01b038616610da55760405162461bcd60e51b815260040161075490612db3565b6001600160a01b038716610dcb5760405162461bcd60e51b815260040161075490612b81565b83610de85760405162461bcd60e51b815260040161075490612e16565b82610e055760405162461bcd60e51b815260040161075490612baf565b6000838152603f602052604090205415610e315760405162461bcd60e51b815260040161075490612d32565b6000610e428789888c8989896112f7565b6000818152603c602052604090205490915060ff1615610e745760405162461bcd60e51b815260040161075490612cc4565b80603f600086815260200190815260200160002081905550866001600160a01b0316896001600160a01b0316857f68c55835fbe7c27942e2ff7632542cf70ee33ba41b292bff9cb6183e3db7e63b8b8a8a89604051610ed69493929190612758565b60405180910390a4506035548114610f005760405162461bcd60e51b8152600401610754906128c5565b5050505050505050565b610f1a610f156118e4565b611b8f565b565b610f24611228565b610f405760405162461bcd60e51b815260040161075490612c16565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b6000610f9c848361161a565b90506000610fa86118e4565b6040516323b872dd60e01b81529091506001600160a01b038616906323b872dd90610fdb9084903090889060040161271b565b600060405180830381600087803b158015610ff557600080fd5b505af1158015611009573d6000803e3d6000fd5b505050506110298585846040518060200160405280600081525087611bd1565b603754156110e4576037543410156110535760405162461bcd60e51b815260040161075490612d69565b6036546037546040516001600160a01b039092169181156108fc0291906000818181858888f1935050505015801561108f573d6000803e3d6000fd5b506037543411156110e457806001600160a01b03166108fc6110bc60375434611e5b90919063ffffffff16565b6040518115909202916000818181858888f19350505050158015610a36573d6000803e3d6000fd5b5050505050565b600054610100900460ff1680611104575060005460ff16155b6111205760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff1615801561114b576000805460ff1961ff0019909116610100171660011790555b60016035558015610833576000805461ff001916905550565b61116f6103f86118e4565b61118b5760405162461bcd60e51b815260040161075490612acb565b61083381611ea4565b61119f6103f86118e4565b6111bb5760405162461bcd60e51b815260040161075490612acb565b60345460ff16156111de5760405162461bcd60e51b815260040161075490612b57565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610b386118e4565b60345461010090046001600160a01b031690565b60345460009061010090046001600160a01b03166112446118e4565b6001600160a01b031614905090565b61125b611228565b6112775760405162461bcd60e51b815260040161075490612c16565b6001600160a01b03811661129d5760405162461bcd60e51b815260040161075490612ddf565b603d80546001600160a01b0319166001600160a01b0383161790556040517f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e3906107ae908390612707565b603d546001600160a01b031681565b6000838389898989876040516020016113169796959493929190612619565b604051602081830303815290604052805190602001209050979650505050505050565b603e54600160a01b900460ff1681565b603e546001600160a01b031681565b611360611228565b61137c5760405162461bcd60e51b815260040161075490612c16565b6001600160a01b0389166113a25760405162461bcd60e51b8152600401610754906129a6565b6001600160a01b03808a166000908152603960205260409020541680156113db5760405162461bcd60e51b815260040161075490612b13565b600060388a8a6040516020016113f39392919061268e565b60408051601f1981840301815290829052603e54634423ac3360e11b83529092506001600160a01b03169063884758669061143e908b908b9086908c908c908c908c90600401612854565b602060405180830381600087803b15801561145857600080fd5b505af115801561146c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114909190612189565b6001600160a01b03808d16600081815260396020908152604080832080549587166001600160a01b03199687168117909155808452603a909252918290208054909416831790935551929450917f622ea91961d2c1c42b6f59a73d152d990066165d59f27d922ce6d1f59650638c9061150a9085906128b2565b60405180910390a35050505050505050505050565b600054610100900460ff1680611538575060005460ff16155b6115545760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff1615801561157f576000805460ff1961ff0019909116610100171660011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a380156108d0576000805461ff00191690555050565b603c6020526000908152604090205460ff1681565b603a602052600090815260409020546001600160a01b031681565b60408051600481526024810182526020810180516001600160e01b03166302d05d3f60e01b1790529051600091829182916001600160a01b038716916116609190612672565b600060405180830381855afa9150503d806000811461169b576040519150601f19603f3d011682016040523d82523d6000602084013e6116a0565b606091505b509150915081156116c857808060200190518101906116bf9190612189565b92505050610bf1565b6040516331a9108f60e11b81526001600160a01b03861690636352211e906116f4908790600401612836565b60206040518083038186803b15801561170c57600080fd5b505afa158015611720573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117449190612189565b95945050505050565b6000908152603f6020526040902054151590565b6036546001600160a01b031690565b600054610100900460ff1680611789575060005460ff16155b6117a55760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff161580156117d0576000805460ff1961ff0019909116610100171660011790555b6117d982610be4565b6117e6576117e682611ea4565b80156108d0576000805461ff00191690555050565b60375490565b6039602052600090815260409020546001600160a01b031681565b611824611228565b6118405760405162461bcd60e51b815260040161075490612c16565b61083381611ee6565b611851611228565b61186d5760405162461bcd60e51b815260040161075490612c16565b6001600160a01b0381166118935760405162461bcd60e51b815260040161075490612c8d565b603680546001600160a01b0319166001600160a01b0383811691909117918290556040517f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb926107ae921690612707565b3390565b60006118fa608084016060850161216d565b90506040830135600061193f611913602087018761216d565b611923604088016020890161216d565b848660808a013560a08b013561059760e08d0160c08e016125a9565b60a08601356000908152603f602052604090205490915081146119745760405162461bcd60e51b8152600401610754906129ec565b6000818152603c602052604090205460ff16156119a35760405162461bcd60e51b815260040161075490612cc4565b6000818152603c60209081526040808320805460ff191660011790556001600160a01b0386168352603b90915290205460ff168015611a4357604051632142170760e11b81526001600160a01b038516906342842e0e90611a0c9030908990889060040161271b565b600060405180830381600087803b158015611a2657600080fd5b505af1158015611a3a573d6000803e3d6000fd5b50505050611aba565b6001600160a01b03808516600090815260396020526040908190205490516340c10f1960e01b815291169081906340c10f1990611a86908990889060040161273f565b600060405180830381600087803b158015611aa057600080fd5b505af1158015611ab4573d6000803e3d6000fd5b50505050505b611ac7602087018761216d565b6001600160a01b0390811690851660a08801357f8738727192721a6f1909e42e987fa3faf27386067521caf12f11c5dc4013c2ac611b0b60408b0160208c0161216d565b60408b013560808c0135611b2560e08e0160c08f016125a9565b8c604051611b379594939291906127f5565b60405180910390a4505050505050565b60006001600160a01b038216611b6f5760405162461bcd60e51b815260040161075490612c4b565b506001600160a01b03166000908152602091909152604090205460ff1690565b611b9a603382611f73565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b603e54600160a01b900460ff1615611bfb5760405162461bcd60e51b815260040161075490612a23565b60345460ff1615611c1e5760405162461bcd60e51b815260040161075490612b57565b603580546001908101918290556001600160a01b0387166000818152603b6020526040808220805460ff1916909417909355915163c87b56dd60e01b815288928392909163c87b56dd90611c76908890600401612836565b60006040518083038186803b158015611c8e57600080fd5b505afa158015611ca2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611cca9190810190612510565b6001600160a01b03808b166000908152603a60205260409020549192508a911615611d6257506001600160a01b03808a166000818152603a602052604090819020549051630852cd8d60e31b81529216916342966c6890611d2f908990600401612836565b600060405180830381600087803b158015611d4957600080fd5b505af1158015611d5d573d6000803e3d6000fd5b505050505b886001600160a01b0316611d746118e4565b6001600160a01b0316826001600160a01b03167f8586062302f52eda0114687cd36998f16298ea820e0a6f8878bbbfefebc09e9f8b8b896001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611de357600080fd5b505afa158015611df7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1b9190612591565b8c89604051611e2e959493929190612784565b60405180910390a4505050506035548114610a365760405162461bcd60e51b8152600401610754906128c5565b6000611e9d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611fbb565b9392505050565b611eaf603382611fe7565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6001600160a01b038116611f0c5760405162461bcd60e51b815260040161075490612e4d565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b611f7d8282611b47565b611f995760405162461bcd60e51b815260040161075490612a4e565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b60008184841115611fdf5760405162461bcd60e51b815260040161075491906128b2565b505050900390565b611ff18282611b47565b1561200e5760405162461bcd60e51b815260040161075490612938565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261206957600085556120af565b82601f1061208257805160ff19168380011785556120af565b828001600101855582156120af579182015b828111156120af578251825591602001919060010190612094565b506120bb9291506120bf565b5090565b5b808211156120bb57600081556001016120c0565b60006120e76120e284612ef4565b612ed0565b90508281528383830111156120fb57600080fd5b828260208301376000602084830101529392505050565b60008083601f840112612123578182fd5b50813567ffffffffffffffff81111561213a578182fd5b60208301915083602082850101111561215257600080fd5b9250929050565b803563ffffffff81168114610ab757600080fd5b60006020828403121561217e578081fd5b8135611e9d81612f46565b60006020828403121561219a578081fd5b8151611e9d81612f46565b600080600080600080600060e0888a0312156121bf578283fd5b87356121ca81612f46565b965060208801356121da81612f46565b955060408801356121ea81612f46565b9450606088013593506080880135925060a0880135915061220d60c08901612159565b905092959891949750929550565b600080600080600060a08688031215612232578081fd5b853561223d81612f46565b9450602086013561224d81612f46565b9350604086013561225d81612f46565b9250606086013561226d81612f46565b9150608086013567ffffffffffffffff811115612288578182fd5b8601601f81018813612298578182fd5b6122a7888235602084016120d4565b9150509295509295909350565b6000806000606084860312156122c8578283fd5b83356122d381612f46565b925060208401356122e381612f46565b929592945050506040919091013590565b600080600080600080600060e0888a03121561230e578081fd5b873561231981612f46565b9650602088013561232981612f46565b955060408801359450606088013561234081612f46565b93506080880135925060a0880135915061220d60c08901612159565b60008060008060808587031215612371578182fd5b843561237c81612f46565b9350602085013561238c81612f46565b925060408501359150606085013567ffffffffffffffff8111156123ae578182fd5b8501601f810187136123be578182fd5b6123cd878235602084016120d4565b91505092959194509250565b600080600080600080600080600060a08a8c0312156123f6578283fd5b893561240181612f46565b985060208a013567ffffffffffffffff8082111561241d578485fd5b6124298d838e01612112565b909a50985060408c0135915080821115612441578485fd5b61244d8d838e01612112565b909850965060608c0135915080821115612465578485fd5b6124718d838e01612112565b909650945060808c0135915080821115612489578384fd5b506124968c828d01612112565b915080935050809150509295985092959850929598565b600080604083850312156124bf578182fd5b82356124ca81612f46565b946020939093013593505050565b6000602082840312156124e9578081fd5b81358015158114611e9d578182fd5b600060208284031215612509578081fd5b5035919050565b600060208284031215612521578081fd5b815167ffffffffffffffff811115612537578182fd5b8201601f81018413612547578182fd5b80516125556120e282612ef4565b818152856020838501011115612569578384fd5b611744826020830160208601612f16565b600060e0828403121561258b578081fd5b50919050565b6000602082840312156125a2578081fd5b5051919050565b6000602082840312156125ba578081fd5b611e9d82612159565b600081518084526125db816020860160208601612f16565b601f01601f19169290920160200192915050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b9687526020870195909552606093841b6bffffffffffffffffffffffff19908116604088015292841b83166054870152606886019190915290911b16608883015260e01b6001600160e01b031916609c82015260a00190565b60008251612684818460208701612f16565b9190910192915050565b60008085546001808216600081146126ad57600181146126c4576126f3565b60ff198316865260028304607f16860193506126f3565b600283048986526020808720875b838110156126eb5781548a8201529085019082016126d2565b505050860193505b505050838582379092019182525092915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039490941684526020840192909252604083015263ffffffff16606082015260800190565b6001600160a01b038616815260a0602082018190526000906127a8908301876125c3565b85604084015284606084015282810360808401526127c681856125c3565b98975050505050505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b6001600160a01b0395861681526020810194909452604084019290925263ffffffff166060830152909116608082015260a00190565b901515815260200190565b90815260200190565b6001600160e01b031991909116815260200190565b60006080825261286860808301898b6125ef565b828103602084015261287a81896125c3565b9050828103604084015261288f8187896125ef565b905082810360608401526128a48185876125ef565b9a9950505050505050505050565b600060208252611e9d60208301846125c3565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b6020808252601f908201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604082015260600190565b60208082526019908201527f4e46544272696467653a20696e76616c69642073656e64657200000000000000604082015260600190565b60208082526026908201527f4e46544272696467653a204e756c6c206f726967696e616c20746f6b656e206160408201526564647265737360d01b606082015260800190565b6020808252601b908201527f4e46544272696467653a2057726f6e6720747844617461486173680000000000604082015260600190565b6020808252601190820152704272696467653a20557067726164696e6760781b604082015260600190565b6020808252818101527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c65604082015260600190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b60208082526024908201527f4e46544272696467653a205369646520746f6b656e20616c72656164792065786040820152636973747360e01b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252601490820152734e46544272696467653a204e756c6c2046726f6d60601b604082015260600190565b60208082526016908201527509c8ca884e4d2c8ceca74409cead8d840a8f090c2e6d60531b604082015260600190565b60208082526019908201527f4e46544272696467653a204e6f742046656465726174696f6e00000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526022908201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601e908201527f4e46544272696467653a2046656465726174696f6e20697320656d7074790000604082015260600190565b6020808252601a908201527f4e46544272696467653a20416c726561647920636c61696d6564000000000000604082015260600190565b60208082526018908201527f4e46544272696467653a20556e6b6e6f776e20746f6b656e0000000000000000604082015260600190565b6020808252601b908201527f4e46544272696467653a20416c72656164792061636365707465640000000000604082015260600190565b6020808252602a908201527f4e46544272696467653a2076616c756520697320736d616c6c6572207468616e6040820152692066697865642066656560b01b606082015260800190565b6020808252601290820152714e46544272696467653a204e756c6c20546f60701b604082015260600190565b6020808252601f908201527f4e46544272696467653a20416c6c6f77546f6b656e7320697320656d70747900604082015260600190565b60208082526019908201527f4e46544272696467653a204e756c6c20426c6f636b4861736800000000000000604082015260600190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526021908201527f4e46544272696467653a20656d7074792053696465546f6b656e466163746f726040820152607960f81b606082015260800190565b60405181810167ffffffffffffffff81118282101715612eec57fe5b604052919050565b600067ffffffffffffffff821115612f0857fe5b50601f01601f191660200190565b60005b83811015612f31578181015183820152602001612f19565b83811115612f40576000848401525b50505050565b6001600160a01b038116811461083357600080fdfea2646970667358221220c2db86366b65f97c4730018c60c95ed2c68e7f2ccd8332c152047ef6d532db2764736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "__Pausable_init(address)": {
+ "details": "Initializes the contract in unpaused state. Assigns the Pauser role to the deployer."
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "pause()": {
+ "details": "Called by a pauser to pause, triggers stopped state."
+ },
+ "paused()": {
+ "details": "Returns true if the contract is paused, and false otherwise."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "unpause()": {
+ "details": "Called by a pauser to unpause, returns to normal state."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "claim((address,address,uint256,address,bytes32,bytes32,uint32))": {
+ "notice": "Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data"
+ },
+ "onERC721Received(address,address,uint256,bytes)": {
+ "notice": "Always returns `IERC721Receiver.onERC721Received.selector`."
+ },
+ "receiveTokensTo(address,address,uint256)": {
+ "notice": "ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom"
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15789,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15792,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15832,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 15856,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "_pausers",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_struct(Role)10133_storage"
+ },
+ {
+ "astId": 15978,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "_paused",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16076,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "_owner",
+ "offset": 1,
+ "slot": "52",
+ "type": "t_address"
+ },
+ {
+ "astId": 16790,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "_guardCounter",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 8062,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "federation",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_address_payable"
+ },
+ {
+ "astId": 8064,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "fixedFee",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 8066,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "symbolPrefix",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 8070,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "sideTokenAddressByOriginalTokenAddress",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 8074,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "originalTokenAddressBySideTokenAddress",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 8078,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "isAddressFromCrossedOriginalToken",
+ "offset": 0,
+ "slot": "59",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 8082,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "claimed",
+ "offset": 0,
+ "slot": "60",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ },
+ {
+ "astId": 8084,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "allowTokens",
+ "offset": 0,
+ "slot": "61",
+ "type": "t_contract(IAllowTokens)7210"
+ },
+ {
+ "astId": 8086,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "sideTokenFactory",
+ "offset": 0,
+ "slot": "62",
+ "type": "t_contract(ISideNFTTokenFactory)7998"
+ },
+ {
+ "astId": 8088,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "isUpgrading",
+ "offset": 20,
+ "slot": "62",
+ "type": "t_bool"
+ },
+ {
+ "astId": 8092,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "transactionDataHashes",
+ "offset": 0,
+ "slot": "63",
+ "type": "t_mapping(t_bytes32,t_bytes32)"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_address_payable": {
+ "encoding": "inplace",
+ "label": "address payable",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IAllowTokens)7210": {
+ "encoding": "inplace",
+ "label": "contract IAllowTokens",
+ "numberOfBytes": "20"
+ },
+ "t_contract(ISideNFTTokenFactory)7998": {
+ "encoding": "inplace",
+ "label": "contract ISideNFTTokenFactory",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_address)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bytes32)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bytes32)",
+ "numberOfBytes": "32",
+ "value": "t_bytes32"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)10133_storage": {
+ "encoding": "inplace",
+ "label": "struct Roles.Role",
+ "members": [
+ {
+ "astId": 10132,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "bearer",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_address,t_bool)"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/NFTERC721TestToken.json b/bridge/deployments/rinkeby/NFTERC721TestToken.json
new file mode 100644
index 000000000..f9bcee448
--- /dev/null
+++ b/bridge/deployments/rinkeby/NFTERC721TestToken.json
@@ -0,0 +1,857 @@
+{
+ "address": "0xF0C541AB4e8b780f3e4F5E32d2bA4f2149d8baec",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name_",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol_",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "approved",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "approved",
+ "type": "bool"
+ }
+ ],
+ "name": "ApprovalForAll",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "baseURI",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "contractURI",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getApproved",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ }
+ ],
+ "name": "isApprovedForAll",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "ownerOf",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "safeMint",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "safeTransferFrom",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "name": "safeTransferFrom",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "internalType": "bool",
+ "name": "approved",
+ "type": "bool"
+ }
+ ],
+ "name": "setApprovalForAll",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "baseURI",
+ "type": "string"
+ }
+ ],
+ "name": "setBaseURI",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "contractURI_",
+ "type": "string"
+ }
+ ],
+ "name": "setContractURI",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "_tokenURI",
+ "type": "string"
+ }
+ ],
+ "name": "setTokenURI",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes4",
+ "name": "interfaceId",
+ "type": "bytes4"
+ }
+ ],
+ "name": "supportsInterface",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "index",
+ "type": "uint256"
+ }
+ ],
+ "name": "tokenByIndex",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "index",
+ "type": "uint256"
+ }
+ ],
+ "name": "tokenOfOwnerByIndex",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "tokenURI",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xf33df5c1fba0c36fcc5913c0f1b3dc9207e6279088c5f4afdcf905b42764824b",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0xF0C541AB4e8b780f3e4F5E32d2bA4f2149d8baec",
+ "transactionIndex": 1,
+ "gasUsed": "1941410",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xbbcb31e73e8733a52627ae96b990172c302cc3617210b83e788a958591364034",
+ "transactionHash": "0xf33df5c1fba0c36fcc5913c0f1b3dc9207e6279088c5f4afdcf905b42764824b",
+ "logs": [],
+ "blockNumber": 9269461,
+ "cumulativeGasUsed": "1992544",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "The Drops",
+ "drop"
+ ],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"baseURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"contractURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"baseURI\",\"type\":\"string\"}],\"name\":\"setBaseURI\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"contractURI_\",\"type\":\"string\"}],\"name\":\"setContractURI\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_tokenURI\",\"type\":\"string\"}],\"name\":\"setTokenURI\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"tokenByIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"tokenOfOwnerByIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"See {IERC721-approve}.\"},\"balanceOf(address)\":{\"details\":\"See {IERC721-balanceOf}.\"},\"baseURI()\":{\"details\":\"Returns the base URI set via {_setBaseURI}. This will be automatically added as a prefix in {tokenURI} to each token's URI, or to the token ID if no specific URI is set for that token ID.\"},\"getApproved(uint256)\":{\"details\":\"See {IERC721-getApproved}.\"},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC721-isApprovedForAll}.\"},\"name()\":{\"details\":\"See {IERC721Metadata-name}.\"},\"ownerOf(uint256)\":{\"details\":\"See {IERC721-ownerOf}.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"See {IERC721-setApprovalForAll}.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}. Time complexity O(1), guaranteed to always use less than 30 000 gas.\"},\"symbol()\":{\"details\":\"See {IERC721Metadata-symbol}.\"},\"tokenByIndex(uint256)\":{\"details\":\"See {IERC721Enumerable-tokenByIndex}.\"},\"tokenOfOwnerByIndex(address,uint256)\":{\"details\":\"See {IERC721Enumerable-tokenOfOwnerByIndex}.\"},\"tokenURI(uint256)\":{\"details\":\"See {IERC721Metadata-tokenURI}.\"},\"totalSupply()\":{\"details\":\"See {IERC721Enumerable-totalSupply}.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-transferFrom}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/test/nftbridge/NFTERC721TestToken.sol\":\"NFTERC721TestToken\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/test/nftbridge/NFTERC721TestToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\npragma solidity ^0.7.6;\\r\\n\\r\\nimport \\\"../../zeppelin/token/ERC721/ERC721.sol\\\";\\r\\n\\r\\ncontract NFTERC721TestToken is ERC721 {\\r\\n\\r\\n string private _contractURI;\\r\\n\\r\\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\\r\\n\\r\\n function safeMint(address to, uint256 tokenId) public {\\r\\n _safeMint(to, tokenId);\\r\\n }\\r\\n\\r\\n function setBaseURI(string memory baseURI) public {\\r\\n _setBaseURI(baseURI);\\r\\n }\\r\\n\\r\\n function setContractURI(string memory contractURI_) public {\\r\\n _contractURI = contractURI_;\\r\\n }\\r\\n\\r\\n function contractURI() public view returns (string memory) {\\r\\n return _contractURI;\\r\\n }\\r\\n\\r\\n function setTokenURI(uint256 tokenId, string memory _tokenURI) public {\\r\\n _setTokenURI(tokenId, _tokenURI);\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0xfaa852c22fbd356afad7a44c62ba1cdf118d962994f230bea7576159ecb17cba\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC165.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Implementation of the {IERC165} interface.\\r\\n *\\r\\n * Contracts may inherit from this and call {_registerInterface} to declare\\r\\n * their support of an interface.\\r\\n */\\r\\nabstract contract ERC165 is IERC165 {\\r\\n /*\\r\\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\\r\\n\\r\\n /**\\r\\n * @dev Mapping of interface ids to whether or not it's supported.\\r\\n */\\r\\n mapping(bytes4 => bool) private _supportedInterfaces;\\r\\n\\r\\n constructor () {\\r\\n // Derived contracts need only register support for their own interfaces,\\r\\n // we register support for ERC165 itself here\\r\\n _registerInterface(_INTERFACE_ID_ERC165);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC165-supportsInterface}.\\r\\n *\\r\\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\\r\\n */\\r\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\r\\n return _supportedInterfaces[interfaceId];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Registers the contract as an implementer of the interface defined by\\r\\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\\r\\n * registering its interface id is not required.\\r\\n *\\r\\n * See {IERC165-supportsInterface}.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\\r\\n */\\r\\n function _registerInterface(bytes4 interfaceId) internal virtual {\\r\\n require(interfaceId != 0xffffffff, \\\"ERC165: invalid interface id\\\");\\r\\n _supportedInterfaces[interfaceId] = true;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x5415f8c63658ee08e6284e6f270b2490331aea0c375b6451c4c9ed14a805a336\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC165 standard, as defined in the\\r\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\r\\n *\\r\\n * Implementers can declare support of contract interfaces, which can then be\\r\\n * queried by others ({ERC165Checker}).\\r\\n *\\r\\n * For an implementation, see {ERC165}.\\r\\n */\\r\\ninterface IERC165 {\\r\\n /**\\r\\n * @dev Returns true if this contract implements the interface defined by\\r\\n * `interfaceId`. See the corresponding\\r\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\r\\n * to learn more about how these ids are created.\\r\\n *\\r\\n * This function call must use less than 30 000 gas.\\r\\n */\\r\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\r\\n}\\r\\n\",\"keccak256\":\"0xd5da4ccf6a22475f021130a32aaad92daf6eecce9258cb7a8a5c48d109607767\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\r\\n * checks.\\r\\n *\\r\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\r\\n * in bugs, because programmers usually assume that an overflow raises an\\r\\n * error, which is the standard behavior in high level programming languages.\\r\\n * `SafeMath` restores this intuition by reverting the transaction when an\\r\\n * operation overflows.\\r\\n *\\r\\n * Using this library instead of the unchecked operations eliminates an entire\\r\\n * class of bugs, so it's recommended to use it always.\\r\\n */\\r\\nlibrary SafeMath {\\r\\n /**\\r\\n * @dev Returns the addition of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `+` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Addition cannot overflow.\\r\\n */\\r\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n uint256 c = a + b;\\r\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n */\\r\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b <= a, errorMessage);\\r\\n uint256 c = a - b;\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `*` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Multiplication cannot overflow.\\r\\n */\\r\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\r\\n // benefit is lost if 'b' is also tested.\\r\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\r\\n if (a == 0) {\\r\\n return 0;\\r\\n }\\r\\n\\r\\n uint256 c = a * b;\\r\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n // Solidity only automatically asserts when dividing by 0\\r\\n require(b > 0, errorMessage);\\r\\n uint256 c = a / b;\\r\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts with custom message when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b != 0, errorMessage);\\r\\n return a % b;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x29ffa7ff59806a3add585615cc102b70b43049587dcc73649f77b427f35b009d\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"./IERC721.sol\\\";\\r\\nimport \\\"./IERC721Metadata.sol\\\";\\r\\nimport \\\"./IERC721Enumerable.sol\\\";\\r\\nimport \\\"./IERC721Receiver.sol\\\";\\r\\nimport \\\"../../introspection/ERC165.sol\\\";\\r\\nimport \\\"../../math/SafeMath.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\nimport \\\"../../utils/EnumerableSet.sol\\\";\\r\\nimport \\\"../../utils/EnumerableMap.sol\\\";\\r\\nimport \\\"../../utils/Strings.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC721 Non-Fungible Token Standard basic implementation\\r\\n * @dev see https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\\r\\n using SafeMath for uint256;\\r\\n using Address for address;\\r\\n using EnumerableSet for EnumerableSet.UintSet;\\r\\n using EnumerableMap for EnumerableMap.UintToAddressMap;\\r\\n using Strings for uint256;\\r\\n\\r\\n // Equals to `bytes4(keccak256(\\\"onERC721Received(address,address,uint256,bytes)\\\"))`\\r\\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\\r\\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\\r\\n\\r\\n // Mapping from holder address to their (enumerable) set of owned tokens\\r\\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\\r\\n\\r\\n // Enumerable mapping from token ids to their owners\\r\\n EnumerableMap.UintToAddressMap private _tokenOwners;\\r\\n\\r\\n // Mapping from token ID to approved address\\r\\n mapping (uint256 => address) private _tokenApprovals;\\r\\n\\r\\n // Mapping from owner to operator approvals\\r\\n mapping (address => mapping (address => bool)) private _operatorApprovals;\\r\\n\\r\\n // Token name\\r\\n string private _name;\\r\\n\\r\\n // Token symbol\\r\\n string private _symbol;\\r\\n\\r\\n // Optional mapping for token URIs\\r\\n mapping (uint256 => string) private _tokenURIs;\\r\\n\\r\\n // Base URI\\r\\n string private _baseURI;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\\r\\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\\r\\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\\r\\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\\r\\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\\r\\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\\r\\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\\r\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\\r\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\\r\\n *\\r\\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\\r\\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('name()')) == 0x06fdde03\\r\\n * bytes4(keccak256('symbol()')) == 0x95d89b41\\r\\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\\r\\n *\\r\\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\\r\\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\\r\\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\\r\\n *\\r\\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\r\\n */\\r\\n constructor (string memory name_, string memory symbol_) {\\r\\n _name = name_;\\r\\n _symbol = symbol_;\\r\\n\\r\\n // register the supported interfaces to conform to ERC721 via ERC165\\r\\n _registerInterface(_INTERFACE_ID_ERC721);\\r\\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\\r\\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-balanceOf}.\\r\\n */\\r\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\r\\n require(owner != address(0), \\\"ERC721: balance query for the zero address\\\");\\r\\n return _holderTokens[owner].length();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-ownerOf}.\\r\\n */\\r\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\r\\n return _tokenOwners.get(tokenId, \\\"ERC721: owner query for nonexistent token\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-name}.\\r\\n */\\r\\n function name() public view virtual override returns (string memory) {\\r\\n return _name;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-symbol}.\\r\\n */\\r\\n function symbol() public view virtual override returns (string memory) {\\r\\n return _symbol;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-tokenURI}.\\r\\n */\\r\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\r\\n require(_exists(tokenId), \\\"ERC721Metadata: URI query for nonexistent token\\\");\\r\\n\\r\\n string memory _tokenURI = _tokenURIs[tokenId];\\r\\n string memory base = baseURI();\\r\\n\\r\\n // If there is no base URI, return the token URI.\\r\\n if (bytes(base).length == 0) {\\r\\n return _tokenURI;\\r\\n }\\r\\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\\r\\n if (bytes(_tokenURI).length > 0) {\\r\\n return string(abi.encodePacked(base, _tokenURI));\\r\\n }\\r\\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\\r\\n return string(abi.encodePacked(base, tokenId.toString()));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the base URI set via {_setBaseURI}. This will be\\r\\n * automatically added as a prefix in {tokenURI} to each token's URI, or\\r\\n * to the token ID if no specific URI is set for that token ID.\\r\\n */\\r\\n function baseURI() public view virtual returns (string memory) {\\r\\n return _baseURI;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\r\\n */\\r\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\r\\n return _holderTokens[owner].at(index);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-totalSupply}.\\r\\n */\\r\\n function totalSupply() public view virtual override returns (uint256) {\\r\\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\\r\\n return _tokenOwners.length();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\r\\n */\\r\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\r\\n (uint256 tokenId, ) = _tokenOwners.at(index);\\r\\n return tokenId;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-approve}.\\r\\n */\\r\\n function approve(address to, uint256 tokenId) public virtual override {\\r\\n address owner = ERC721.ownerOf(tokenId);\\r\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\r\\n\\r\\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\\r\\n \\\"ERC721: approve caller is not owner nor approved for all\\\"\\r\\n );\\r\\n\\r\\n _approve(to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-getApproved}.\\r\\n */\\r\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\r\\n require(_exists(tokenId), \\\"ERC721: approved query for nonexistent token\\\");\\r\\n\\r\\n return _tokenApprovals[tokenId];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-setApprovalForAll}.\\r\\n */\\r\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\r\\n require(operator != _msgSender(), \\\"ERC721: approve to caller\\\");\\r\\n\\r\\n _operatorApprovals[_msgSender()][operator] = approved;\\r\\n emit ApprovalForAll(_msgSender(), operator, approved);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-isApprovedForAll}.\\r\\n */\\r\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\r\\n return _operatorApprovals[owner][operator];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-transferFrom}.\\r\\n */\\r\\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\\r\\n //solhint-disable-next-line max-line-length\\r\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\r\\n\\r\\n _transfer(from, to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-safeTransferFrom}.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\\r\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-safeTransferFrom}.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\\r\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\r\\n _safeTransfer(from, to, tokenId, _data);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\r\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\r\\n *\\r\\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\\r\\n *\\r\\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\r\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\\r\\n _transfer(from, to, tokenId);\\r\\n require(_checkOnERC721Received(from, to, tokenId, _data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns whether `tokenId` exists.\\r\\n *\\r\\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\r\\n *\\r\\n * Tokens start existing when they are minted (`_mint`),\\r\\n * and stop existing when they are burned (`_burn`).\\r\\n */\\r\\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\\r\\n return _tokenOwners.contains(tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\r\\n require(_exists(tokenId), \\\"ERC721: operator query for nonexistent token\\\");\\r\\n address owner = ERC721.ownerOf(tokenId);\\r\\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\r\\n *\\r\\n * Requirements:\\r\\n d*\\r\\n * - `tokenId` must not exist.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\r\\n _safeMint(to, tokenId, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\r\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\r\\n */\\r\\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\\r\\n _mint(to, tokenId);\\r\\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Mints `tokenId` and transfers it to `to`.\\r\\n *\\r\\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must not exist.\\r\\n * - `to` cannot be the zero address.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _mint(address to, uint256 tokenId) internal virtual {\\r\\n require(to != address(0), \\\"ERC721: mint to the zero address\\\");\\r\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\r\\n\\r\\n _beforeTokenTransfer(address(0), to, tokenId);\\r\\n\\r\\n _holderTokens[to].add(tokenId);\\r\\n\\r\\n _tokenOwners.set(tokenId, to);\\r\\n\\r\\n emit Transfer(address(0), to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Destroys `tokenId`.\\r\\n * The approval is cleared when the token is burned.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _burn(uint256 tokenId) internal virtual {\\r\\n address owner = ERC721.ownerOf(tokenId); // internal owner\\r\\n\\r\\n _beforeTokenTransfer(owner, address(0), tokenId);\\r\\n\\r\\n // Clear approvals\\r\\n _approve(address(0), tokenId);\\r\\n\\r\\n // Clear metadata (if any)\\r\\n if (bytes(_tokenURIs[tokenId]).length != 0) {\\r\\n delete _tokenURIs[tokenId];\\r\\n }\\r\\n\\r\\n _holderTokens[owner].remove(tokenId);\\r\\n\\r\\n _tokenOwners.remove(tokenId);\\r\\n\\r\\n emit Transfer(owner, address(0), tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers `tokenId` from `from` to `to`.\\r\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must be owned by `from`.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\\r\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer of token that is not own\\\"); // internal owner\\r\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\r\\n\\r\\n _beforeTokenTransfer(from, to, tokenId);\\r\\n\\r\\n // Clear approvals from the previous owner\\r\\n _approve(address(0), tokenId);\\r\\n\\r\\n _holderTokens[from].remove(tokenId);\\r\\n _holderTokens[to].add(tokenId);\\r\\n\\r\\n _tokenOwners.set(tokenId, to);\\r\\n\\r\\n emit Transfer(from, to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\\r\\n require(_exists(tokenId), \\\"ERC721Metadata: URI set of nonexistent token\\\");\\r\\n _tokenURIs[tokenId] = _tokenURI;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Internal function to set the base URI for all token IDs. It is\\r\\n * automatically added as a prefix to the value returned in {tokenURI},\\r\\n * or to the token ID if {tokenURI} is empty.\\r\\n */\\r\\n function _setBaseURI(string memory baseURI_) internal virtual {\\r\\n _baseURI = baseURI_;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\r\\n * The call is not executed if the target address is not a contract.\\r\\n *\\r\\n * @param from address representing the previous owner of the given token ID\\r\\n * @param to target address that will receive the tokens\\r\\n * @param tokenId uint256 ID of the token to be transferred\\r\\n * @param _data bytes optional data to send along with the call\\r\\n * @return bool whether the call correctly returned the expected magic value\\r\\n */\\r\\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\\r\\n private returns (bool)\\r\\n {\\r\\n if (!to.isContract()) {\\r\\n return true;\\r\\n }\\r\\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\\r\\n IERC721Receiver(to).onERC721Received.selector,\\r\\n _msgSender(),\\r\\n from,\\r\\n tokenId,\\r\\n _data\\r\\n ), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n bytes4 retval = abi.decode(returndata, (bytes4));\\r\\n return (retval == _ERC721_RECEIVED);\\r\\n }\\r\\n\\r\\n function _approve(address to, uint256 tokenId) private {\\r\\n _tokenApprovals[tokenId] = to;\\r\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Hook that is called before any token transfer. This includes minting\\r\\n * and burning.\\r\\n *\\r\\n * Calling conditions:\\r\\n *\\r\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\r\\n * transferred to `to`.\\r\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\r\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n *\\r\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\r\\n */\\r\\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\\r\\n}\\r\\n\",\"keccak256\":\"0x4180eedc31f632ef146dd07583840a9688de44bdb9e7fe2425c448fd57496004\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../../introspection/IERC165.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Required interface of an ERC721 compliant contract.\\r\\n */\\r\\ninterface IERC721 is IERC165 {\\r\\n /**\\r\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\r\\n */\\r\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\r\\n */\\r\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\r\\n */\\r\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of tokens in ``owner``'s account.\\r\\n */\\r\\n function balanceOf(address owner) external view returns (uint256 balance);\\r\\n\\r\\n /**\\r\\n * @dev Returns the owner of the `tokenId` token.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\r\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Transfers `tokenId` token from `from` to `to`.\\r\\n *\\r\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must be owned by `from`.\\r\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transferFrom(address from, address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\r\\n * The approval is cleared when the token is transferred.\\r\\n *\\r\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - The caller must own the token or be an approved operator.\\r\\n * - `tokenId` must exist.\\r\\n *\\r\\n * Emits an {Approval} event.\\r\\n */\\r\\n function approve(address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the account approved for `tokenId` token.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function getApproved(uint256 tokenId) external view returns (address operator);\\r\\n\\r\\n /**\\r\\n * @dev Approve or remove `operator` as an operator for the caller.\\r\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - The `operator` cannot be the caller.\\r\\n *\\r\\n * Emits an {ApprovalForAll} event.\\r\\n */\\r\\n function setApprovalForAll(address operator, bool _approved) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\r\\n *\\r\\n * See {setApprovalForAll}\\r\\n */\\r\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\r\\n}\\r\\n\",\"keccak256\":\"0xd3c22060e78ce52f5cb41b3ab9b29bb5582aa4a58015e878116251cba658324c\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC721.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\r\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ninterface IERC721Enumerable is IERC721 {\\r\\n\\r\\n /**\\r\\n * @dev Returns the total amount of tokens stored by the contract.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\r\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\r\\n */\\r\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\r\\n * Use along with {totalSupply} to enumerate all tokens.\\r\\n */\\r\\n function tokenByIndex(uint256 index) external view returns (uint256);\\r\\n}\\r\\n\",\"keccak256\":\"0x5539b1567797a57e7a135dcc446fdbb02b1ae2b450799274db88a47dea81e6fa\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC721.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\r\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ninterface IERC721Metadata is IERC721 {\\r\\n\\r\\n /**\\r\\n * @dev Returns the token collection name.\\r\\n */\\r\\n function name() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the token collection symbol.\\r\\n */\\r\\n function symbol() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\r\\n */\\r\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\r\\n}\\r\\n\",\"keccak256\":\"0xe92ae6f0b94fce8480d16a24faa8835926cd5fc074a4d418de94aaddbdecf49d\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @title ERC721 token receiver interface\\r\\n * @dev Interface for any contract that wants to support safeTransfers\\r\\n * from ERC721 asset contracts.\\r\\n */\\r\\ninterface IERC721Receiver {\\r\\n /**\\r\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\r\\n * by `operator` from `from`, this function is called.\\r\\n *\\r\\n * It must return its Solidity selector to confirm the token transfer.\\r\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\r\\n *\\r\\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\\r\\n */\\r\\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\\r\\n}\\r\\n\",\"keccak256\":\"0x515410f905897b0d658f1746064cc2a94d52a1bc625fab215dccb7fb5ead50f7\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/EnumerableMap.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Library for managing an enumerable variant of Solidity's\\r\\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\\r\\n * type.\\r\\n *\\r\\n * Maps have the following properties:\\r\\n *\\r\\n * - Entries are added, removed, and checked for existence in constant time\\r\\n * (O(1)).\\r\\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\\r\\n *\\r\\n * ```\\r\\n * contract Example {\\r\\n * // Add the library methods\\r\\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\\r\\n *\\r\\n * // Declare a set state variable\\r\\n * EnumerableMap.UintToAddressMap private myMap;\\r\\n * }\\r\\n * ```\\r\\n *\\r\\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\\r\\n * supported.\\r\\n */\\r\\nlibrary EnumerableMap {\\r\\n // To implement this library for multiple types with as little code\\r\\n // repetition as possible, we write it in terms of a generic Map type with\\r\\n // bytes32 keys and values.\\r\\n // The Map implementation uses private functions, and user-facing\\r\\n // implementations (such as Uint256ToAddressMap) are just wrappers around\\r\\n // the underlying Map.\\r\\n // This means that we can only create new EnumerableMaps for types that fit\\r\\n // in bytes32.\\r\\n\\r\\n struct MapEntry {\\r\\n bytes32 _key;\\r\\n bytes32 _value;\\r\\n }\\r\\n\\r\\n struct Map {\\r\\n // Storage of map keys and values\\r\\n MapEntry[] _entries;\\r\\n\\r\\n // Position of the entry defined by a key in the `entries` array, plus 1\\r\\n // because index 0 means a key is not in the map.\\r\\n mapping (bytes32 => uint256) _indexes;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Adds a key-value pair to a map, or updates the value for an existing\\r\\n * key. O(1).\\r\\n *\\r\\n * Returns true if the key was added to the map, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\\r\\n // We read and store the key's index to prevent multiple reads from the same storage slot\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n\\r\\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\\r\\n map._entries.push(MapEntry({ _key: key, _value: value }));\\r\\n // The entry is stored at length-1, but we add 1 to all indexes\\r\\n // and use 0 as a sentinel value\\r\\n map._indexes[key] = map._entries.length;\\r\\n return true;\\r\\n } else {\\r\\n map._entries[keyIndex - 1]._value = value;\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a key-value pair from a map. O(1).\\r\\n *\\r\\n * Returns true if the key was removed from the map, that is if it was present.\\r\\n */\\r\\n function _remove(Map storage map, bytes32 key) private returns (bool) {\\r\\n // We read and store the key's index to prevent multiple reads from the same storage slot\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n\\r\\n if (keyIndex != 0) { // Equivalent to contains(map, key)\\r\\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\\r\\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\\r\\n // This modifies the order of the array, as noted in {at}.\\r\\n\\r\\n uint256 toDeleteIndex = keyIndex - 1;\\r\\n uint256 lastIndex = map._entries.length - 1;\\r\\n\\r\\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\\r\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\r\\n\\r\\n MapEntry storage lastEntry = map._entries[lastIndex];\\r\\n\\r\\n // Move the last entry to the index where the entry to delete is\\r\\n map._entries[toDeleteIndex] = lastEntry;\\r\\n // Update the index for the moved entry\\r\\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\\r\\n\\r\\n // Delete the slot where the moved entry was stored\\r\\n map._entries.pop();\\r\\n\\r\\n // Delete the index for the deleted slot\\r\\n delete map._indexes[key];\\r\\n\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the key is in the map. O(1).\\r\\n */\\r\\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\\r\\n return map._indexes[key] != 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of key-value pairs in the map. O(1).\\r\\n */\\r\\n function _length(Map storage map) private view returns (uint256) {\\r\\n return map._entries.length;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of entries inside the\\r\\n * array, and it may change when more entries are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\\r\\n require(map._entries.length > index, \\\"EnumerableMap: index out of bounds\\\");\\r\\n\\r\\n MapEntry storage entry = map._entries[index];\\r\\n return (entry._key, entry._value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Tries to returns the value associated with `key`. O(1).\\r\\n * Does not revert if `key` is not in the map.\\r\\n */\\r\\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\\r\\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value associated with `key`. O(1).\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `key` must be in the map.\\r\\n */\\r\\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n require(keyIndex != 0, \\\"EnumerableMap: nonexistent key\\\"); // Equivalent to contains(map, key)\\r\\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\\r\\n *\\r\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\r\\n * message unnecessarily. For custom revert reasons use {_tryGet}.\\r\\n */\\r\\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\\r\\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\\r\\n }\\r\\n\\r\\n // UintToAddressMap\\r\\n\\r\\n struct UintToAddressMap {\\r\\n Map _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Adds a key-value pair to a map, or updates the value for an existing\\r\\n * key. O(1).\\r\\n *\\r\\n * Returns true if the key was added to the map, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\\r\\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the key was removed from the map, that is if it was present.\\r\\n */\\r\\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\\r\\n return _remove(map._inner, bytes32(key));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the key is in the map. O(1).\\r\\n */\\r\\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\\r\\n return _contains(map._inner, bytes32(key));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of elements in the map. O(1).\\r\\n */\\r\\n function length(UintToAddressMap storage map) internal view returns (uint256) {\\r\\n return _length(map._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the element stored at position `index` in the set. O(1).\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\\r\\n (bytes32 key, bytes32 value) = _at(map._inner, index);\\r\\n return (uint256(key), address(uint160(uint256(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Tries to returns the value associated with `key`. O(1).\\r\\n * Does not revert if `key` is not in the map.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\\r\\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\\r\\n return (success, address(uint160(uint256(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value associated with `key`. O(1).\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `key` must be in the map.\\r\\n */\\r\\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\\r\\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\\r\\n *\\r\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\r\\n * message unnecessarily. For custom revert reasons use {tryGet}.\\r\\n */\\r\\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\\r\\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x5538ae23826bfaa205dc16a24a50f18feaae576a1c46ddea7086bbbd4c13d84e\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Library for managing\\r\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\r\\n * types.\\r\\n *\\r\\n * Sets have the following properties:\\r\\n *\\r\\n * - Elements are added, removed, and checked for existence in constant time\\r\\n * (O(1)).\\r\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\r\\n *\\r\\n * ```\\r\\n * contract Example {\\r\\n * // Add the library methods\\r\\n * using EnumerableSet for EnumerableSet.AddressSet;\\r\\n *\\r\\n * // Declare a set state variable\\r\\n * EnumerableSet.AddressSet private mySet;\\r\\n * }\\r\\n * ```\\r\\n *\\r\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\r\\n * and `uint256` (`UintSet`) are supported.\\r\\n */\\r\\nlibrary EnumerableSet {\\r\\n // To implement this library for multiple types with as little code\\r\\n // repetition as possible, we write it in terms of a generic Set type with\\r\\n // bytes32 values.\\r\\n // The Set implementation uses private functions, and user-facing\\r\\n // implementations (such as AddressSet) are just wrappers around the\\r\\n // underlying Set.\\r\\n // This means that we can only create new EnumerableSets for types that fit\\r\\n // in bytes32.\\r\\n\\r\\n struct Set {\\r\\n // Storage of set values\\r\\n bytes32[] _values;\\r\\n\\r\\n // Position of the value in the `values` array, plus 1 because index 0\\r\\n // means a value is not in the set.\\r\\n mapping (bytes32 => uint256) _indexes;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\r\\n if (!_contains(set, value)) {\\r\\n set._values.push(value);\\r\\n // The value is stored at length-1, but we add 1 to all indexes\\r\\n // and use 0 as a sentinel value\\r\\n set._indexes[value] = set._values.length;\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\r\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\r\\n uint256 valueIndex = set._indexes[value];\\r\\n\\r\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\r\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\r\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\r\\n // This modifies the order of the array, as noted in {at}.\\r\\n\\r\\n uint256 toDeleteIndex = valueIndex - 1;\\r\\n uint256 lastIndex = set._values.length - 1;\\r\\n\\r\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\r\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\r\\n\\r\\n bytes32 lastvalue = set._values[lastIndex];\\r\\n\\r\\n // Move the last value to the index where the value to delete is\\r\\n set._values[toDeleteIndex] = lastvalue;\\r\\n // Update the index for the moved value\\r\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\r\\n\\r\\n // Delete the slot where the moved value was stored\\r\\n set._values.pop();\\r\\n\\r\\n // Delete the index for the deleted slot\\r\\n delete set._indexes[value];\\r\\n\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\r\\n return set._indexes[value] != 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values on the set. O(1).\\r\\n */\\r\\n function _length(Set storage set) private view returns (uint256) {\\r\\n return set._values.length;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\r\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\r\\n return set._values[index];\\r\\n }\\r\\n\\r\\n // Bytes32Set\\r\\n\\r\\n struct Bytes32Set {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\r\\n return _add(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\r\\n return _remove(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\r\\n return _contains(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values in the set. O(1).\\r\\n */\\r\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\r\\n return _at(set._inner, index);\\r\\n }\\r\\n\\r\\n // AddressSet\\r\\n\\r\\n struct AddressSet {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(AddressSet storage set, address value) internal returns (bool) {\\r\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\r\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\r\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values in the set. O(1).\\r\\n */\\r\\n function length(AddressSet storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\r\\n return address(uint160(uint256(_at(set._inner, index))));\\r\\n }\\r\\n\\r\\n\\r\\n // UintSet\\r\\n\\r\\n struct UintSet {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\r\\n return _add(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\r\\n return _remove(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\r\\n return _contains(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values on the set. O(1).\\r\\n */\\r\\n function length(UintSet storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\r\\n return uint256(_at(set._inner, index));\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x4c3f4a13b8f0c2b911044b85d3db13396e772cb9b79f7fb16ec8d41ca5fc7321\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev String operations.\\r\\n */\\r\\nlibrary Strings {\\r\\n /**\\r\\n * @dev Converts a `uint256` to its ASCII `string` representation.\\r\\n */\\r\\n function toString(uint256 value) internal pure returns (string memory) {\\r\\n // Inspired by OraclizeAPI's implementation - MIT licence\\r\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\r\\n\\r\\n if (value == 0) {\\r\\n return \\\"0\\\";\\r\\n }\\r\\n uint256 temp = value;\\r\\n uint256 digits;\\r\\n while (temp != 0) {\\r\\n digits++;\\r\\n temp /= 10;\\r\\n }\\r\\n bytes memory buffer = new bytes(digits);\\r\\n uint256 index = digits - 1;\\r\\n temp = value;\\r\\n while (temp != 0) {\\r\\n buffer[index--] = bytes1(uint8(48 + temp % 10));\\r\\n temp /= 10;\\r\\n }\\r\\n return string(buffer);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x0f1313d4fbca3b365d39200fc056b6db57b957b53dabb06d6fff3566fb8caa29\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x60806040523480156200001157600080fd5b50604051620022da380380620022da833981810160405260408110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405250839150829050620001b56301ffc9a760e01b62000221565b8151620001ca906006906020850190620002a6565b508051620001e0906007906020840190620002a6565b50620001f36380ac58cd60e01b62000221565b62000205635b5e139f60e01b62000221565b6200021763780e9d6360e01b62000221565b5050505062000352565b6001600160e01b0319808216141562000281576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620002de576000855562000329565b82601f10620002f957805160ff191683800117855562000329565b8280016001018555821562000329579182015b82811115620003295782518255916020019190600101906200030c565b50620003379291506200033b565b5090565b5b808211156200033757600081556001016200033c565b611f7880620003626000396000f3fe608060405234801561001057600080fd5b50600436106101425760003560e01c80636352211e116100b8578063a14481941161007c578063a14481941461057b578063a22cb465146105a7578063b88d4fde146105d5578063c87b56dd14610699578063e8a3d485146106b6578063e985e9c5146106be57610142565b80636352211e146104845780636c0360eb146104a157806370a08231146104a9578063938e3d7b146104cf57806395d89b411461057357610142565b806318160ddd1161010a57806318160ddd1461031157806323b872dd1461032b5780632f745c591461036157806342842e0e1461038d5780634f6ccce7146103c357806355f804b3146103e057610142565b806301ffc9a71461014757806306fdde0314610182578063081812fc146101ff578063095ea7b314610238578063162094c414610266575b600080fd5b61016e6004803603602081101561015d57600080fd5b50356001600160e01b0319166106ec565b604080519115158252519081900360200190f35b61018a61070f565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101c45781810151838201526020016101ac565b50505050905090810190601f1680156101f15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61021c6004803603602081101561021557600080fd5b50356107a5565b604080516001600160a01b039092168252519081900360200190f35b6102646004803603604081101561024e57600080fd5b506001600160a01b038135169060200135610807565b005b6102646004803603604081101561027c57600080fd5b81359190810190604081016020820135600160201b81111561029d57600080fd5b8201836020820111156102af57600080fd5b803590602001918460018302840111600160201b831117156102d057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506108e2945050505050565b6103196108f0565b60408051918252519081900360200190f35b6102646004803603606081101561034157600080fd5b506001600160a01b03813581169160208101359091169060400135610901565b6103196004803603604081101561037757600080fd5b506001600160a01b038135169060200135610958565b610264600480360360608110156103a357600080fd5b506001600160a01b03813581169160208101359091169060400135610983565b610319600480360360208110156103d957600080fd5b503561099e565b610264600480360360208110156103f657600080fd5b810190602081018135600160201b81111561041057600080fd5b82018360208201111561042257600080fd5b803590602001918460018302840111600160201b8311171561044357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506109b4945050505050565b61021c6004803603602081101561049a57600080fd5b50356109c0565b61018a6109e8565b610319600480360360208110156104bf57600080fd5b50356001600160a01b0316610a49565b610264600480360360208110156104e557600080fd5b810190602081018135600160201b8111156104ff57600080fd5b82018360208201111561051157600080fd5b803590602001918460018302840111600160201b8311171561053257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610ab1945050505050565b61018a610ac4565b6102646004803603604081101561059157600080fd5b506001600160a01b038135169060200135610b25565b610264600480360360408110156105bd57600080fd5b506001600160a01b0381351690602001351515610b2f565b610264600480360360808110156105eb57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561062557600080fd5b82018360208201111561063757600080fd5b803590602001918460018302840111600160201b8311171561065857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610c34945050505050565b61018a600480360360208110156106af57600080fd5b5035610c92565b61018a610f13565b61016e600480360360408110156106d457600080fd5b506001600160a01b0381358116916020013516610f74565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60068054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561079b5780601f106107705761010080835404028352916020019161079b565b820191906000526020600020905b81548152906001019060200180831161077e57829003601f168201915b5050505050905090565b60006107b082610fa2565b6107eb5760405162461bcd60e51b815260040180806020018281038252602c815260200180611e41602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610812826109c0565b9050806001600160a01b0316836001600160a01b031614156108655760405162461bcd60e51b8152600401808060200182810382526021815260200180611ef16021913960400191505060405180910390fd5b806001600160a01b0316610877610faf565b6001600160a01b03161480610898575061089881610893610faf565b610f74565b6108d35760405162461bcd60e51b8152600401808060200182810382526038815260200180611d946038913960400191505060405180910390fd5b6108dd8383610fb3565b505050565b6108ec8282611021565b5050565b60006108fc6002611084565b905090565b61091261090c610faf565b8261108f565b61094d5760405162461bcd60e51b8152600401808060200182810382526031815260200180611f126031913960400191505060405180910390fd5b6108dd838383611133565b6001600160a01b038216600090815260016020526040812061097a908361127f565b90505b92915050565b6108dd83838360405180602001604052806000815250610c34565b6000806109ac60028461128b565b509392505050565b6109bd816112a7565b50565b600061097d82604051806060016040528060298152602001611df660299139600291906112ba565b60098054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561079b5780601f106107705761010080835404028352916020019161079b565b60006001600160a01b038216610a905760405162461bcd60e51b815260040180806020018281038252602a815260200180611dcc602a913960400191505060405180910390fd5b6001600160a01b038216600090815260016020526040902061097d90611084565b80516108ec90600a906020840190611b9c565b60078054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561079b5780601f106107705761010080835404028352916020019161079b565b6108ec82826112d1565b610b37610faf565b6001600160a01b0316826001600160a01b03161415610b9d576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b8060056000610baa610faf565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610bee610faf565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b610c45610c3f610faf565b8361108f565b610c805760405162461bcd60e51b8152600401808060200182810382526031815260200180611f126031913960400191505060405180910390fd5b610c8c848484846112eb565b50505050565b6060610c9d82610fa2565b610cd85760405162461bcd60e51b815260040180806020018281038252602f815260200180611ec2602f913960400191505060405180910390fd5b60008281526008602090815260408083208054825160026001831615610100026000190190921691909104601f810185900485028201850190935282815292909190830182828015610d6b5780601f10610d4057610100808354040283529160200191610d6b565b820191906000526020600020905b815481529060010190602001808311610d4e57829003601f168201915b505050505090506000610d7c6109e8565b9050805160001415610d905750905061070a565b815115610e515780826040516020018083805190602001908083835b60208310610dcb5780518252601f199092019160209182019101610dac565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610e135780518252601f199092019160209182019101610df4565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529250505061070a565b80610e5b8561133d565b6040516020018083805190602001908083835b60208310610e8d5780518252601f199092019160209182019101610e6e565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610ed55780518252601f199092019160209182019101610eb6565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b600a8054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561079b5780601f106107705761010080835404028352916020019161079b565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b600061097d600283611418565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610fe8826109c0565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b61102a82610fa2565b6110655760405162461bcd60e51b815260040180806020018281038252602c815260200180611e6d602c913960400191505060405180910390fd5b600082815260086020908152604090912082516108dd92840190611b9c565b600061097d82611424565b600061109a82610fa2565b6110d55760405162461bcd60e51b815260040180806020018281038252602c815260200180611d68602c913960400191505060405180910390fd5b60006110e0836109c0565b9050806001600160a01b0316846001600160a01b0316148061111b5750836001600160a01b0316611110846107a5565b6001600160a01b0316145b8061112b575061112b8185610f74565b949350505050565b826001600160a01b0316611146826109c0565b6001600160a01b03161461118b5760405162461bcd60e51b8152600401808060200182810382526029815260200180611e996029913960400191505060405180910390fd5b6001600160a01b0382166111d05760405162461bcd60e51b8152600401808060200182810382526024815260200180611d446024913960400191505060405180910390fd5b6111db8383836108dd565b6111e6600082610fb3565b6001600160a01b03831660009081526001602052604090206112089082611428565b506001600160a01b038216600090815260016020526040902061122b9082611434565b5061123860028284611440565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600061097a8383611456565b600080808061129a86866114ba565b9097909650945050505050565b80516108ec906009906020840190611b9c565b60006112c7848484611535565b90505b9392505050565b6108ec8282604051806020016040528060008152506115ff565b6112f6848484611133565b61130284848484611651565b610c8c5760405162461bcd60e51b8152600401808060200182810382526032815260200180611d126032913960400191505060405180910390fd5b60608161136257506040805180820190915260018152600360fc1b602082015261070a565b8160005b811561137a57600101600a82049150611366565b60008167ffffffffffffffff8111801561139357600080fd5b506040519080825280601f01601f1916602001820160405280156113be576020820181803683370190505b50859350905060001982015b831561140f57600a840660300160f81b828280600190039350815181106113ed57fe5b60200101906001600160f81b031916908160001a905350600a840493506113ca565b50949350505050565b600061097a83836117b9565b5490565b600061097a83836117d1565b600061097a8383611897565b60006112c784846001600160a01b0385166118e1565b815460009082106114985760405162461bcd60e51b8152600401808060200182810382526022815260200180611cf06022913960400191505060405180910390fd5b8260000182815481106114a757fe5b9060005260206000200154905092915050565b8154600090819083106114fe5760405162461bcd60e51b8152600401808060200182810382526022815260200180611e1f6022913960400191505060405180910390fd5b600084600001848154811061150f57fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816115d05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561159557818101518382015260200161157d565b50505050905090810190601f1680156115c25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508460000160018203815481106115e357fe5b9060005260206000209060020201600101549150509392505050565b6116098383611978565b6116166000848484611651565b6108dd5760405162461bcd60e51b8152600401808060200182810382526032815260200180611d126032913960400191505060405180910390fd5b6000611665846001600160a01b0316611aa6565b6116715750600161112b565b600061177f630a85bd0160e11b611686610faf565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156116ed5781810151838201526020016116d5565b50505050905090810190601f16801561171a5780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001611d12603291396001600160a01b0388169190611aac565b9050600081806020019051602081101561179857600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60009081526001919091016020526040902054151590565b6000818152600183016020526040812054801561188d578354600019808301919081019060009087908390811061180457fe5b906000526020600020015490508087600001848154811061182157fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061185157fe5b6001900381819060005260206000200160009055905586600101600087815260200190815260200160002060009055600194505050505061097d565b600091505061097d565b60006118a383836117b9565b6118d95750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561097d565b50600061097d565b6000828152600184016020526040812054806119465750506040805180820182528381526020808201848152865460018181018955600089815284812095516002909302909501918255915190820155865486845281880190925292909120556112ca565b8285600001600183038154811061195957fe5b90600052602060002090600202016001018190555060009150506112ca565b6001600160a01b0382166119d3576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6119dc81610fa2565b15611a2e576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b611a3a600083836108dd565b6001600160a01b0382166000908152600160205260409020611a5c9082611434565b50611a6960028284611440565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b3b151590565b60606112c7848460008585611ac5565b60405180910390fd5b611ace85611aa6565b611aea5760405162461bcd60e51b8152600401611abc90611c8c565b600080866001600160a01b03168587604051611b069190611c3d565b60006040518083038185875af1925050503d8060008114611b43576040519150601f19603f3d011682016040523d82523d6000602084013e611b48565b606091505b5091509150611b58828286611b63565b979650505050505050565b60608315611b725750816112ca565b825115611b825782518084602001fd5b8160405162461bcd60e51b8152600401611abc9190611c59565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611bd25760008555611c18565b82601f10611beb57805160ff1916838001178555611c18565b82800160010185558215611c18579182015b82811115611c18578251825591602001919060010190611bfd565b50611c24929150611c28565b5090565b5b80821115611c245760008155600101611c29565b60008251611c4f818460208701611cc3565b9190910192915050565b6000602082528251806020840152611c78816040850160208701611cc3565b601f01601f19169190910160400192915050565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60005b83811015611cde578181015183820152602001611cc6565b83811115610c8c575050600091015256fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732314d657461646174613a2055524920736574206f66206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a264697066735822122035771dce7eba2aa8f2ea7dea8aa8250633a73f64284bc80cfce60ee5b60e7f1664736f6c63430007060033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101425760003560e01c80636352211e116100b8578063a14481941161007c578063a14481941461057b578063a22cb465146105a7578063b88d4fde146105d5578063c87b56dd14610699578063e8a3d485146106b6578063e985e9c5146106be57610142565b80636352211e146104845780636c0360eb146104a157806370a08231146104a9578063938e3d7b146104cf57806395d89b411461057357610142565b806318160ddd1161010a57806318160ddd1461031157806323b872dd1461032b5780632f745c591461036157806342842e0e1461038d5780634f6ccce7146103c357806355f804b3146103e057610142565b806301ffc9a71461014757806306fdde0314610182578063081812fc146101ff578063095ea7b314610238578063162094c414610266575b600080fd5b61016e6004803603602081101561015d57600080fd5b50356001600160e01b0319166106ec565b604080519115158252519081900360200190f35b61018a61070f565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101c45781810151838201526020016101ac565b50505050905090810190601f1680156101f15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61021c6004803603602081101561021557600080fd5b50356107a5565b604080516001600160a01b039092168252519081900360200190f35b6102646004803603604081101561024e57600080fd5b506001600160a01b038135169060200135610807565b005b6102646004803603604081101561027c57600080fd5b81359190810190604081016020820135600160201b81111561029d57600080fd5b8201836020820111156102af57600080fd5b803590602001918460018302840111600160201b831117156102d057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506108e2945050505050565b6103196108f0565b60408051918252519081900360200190f35b6102646004803603606081101561034157600080fd5b506001600160a01b03813581169160208101359091169060400135610901565b6103196004803603604081101561037757600080fd5b506001600160a01b038135169060200135610958565b610264600480360360608110156103a357600080fd5b506001600160a01b03813581169160208101359091169060400135610983565b610319600480360360208110156103d957600080fd5b503561099e565b610264600480360360208110156103f657600080fd5b810190602081018135600160201b81111561041057600080fd5b82018360208201111561042257600080fd5b803590602001918460018302840111600160201b8311171561044357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506109b4945050505050565b61021c6004803603602081101561049a57600080fd5b50356109c0565b61018a6109e8565b610319600480360360208110156104bf57600080fd5b50356001600160a01b0316610a49565b610264600480360360208110156104e557600080fd5b810190602081018135600160201b8111156104ff57600080fd5b82018360208201111561051157600080fd5b803590602001918460018302840111600160201b8311171561053257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610ab1945050505050565b61018a610ac4565b6102646004803603604081101561059157600080fd5b506001600160a01b038135169060200135610b25565b610264600480360360408110156105bd57600080fd5b506001600160a01b0381351690602001351515610b2f565b610264600480360360808110156105eb57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561062557600080fd5b82018360208201111561063757600080fd5b803590602001918460018302840111600160201b8311171561065857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610c34945050505050565b61018a600480360360208110156106af57600080fd5b5035610c92565b61018a610f13565b61016e600480360360408110156106d457600080fd5b506001600160a01b0381358116916020013516610f74565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60068054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561079b5780601f106107705761010080835404028352916020019161079b565b820191906000526020600020905b81548152906001019060200180831161077e57829003601f168201915b5050505050905090565b60006107b082610fa2565b6107eb5760405162461bcd60e51b815260040180806020018281038252602c815260200180611e41602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610812826109c0565b9050806001600160a01b0316836001600160a01b031614156108655760405162461bcd60e51b8152600401808060200182810382526021815260200180611ef16021913960400191505060405180910390fd5b806001600160a01b0316610877610faf565b6001600160a01b03161480610898575061089881610893610faf565b610f74565b6108d35760405162461bcd60e51b8152600401808060200182810382526038815260200180611d946038913960400191505060405180910390fd5b6108dd8383610fb3565b505050565b6108ec8282611021565b5050565b60006108fc6002611084565b905090565b61091261090c610faf565b8261108f565b61094d5760405162461bcd60e51b8152600401808060200182810382526031815260200180611f126031913960400191505060405180910390fd5b6108dd838383611133565b6001600160a01b038216600090815260016020526040812061097a908361127f565b90505b92915050565b6108dd83838360405180602001604052806000815250610c34565b6000806109ac60028461128b565b509392505050565b6109bd816112a7565b50565b600061097d82604051806060016040528060298152602001611df660299139600291906112ba565b60098054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561079b5780601f106107705761010080835404028352916020019161079b565b60006001600160a01b038216610a905760405162461bcd60e51b815260040180806020018281038252602a815260200180611dcc602a913960400191505060405180910390fd5b6001600160a01b038216600090815260016020526040902061097d90611084565b80516108ec90600a906020840190611b9c565b60078054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561079b5780601f106107705761010080835404028352916020019161079b565b6108ec82826112d1565b610b37610faf565b6001600160a01b0316826001600160a01b03161415610b9d576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b8060056000610baa610faf565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610bee610faf565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b610c45610c3f610faf565b8361108f565b610c805760405162461bcd60e51b8152600401808060200182810382526031815260200180611f126031913960400191505060405180910390fd5b610c8c848484846112eb565b50505050565b6060610c9d82610fa2565b610cd85760405162461bcd60e51b815260040180806020018281038252602f815260200180611ec2602f913960400191505060405180910390fd5b60008281526008602090815260408083208054825160026001831615610100026000190190921691909104601f810185900485028201850190935282815292909190830182828015610d6b5780601f10610d4057610100808354040283529160200191610d6b565b820191906000526020600020905b815481529060010190602001808311610d4e57829003601f168201915b505050505090506000610d7c6109e8565b9050805160001415610d905750905061070a565b815115610e515780826040516020018083805190602001908083835b60208310610dcb5780518252601f199092019160209182019101610dac565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610e135780518252601f199092019160209182019101610df4565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529250505061070a565b80610e5b8561133d565b6040516020018083805190602001908083835b60208310610e8d5780518252601f199092019160209182019101610e6e565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610ed55780518252601f199092019160209182019101610eb6565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b600a8054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561079b5780601f106107705761010080835404028352916020019161079b565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b600061097d600283611418565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610fe8826109c0565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b61102a82610fa2565b6110655760405162461bcd60e51b815260040180806020018281038252602c815260200180611e6d602c913960400191505060405180910390fd5b600082815260086020908152604090912082516108dd92840190611b9c565b600061097d82611424565b600061109a82610fa2565b6110d55760405162461bcd60e51b815260040180806020018281038252602c815260200180611d68602c913960400191505060405180910390fd5b60006110e0836109c0565b9050806001600160a01b0316846001600160a01b0316148061111b5750836001600160a01b0316611110846107a5565b6001600160a01b0316145b8061112b575061112b8185610f74565b949350505050565b826001600160a01b0316611146826109c0565b6001600160a01b03161461118b5760405162461bcd60e51b8152600401808060200182810382526029815260200180611e996029913960400191505060405180910390fd5b6001600160a01b0382166111d05760405162461bcd60e51b8152600401808060200182810382526024815260200180611d446024913960400191505060405180910390fd5b6111db8383836108dd565b6111e6600082610fb3565b6001600160a01b03831660009081526001602052604090206112089082611428565b506001600160a01b038216600090815260016020526040902061122b9082611434565b5061123860028284611440565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600061097a8383611456565b600080808061129a86866114ba565b9097909650945050505050565b80516108ec906009906020840190611b9c565b60006112c7848484611535565b90505b9392505050565b6108ec8282604051806020016040528060008152506115ff565b6112f6848484611133565b61130284848484611651565b610c8c5760405162461bcd60e51b8152600401808060200182810382526032815260200180611d126032913960400191505060405180910390fd5b60608161136257506040805180820190915260018152600360fc1b602082015261070a565b8160005b811561137a57600101600a82049150611366565b60008167ffffffffffffffff8111801561139357600080fd5b506040519080825280601f01601f1916602001820160405280156113be576020820181803683370190505b50859350905060001982015b831561140f57600a840660300160f81b828280600190039350815181106113ed57fe5b60200101906001600160f81b031916908160001a905350600a840493506113ca565b50949350505050565b600061097a83836117b9565b5490565b600061097a83836117d1565b600061097a8383611897565b60006112c784846001600160a01b0385166118e1565b815460009082106114985760405162461bcd60e51b8152600401808060200182810382526022815260200180611cf06022913960400191505060405180910390fd5b8260000182815481106114a757fe5b9060005260206000200154905092915050565b8154600090819083106114fe5760405162461bcd60e51b8152600401808060200182810382526022815260200180611e1f6022913960400191505060405180910390fd5b600084600001848154811061150f57fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816115d05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561159557818101518382015260200161157d565b50505050905090810190601f1680156115c25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508460000160018203815481106115e357fe5b9060005260206000209060020201600101549150509392505050565b6116098383611978565b6116166000848484611651565b6108dd5760405162461bcd60e51b8152600401808060200182810382526032815260200180611d126032913960400191505060405180910390fd5b6000611665846001600160a01b0316611aa6565b6116715750600161112b565b600061177f630a85bd0160e11b611686610faf565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156116ed5781810151838201526020016116d5565b50505050905090810190601f16801561171a5780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001611d12603291396001600160a01b0388169190611aac565b9050600081806020019051602081101561179857600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60009081526001919091016020526040902054151590565b6000818152600183016020526040812054801561188d578354600019808301919081019060009087908390811061180457fe5b906000526020600020015490508087600001848154811061182157fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061185157fe5b6001900381819060005260206000200160009055905586600101600087815260200190815260200160002060009055600194505050505061097d565b600091505061097d565b60006118a383836117b9565b6118d95750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561097d565b50600061097d565b6000828152600184016020526040812054806119465750506040805180820182528381526020808201848152865460018181018955600089815284812095516002909302909501918255915190820155865486845281880190925292909120556112ca565b8285600001600183038154811061195957fe5b90600052602060002090600202016001018190555060009150506112ca565b6001600160a01b0382166119d3576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6119dc81610fa2565b15611a2e576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b611a3a600083836108dd565b6001600160a01b0382166000908152600160205260409020611a5c9082611434565b50611a6960028284611440565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b3b151590565b60606112c7848460008585611ac5565b60405180910390fd5b611ace85611aa6565b611aea5760405162461bcd60e51b8152600401611abc90611c8c565b600080866001600160a01b03168587604051611b069190611c3d565b60006040518083038185875af1925050503d8060008114611b43576040519150601f19603f3d011682016040523d82523d6000602084013e611b48565b606091505b5091509150611b58828286611b63565b979650505050505050565b60608315611b725750816112ca565b825115611b825782518084602001fd5b8160405162461bcd60e51b8152600401611abc9190611c59565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611bd25760008555611c18565b82601f10611beb57805160ff1916838001178555611c18565b82800160010185558215611c18579182015b82811115611c18578251825591602001919060010190611bfd565b50611c24929150611c28565b5090565b5b80821115611c245760008155600101611c29565b60008251611c4f818460208701611cc3565b9190910192915050565b6000602082528251806020840152611c78816040850160208701611cc3565b601f01601f19169190910160400192915050565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60005b83811015611cde578181015183820152602001611cc6565b83811115610c8c575050600091015256fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732314d657461646174613a2055524920736574206f66206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a264697066735822122035771dce7eba2aa8f2ea7dea8aa8250633a73f64284bc80cfce60ee5b60e7f1664736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "approve(address,uint256)": {
+ "details": "See {IERC721-approve}."
+ },
+ "balanceOf(address)": {
+ "details": "See {IERC721-balanceOf}."
+ },
+ "baseURI()": {
+ "details": "Returns the base URI set via {_setBaseURI}. This will be automatically added as a prefix in {tokenURI} to each token's URI, or to the token ID if no specific URI is set for that token ID."
+ },
+ "getApproved(uint256)": {
+ "details": "See {IERC721-getApproved}."
+ },
+ "isApprovedForAll(address,address)": {
+ "details": "See {IERC721-isApprovedForAll}."
+ },
+ "name()": {
+ "details": "See {IERC721Metadata-name}."
+ },
+ "ownerOf(uint256)": {
+ "details": "See {IERC721-ownerOf}."
+ },
+ "safeTransferFrom(address,address,uint256)": {
+ "details": "See {IERC721-safeTransferFrom}."
+ },
+ "safeTransferFrom(address,address,uint256,bytes)": {
+ "details": "See {IERC721-safeTransferFrom}."
+ },
+ "setApprovalForAll(address,bool)": {
+ "details": "See {IERC721-setApprovalForAll}."
+ },
+ "supportsInterface(bytes4)": {
+ "details": "See {IERC165-supportsInterface}. Time complexity O(1), guaranteed to always use less than 30 000 gas."
+ },
+ "symbol()": {
+ "details": "See {IERC721Metadata-symbol}."
+ },
+ "tokenByIndex(uint256)": {
+ "details": "See {IERC721Enumerable-tokenByIndex}."
+ },
+ "tokenOfOwnerByIndex(address,uint256)": {
+ "details": "See {IERC721Enumerable-tokenOfOwnerByIndex}."
+ },
+ "tokenURI(uint256)": {
+ "details": "See {IERC721Metadata-tokenURI}."
+ },
+ "totalSupply()": {
+ "details": "See {IERC721Enumerable-totalSupply}."
+ },
+ "transferFrom(address,address,uint256)": {
+ "details": "See {IERC721-transferFrom}."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 10441,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_supportedInterfaces",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_bytes4,t_bool)"
+ },
+ {
+ "astId": 13327,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_holderTokens",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_mapping(t_address,t_struct(UintSet)18075_storage)"
+ },
+ {
+ "astId": 13329,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_tokenOwners",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_struct(UintToAddressMap)17452_storage"
+ },
+ {
+ "astId": 13333,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_tokenApprovals",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_mapping(t_uint256,t_address)"
+ },
+ {
+ "astId": 13339,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_operatorApprovals",
+ "offset": 0,
+ "slot": "5",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 13341,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_name",
+ "offset": 0,
+ "slot": "6",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 13343,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_symbol",
+ "offset": 0,
+ "slot": "7",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 13347,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_tokenURIs",
+ "offset": 0,
+ "slot": "8",
+ "type": "t_mapping(t_uint256,t_string_storage)"
+ },
+ {
+ "astId": 13349,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_baseURI",
+ "offset": 0,
+ "slot": "9",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 9801,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_contractURI",
+ "offset": 0,
+ "slot": "10",
+ "type": "t_string_storage"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_bytes32)dyn_storage": {
+ "base": "t_bytes32",
+ "encoding": "dynamic_array",
+ "label": "bytes32[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_struct(MapEntry)17126_storage)dyn_storage": {
+ "base": "t_struct(MapEntry)17126_storage",
+ "encoding": "dynamic_array",
+ "label": "struct EnumerableMap.MapEntry[]",
+ "numberOfBytes": "32"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_bytes4": {
+ "encoding": "inplace",
+ "label": "bytes4",
+ "numberOfBytes": "4"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_mapping(t_address,t_struct(UintSet)18075_storage)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => struct EnumerableSet.UintSet)",
+ "numberOfBytes": "32",
+ "value": "t_struct(UintSet)18075_storage"
+ },
+ "t_mapping(t_bytes32,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_mapping(t_bytes4,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes4",
+ "label": "mapping(bytes4 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_uint256,t_address)": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_uint256,t_string_storage)": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => string)",
+ "numberOfBytes": "32",
+ "value": "t_string_storage"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(Map)17134_storage": {
+ "encoding": "inplace",
+ "label": "struct EnumerableMap.Map",
+ "members": [
+ {
+ "astId": 17129,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_entries",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_array(t_struct(MapEntry)17126_storage)dyn_storage"
+ },
+ {
+ "astId": 17133,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_indexes",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_mapping(t_bytes32,t_uint256)"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(MapEntry)17126_storage": {
+ "encoding": "inplace",
+ "label": "struct EnumerableMap.MapEntry",
+ "members": [
+ {
+ "astId": 17123,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_key",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bytes32"
+ },
+ {
+ "astId": 17125,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_value",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_bytes32"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Set)17689_storage": {
+ "encoding": "inplace",
+ "label": "struct EnumerableSet.Set",
+ "members": [
+ {
+ "astId": 17684,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_values",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_array(t_bytes32)dyn_storage"
+ },
+ {
+ "astId": 17688,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_indexes",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_mapping(t_bytes32,t_uint256)"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(UintSet)18075_storage": {
+ "encoding": "inplace",
+ "label": "struct EnumerableSet.UintSet",
+ "members": [
+ {
+ "astId": 18074,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_inner",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_struct(Set)17689_storage"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(UintToAddressMap)17452_storage": {
+ "encoding": "inplace",
+ "label": "struct EnumerableMap.UintToAddressMap",
+ "members": [
+ {
+ "astId": 17451,
+ "contract": "contracts/test/nftbridge/NFTERC721TestToken.sol:NFTERC721TestToken",
+ "label": "_inner",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_struct(Map)17134_storage"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/NftBridgeProxy.json b/bridge/deployments/rinkeby/NftBridgeProxy.json
new file mode 100644
index 000000000..4ea6450b8
--- /dev/null
+++ b/bridge/deployments/rinkeby/NftBridgeProxy.json
@@ -0,0 +1,248 @@
+{
+ "address": "0xB9b8d1e30F0EBEC0C8F4CF0B1717566d84FC4080",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x10a2e24b269aff23062542408e7948b6d6efd82e21e4e0e3c15cc4a6e97bc560",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0xB9b8d1e30F0EBEC0C8F4CF0B1717566d84FC4080",
+ "transactionIndex": 0,
+ "gasUsed": "752421",
+ "logsBloom": "0x00000000020000000000000000000000000000000000000000800000000000001000000000000000000000000000002000080400000000000000000000000000005000000080200000000000000000000001000000000000000000000000000000000000020000000000000000000800000010004020000000000000000000400000001000000000000000000000000010000000000000000000000000000000000800000000000000000000000000020000000000000000200801000000000008000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000040000000000000",
+ "blockHash": "0xde0760fb1d40bbfaf5f171b0cc0da9cba2f74cb5772f593a36f5de3e2825a24e",
+ "transactionHash": "0x10a2e24b269aff23062542408e7948b6d6efd82e21e4e0e3c15cc4a6e97bc560",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9269456,
+ "transactionHash": "0x10a2e24b269aff23062542408e7948b6d6efd82e21e4e0e3c15cc4a6e97bc560",
+ "address": "0xB9b8d1e30F0EBEC0C8F4CF0B1717566d84FC4080",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x00000000000000000000000004994d7ff4938c5953a6c8411ad30083c9097348"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0xde0760fb1d40bbfaf5f171b0cc0da9cba2f74cb5772f593a36f5de3e2825a24e"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9269456,
+ "transactionHash": "0x10a2e24b269aff23062542408e7948b6d6efd82e21e4e0e3c15cc4a6e97bc560",
+ "address": "0xB9b8d1e30F0EBEC0C8F4CF0B1717566d84FC4080",
+ "topics": [
+ "0x6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f8",
+ "0x00000000000000000000000004994d7ff4938c5953a6c8411ad30083c9097348"
+ ],
+ "data": "0x",
+ "logIndex": 1,
+ "blockHash": "0xde0760fb1d40bbfaf5f171b0cc0da9cba2f74cb5772f593a36f5de3e2825a24e"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9269456,
+ "transactionHash": "0x10a2e24b269aff23062542408e7948b6d6efd82e21e4e0e3c15cc4a6e97bc560",
+ "address": "0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24",
+ "topics": [
+ "0x93baa6efbd2244243bfee6ce4cfdd1d04fc4c0e9a786abd3a41313bd352db153",
+ "0x000000000000000000000000b9b8d1e30f0ebec0c8f4cf0b1717566d84fc4080",
+ "0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b",
+ "0x000000000000000000000000b9b8d1e30f0ebec0c8f4cf0b1717566d84fc4080"
+ ],
+ "data": "0x",
+ "logIndex": 2,
+ "blockHash": "0xde0760fb1d40bbfaf5f171b0cc0da9cba2f74cb5772f593a36f5de3e2825a24e"
+ }
+ ],
+ "blockNumber": 9269456,
+ "cumulativeGasUsed": "752421",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0xebD27fD00Eb737D91c1a66B750a45361D234Eb74",
+ "0x0b32Ea549AB1F9F7390442B5E9438b58A105cB5f",
+ "0x2fb3b36100000000000000000000000004994d7ff4938c5953a6c8411ad30083c9097348000000000000000000000000bc383764cebc13b66c04e1abeb36804a0caaa5c600000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e62df026fb687e4917daa88a777366b7e550d2000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000016500000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"stateVariables\":{\"_ADMIN_SLOT\":{\"details\":\"Storage slot with the admin of the contract. This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\r\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\r\\n * be specified by overriding the virtual {_implementation} function.\\r\\n *\\r\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\r\\n * different contract through the {_delegate} function.\\r\\n *\\r\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\r\\n */\\r\\nabstract contract Proxy {\\r\\n /**\\r\\n * @dev Delegates the current call to `implementation`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _delegate(address implementation) internal virtual {\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n // Copy msg.data. We take full control of memory in this inline assembly\\r\\n // block because it will not return to Solidity code. We overwrite the\\r\\n // Solidity scratch pad at memory position 0.\\r\\n calldatacopy(0, 0, calldatasize())\\r\\n\\r\\n // Call the implementation.\\r\\n // out and outsize are 0 because we don't know the size yet.\\r\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\r\\n\\r\\n // Copy the returned data.\\r\\n returndatacopy(0, 0, returndatasize())\\r\\n\\r\\n switch result\\r\\n // delegatecall returns 0 on error.\\r\\n case 0 { revert(0, returndatasize()) }\\r\\n default { return(0, returndatasize()) }\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\r\\n * and {_fallback} should delegate.\\r\\n */\\r\\n function _implementation() internal view virtual returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _fallback() internal virtual {\\r\\n _beforeFallback();\\r\\n _delegate(_implementation());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\r\\n * function in the contract matches the call data.\\r\\n */\\r\\n fallback () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\r\\n * is empty.\\r\\n */\\r\\n receive () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\r\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\r\\n *\\r\\n * If overriden should call `super._beforeFallback()`.\\r\\n */\\r\\n function _beforeFallback() internal virtual {\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x6374180266624d2291abb230bdf0d364858fa164844f5d2d83ad5325852390c9\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./UpgradeableProxy.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\r\\n *\\r\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\r\\n * clashing], which can potentially be used in an attack, this contract uses the\\r\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\r\\n * things that go hand in hand:\\r\\n *\\r\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\r\\n * that call matches one of the admin functions exposed by the proxy itself.\\r\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\r\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\r\\n * \\\"admin cannot fallback to proxy target\\\".\\r\\n *\\r\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\r\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\r\\n * to sudden errors when trying to call a function from the proxy implementation.\\r\\n *\\r\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\r\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\r\\n */\\r\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\r\\n /**\\r\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\r\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\r\\n */\\r\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\r\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\r\\n _setAdmin(admin_);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the admin account has changed.\\r\\n */\\r\\n event AdminChanged(address previousAdmin, address newAdmin);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the admin of the contract.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\r\\n\\r\\n /**\\r\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\r\\n */\\r\\n modifier ifAdmin() {\\r\\n if (msg.sender == _admin()) {\\r\\n _;\\r\\n } else {\\r\\n _fallback();\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\r\\n */\\r\\n function admin() external ifAdmin returns (address admin_) {\\r\\n admin_ = _admin();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\r\\n */\\r\\n function implementation() external ifAdmin returns (address implementation_) {\\r\\n implementation_ = _implementation();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Changes the admin of the proxy.\\r\\n *\\r\\n * Emits an {AdminChanged} event.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\r\\n */\\r\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\r\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\r\\n emit AdminChanged(_admin(), newAdmin);\\r\\n _setAdmin(newAdmin);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\r\\n */\\r\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\r\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\r\\n * proxied contract.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\r\\n */\\r\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n Address.functionDelegateCall(newImplementation, data);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n */\\r\\n function _admin() internal view virtual returns (address adm) {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n adm := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 admin slot.\\r\\n */\\r\\n function _setAdmin(address newAdmin) private {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newAdmin)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\r\\n */\\r\\n function _beforeFallback() internal virtual override {\\r\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\r\\n super._beforeFallback();\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x7496c2c54dd8e648d6999687cf759521e6ab229d0d8ddb4db62f3b51dbe68811\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./Proxy.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\r\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\r\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\r\\n * implementation behind the proxy.\\r\\n *\\r\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\r\\n * {TransparentUpgradeableProxy}.\\r\\n */\\r\\ncontract UpgradeableProxy is Proxy {\\r\\n /**\\r\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\r\\n *\\r\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\r\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\r\\n */\\r\\n constructor(address _logic, bytes memory _data) payable {\\r\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\r\\n _setImplementation(_logic);\\r\\n if(_data.length > 0) {\\r\\n Address.functionDelegateCall(_logic, _data);\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the implementation is upgraded.\\r\\n */\\r\\n event Upgraded(address indexed implementation);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the address of the current implementation.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation address.\\r\\n */\\r\\n function _implementation() internal view virtual override returns (address impl) {\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n impl := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrades the proxy to a new implementation.\\r\\n *\\r\\n * Emits an {Upgraded} event.\\r\\n */\\r\\n function _upgradeTo(address newImplementation) internal virtual {\\r\\n _setImplementation(newImplementation);\\r\\n emit Upgraded(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 implementation slot.\\r\\n */\\r\\n function _setImplementation(address newImplementation) private {\\r\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\r\\n\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newImplementation)\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x4d3fcb8487e53abb8658817c4b90038b24d81d0a32d989f03b54d4cfab929f62\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000c9f38038062000c9f83398101604081905262000026916200022e565b8281620000338262000071565b8051156200005457620000528282620000d360201b620002ca1760201c565b505b506200005d9050565b620000688262000102565b5050506200041d565b62000087816200012660201b620002f61760201c565b620000af5760405162461bcd60e51b8152600401620000a69062000347565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6060620000fb838360405180606001604052806027815260200162000c786027913962000130565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b60606200013d8462000126565b6200015c5760405162461bcd60e51b8152600401620000a690620003a4565b600080856001600160a01b031685604051620001799190620002f4565b600060405180830381855af49150503d8060008114620001b6576040519150601f19603f3d011682016040523d82523d6000602084013e620001bb565b606091505b509092509050620001ce828286620001d8565b9695505050505050565b60608315620001e9575081620000fb565b825115620001fa5782518084602001fd5b8160405162461bcd60e51b8152600401620000a6919062000312565b80516001600160a01b03811681146200012b57600080fd5b60008060006060848603121562000243578283fd5b6200024e8462000216565b92506200025e6020850162000216565b60408501519092506001600160401b03808211156200027b578283fd5b818601915086601f8301126200028f578283fd5b8151818111156200029c57fe5b604051601f8201601f191681016020018381118282101715620002bb57fe5b604052818152838201602001891015620002d3578485fd5b620002e6826020830160208701620003ea565b809450505050509250925092565b6000825162000308818460208701620003ea565b9190910192915050565b600060208252825180602084015262000333816040850160208701620003ea565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b8381101562000407578181015183820152602001620003ed565b8381111562000417576000848401525b50505050565b61084b806200042d6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209ba77a19de177ea34b608207423a21765cca1077e9d39a414a7175e09fb147e464736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209ba77a19de177ea34b608207423a21765cca1077e9d39a414a7175e09fb147e464736f6c63430007060033",
+ "devdoc": {
+ "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.",
+ "events": {
+ "AdminChanged(address,address)": {
+ "details": "Emitted when the admin account has changed."
+ }
+ },
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "constructor": {
+ "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "stateVariables": {
+ "_ADMIN_SLOT": {
+ "details": "Storage slot with the admin of the contract. This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/ProxyAdmin.json b/bridge/deployments/rinkeby/ProxyAdmin.json
new file mode 100644
index 000000000..cdf5ec099
--- /dev/null
+++ b/bridge/deployments/rinkeby/ProxyAdmin.json
@@ -0,0 +1,261 @@
+{
+ "address": "0x0b32Ea549AB1F9F7390442B5E9438b58A105cB5f",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeProxyAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ }
+ ],
+ "name": "getProxyAdmin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ }
+ ],
+ "name": "getProxyImplementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgrade",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xa9f864fc2fe75d505453d69f6a7a7151db4185156e396c0cf21573663ea84280",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0x0b32Ea549AB1F9F7390442B5E9438b58A105cB5f",
+ "transactionIndex": 1,
+ "gasUsed": "499388",
+ "logsBloom": "0x00000000000002000000000000000800000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000800000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000020000000000000000000000000",
+ "blockHash": "0x8087d683a7cf20d7dd19c6201072790f6f45d3f9b5d0d009566cf267d4e6a2a8",
+ "transactionHash": "0xa9f864fc2fe75d505453d69f6a7a7151db4185156e396c0cf21573663ea84280",
+ "logs": [
+ {
+ "transactionIndex": 1,
+ "blockNumber": 9264191,
+ "transactionHash": "0xa9f864fc2fe75d505453d69f6a7a7151db4185156e396c0cf21573663ea84280",
+ "address": "0x0b32Ea549AB1F9F7390442B5E9438b58A105cB5f",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b"
+ ],
+ "data": "0x",
+ "logIndex": 1,
+ "blockHash": "0x8087d683a7cf20d7dd19c6201072790f6f45d3f9b5d0d009566cf267d4e6a2a8"
+ }
+ ],
+ "blockNumber": 9264191,
+ "cumulativeGasUsed": "644417",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\",\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"details\":\"Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`.\"},\"getProxyAdmin(address)\":{\"details\":\"Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"getProxyImplementation(address)\":{\"details\":\"Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"details\":\"Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`.\"},\"upgradeAndCall(address,address,bytes)\":{\"details\":\"Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol\":\"ProxyAdmin\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../GSN/Context.sol\\\";\\r\\n/**\\r\\n * @dev Contract module which provides a basic access control mechanism, where\\r\\n * there is an account (an owner) that can be granted exclusive access to\\r\\n * specific functions.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the modifier\\r\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\r\\n * the owner.\\r\\n */\\r\\nabstract contract Ownable is Context {\\r\\n address private _owner;\\r\\n\\r\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract setting the deployer as the initial owner.\\r\\n */\\r\\n constructor () {\\r\\n _owner = _msgSender();\\r\\n emit OwnershipTransferred(address(0), _owner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the address of the current owner.\\r\\n */\\r\\n function owner() public view returns (address) {\\r\\n return _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Throws if called by any account other than the owner.\\r\\n */\\r\\n modifier onlyOwner() {\\r\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the caller is the current owner.\\r\\n */\\r\\n function isOwner() public view returns (bool) {\\r\\n return _msgSender() == _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Leaves the contract without owner. It will not be possible to call\\r\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\r\\n *\\r\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\r\\n * thereby removing any functionality that is only available to the owner.\\r\\n */\\r\\n function renounceOwnership() public onlyOwner {\\r\\n emit OwnershipTransferred(_owner, address(0));\\r\\n _owner = address(0);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n * Can only be called by the current owner.\\r\\n */\\r\\n function transferOwnership(address newOwner) public onlyOwner {\\r\\n _transferOwnership(newOwner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n */\\r\\n function _transferOwnership(address newOwner) internal {\\r\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\r\\n emit OwnershipTransferred(_owner, newOwner);\\r\\n _owner = newOwner;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x3ec7bb8e187578031499df70ffa27e8e2fdd4933003df5e8ac1c4a49e40a2fb5\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\r\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\r\\n * be specified by overriding the virtual {_implementation} function.\\r\\n *\\r\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\r\\n * different contract through the {_delegate} function.\\r\\n *\\r\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\r\\n */\\r\\nabstract contract Proxy {\\r\\n /**\\r\\n * @dev Delegates the current call to `implementation`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _delegate(address implementation) internal virtual {\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n // Copy msg.data. We take full control of memory in this inline assembly\\r\\n // block because it will not return to Solidity code. We overwrite the\\r\\n // Solidity scratch pad at memory position 0.\\r\\n calldatacopy(0, 0, calldatasize())\\r\\n\\r\\n // Call the implementation.\\r\\n // out and outsize are 0 because we don't know the size yet.\\r\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\r\\n\\r\\n // Copy the returned data.\\r\\n returndatacopy(0, 0, returndatasize())\\r\\n\\r\\n switch result\\r\\n // delegatecall returns 0 on error.\\r\\n case 0 { revert(0, returndatasize()) }\\r\\n default { return(0, returndatasize()) }\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\r\\n * and {_fallback} should delegate.\\r\\n */\\r\\n function _implementation() internal view virtual returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _fallback() internal virtual {\\r\\n _beforeFallback();\\r\\n _delegate(_implementation());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\r\\n * function in the contract matches the call data.\\r\\n */\\r\\n fallback () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\r\\n * is empty.\\r\\n */\\r\\n receive () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\r\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\r\\n *\\r\\n * If overriden should call `super._beforeFallback()`.\\r\\n */\\r\\n function _beforeFallback() internal virtual {\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x6374180266624d2291abb230bdf0d364858fa164844f5d2d83ad5325852390c9\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../../ownership/Ownable.sol\\\";\\r\\nimport \\\"./TransparentUpgradeableProxy.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\\r\\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\\r\\n */\\r\\ncontract ProxyAdmin is Ownable {\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation of `proxy`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - This contract must be the admin of `proxy`.\\r\\n */\\r\\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\r\\n // We need to manually run the static call since the getter cannot be flagged as view\\r\\n // bytes4(keccak256(\\\"implementation()\\\")) == 0x5c60da1b\\r\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"5c60da1b\\\");\\r\\n require(success);\\r\\n return abi.decode(returndata, (address));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin of `proxy`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - This contract must be the admin of `proxy`.\\r\\n */\\r\\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\r\\n // We need to manually run the static call since the getter cannot be flagged as view\\r\\n // bytes4(keccak256(\\\"admin()\\\")) == 0xf851a440\\r\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"f851a440\\\");\\r\\n require(success);\\r\\n return abi.decode(returndata, (address));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Changes the admin of `proxy` to `newAdmin`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - This contract must be the current admin of `proxy`.\\r\\n */\\r\\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\\r\\n proxy.changeAdmin(newAdmin);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - This contract must be the admin of `proxy`.\\r\\n */\\r\\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\\r\\n proxy.upgradeTo(implementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\\r\\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - This contract must be the admin of `proxy`.\\r\\n */\\r\\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\\r\\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x1e84c0b4c1b38c2f900deccba81c2be954a7f74cef984b2e5046ab8295df5ff4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./UpgradeableProxy.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\r\\n *\\r\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\r\\n * clashing], which can potentially be used in an attack, this contract uses the\\r\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\r\\n * things that go hand in hand:\\r\\n *\\r\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\r\\n * that call matches one of the admin functions exposed by the proxy itself.\\r\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\r\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\r\\n * \\\"admin cannot fallback to proxy target\\\".\\r\\n *\\r\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\r\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\r\\n * to sudden errors when trying to call a function from the proxy implementation.\\r\\n *\\r\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\r\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\r\\n */\\r\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\r\\n /**\\r\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\r\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\r\\n */\\r\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\r\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\r\\n _setAdmin(admin_);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the admin account has changed.\\r\\n */\\r\\n event AdminChanged(address previousAdmin, address newAdmin);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the admin of the contract.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\r\\n\\r\\n /**\\r\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\r\\n */\\r\\n modifier ifAdmin() {\\r\\n if (msg.sender == _admin()) {\\r\\n _;\\r\\n } else {\\r\\n _fallback();\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\r\\n */\\r\\n function admin() external ifAdmin returns (address admin_) {\\r\\n admin_ = _admin();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\r\\n */\\r\\n function implementation() external ifAdmin returns (address implementation_) {\\r\\n implementation_ = _implementation();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Changes the admin of the proxy.\\r\\n *\\r\\n * Emits an {AdminChanged} event.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\r\\n */\\r\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\r\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\r\\n emit AdminChanged(_admin(), newAdmin);\\r\\n _setAdmin(newAdmin);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\r\\n */\\r\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\r\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\r\\n * proxied contract.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\r\\n */\\r\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n Address.functionDelegateCall(newImplementation, data);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n */\\r\\n function _admin() internal view virtual returns (address adm) {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n adm := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 admin slot.\\r\\n */\\r\\n function _setAdmin(address newAdmin) private {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newAdmin)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\r\\n */\\r\\n function _beforeFallback() internal virtual override {\\r\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\r\\n super._beforeFallback();\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x7496c2c54dd8e648d6999687cf759521e6ab229d0d8ddb4db62f3b51dbe68811\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./Proxy.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\r\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\r\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\r\\n * implementation behind the proxy.\\r\\n *\\r\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\r\\n * {TransparentUpgradeableProxy}.\\r\\n */\\r\\ncontract UpgradeableProxy is Proxy {\\r\\n /**\\r\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\r\\n *\\r\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\r\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\r\\n */\\r\\n constructor(address _logic, bytes memory _data) payable {\\r\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\r\\n _setImplementation(_logic);\\r\\n if(_data.length > 0) {\\r\\n Address.functionDelegateCall(_logic, _data);\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the implementation is upgraded.\\r\\n */\\r\\n event Upgraded(address indexed implementation);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the address of the current implementation.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation address.\\r\\n */\\r\\n function _implementation() internal view virtual override returns (address impl) {\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n impl := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrades the proxy to a new implementation.\\r\\n *\\r\\n * Emits an {Upgraded} event.\\r\\n */\\r\\n function _upgradeTo(address newImplementation) internal virtual {\\r\\n _setImplementation(newImplementation);\\r\\n emit Upgraded(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 implementation slot.\\r\\n */\\r\\n function _setImplementation(address newImplementation) private {\\r\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\r\\n\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newImplementation)\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x4d3fcb8487e53abb8658817c4b90038b24d81d0a32d989f03b54d4cfab929f62\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50610019610066565b600080546001600160a01b0319166001600160a01b03928316178082556040519216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a361006a565b3390565b61079e806100796000396000f3fe6080604052600436106100865760003560e01c80638f32d59b116100595780638f32d59b1461010d5780639623609d1461012f57806399a88ec414610142578063f2fde38b14610162578063f3b7dead1461018257610086565b8063204e1c7a1461008b578063715018a6146100c15780637eff275e146100d85780638da5cb5b146100f8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610503565b6101a2565b6040516100b89190610656565b60405180910390f35b3480156100cd57600080fd5b506100d6610228565b005b3480156100e457600080fd5b506100d66100f3366004610542565b61029f565b34801561010457600080fd5b506100ab610325565b34801561011957600080fd5b50610122610334565b6040516100b891906106cd565b6100d661013d36600461057a565b610358565b34801561014e57600080fd5b506100d661015d366004610542565b6103e3565b34801561016e57600080fd5b506100d661017d366004610503565b610433565b34801561018e57600080fd5b506100ab61019d366004610503565b610463565b6000806000836001600160a01b03166040516101bd90610636565b600060405180830381855afa9150503d80600081146101f8576040519150601f19603f3d011682016040523d82523d6000602084013e6101fd565b606091505b50915091508161020c57600080fd5b808060200190518101906102209190610526565b949350505050565b610230610334565b6102555760405162461bcd60e51b815260040161024c9061071e565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6102a7610334565b6102c35760405162461bcd60e51b815260040161024c9061071e565b6040516308f2839760e41b81526001600160a01b03831690638f283970906102ef908490600401610656565b600060405180830381600087803b15801561030957600080fd5b505af115801561031d573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031690565b600080546001600160a01b031661034961047e565b6001600160a01b031614905090565b610360610334565b61037c5760405162461bcd60e51b815260040161024c9061071e565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906103ac908690869060040161066a565b6000604051808303818588803b1580156103c557600080fd5b505af11580156103d9573d6000803e3d6000fd5b5050505050505050565b6103eb610334565b6104075760405162461bcd60e51b815260040161024c9061071e565b604051631b2ce7f360e11b81526001600160a01b03831690633659cfe6906102ef908490600401610656565b61043b610334565b6104575760405162461bcd60e51b815260040161024c9061071e565b61046081610482565b50565b6000806000836001600160a01b03166040516101bd90610646565b3390565b6001600160a01b0381166104a85760405162461bcd60e51b815260040161024c906106d8565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600060208284031215610514578081fd5b813561051f81610753565b9392505050565b600060208284031215610537578081fd5b815161051f81610753565b60008060408385031215610554578081fd5b823561055f81610753565b9150602083013561056f81610753565b809150509250929050565b60008060006060848603121561058e578081fd5b833561059981610753565b92506020848101356105aa81610753565b9250604085013567ffffffffffffffff808211156105c6578384fd5b818701915087601f8301126105d9578384fd5b8135818111156105e557fe5b604051601f8201601f191681018501838111828210171561060257fe5b60405281815283820185018a1015610618578586fd5b81858501868301378585838301015280955050505050509250925092565b635c60da1b60e01b815260040190565b6303e1469160e61b815260040190565b6001600160a01b0391909116815260200190565b600060018060a01b038416825260206040818401528351806040850152825b818110156106a557858101830151858201606001528201610689565b818111156106b65783606083870101525b50601f01601f191692909201606001949350505050565b901515815260200190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6001600160a01b038116811461046057600080fdfea2646970667358221220ecb38947c02000e07555426acf5ccb5e5c20c0e36da0dc0eb29683cde66ca65b64736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106100865760003560e01c80638f32d59b116100595780638f32d59b1461010d5780639623609d1461012f57806399a88ec414610142578063f2fde38b14610162578063f3b7dead1461018257610086565b8063204e1c7a1461008b578063715018a6146100c15780637eff275e146100d85780638da5cb5b146100f8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610503565b6101a2565b6040516100b89190610656565b60405180910390f35b3480156100cd57600080fd5b506100d6610228565b005b3480156100e457600080fd5b506100d66100f3366004610542565b61029f565b34801561010457600080fd5b506100ab610325565b34801561011957600080fd5b50610122610334565b6040516100b891906106cd565b6100d661013d36600461057a565b610358565b34801561014e57600080fd5b506100d661015d366004610542565b6103e3565b34801561016e57600080fd5b506100d661017d366004610503565b610433565b34801561018e57600080fd5b506100ab61019d366004610503565b610463565b6000806000836001600160a01b03166040516101bd90610636565b600060405180830381855afa9150503d80600081146101f8576040519150601f19603f3d011682016040523d82523d6000602084013e6101fd565b606091505b50915091508161020c57600080fd5b808060200190518101906102209190610526565b949350505050565b610230610334565b6102555760405162461bcd60e51b815260040161024c9061071e565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6102a7610334565b6102c35760405162461bcd60e51b815260040161024c9061071e565b6040516308f2839760e41b81526001600160a01b03831690638f283970906102ef908490600401610656565b600060405180830381600087803b15801561030957600080fd5b505af115801561031d573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031690565b600080546001600160a01b031661034961047e565b6001600160a01b031614905090565b610360610334565b61037c5760405162461bcd60e51b815260040161024c9061071e565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906103ac908690869060040161066a565b6000604051808303818588803b1580156103c557600080fd5b505af11580156103d9573d6000803e3d6000fd5b5050505050505050565b6103eb610334565b6104075760405162461bcd60e51b815260040161024c9061071e565b604051631b2ce7f360e11b81526001600160a01b03831690633659cfe6906102ef908490600401610656565b61043b610334565b6104575760405162461bcd60e51b815260040161024c9061071e565b61046081610482565b50565b6000806000836001600160a01b03166040516101bd90610646565b3390565b6001600160a01b0381166104a85760405162461bcd60e51b815260040161024c906106d8565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600060208284031215610514578081fd5b813561051f81610753565b9392505050565b600060208284031215610537578081fd5b815161051f81610753565b60008060408385031215610554578081fd5b823561055f81610753565b9150602083013561056f81610753565b809150509250929050565b60008060006060848603121561058e578081fd5b833561059981610753565b92506020848101356105aa81610753565b9250604085013567ffffffffffffffff808211156105c6578384fd5b818701915087601f8301126105d9578384fd5b8135818111156105e557fe5b604051601f8201601f191681018501838111828210171561060257fe5b60405281815283820185018a1015610618578586fd5b81858501868301378585838301015280955050505050509250925092565b635c60da1b60e01b815260040190565b6303e1469160e61b815260040190565b6001600160a01b0391909116815260200190565b600060018060a01b038416825260206040818401528351806040850152825b818110156106a557858101830151858201606001528201610689565b818111156106b65783606083870101525b50601f01601f191692909201606001949350505050565b901515815260200190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6001600160a01b038116811461046057600080fdfea2646970667358221220ecb38947c02000e07555426acf5ccb5e5c20c0e36da0dc0eb29683cde66ca65b64736f6c63430007060033",
+ "devdoc": {
+ "details": "This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.",
+ "kind": "dev",
+ "methods": {
+ "changeProxyAdmin(address,address)": {
+ "details": "Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`."
+ },
+ "getProxyAdmin(address)": {
+ "details": "Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "getProxyImplementation(address)": {
+ "details": "Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "upgrade(address,address)": {
+ "details": "Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "upgradeAndCall(address,address,bytes)": {
+ "details": "Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 10891,
+ "contract": "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol:ProxyAdmin",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/SideNFTTokenFactory.json b/bridge/deployments/rinkeby/SideNFTTokenFactory.json
new file mode 100644
index 000000000..fbfcd5742
--- /dev/null
+++ b/bridge/deployments/rinkeby/SideNFTTokenFactory.json
@@ -0,0 +1,184 @@
+{
+ "address": "0x1e62df026FB687E4917dAA88A777366B7e550D20",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sideTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "baseURI",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "contractURI",
+ "type": "string"
+ }
+ ],
+ "name": "SideNFTTokenCreated",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "baseURI",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "contractURI",
+ "type": "string"
+ }
+ ],
+ "name": "createSideNFTToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x69ac20b828cbf55019c1079df99add6f01ede0f71f8e90c67a66e0725c1984e6",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0x1e62df026FB687E4917dAA88A777366B7e550D20",
+ "transactionIndex": 0,
+ "gasUsed": "2311507",
+ "logsBloom": "0x00000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000",
+ "blockHash": "0x53b1c3660b440bd028e75da90c379f485c696f094c9d6cfffd61a5341a6c3742",
+ "transactionHash": "0x69ac20b828cbf55019c1079df99add6f01ede0f71f8e90c67a66e0725c1984e6",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 9269454,
+ "transactionHash": "0x69ac20b828cbf55019c1079df99add6f01ede0f71f8e90c67a66e0725c1984e6",
+ "address": "0x1e62df026FB687E4917dAA88A777366B7e550D20",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ],
+ "data": "0x0000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b",
+ "logIndex": 0,
+ "blockHash": "0x53b1c3660b440bd028e75da90c379f485c696f094c9d6cfffd61a5341a6c3742"
+ }
+ ],
+ "blockNumber": 9269454,
+ "cumulativeGasUsed": "2311507",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sideTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"baseURI\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"contractURI\",\"type\":\"string\"}],\"name\":\"SideNFTTokenCreated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"baseURI\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"contractURI\",\"type\":\"string\"}],\"name\":\"createSideNFTToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/nftbridge/SideNFTTokenFactory.sol\":\"SideNFTTokenFactory\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/nftbridge/ISideNFTToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideNFTToken {\\r\\n function mint(address account, uint256 tokenId) external;\\r\\n}\",\"keccak256\":\"0xcedb55e825518cb74679fa8a249cc36f5621d3787075cfaf483729e44cd605d3\",\"license\":\"MIT\"},\"contracts/nftbridge/ISideNFTTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideNFTTokenFactory {\\r\\n\\r\\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\\r\\n string calldata contractURI) external returns(address);\\r\\n\\r\\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\\r\\n}\",\"keccak256\":\"0x94993f1c48d9cc1e806d04fc5468566c5314f992705729024c4f9bcdd1eeb99f\",\"license\":\"MIT\"},\"contracts/nftbridge/SideNFTToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./ISideNFTToken.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC721/ERC721.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC721/ERC721Burnable.sol\\\";\\r\\n\\r\\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\\r\\n address public minter;\\r\\n string private _contractURI;\\r\\n\\r\\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\\r\\n require(_minter != address(0), \\\"SideToken: Empty Minter\\\");\\r\\n minter = _minter;\\r\\n _setBaseURI(_baseURI);\\r\\n _setContractURI(contractURI_);\\r\\n }\\r\\n\\r\\n function _setContractURI(string memory contractURI_) internal {\\r\\n _contractURI = contractURI_;\\r\\n }\\r\\n\\r\\n function contractURI() public view returns (string memory) {\\r\\n return _contractURI;\\r\\n }\\r\\n\\r\\n modifier onlyMinter() {\\r\\n require(_msgSender() == minter, \\\"SideToken: Caller is not the minter\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function mint(address account, uint256 tokenId) external onlyMinter override {\\r\\n _mint(account, tokenId);\\r\\n }\\r\\n}\",\"keccak256\":\"0x83256170d784726faef65af12824e6c60d296b1360e5b949bc65dd674233ee95\",\"license\":\"MIT\"},\"contracts/nftbridge/SideNFTTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../zeppelin/ownership/Secondary.sol\\\";\\r\\nimport \\\"./ISideNFTTokenFactory.sol\\\";\\r\\nimport \\\"./SideNFTToken.sol\\\";\\r\\n\\r\\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\\r\\n\\r\\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\\r\\n string calldata contractURI) external onlyPrimary override returns(address) {\\r\\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\\r\\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\\r\\n return sideTokenAddress;\\r\\n }\\r\\n}\",\"keccak256\":\"0x69b402f7f4a3c074dcb2756e6def4f60a0c6d090e28d28d2ec5e158144fbf0ad\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC165.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Implementation of the {IERC165} interface.\\r\\n *\\r\\n * Contracts may inherit from this and call {_registerInterface} to declare\\r\\n * their support of an interface.\\r\\n */\\r\\nabstract contract ERC165 is IERC165 {\\r\\n /*\\r\\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\\r\\n\\r\\n /**\\r\\n * @dev Mapping of interface ids to whether or not it's supported.\\r\\n */\\r\\n mapping(bytes4 => bool) private _supportedInterfaces;\\r\\n\\r\\n constructor () {\\r\\n // Derived contracts need only register support for their own interfaces,\\r\\n // we register support for ERC165 itself here\\r\\n _registerInterface(_INTERFACE_ID_ERC165);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC165-supportsInterface}.\\r\\n *\\r\\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\\r\\n */\\r\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\r\\n return _supportedInterfaces[interfaceId];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Registers the contract as an implementer of the interface defined by\\r\\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\\r\\n * registering its interface id is not required.\\r\\n *\\r\\n * See {IERC165-supportsInterface}.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\\r\\n */\\r\\n function _registerInterface(bytes4 interfaceId) internal virtual {\\r\\n require(interfaceId != 0xffffffff, \\\"ERC165: invalid interface id\\\");\\r\\n _supportedInterfaces[interfaceId] = true;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x5415f8c63658ee08e6284e6f270b2490331aea0c375b6451c4c9ed14a805a336\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC165 standard, as defined in the\\r\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\r\\n *\\r\\n * Implementers can declare support of contract interfaces, which can then be\\r\\n * queried by others ({ERC165Checker}).\\r\\n *\\r\\n * For an implementation, see {ERC165}.\\r\\n */\\r\\ninterface IERC165 {\\r\\n /**\\r\\n * @dev Returns true if this contract implements the interface defined by\\r\\n * `interfaceId`. See the corresponding\\r\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\r\\n * to learn more about how these ids are created.\\r\\n *\\r\\n * This function call must use less than 30 000 gas.\\r\\n */\\r\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\r\\n}\\r\\n\",\"keccak256\":\"0xd5da4ccf6a22475f021130a32aaad92daf6eecce9258cb7a8a5c48d109607767\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\r\\n * checks.\\r\\n *\\r\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\r\\n * in bugs, because programmers usually assume that an overflow raises an\\r\\n * error, which is the standard behavior in high level programming languages.\\r\\n * `SafeMath` restores this intuition by reverting the transaction when an\\r\\n * operation overflows.\\r\\n *\\r\\n * Using this library instead of the unchecked operations eliminates an entire\\r\\n * class of bugs, so it's recommended to use it always.\\r\\n */\\r\\nlibrary SafeMath {\\r\\n /**\\r\\n * @dev Returns the addition of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `+` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Addition cannot overflow.\\r\\n */\\r\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n uint256 c = a + b;\\r\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n */\\r\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b <= a, errorMessage);\\r\\n uint256 c = a - b;\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `*` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Multiplication cannot overflow.\\r\\n */\\r\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\r\\n // benefit is lost if 'b' is also tested.\\r\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\r\\n if (a == 0) {\\r\\n return 0;\\r\\n }\\r\\n\\r\\n uint256 c = a * b;\\r\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n // Solidity only automatically asserts when dividing by 0\\r\\n require(b > 0, errorMessage);\\r\\n uint256 c = a / b;\\r\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts with custom message when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b != 0, errorMessage);\\r\\n return a % b;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x29ffa7ff59806a3add585615cc102b70b43049587dcc73649f77b427f35b009d\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Secondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../GSN/Context.sol\\\";\\r\\n/**\\r\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\r\\n */\\r\\nabstract contract Secondary is Context {\\r\\n address private _primary;\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the primary contract changes.\\r\\n */\\r\\n event PrimaryTransferred(\\r\\n address recipient\\r\\n );\\r\\n\\r\\n /**\\r\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\r\\n */\\r\\n constructor () {\\r\\n _primary = _msgSender();\\r\\n emit PrimaryTransferred(_primary);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Reverts if called from any account other than the primary.\\r\\n */\\r\\n modifier onlyPrimary() {\\r\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @return the address of the primary.\\r\\n */\\r\\n function primary() public view returns (address) {\\r\\n return _primary;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers contract to a new primary.\\r\\n * @param recipient The address of new primary.\\r\\n */\\r\\n function transferPrimary(address recipient) public onlyPrimary {\\r\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\r\\n _primary = recipient;\\r\\n emit PrimaryTransferred(_primary);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x9138d9f1c2d4b2b9d6fd72ceb5ef461ffcd2c26ade7b15a5ee86456ecda089ca\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"./IERC721.sol\\\";\\r\\nimport \\\"./IERC721Metadata.sol\\\";\\r\\nimport \\\"./IERC721Enumerable.sol\\\";\\r\\nimport \\\"./IERC721Receiver.sol\\\";\\r\\nimport \\\"../../introspection/ERC165.sol\\\";\\r\\nimport \\\"../../math/SafeMath.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\nimport \\\"../../utils/EnumerableSet.sol\\\";\\r\\nimport \\\"../../utils/EnumerableMap.sol\\\";\\r\\nimport \\\"../../utils/Strings.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC721 Non-Fungible Token Standard basic implementation\\r\\n * @dev see https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\\r\\n using SafeMath for uint256;\\r\\n using Address for address;\\r\\n using EnumerableSet for EnumerableSet.UintSet;\\r\\n using EnumerableMap for EnumerableMap.UintToAddressMap;\\r\\n using Strings for uint256;\\r\\n\\r\\n // Equals to `bytes4(keccak256(\\\"onERC721Received(address,address,uint256,bytes)\\\"))`\\r\\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\\r\\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\\r\\n\\r\\n // Mapping from holder address to their (enumerable) set of owned tokens\\r\\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\\r\\n\\r\\n // Enumerable mapping from token ids to their owners\\r\\n EnumerableMap.UintToAddressMap private _tokenOwners;\\r\\n\\r\\n // Mapping from token ID to approved address\\r\\n mapping (uint256 => address) private _tokenApprovals;\\r\\n\\r\\n // Mapping from owner to operator approvals\\r\\n mapping (address => mapping (address => bool)) private _operatorApprovals;\\r\\n\\r\\n // Token name\\r\\n string private _name;\\r\\n\\r\\n // Token symbol\\r\\n string private _symbol;\\r\\n\\r\\n // Optional mapping for token URIs\\r\\n mapping (uint256 => string) private _tokenURIs;\\r\\n\\r\\n // Base URI\\r\\n string private _baseURI;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\\r\\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\\r\\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\\r\\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\\r\\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\\r\\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\\r\\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\\r\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\\r\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\\r\\n *\\r\\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\\r\\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('name()')) == 0x06fdde03\\r\\n * bytes4(keccak256('symbol()')) == 0x95d89b41\\r\\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\\r\\n *\\r\\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\\r\\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\\r\\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\\r\\n *\\r\\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\r\\n */\\r\\n constructor (string memory name_, string memory symbol_) {\\r\\n _name = name_;\\r\\n _symbol = symbol_;\\r\\n\\r\\n // register the supported interfaces to conform to ERC721 via ERC165\\r\\n _registerInterface(_INTERFACE_ID_ERC721);\\r\\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\\r\\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-balanceOf}.\\r\\n */\\r\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\r\\n require(owner != address(0), \\\"ERC721: balance query for the zero address\\\");\\r\\n return _holderTokens[owner].length();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-ownerOf}.\\r\\n */\\r\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\r\\n return _tokenOwners.get(tokenId, \\\"ERC721: owner query for nonexistent token\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-name}.\\r\\n */\\r\\n function name() public view virtual override returns (string memory) {\\r\\n return _name;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-symbol}.\\r\\n */\\r\\n function symbol() public view virtual override returns (string memory) {\\r\\n return _symbol;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-tokenURI}.\\r\\n */\\r\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\r\\n require(_exists(tokenId), \\\"ERC721Metadata: URI query for nonexistent token\\\");\\r\\n\\r\\n string memory _tokenURI = _tokenURIs[tokenId];\\r\\n string memory base = baseURI();\\r\\n\\r\\n // If there is no base URI, return the token URI.\\r\\n if (bytes(base).length == 0) {\\r\\n return _tokenURI;\\r\\n }\\r\\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\\r\\n if (bytes(_tokenURI).length > 0) {\\r\\n return string(abi.encodePacked(base, _tokenURI));\\r\\n }\\r\\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\\r\\n return string(abi.encodePacked(base, tokenId.toString()));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the base URI set via {_setBaseURI}. This will be\\r\\n * automatically added as a prefix in {tokenURI} to each token's URI, or\\r\\n * to the token ID if no specific URI is set for that token ID.\\r\\n */\\r\\n function baseURI() public view virtual returns (string memory) {\\r\\n return _baseURI;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\r\\n */\\r\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\r\\n return _holderTokens[owner].at(index);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-totalSupply}.\\r\\n */\\r\\n function totalSupply() public view virtual override returns (uint256) {\\r\\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\\r\\n return _tokenOwners.length();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\r\\n */\\r\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\r\\n (uint256 tokenId, ) = _tokenOwners.at(index);\\r\\n return tokenId;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-approve}.\\r\\n */\\r\\n function approve(address to, uint256 tokenId) public virtual override {\\r\\n address owner = ERC721.ownerOf(tokenId);\\r\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\r\\n\\r\\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\\r\\n \\\"ERC721: approve caller is not owner nor approved for all\\\"\\r\\n );\\r\\n\\r\\n _approve(to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-getApproved}.\\r\\n */\\r\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\r\\n require(_exists(tokenId), \\\"ERC721: approved query for nonexistent token\\\");\\r\\n\\r\\n return _tokenApprovals[tokenId];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-setApprovalForAll}.\\r\\n */\\r\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\r\\n require(operator != _msgSender(), \\\"ERC721: approve to caller\\\");\\r\\n\\r\\n _operatorApprovals[_msgSender()][operator] = approved;\\r\\n emit ApprovalForAll(_msgSender(), operator, approved);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-isApprovedForAll}.\\r\\n */\\r\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\r\\n return _operatorApprovals[owner][operator];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-transferFrom}.\\r\\n */\\r\\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\\r\\n //solhint-disable-next-line max-line-length\\r\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\r\\n\\r\\n _transfer(from, to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-safeTransferFrom}.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\\r\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-safeTransferFrom}.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\\r\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\r\\n _safeTransfer(from, to, tokenId, _data);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\r\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\r\\n *\\r\\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\\r\\n *\\r\\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\r\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\\r\\n _transfer(from, to, tokenId);\\r\\n require(_checkOnERC721Received(from, to, tokenId, _data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns whether `tokenId` exists.\\r\\n *\\r\\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\r\\n *\\r\\n * Tokens start existing when they are minted (`_mint`),\\r\\n * and stop existing when they are burned (`_burn`).\\r\\n */\\r\\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\\r\\n return _tokenOwners.contains(tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\r\\n require(_exists(tokenId), \\\"ERC721: operator query for nonexistent token\\\");\\r\\n address owner = ERC721.ownerOf(tokenId);\\r\\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\r\\n *\\r\\n * Requirements:\\r\\n d*\\r\\n * - `tokenId` must not exist.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\r\\n _safeMint(to, tokenId, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\r\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\r\\n */\\r\\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\\r\\n _mint(to, tokenId);\\r\\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Mints `tokenId` and transfers it to `to`.\\r\\n *\\r\\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must not exist.\\r\\n * - `to` cannot be the zero address.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _mint(address to, uint256 tokenId) internal virtual {\\r\\n require(to != address(0), \\\"ERC721: mint to the zero address\\\");\\r\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\r\\n\\r\\n _beforeTokenTransfer(address(0), to, tokenId);\\r\\n\\r\\n _holderTokens[to].add(tokenId);\\r\\n\\r\\n _tokenOwners.set(tokenId, to);\\r\\n\\r\\n emit Transfer(address(0), to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Destroys `tokenId`.\\r\\n * The approval is cleared when the token is burned.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _burn(uint256 tokenId) internal virtual {\\r\\n address owner = ERC721.ownerOf(tokenId); // internal owner\\r\\n\\r\\n _beforeTokenTransfer(owner, address(0), tokenId);\\r\\n\\r\\n // Clear approvals\\r\\n _approve(address(0), tokenId);\\r\\n\\r\\n // Clear metadata (if any)\\r\\n if (bytes(_tokenURIs[tokenId]).length != 0) {\\r\\n delete _tokenURIs[tokenId];\\r\\n }\\r\\n\\r\\n _holderTokens[owner].remove(tokenId);\\r\\n\\r\\n _tokenOwners.remove(tokenId);\\r\\n\\r\\n emit Transfer(owner, address(0), tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers `tokenId` from `from` to `to`.\\r\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must be owned by `from`.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\\r\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer of token that is not own\\\"); // internal owner\\r\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\r\\n\\r\\n _beforeTokenTransfer(from, to, tokenId);\\r\\n\\r\\n // Clear approvals from the previous owner\\r\\n _approve(address(0), tokenId);\\r\\n\\r\\n _holderTokens[from].remove(tokenId);\\r\\n _holderTokens[to].add(tokenId);\\r\\n\\r\\n _tokenOwners.set(tokenId, to);\\r\\n\\r\\n emit Transfer(from, to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\\r\\n require(_exists(tokenId), \\\"ERC721Metadata: URI set of nonexistent token\\\");\\r\\n _tokenURIs[tokenId] = _tokenURI;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Internal function to set the base URI for all token IDs. It is\\r\\n * automatically added as a prefix to the value returned in {tokenURI},\\r\\n * or to the token ID if {tokenURI} is empty.\\r\\n */\\r\\n function _setBaseURI(string memory baseURI_) internal virtual {\\r\\n _baseURI = baseURI_;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\r\\n * The call is not executed if the target address is not a contract.\\r\\n *\\r\\n * @param from address representing the previous owner of the given token ID\\r\\n * @param to target address that will receive the tokens\\r\\n * @param tokenId uint256 ID of the token to be transferred\\r\\n * @param _data bytes optional data to send along with the call\\r\\n * @return bool whether the call correctly returned the expected magic value\\r\\n */\\r\\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\\r\\n private returns (bool)\\r\\n {\\r\\n if (!to.isContract()) {\\r\\n return true;\\r\\n }\\r\\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\\r\\n IERC721Receiver(to).onERC721Received.selector,\\r\\n _msgSender(),\\r\\n from,\\r\\n tokenId,\\r\\n _data\\r\\n ), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n bytes4 retval = abi.decode(returndata, (bytes4));\\r\\n return (retval == _ERC721_RECEIVED);\\r\\n }\\r\\n\\r\\n function _approve(address to, uint256 tokenId) private {\\r\\n _tokenApprovals[tokenId] = to;\\r\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Hook that is called before any token transfer. This includes minting\\r\\n * and burning.\\r\\n *\\r\\n * Calling conditions:\\r\\n *\\r\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\r\\n * transferred to `to`.\\r\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\r\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n *\\r\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\r\\n */\\r\\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\\r\\n}\\r\\n\",\"keccak256\":\"0x4180eedc31f632ef146dd07583840a9688de44bdb9e7fe2425c448fd57496004\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"./ERC721.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC721 Burnable Token\\r\\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\\r\\n */\\r\\nabstract contract ERC721Burnable is Context, ERC721 {\\r\\n /**\\r\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - The caller must own `tokenId` or be an approved operator.\\r\\n */\\r\\n function burn(uint256 tokenId) public virtual {\\r\\n //solhint-disable-next-line max-line-length\\r\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721Burnable: caller is not owner nor approved\\\");\\r\\n _burn(tokenId);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x699ce4b0903e16b958d6a008703c24be7d11a7d3223e5e9ab9523a8f81687f13\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../../introspection/IERC165.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Required interface of an ERC721 compliant contract.\\r\\n */\\r\\ninterface IERC721 is IERC165 {\\r\\n /**\\r\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\r\\n */\\r\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\r\\n */\\r\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\r\\n */\\r\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of tokens in ``owner``'s account.\\r\\n */\\r\\n function balanceOf(address owner) external view returns (uint256 balance);\\r\\n\\r\\n /**\\r\\n * @dev Returns the owner of the `tokenId` token.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\r\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Transfers `tokenId` token from `from` to `to`.\\r\\n *\\r\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must be owned by `from`.\\r\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transferFrom(address from, address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\r\\n * The approval is cleared when the token is transferred.\\r\\n *\\r\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - The caller must own the token or be an approved operator.\\r\\n * - `tokenId` must exist.\\r\\n *\\r\\n * Emits an {Approval} event.\\r\\n */\\r\\n function approve(address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the account approved for `tokenId` token.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function getApproved(uint256 tokenId) external view returns (address operator);\\r\\n\\r\\n /**\\r\\n * @dev Approve or remove `operator` as an operator for the caller.\\r\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - The `operator` cannot be the caller.\\r\\n *\\r\\n * Emits an {ApprovalForAll} event.\\r\\n */\\r\\n function setApprovalForAll(address operator, bool _approved) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\r\\n *\\r\\n * See {setApprovalForAll}\\r\\n */\\r\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\r\\n}\\r\\n\",\"keccak256\":\"0xd3c22060e78ce52f5cb41b3ab9b29bb5582aa4a58015e878116251cba658324c\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC721.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\r\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ninterface IERC721Enumerable is IERC721 {\\r\\n\\r\\n /**\\r\\n * @dev Returns the total amount of tokens stored by the contract.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\r\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\r\\n */\\r\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\r\\n * Use along with {totalSupply} to enumerate all tokens.\\r\\n */\\r\\n function tokenByIndex(uint256 index) external view returns (uint256);\\r\\n}\\r\\n\",\"keccak256\":\"0x5539b1567797a57e7a135dcc446fdbb02b1ae2b450799274db88a47dea81e6fa\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC721.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\r\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ninterface IERC721Metadata is IERC721 {\\r\\n\\r\\n /**\\r\\n * @dev Returns the token collection name.\\r\\n */\\r\\n function name() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the token collection symbol.\\r\\n */\\r\\n function symbol() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\r\\n */\\r\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\r\\n}\\r\\n\",\"keccak256\":\"0xe92ae6f0b94fce8480d16a24faa8835926cd5fc074a4d418de94aaddbdecf49d\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @title ERC721 token receiver interface\\r\\n * @dev Interface for any contract that wants to support safeTransfers\\r\\n * from ERC721 asset contracts.\\r\\n */\\r\\ninterface IERC721Receiver {\\r\\n /**\\r\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\r\\n * by `operator` from `from`, this function is called.\\r\\n *\\r\\n * It must return its Solidity selector to confirm the token transfer.\\r\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\r\\n *\\r\\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\\r\\n */\\r\\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\\r\\n}\\r\\n\",\"keccak256\":\"0x515410f905897b0d658f1746064cc2a94d52a1bc625fab215dccb7fb5ead50f7\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/EnumerableMap.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Library for managing an enumerable variant of Solidity's\\r\\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\\r\\n * type.\\r\\n *\\r\\n * Maps have the following properties:\\r\\n *\\r\\n * - Entries are added, removed, and checked for existence in constant time\\r\\n * (O(1)).\\r\\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\\r\\n *\\r\\n * ```\\r\\n * contract Example {\\r\\n * // Add the library methods\\r\\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\\r\\n *\\r\\n * // Declare a set state variable\\r\\n * EnumerableMap.UintToAddressMap private myMap;\\r\\n * }\\r\\n * ```\\r\\n *\\r\\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\\r\\n * supported.\\r\\n */\\r\\nlibrary EnumerableMap {\\r\\n // To implement this library for multiple types with as little code\\r\\n // repetition as possible, we write it in terms of a generic Map type with\\r\\n // bytes32 keys and values.\\r\\n // The Map implementation uses private functions, and user-facing\\r\\n // implementations (such as Uint256ToAddressMap) are just wrappers around\\r\\n // the underlying Map.\\r\\n // This means that we can only create new EnumerableMaps for types that fit\\r\\n // in bytes32.\\r\\n\\r\\n struct MapEntry {\\r\\n bytes32 _key;\\r\\n bytes32 _value;\\r\\n }\\r\\n\\r\\n struct Map {\\r\\n // Storage of map keys and values\\r\\n MapEntry[] _entries;\\r\\n\\r\\n // Position of the entry defined by a key in the `entries` array, plus 1\\r\\n // because index 0 means a key is not in the map.\\r\\n mapping (bytes32 => uint256) _indexes;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Adds a key-value pair to a map, or updates the value for an existing\\r\\n * key. O(1).\\r\\n *\\r\\n * Returns true if the key was added to the map, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\\r\\n // We read and store the key's index to prevent multiple reads from the same storage slot\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n\\r\\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\\r\\n map._entries.push(MapEntry({ _key: key, _value: value }));\\r\\n // The entry is stored at length-1, but we add 1 to all indexes\\r\\n // and use 0 as a sentinel value\\r\\n map._indexes[key] = map._entries.length;\\r\\n return true;\\r\\n } else {\\r\\n map._entries[keyIndex - 1]._value = value;\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a key-value pair from a map. O(1).\\r\\n *\\r\\n * Returns true if the key was removed from the map, that is if it was present.\\r\\n */\\r\\n function _remove(Map storage map, bytes32 key) private returns (bool) {\\r\\n // We read and store the key's index to prevent multiple reads from the same storage slot\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n\\r\\n if (keyIndex != 0) { // Equivalent to contains(map, key)\\r\\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\\r\\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\\r\\n // This modifies the order of the array, as noted in {at}.\\r\\n\\r\\n uint256 toDeleteIndex = keyIndex - 1;\\r\\n uint256 lastIndex = map._entries.length - 1;\\r\\n\\r\\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\\r\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\r\\n\\r\\n MapEntry storage lastEntry = map._entries[lastIndex];\\r\\n\\r\\n // Move the last entry to the index where the entry to delete is\\r\\n map._entries[toDeleteIndex] = lastEntry;\\r\\n // Update the index for the moved entry\\r\\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\\r\\n\\r\\n // Delete the slot where the moved entry was stored\\r\\n map._entries.pop();\\r\\n\\r\\n // Delete the index for the deleted slot\\r\\n delete map._indexes[key];\\r\\n\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the key is in the map. O(1).\\r\\n */\\r\\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\\r\\n return map._indexes[key] != 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of key-value pairs in the map. O(1).\\r\\n */\\r\\n function _length(Map storage map) private view returns (uint256) {\\r\\n return map._entries.length;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of entries inside the\\r\\n * array, and it may change when more entries are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\\r\\n require(map._entries.length > index, \\\"EnumerableMap: index out of bounds\\\");\\r\\n\\r\\n MapEntry storage entry = map._entries[index];\\r\\n return (entry._key, entry._value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Tries to returns the value associated with `key`. O(1).\\r\\n * Does not revert if `key` is not in the map.\\r\\n */\\r\\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\\r\\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value associated with `key`. O(1).\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `key` must be in the map.\\r\\n */\\r\\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n require(keyIndex != 0, \\\"EnumerableMap: nonexistent key\\\"); // Equivalent to contains(map, key)\\r\\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\\r\\n *\\r\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\r\\n * message unnecessarily. For custom revert reasons use {_tryGet}.\\r\\n */\\r\\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\\r\\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\\r\\n }\\r\\n\\r\\n // UintToAddressMap\\r\\n\\r\\n struct UintToAddressMap {\\r\\n Map _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Adds a key-value pair to a map, or updates the value for an existing\\r\\n * key. O(1).\\r\\n *\\r\\n * Returns true if the key was added to the map, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\\r\\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the key was removed from the map, that is if it was present.\\r\\n */\\r\\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\\r\\n return _remove(map._inner, bytes32(key));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the key is in the map. O(1).\\r\\n */\\r\\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\\r\\n return _contains(map._inner, bytes32(key));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of elements in the map. O(1).\\r\\n */\\r\\n function length(UintToAddressMap storage map) internal view returns (uint256) {\\r\\n return _length(map._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the element stored at position `index` in the set. O(1).\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\\r\\n (bytes32 key, bytes32 value) = _at(map._inner, index);\\r\\n return (uint256(key), address(uint160(uint256(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Tries to returns the value associated with `key`. O(1).\\r\\n * Does not revert if `key` is not in the map.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\\r\\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\\r\\n return (success, address(uint160(uint256(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value associated with `key`. O(1).\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `key` must be in the map.\\r\\n */\\r\\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\\r\\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\\r\\n *\\r\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\r\\n * message unnecessarily. For custom revert reasons use {tryGet}.\\r\\n */\\r\\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\\r\\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x5538ae23826bfaa205dc16a24a50f18feaae576a1c46ddea7086bbbd4c13d84e\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Library for managing\\r\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\r\\n * types.\\r\\n *\\r\\n * Sets have the following properties:\\r\\n *\\r\\n * - Elements are added, removed, and checked for existence in constant time\\r\\n * (O(1)).\\r\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\r\\n *\\r\\n * ```\\r\\n * contract Example {\\r\\n * // Add the library methods\\r\\n * using EnumerableSet for EnumerableSet.AddressSet;\\r\\n *\\r\\n * // Declare a set state variable\\r\\n * EnumerableSet.AddressSet private mySet;\\r\\n * }\\r\\n * ```\\r\\n *\\r\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\r\\n * and `uint256` (`UintSet`) are supported.\\r\\n */\\r\\nlibrary EnumerableSet {\\r\\n // To implement this library for multiple types with as little code\\r\\n // repetition as possible, we write it in terms of a generic Set type with\\r\\n // bytes32 values.\\r\\n // The Set implementation uses private functions, and user-facing\\r\\n // implementations (such as AddressSet) are just wrappers around the\\r\\n // underlying Set.\\r\\n // This means that we can only create new EnumerableSets for types that fit\\r\\n // in bytes32.\\r\\n\\r\\n struct Set {\\r\\n // Storage of set values\\r\\n bytes32[] _values;\\r\\n\\r\\n // Position of the value in the `values` array, plus 1 because index 0\\r\\n // means a value is not in the set.\\r\\n mapping (bytes32 => uint256) _indexes;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\r\\n if (!_contains(set, value)) {\\r\\n set._values.push(value);\\r\\n // The value is stored at length-1, but we add 1 to all indexes\\r\\n // and use 0 as a sentinel value\\r\\n set._indexes[value] = set._values.length;\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\r\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\r\\n uint256 valueIndex = set._indexes[value];\\r\\n\\r\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\r\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\r\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\r\\n // This modifies the order of the array, as noted in {at}.\\r\\n\\r\\n uint256 toDeleteIndex = valueIndex - 1;\\r\\n uint256 lastIndex = set._values.length - 1;\\r\\n\\r\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\r\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\r\\n\\r\\n bytes32 lastvalue = set._values[lastIndex];\\r\\n\\r\\n // Move the last value to the index where the value to delete is\\r\\n set._values[toDeleteIndex] = lastvalue;\\r\\n // Update the index for the moved value\\r\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\r\\n\\r\\n // Delete the slot where the moved value was stored\\r\\n set._values.pop();\\r\\n\\r\\n // Delete the index for the deleted slot\\r\\n delete set._indexes[value];\\r\\n\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\r\\n return set._indexes[value] != 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values on the set. O(1).\\r\\n */\\r\\n function _length(Set storage set) private view returns (uint256) {\\r\\n return set._values.length;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\r\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\r\\n return set._values[index];\\r\\n }\\r\\n\\r\\n // Bytes32Set\\r\\n\\r\\n struct Bytes32Set {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\r\\n return _add(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\r\\n return _remove(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\r\\n return _contains(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values in the set. O(1).\\r\\n */\\r\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\r\\n return _at(set._inner, index);\\r\\n }\\r\\n\\r\\n // AddressSet\\r\\n\\r\\n struct AddressSet {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(AddressSet storage set, address value) internal returns (bool) {\\r\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\r\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\r\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values in the set. O(1).\\r\\n */\\r\\n function length(AddressSet storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\r\\n return address(uint160(uint256(_at(set._inner, index))));\\r\\n }\\r\\n\\r\\n\\r\\n // UintSet\\r\\n\\r\\n struct UintSet {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\r\\n return _add(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\r\\n return _remove(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\r\\n return _contains(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values on the set. O(1).\\r\\n */\\r\\n function length(UintSet storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\r\\n return uint256(_at(set._inner, index));\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x4c3f4a13b8f0c2b911044b85d3db13396e772cb9b79f7fb16ec8d41ca5fc7321\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev String operations.\\r\\n */\\r\\nlibrary Strings {\\r\\n /**\\r\\n * @dev Converts a `uint256` to its ASCII `string` representation.\\r\\n */\\r\\n function toString(uint256 value) internal pure returns (string memory) {\\r\\n // Inspired by OraclizeAPI's implementation - MIT licence\\r\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\r\\n\\r\\n if (value == 0) {\\r\\n return \\\"0\\\";\\r\\n }\\r\\n uint256 temp = value;\\r\\n uint256 digits;\\r\\n while (temp != 0) {\\r\\n digits++;\\r\\n temp /= 10;\\r\\n }\\r\\n bytes memory buffer = new bytes(digits);\\r\\n uint256 index = digits - 1;\\r\\n temp = value;\\r\\n while (temp != 0) {\\r\\n buffer[index--] = bytes1(uint8(48 + temp % 10));\\r\\n temp /= 10;\\r\\n }\\r\\n return string(buffer);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x0f1313d4fbca3b365d39200fc056b6db57b957b53dabb06d6fff3566fb8caa29\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50610019610074565b600080546001600160a01b0319166001600160a01b0392831617908190556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610067921690610078565b60405180910390a161008c565b3390565b6001600160a01b0391909116815260200190565b61286d8061009b6000396000f3fe60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b578063884758661462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002c7565b6200009d565b005b6200007b62000075366004620002f7565b6200016c565b6040516200008a9190620003ed565b60405180910390f35b6200007b6200025c565b6000546001600160a01b0316620000b36200026b565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000512565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc90620004c8565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d99262000161921690620003ed565b60405180910390a150565b600080546001600160a01b0316620001836200026b565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000512565b600089898989620001bc6200025c565b8a8a8a8a604051620001ce906200026f565b620001e29998979695949392919062000401565b604051809103906000f080158015620001ff573d6000803e3d6000fd5b509050806001600160a01b03167f3d0677e9be6c322795ce7407a961a98bb2822f9ed8a66c3c11d2ac9bab6d401a898989898989604051620002479695949392919062000479565b60405180910390a29998505050505050505050565b6000546001600160a01b031690565b3390565b6122d9806200055f83390190565b60008083601f8401126200028f578182fd5b50813567ffffffffffffffff811115620002a7578182fd5b602083019150836020828501011115620002c057600080fd5b9250929050565b600060208284031215620002d9578081fd5b81356001600160a01b0381168114620002f0578182fd5b9392505050565b6000806000806000806000806080898b03121562000313578384fd5b883567ffffffffffffffff808211156200032b578586fd5b620003398c838d016200027d565b909a50985060208b013591508082111562000352578586fd5b620003608c838d016200027d565b909850965060408b013591508082111562000379578586fd5b620003878c838d016200027d565b909650945060608b0135915080821115620003a0578384fd5b50620003af8b828c016200027d565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060a082526200041760a083018b8d620003c3565b82810360208401526200042c818a8c620003c3565b6001600160a01b03891660408501528381036060850152905062000452818789620003c3565b9050828103608084015262000469818587620003c3565b9c9b505050505050505050505050565b6000606082526200048f60608301888a620003c3565b8281036020840152620004a4818789620003c3565b90508281036040840152620004bb818587620003c3565b9998505050505050505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b50604051620022d9380380620022d983398101604081905262000034916200030f565b8484620000486301ffc9a760e01b6200011a565b81516200005d906006906020850190620001c8565b50805162000073906007906020840190620001c8565b50620000866380ac58cd60e01b6200011a565b62000098635b5e139f60e01b6200011a565b620000aa63780e9d6360e01b6200011a565b50506001600160a01b038316620000de5760405162461bcd60e51b8152600401620000d590620003e4565b60405180910390fd5b600a80546001600160a01b0319166001600160a01b03851617905562000104826200019f565b6200010f81620001b8565b50505050506200041b565b6001600160e01b031980821614156200017a576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b8051620001b4906009906020840190620001c8565b5050565b8051620001b490600b9060208401905b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200020057600085556200024b565b82601f106200021b57805160ff19168380011785556200024b565b828001600101855582156200024b579182015b828111156200024b5782518255916020019190600101906200022e565b50620002599291506200025d565b5090565b5b808211156200025957600081556001016200025e565b600082601f83011262000285578081fd5b81516001600160401b03808211156200029a57fe5b6040516020601f8401601f1916820181018381118382101715620002ba57fe5b6040528382528584018101871015620002d1578485fd5b8492505b83831015620002f45785830181015182840182015291820191620002d5565b838311156200030557848185840101525b5095945050505050565b600080600080600060a0868803121562000327578081fd5b85516001600160401b03808211156200033e578283fd5b6200034c89838a0162000274565b9650602088015191508082111562000362578283fd5b6200037089838a0162000274565b604089015190965091506001600160a01b03821682146200038f578283fd5b606088015191945080821115620003a4578283fd5b620003b289838a0162000274565b93506080880151915080821115620003c8578283fd5b50620003d78882890162000274565b9150509295509295909350565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b611eae806200042b6000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806342966c68116100b857806395d89b411161007c57806395d89b411461026c578063a22cb46514610274578063b88d4fde14610287578063c87b56dd1461029a578063e8a3d485146102ad578063e985e9c5146102b557610137565b806342966c68146102185780634f6ccce71461022b5780636352211e1461023e5780636c0360eb1461025157806370a082311461025957610137565b806318160ddd116100ff57806318160ddd146101b757806323b872dd146101cc5780632f745c59146101df57806340c10f19146101f257806342842e0e1461020557610137565b806301ffc9a71461013c57806306fdde0314610165578063075461721461017a578063081812fc1461018f578063095ea7b3146101a2575b600080fd5b61014f61014a366004611ac4565b6102c8565b60405161015c9190611b34565b60405180910390f35b61016d6102eb565b60405161015c9190611b3f565b610182610381565b60405161015c9190611b20565b61018261019d366004611aec565b610390565b6101b56101b0366004611a9b565b6103f2565b005b6101bf6104c8565b60405161015c9190611bec565b6101b56101da366004611966565b6104d9565b6101bf6101ed366004611a9b565b610530565b6101b5610200366004611a9b565b61055b565b6101b5610213366004611966565b6105ac565b6101b5610226366004611aec565b6105c7565b6101bf610239366004611aec565b610619565b61018261024c366004611aec565b61062f565b61016d610657565b6101bf61026736600461191a565b6106b8565b61016d610720565b6101b5610282366004611a61565b610781565b6101b56102953660046119a1565b610886565b61016d6102a8366004611aec565b6108e4565b61016d610b65565b61014f6102c3366004611934565b610bc6565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b820191906000526020600020905b81548152906001019060200180831161035a57829003601f168201915b5050505050905090565b600a546001600160a01b031681565b600061039b82610bf4565b6103d65760405162461bcd60e51b815260040180806020018281038252602c815260200180611d73602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006103fd8261062f565b9050806001600160a01b0316836001600160a01b031614156104505760405162461bcd60e51b8152600401808060200182810382526021815260200180611df76021913960400191505060405180910390fd5b806001600160a01b0316610462610c01565b6001600160a01b0316148061047e575061047e816102c3610c01565b6104b95760405162461bcd60e51b8152600401808060200182810382526038815260200180611cc66038913960400191505060405180910390fd5b6104c38383610c05565b505050565b60006104d46002610c73565b905090565b6104ea6104e4610c01565b82610c7e565b6105255760405162461bcd60e51b8152600401808060200182810382526031815260200180611e186031913960400191505060405180910390fd5b6104c3838383610d22565b6001600160a01b03821660009081526001602052604081206105529083610e6e565b90505b92915050565b600a546001600160a01b031661056f610c01565b6001600160a01b03161461059e5760405162461bcd60e51b815260040161059590611b72565b60405180910390fd5b6105a88282610e7a565b5050565b6104c383838360405180602001604052806000815250610886565b6105d26104e4610c01565b61060d5760405162461bcd60e51b8152600401808060200182810382526030815260200180611e496030913960400191505060405180910390fd5b61061681610fa8565b50565b600080610627600284611075565b509392505050565b600061055582604051806060016040528060298152602001611d286029913960029190611091565b60098054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b60006001600160a01b0382166106ff5760405162461bcd60e51b815260040180806020018281038252602a815260200180611cfe602a913960400191505060405180910390fd5b6001600160a01b038216600090815260016020526040902061055590610c73565b60078054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b610789610c01565b6001600160a01b0316826001600160a01b031614156107ef576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b80600560006107fc610c01565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610840610c01565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b610897610891610c01565b83610c7e565b6108d25760405162461bcd60e51b8152600401808060200182810382526031815260200180611e186031913960400191505060405180910390fd5b6108de848484846110a8565b50505050565b60606108ef82610bf4565b61092a5760405162461bcd60e51b815260040180806020018281038252602f815260200180611dc8602f913960400191505060405180910390fd5b60008281526008602090815260408083208054825160026001831615610100026000190190921691909104601f8101859004850282018501909352828152929091908301828280156109bd5780601f10610992576101008083540402835291602001916109bd565b820191906000526020600020905b8154815290600101906020018083116109a057829003601f168201915b5050505050905060006109ce610657565b90508051600014156109e2575090506102e6565b815115610aa35780826040516020018083805190602001908083835b60208310610a1d5780518252601f1990920191602091820191016109fe565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610a655780518252601f199092019160209182019101610a46565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052925050506102e6565b80610aad856110fa565b6040516020018083805190602001908083835b60208310610adf5780518252601f199092019160209182019101610ac0565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610b275780518252601f199092019160209182019101610b08565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b600b8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006105556002836111d5565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610c3a8261062f565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610555826111e1565b6000610c8982610bf4565b610cc45760405162461bcd60e51b815260040180806020018281038252602c815260200180611c9a602c913960400191505060405180910390fd5b6000610ccf8361062f565b9050806001600160a01b0316846001600160a01b03161480610d0a5750836001600160a01b0316610cff84610390565b6001600160a01b0316145b80610d1a5750610d1a8185610bc6565b949350505050565b826001600160a01b0316610d358261062f565b6001600160a01b031614610d7a5760405162461bcd60e51b8152600401808060200182810382526029815260200180611d9f6029913960400191505060405180910390fd5b6001600160a01b038216610dbf5760405162461bcd60e51b8152600401808060200182810382526024815260200180611c766024913960400191505060405180910390fd5b610dca8383836104c3565b610dd5600082610c05565b6001600160a01b0383166000908152600160205260409020610df790826111e5565b506001600160a01b0382166000908152600160205260409020610e1a90826111f1565b50610e27600282846111fd565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006105528383611213565b6001600160a01b038216610ed5576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b610ede81610bf4565b15610f30576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b610f3c600083836104c3565b6001600160a01b0382166000908152600160205260409020610f5e90826111f1565b50610f6b600282846111fd565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000610fb38261062f565b9050610fc1816000846104c3565b610fcc600083610c05565b600082815260086020526040902054600260001961010060018416150201909116041561100a57600082815260086020526040812061100a916118ab565b6001600160a01b038116600090815260016020526040902061102c90836111e5565b50611038600283611277565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60008080806110848686611283565b9097909650945050505050565b600061109e8484846112fe565b90505b9392505050565b6110b3848484610d22565b6110bf848484846113c8565b6108de5760405162461bcd60e51b8152600401808060200182810382526032815260200180611c446032913960400191505060405180910390fd5b60608161111f57506040805180820190915260018152600360fc1b60208201526102e6565b8160005b811561113757600101600a82049150611123565b60008167ffffffffffffffff8111801561115057600080fd5b506040519080825280601f01601f19166020018201604052801561117b576020820181803683370190505b50859350905060001982015b83156111cc57600a840660300160f81b828280600190039350815181106111aa57fe5b60200101906001600160f81b031916908160001a905350600a84049350611187565b50949350505050565b60006105528383611530565b5490565b60006105528383611548565b6000610552838361160e565b600061109e84846001600160a01b038516611658565b815460009082106112555760405162461bcd60e51b8152600401808060200182810382526022815260200180611c226022913960400191505060405180910390fd5b82600001828154811061126457fe5b9060005260206000200154905092915050565b600061055283836116ef565b8154600090819083106112c75760405162461bcd60e51b8152600401808060200182810382526022815260200180611d516022913960400191505060405180910390fd5b60008460000184815481106112d857fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816113995760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561135e578181015183820152602001611346565b50505050905090810190601f16801561138b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508460000160018203815481106113ac57fe5b9060005260206000209060020201600101549150509392505050565b60006113dc846001600160a01b03166117c3565b6113e857506001610d1a565b60006114f6630a85bd0160e11b6113fd610c01565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561146457818101518382015260200161144c565b50505050905090810190601f1680156114915780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001611c44603291396001600160a01b03881691906117c9565b9050600081806020019051602081101561150f57600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60009081526001919091016020526040902054151590565b60008181526001830160205260408120548015611604578354600019808301919081019060009087908390811061157b57fe5b906000526020600020015490508087600001848154811061159857fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806115c857fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610555565b6000915050610555565b600061161a8383611530565b61165057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610555565b506000610555565b6000828152600184016020526040812054806116bd5750506040805180820182528381526020808201848152865460018181018955600089815284812095516002909302909501918255915190820155865486845281880190925292909120556110a1565b828560000160018303815481106116d057fe5b90600052602060002090600202016001018190555060009150506110a1565b60008181526001830160205260408120548015611604578354600019808301919081019060009087908390811061172257fe5b906000526020600020906002020190508087600001848154811061174257fe5b60009182526020808320845460029093020191825560019384015491840191909155835482528983019052604090209084019055865487908061178157fe5b60008281526020808220600260001990940193840201828155600190810183905592909355888152898201909252604082209190915594506105559350505050565b3b151590565b606061109e8484600085856117dd856117c3565b6117f95760405162461bcd60e51b815260040161059590611bb5565b600080866001600160a01b031685876040516118159190611b04565b60006040518083038185875af1925050503d8060008114611852576040519150601f19603f3d011682016040523d82523d6000602084013e611857565b606091505b5091509150611867828286611872565b979650505050505050565b606083156118815750816110a1565b8251156118915782518084602001fd5b8160405162461bcd60e51b81526004016105959190611b3f565b50805460018160011615610100020316600290046000825580601f106118d15750610616565b601f01602090049060005260206000209081019061061691905b808211156118ff57600081556001016118eb565b5090565b80356001600160a01b03811681146102e657600080fd5b60006020828403121561192b578081fd5b61055282611903565b60008060408385031215611946578081fd5b61194f83611903565b915061195d60208401611903565b90509250929050565b60008060006060848603121561197a578081fd5b61198384611903565b925061199160208501611903565b9150604084013590509250925092565b600080600080608085870312156119b6578081fd5b6119bf85611903565b935060206119ce818701611903565b935060408601359250606086013567ffffffffffffffff808211156119f1578384fd5b818801915088601f830112611a04578384fd5b813581811115611a1057fe5b604051601f8201601f1916810185018381118282101715611a2d57fe5b60405281815283820185018b1015611a43578586fd5b81858501868301379081019093019390935250939692955090935050565b60008060408385031215611a73578182fd5b611a7c83611903565b915060208301358015158114611a90578182fd5b809150509250929050565b60008060408385031215611aad578182fd5b611ab683611903565b946020939093013593505050565b600060208284031215611ad5578081fd5b81356001600160e01b0319811681146110a1578182fd5b600060208284031215611afd578081fd5b5035919050565b60008251611b16818460208701611bf5565b9190910192915050565b6001600160a01b0391909116815260200190565b901515815260200190565b6000602082528251806020840152611b5e816040850160208701611bf5565b601f01601f19169190910160400192915050565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b90815260200190565b60005b83811015611c10578181015183820152602001611bf8565b838111156108de575050600091015256fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665644552433732314275726e61626c653a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a26469706673582212205307f2282cc3339095cc0f4126ed0dad47c6f8ccf92f08d8924edffb57bc62f264736f6c63430007060033a264697066735822122003345c4b244dad413e4ec6ea2b273db60207e29a100d6c2a37386abca0146aac64736f6c63430007060033",
+ "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b578063884758661462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002c7565b6200009d565b005b6200007b62000075366004620002f7565b6200016c565b6040516200008a9190620003ed565b60405180910390f35b6200007b6200025c565b6000546001600160a01b0316620000b36200026b565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000512565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc90620004c8565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d99262000161921690620003ed565b60405180910390a150565b600080546001600160a01b0316620001836200026b565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000512565b600089898989620001bc6200025c565b8a8a8a8a604051620001ce906200026f565b620001e29998979695949392919062000401565b604051809103906000f080158015620001ff573d6000803e3d6000fd5b509050806001600160a01b03167f3d0677e9be6c322795ce7407a961a98bb2822f9ed8a66c3c11d2ac9bab6d401a898989898989604051620002479695949392919062000479565b60405180910390a29998505050505050505050565b6000546001600160a01b031690565b3390565b6122d9806200055f83390190565b60008083601f8401126200028f578182fd5b50813567ffffffffffffffff811115620002a7578182fd5b602083019150836020828501011115620002c057600080fd5b9250929050565b600060208284031215620002d9578081fd5b81356001600160a01b0381168114620002f0578182fd5b9392505050565b6000806000806000806000806080898b03121562000313578384fd5b883567ffffffffffffffff808211156200032b578586fd5b620003398c838d016200027d565b909a50985060208b013591508082111562000352578586fd5b620003608c838d016200027d565b909850965060408b013591508082111562000379578586fd5b620003878c838d016200027d565b909650945060608b0135915080821115620003a0578384fd5b50620003af8b828c016200027d565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060a082526200041760a083018b8d620003c3565b82810360208401526200042c818a8c620003c3565b6001600160a01b03891660408501528381036060850152905062000452818789620003c3565b9050828103608084015262000469818587620003c3565b9c9b505050505050505050505050565b6000606082526200048f60608301888a620003c3565b8281036020840152620004a4818789620003c3565b90508281036040840152620004bb818587620003c3565b9998505050505050505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b50604051620022d9380380620022d983398101604081905262000034916200030f565b8484620000486301ffc9a760e01b6200011a565b81516200005d906006906020850190620001c8565b50805162000073906007906020840190620001c8565b50620000866380ac58cd60e01b6200011a565b62000098635b5e139f60e01b6200011a565b620000aa63780e9d6360e01b6200011a565b50506001600160a01b038316620000de5760405162461bcd60e51b8152600401620000d590620003e4565b60405180910390fd5b600a80546001600160a01b0319166001600160a01b03851617905562000104826200019f565b6200010f81620001b8565b50505050506200041b565b6001600160e01b031980821614156200017a576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b8051620001b4906009906020840190620001c8565b5050565b8051620001b490600b9060208401905b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200020057600085556200024b565b82601f106200021b57805160ff19168380011785556200024b565b828001600101855582156200024b579182015b828111156200024b5782518255916020019190600101906200022e565b50620002599291506200025d565b5090565b5b808211156200025957600081556001016200025e565b600082601f83011262000285578081fd5b81516001600160401b03808211156200029a57fe5b6040516020601f8401601f1916820181018381118382101715620002ba57fe5b6040528382528584018101871015620002d1578485fd5b8492505b83831015620002f45785830181015182840182015291820191620002d5565b838311156200030557848185840101525b5095945050505050565b600080600080600060a0868803121562000327578081fd5b85516001600160401b03808211156200033e578283fd5b6200034c89838a0162000274565b9650602088015191508082111562000362578283fd5b6200037089838a0162000274565b604089015190965091506001600160a01b03821682146200038f578283fd5b606088015191945080821115620003a4578283fd5b620003b289838a0162000274565b93506080880151915080821115620003c8578283fd5b50620003d78882890162000274565b9150509295509295909350565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b611eae806200042b6000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806342966c68116100b857806395d89b411161007c57806395d89b411461026c578063a22cb46514610274578063b88d4fde14610287578063c87b56dd1461029a578063e8a3d485146102ad578063e985e9c5146102b557610137565b806342966c68146102185780634f6ccce71461022b5780636352211e1461023e5780636c0360eb1461025157806370a082311461025957610137565b806318160ddd116100ff57806318160ddd146101b757806323b872dd146101cc5780632f745c59146101df57806340c10f19146101f257806342842e0e1461020557610137565b806301ffc9a71461013c57806306fdde0314610165578063075461721461017a578063081812fc1461018f578063095ea7b3146101a2575b600080fd5b61014f61014a366004611ac4565b6102c8565b60405161015c9190611b34565b60405180910390f35b61016d6102eb565b60405161015c9190611b3f565b610182610381565b60405161015c9190611b20565b61018261019d366004611aec565b610390565b6101b56101b0366004611a9b565b6103f2565b005b6101bf6104c8565b60405161015c9190611bec565b6101b56101da366004611966565b6104d9565b6101bf6101ed366004611a9b565b610530565b6101b5610200366004611a9b565b61055b565b6101b5610213366004611966565b6105ac565b6101b5610226366004611aec565b6105c7565b6101bf610239366004611aec565b610619565b61018261024c366004611aec565b61062f565b61016d610657565b6101bf61026736600461191a565b6106b8565b61016d610720565b6101b5610282366004611a61565b610781565b6101b56102953660046119a1565b610886565b61016d6102a8366004611aec565b6108e4565b61016d610b65565b61014f6102c3366004611934565b610bc6565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b820191906000526020600020905b81548152906001019060200180831161035a57829003601f168201915b5050505050905090565b600a546001600160a01b031681565b600061039b82610bf4565b6103d65760405162461bcd60e51b815260040180806020018281038252602c815260200180611d73602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006103fd8261062f565b9050806001600160a01b0316836001600160a01b031614156104505760405162461bcd60e51b8152600401808060200182810382526021815260200180611df76021913960400191505060405180910390fd5b806001600160a01b0316610462610c01565b6001600160a01b0316148061047e575061047e816102c3610c01565b6104b95760405162461bcd60e51b8152600401808060200182810382526038815260200180611cc66038913960400191505060405180910390fd5b6104c38383610c05565b505050565b60006104d46002610c73565b905090565b6104ea6104e4610c01565b82610c7e565b6105255760405162461bcd60e51b8152600401808060200182810382526031815260200180611e186031913960400191505060405180910390fd5b6104c3838383610d22565b6001600160a01b03821660009081526001602052604081206105529083610e6e565b90505b92915050565b600a546001600160a01b031661056f610c01565b6001600160a01b03161461059e5760405162461bcd60e51b815260040161059590611b72565b60405180910390fd5b6105a88282610e7a565b5050565b6104c383838360405180602001604052806000815250610886565b6105d26104e4610c01565b61060d5760405162461bcd60e51b8152600401808060200182810382526030815260200180611e496030913960400191505060405180910390fd5b61061681610fa8565b50565b600080610627600284611075565b509392505050565b600061055582604051806060016040528060298152602001611d286029913960029190611091565b60098054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b60006001600160a01b0382166106ff5760405162461bcd60e51b815260040180806020018281038252602a815260200180611cfe602a913960400191505060405180910390fd5b6001600160a01b038216600090815260016020526040902061055590610c73565b60078054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b610789610c01565b6001600160a01b0316826001600160a01b031614156107ef576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b80600560006107fc610c01565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610840610c01565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b610897610891610c01565b83610c7e565b6108d25760405162461bcd60e51b8152600401808060200182810382526031815260200180611e186031913960400191505060405180910390fd5b6108de848484846110a8565b50505050565b60606108ef82610bf4565b61092a5760405162461bcd60e51b815260040180806020018281038252602f815260200180611dc8602f913960400191505060405180910390fd5b60008281526008602090815260408083208054825160026001831615610100026000190190921691909104601f8101859004850282018501909352828152929091908301828280156109bd5780601f10610992576101008083540402835291602001916109bd565b820191906000526020600020905b8154815290600101906020018083116109a057829003601f168201915b5050505050905060006109ce610657565b90508051600014156109e2575090506102e6565b815115610aa35780826040516020018083805190602001908083835b60208310610a1d5780518252601f1990920191602091820191016109fe565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610a655780518252601f199092019160209182019101610a46565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052925050506102e6565b80610aad856110fa565b6040516020018083805190602001908083835b60208310610adf5780518252601f199092019160209182019101610ac0565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610b275780518252601f199092019160209182019101610b08565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b600b8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006105556002836111d5565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610c3a8261062f565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610555826111e1565b6000610c8982610bf4565b610cc45760405162461bcd60e51b815260040180806020018281038252602c815260200180611c9a602c913960400191505060405180910390fd5b6000610ccf8361062f565b9050806001600160a01b0316846001600160a01b03161480610d0a5750836001600160a01b0316610cff84610390565b6001600160a01b0316145b80610d1a5750610d1a8185610bc6565b949350505050565b826001600160a01b0316610d358261062f565b6001600160a01b031614610d7a5760405162461bcd60e51b8152600401808060200182810382526029815260200180611d9f6029913960400191505060405180910390fd5b6001600160a01b038216610dbf5760405162461bcd60e51b8152600401808060200182810382526024815260200180611c766024913960400191505060405180910390fd5b610dca8383836104c3565b610dd5600082610c05565b6001600160a01b0383166000908152600160205260409020610df790826111e5565b506001600160a01b0382166000908152600160205260409020610e1a90826111f1565b50610e27600282846111fd565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006105528383611213565b6001600160a01b038216610ed5576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b610ede81610bf4565b15610f30576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b610f3c600083836104c3565b6001600160a01b0382166000908152600160205260409020610f5e90826111f1565b50610f6b600282846111fd565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000610fb38261062f565b9050610fc1816000846104c3565b610fcc600083610c05565b600082815260086020526040902054600260001961010060018416150201909116041561100a57600082815260086020526040812061100a916118ab565b6001600160a01b038116600090815260016020526040902061102c90836111e5565b50611038600283611277565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60008080806110848686611283565b9097909650945050505050565b600061109e8484846112fe565b90505b9392505050565b6110b3848484610d22565b6110bf848484846113c8565b6108de5760405162461bcd60e51b8152600401808060200182810382526032815260200180611c446032913960400191505060405180910390fd5b60608161111f57506040805180820190915260018152600360fc1b60208201526102e6565b8160005b811561113757600101600a82049150611123565b60008167ffffffffffffffff8111801561115057600080fd5b506040519080825280601f01601f19166020018201604052801561117b576020820181803683370190505b50859350905060001982015b83156111cc57600a840660300160f81b828280600190039350815181106111aa57fe5b60200101906001600160f81b031916908160001a905350600a84049350611187565b50949350505050565b60006105528383611530565b5490565b60006105528383611548565b6000610552838361160e565b600061109e84846001600160a01b038516611658565b815460009082106112555760405162461bcd60e51b8152600401808060200182810382526022815260200180611c226022913960400191505060405180910390fd5b82600001828154811061126457fe5b9060005260206000200154905092915050565b600061055283836116ef565b8154600090819083106112c75760405162461bcd60e51b8152600401808060200182810382526022815260200180611d516022913960400191505060405180910390fd5b60008460000184815481106112d857fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816113995760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561135e578181015183820152602001611346565b50505050905090810190601f16801561138b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508460000160018203815481106113ac57fe5b9060005260206000209060020201600101549150509392505050565b60006113dc846001600160a01b03166117c3565b6113e857506001610d1a565b60006114f6630a85bd0160e11b6113fd610c01565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561146457818101518382015260200161144c565b50505050905090810190601f1680156114915780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001611c44603291396001600160a01b03881691906117c9565b9050600081806020019051602081101561150f57600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60009081526001919091016020526040902054151590565b60008181526001830160205260408120548015611604578354600019808301919081019060009087908390811061157b57fe5b906000526020600020015490508087600001848154811061159857fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806115c857fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610555565b6000915050610555565b600061161a8383611530565b61165057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610555565b506000610555565b6000828152600184016020526040812054806116bd5750506040805180820182528381526020808201848152865460018181018955600089815284812095516002909302909501918255915190820155865486845281880190925292909120556110a1565b828560000160018303815481106116d057fe5b90600052602060002090600202016001018190555060009150506110a1565b60008181526001830160205260408120548015611604578354600019808301919081019060009087908390811061172257fe5b906000526020600020906002020190508087600001848154811061174257fe5b60009182526020808320845460029093020191825560019384015491840191909155835482528983019052604090209084019055865487908061178157fe5b60008281526020808220600260001990940193840201828155600190810183905592909355888152898201909252604082209190915594506105559350505050565b3b151590565b606061109e8484600085856117dd856117c3565b6117f95760405162461bcd60e51b815260040161059590611bb5565b600080866001600160a01b031685876040516118159190611b04565b60006040518083038185875af1925050503d8060008114611852576040519150601f19603f3d011682016040523d82523d6000602084013e611857565b606091505b5091509150611867828286611872565b979650505050505050565b606083156118815750816110a1565b8251156118915782518084602001fd5b8160405162461bcd60e51b81526004016105959190611b3f565b50805460018160011615610100020316600290046000825580601f106118d15750610616565b601f01602090049060005260206000209081019061061691905b808211156118ff57600081556001016118eb565b5090565b80356001600160a01b03811681146102e657600080fd5b60006020828403121561192b578081fd5b61055282611903565b60008060408385031215611946578081fd5b61194f83611903565b915061195d60208401611903565b90509250929050565b60008060006060848603121561197a578081fd5b61198384611903565b925061199160208501611903565b9150604084013590509250925092565b600080600080608085870312156119b6578081fd5b6119bf85611903565b935060206119ce818701611903565b935060408601359250606086013567ffffffffffffffff808211156119f1578384fd5b818801915088601f830112611a04578384fd5b813581811115611a1057fe5b604051601f8201601f1916810185018381118282101715611a2d57fe5b60405281815283820185018b1015611a43578586fd5b81858501868301379081019093019390935250939692955090935050565b60008060408385031215611a73578182fd5b611a7c83611903565b915060208301358015158114611a90578182fd5b809150509250929050565b60008060408385031215611aad578182fd5b611ab683611903565b946020939093013593505050565b600060208284031215611ad5578081fd5b81356001600160e01b0319811681146110a1578182fd5b600060208284031215611afd578081fd5b5035919050565b60008251611b16818460208701611bf5565b9190910192915050565b6001600160a01b0391909116815260200190565b901515815260200190565b6000602082528251806020840152611b5e816040850160208701611bf5565b601f01601f19169190910160400192915050565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b90815260200190565b60005b83811015611c10578181015183820152602001611bf8565b838111156108de575050600091015256fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665644552433732314275726e61626c653a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a26469706673582212205307f2282cc3339095cc0f4126ed0dad47c6f8ccf92f08d8924edffb57bc62f264736f6c63430007060033a264697066735822122003345c4b244dad413e4ec6ea2b273db60207e29a100d6c2a37386abca0146aac64736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 11018,
+ "contract": "contracts/nftbridge/SideNFTTokenFactory.sol:SideNFTTokenFactory",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/SideTokenFactory.json b/bridge/deployments/rinkeby/SideTokenFactory.json
new file mode 100644
index 000000000..75abdd882
--- /dev/null
+++ b/bridge/deployments/rinkeby/SideTokenFactory.json
@@ -0,0 +1,173 @@
+{
+ "address": "0x1CB41Dc4603612A4da692669916e8F4dEF2994dC",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "SideTokenCreated",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x0ac0dc861dbe1f3aa2103ac686141d22d3de471e3bc6f5396732302bf671fcd5",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0x1CB41Dc4603612A4da692669916e8F4dEF2994dC",
+ "transactionIndex": 1,
+ "gasUsed": "2585928",
+ "logsBloom": "0x00000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000100000",
+ "blockHash": "0xf5619a03f52ee119bca70b94557ea541df4017d4a0b78d3de336f69ed315cc24",
+ "transactionHash": "0x0ac0dc861dbe1f3aa2103ac686141d22d3de471e3bc6f5396732302bf671fcd5",
+ "logs": [
+ {
+ "transactionIndex": 1,
+ "blockNumber": 9264193,
+ "transactionHash": "0x0ac0dc861dbe1f3aa2103ac686141d22d3de471e3bc6f5396732302bf671fcd5",
+ "address": "0x1CB41Dc4603612A4da692669916e8F4dEF2994dC",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ],
+ "data": "0x0000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b",
+ "logIndex": 1,
+ "blockHash": "0xf5619a03f52ee119bca70b94557ea541df4017d4a0b78d3de336f69ed315cc24"
+ }
+ ],
+ "blockNumber": 9264193,
+ "cumulativeGasUsed": "2650696",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"granularity\",\"type\":\"uint256\"}],\"name\":\"SideTokenCreated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"granularity\",\"type\":\"uint256\"}],\"name\":\"createSideToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/SideTokenFactory/SideTokenFactory.sol\":\"SideTokenFactory\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/SideToken/SideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../zeppelin/token/ERC777/ERC777.sol\\\";\\r\\nimport \\\"../interface/IERC677Receiver.sol\\\";\\r\\nimport \\\"../interface/ISideToken.sol\\\";\\r\\nimport \\\"../lib/LibEIP712.sol\\\";\\r\\n\\r\\ncontract SideToken is ISideToken, ERC777 {\\r\\n using Address for address;\\r\\n using SafeMath for uint256;\\r\\n\\r\\n address public minter;\\r\\n uint256 private _granularity;\\r\\n\\r\\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\\r\\n bytes32 public domainSeparator;\\r\\n // keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\r\\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\\r\\n mapping(address => uint) public nonces;\\r\\n\\r\\n // ERC677 Transfer Event\\r\\n event Transfer(address,address,uint256,bytes);\\r\\n\\r\\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\\r\\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\\r\\n require(_minterAddr != address(0), \\\"SideToken: Empty Minter\\\");\\r\\n require(_newGranularity >= 1, \\\"SideToken: Granularity < 1\\\");\\r\\n minter = _minterAddr;\\r\\n _granularity = _newGranularity;\\r\\n\\r\\n uint chainId;\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n chainId := chainid()\\r\\n }\\r\\n domainSeparator = LibEIP712.hashEIP712Domain(\\r\\n name(),\\r\\n \\\"1\\\",\\r\\n chainId,\\r\\n address(this)\\r\\n );\\r\\n }\\r\\n\\r\\n modifier onlyMinter() {\\r\\n require(_msgSender() == minter, \\\"SideToken: Caller is not the minter\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function mint(\\r\\n address account,\\r\\n uint256 amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata operatorData\\r\\n )\\r\\n external onlyMinter override\\r\\n {\\r\\n _mint(_msgSender(), account, amount, userData, operatorData);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\\r\\n * @param recipient The address to transfer to.\\r\\n * @param amount The amount to be transferred.\\r\\n * @param data The extra data to be passed to the receiving contract.\\r\\n */\\r\\n function transferAndCall(address recipient, uint amount, bytes calldata data)\\r\\n external returns (bool success)\\r\\n {\\r\\n address from = _msgSender();\\r\\n\\r\\n _send(from, from, recipient, amount, data, \\\"\\\", false);\\r\\n emit Transfer(from, recipient, amount, data);\\r\\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\\r\\n return true;\\r\\n }\\r\\n\\r\\n function granularity() public view override returns (uint256) {\\r\\n return _granularity;\\r\\n }\\r\\n\\r\\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\\r\\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\\r\\n require(deadline >= block.timestamp, \\\"SideToken: EXPIRED\\\"); // solhint-disable-line not-rely-on-time\\r\\n bytes32 digest = LibEIP712.hashEIP712Message(\\r\\n domainSeparator,\\r\\n keccak256(\\r\\n abi.encode(\\r\\n PERMIT_TYPEHASH,\\r\\n owner,\\r\\n spender,\\r\\n value,\\r\\n nonces[owner]++,\\r\\n deadline\\r\\n )\\r\\n )\\r\\n );\\r\\n address recoveredAddress = ecrecover(digest, v, r, s);\\r\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"SideToken: INVALID_SIGNATURE\\\");\\r\\n _approve(owner, spender, value);\\r\\n }\\r\\n\\r\\n}\",\"keccak256\":\"0x8dc386892a6c2db9d5cda50f159054df2309b4031abd43505a8ff0082a0e8b6a\",\"license\":\"MIT\"},\"contracts/SideTokenFactory/SideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../zeppelin/ownership/Secondary.sol\\\";\\r\\nimport \\\"../interface/ISideTokenFactory.sol\\\";\\r\\nimport \\\"../SideToken/SideToken.sol\\\";\\r\\n\\r\\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\\r\\n\\r\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\\r\\n external onlyPrimary override returns(address) {\\r\\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\\r\\n emit SideTokenCreated(sideToken, symbol, granularity);\\r\\n return sideToken;\\r\\n }\\r\\n}\",\"keccak256\":\"0x1c1fed2932047fa8e68041b33e0f0dc2d461e4e99c74d02da9a4714b4441bbe0\",\"license\":\"MIT\"},\"contracts/interface/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface IERC677Receiver {\\r\\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\\r\\n}\",\"keccak256\":\"0x37338df5bea5204995bca492b0f421fc2ea3e11bafa54b1e6080fd5ed6824a43\",\"license\":\"MIT\"},\"contracts/interface/ISideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideToken {\\r\\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\\r\\n}\",\"keccak256\":\"0x22b96c1de44cc83f38f93cb0bebac0d090b88e1d951373eefdceb2b4284d6ffa\",\"license\":\"MIT\"},\"contracts/interface/ISideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideTokenFactory {\\r\\n\\r\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\\r\\n\\r\\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\\r\\n}\",\"keccak256\":\"0xbac49cc8df91c7aae47037ac9b3956615399bc6fa01d2a49764a7e6e48085b14\",\"license\":\"MIT\"},\"contracts/lib/LibEIP712.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\\r\\nlibrary LibEIP712 {\\r\\n\\r\\n // Hash of the EIP712 Domain Separator Schema\\r\\n // keccak256(abi.encodePacked(\\r\\n // \\\"EIP712Domain(\\\",\\r\\n // \\\"string name,\\\",\\r\\n // \\\"string version,\\\",\\r\\n // \\\"uint256 chainId,\\\",\\r\\n // \\\"address verifyingContract\\\",\\r\\n // \\\")\\\"\\r\\n // ))\\r\\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\\r\\n\\r\\n /// @dev Calculates a EIP712 domain separator.\\r\\n /// @param name The EIP712 domain name.\\r\\n /// @param version The EIP712 domain version.\\r\\n /// @param verifyingContract The EIP712 verifying contract.\\r\\n /// @return result EIP712 domain separator.\\r\\n function hashEIP712Domain(\\r\\n string memory name,\\r\\n string memory version,\\r\\n uint256 chainId,\\r\\n address verifyingContract\\r\\n )\\r\\n internal\\r\\n pure\\r\\n returns (bytes32 result)\\r\\n {\\r\\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\\r\\n\\r\\n // Assembly for more efficient computing:\\r\\n // keccak256(abi.encodePacked(\\r\\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\\r\\n // keccak256(bytes(name)),\\r\\n // keccak256(bytes(version)),\\r\\n // chainId,\\r\\n // uint256(verifyingContract)\\r\\n // ))\\r\\n\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n // Calculate hashes of dynamic data\\r\\n let nameHash := keccak256(add(name, 32), mload(name))\\r\\n let versionHash := keccak256(add(version, 32), mload(version))\\r\\n\\r\\n // Load free memory pointer\\r\\n let memPtr := mload(64)\\r\\n\\r\\n // Store params in memory\\r\\n mstore(memPtr, schemaHash)\\r\\n mstore(add(memPtr, 32), nameHash)\\r\\n mstore(add(memPtr, 64), versionHash)\\r\\n mstore(add(memPtr, 96), chainId)\\r\\n mstore(add(memPtr, 128), verifyingContract)\\r\\n\\r\\n // Compute hash\\r\\n result := keccak256(memPtr, 160)\\r\\n }\\r\\n return result;\\r\\n }\\r\\n\\r\\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\\r\\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\\r\\n /// with getDomainHash().\\r\\n /// @param hashStruct The EIP712 hash struct.\\r\\n /// @return result EIP712 hash applied to the given EIP712 Domain.\\r\\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\\r\\n internal\\r\\n pure\\r\\n returns (bytes32 result)\\r\\n {\\r\\n // Assembly for more efficient computing:\\r\\n // keccak256(abi.encodePacked(\\r\\n // EIP191_HEADER,\\r\\n // EIP712_DOMAIN_HASH,\\r\\n // hashStruct\\r\\n // ));\\r\\n\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n // Load free memory pointer\\r\\n let memPtr := mload(64)\\r\\n\\r\\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\\r\\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\\r\\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\\r\\n\\r\\n // Compute hash\\r\\n result := keccak256(memPtr, 66)\\r\\n }\\r\\n return result;\\r\\n }\\r\\n}\",\"keccak256\":\"0xfcfcf60905df9a2644e372c9e76b8cc7a5034c5c4d6d9f44b1ffb56244551237\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC1820Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\r\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\r\\n * implementers for interfaces in this registry, as well as query support.\\r\\n *\\r\\n * Implementers may be shared by multiple accounts, and can also implement more\\r\\n * than a single interface for each account. Contracts can implement interfaces\\r\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\r\\n * contract.\\r\\n *\\r\\n * {IERC165} interfaces can also be queried via the registry.\\r\\n *\\r\\n * For an in-depth explanation and source code analysis, see the EIP text.\\r\\n */\\r\\ninterface IERC1820Registry {\\r\\n /**\\r\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\r\\n * account is able to set interface implementers for it.\\r\\n *\\r\\n * By default, each account is its own manager. Passing a value of `0x0` in\\r\\n * `newManager` will reset the manager to this initial state.\\r\\n *\\r\\n * Emits a {ManagerChanged} event.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the caller must be the current manager for `account`.\\r\\n */\\r\\n function setManager(address account, address newManager) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the manager for `account`.\\r\\n *\\r\\n * See {setManager}.\\r\\n */\\r\\n function getManager(address account) external view returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Sets the `implementer` contract as `account`'s implementer for\\r\\n * `interfaceHash`.\\r\\n *\\r\\n * `account` being the zero address is an alias for the caller's address.\\r\\n * The zero address can also be used in `implementer` to remove an old one.\\r\\n *\\r\\n * See {interfaceHash} to learn how these are created.\\r\\n *\\r\\n * Emits an {InterfaceImplementerSet} event.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the caller must be the current manager for `_account`.\\r\\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\r\\n * end in 28 zeroes).\\r\\n * - `_implementer` must implement {IERC1820Implementer} and return true when\\r\\n * queried for support, unless `implementer` is the caller. See\\r\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\r\\n */\\r\\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\\r\\n * implementer is registered, returns the zero address.\\r\\n *\\r\\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\r\\n * zeroes), `_account` will be queried for support of it.\\r\\n *\\r\\n * `account` being the zero address is an alias for the caller's address.\\r\\n */\\r\\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\r\\n * corresponding\\r\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\r\\n */\\r\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\r\\n\\r\\n /**\\r\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\r\\n * @param account Address of the contract for which to update the cache.\\r\\n * @param interfaceId ERC165 interface for which to update the cache.\\r\\n */\\r\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\r\\n\\r\\n /**\\r\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\r\\n * If the result is not cached a direct lookup on the contract address is performed.\\r\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\r\\n * {updateERC165Cache} with the contract address.\\r\\n * @param account Address of the contract to check.\\r\\n * @param interfaceId ERC165 interface to check.\\r\\n * @return True if `account` implements `interfaceId`, false otherwise.\\r\\n */\\r\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\\r\\n * @param account Address of the contract to check.\\r\\n * @param interfaceId ERC165 interface to check.\\r\\n * @return True if `account` implements `interfaceId`, false otherwise.\\r\\n */\\r\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\r\\n\\r\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\r\\n\\r\\n event ManagerChanged(address indexed account, address indexed newManager);\\r\\n}\\r\\n\",\"keccak256\":\"0x0c607a83a8f5ec2f214bc754ffb59428d90978e122108fcd91ba193d5fc78018\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\r\\n * checks.\\r\\n *\\r\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\r\\n * in bugs, because programmers usually assume that an overflow raises an\\r\\n * error, which is the standard behavior in high level programming languages.\\r\\n * `SafeMath` restores this intuition by reverting the transaction when an\\r\\n * operation overflows.\\r\\n *\\r\\n * Using this library instead of the unchecked operations eliminates an entire\\r\\n * class of bugs, so it's recommended to use it always.\\r\\n */\\r\\nlibrary SafeMath {\\r\\n /**\\r\\n * @dev Returns the addition of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `+` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Addition cannot overflow.\\r\\n */\\r\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n uint256 c = a + b;\\r\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n */\\r\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b <= a, errorMessage);\\r\\n uint256 c = a - b;\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `*` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Multiplication cannot overflow.\\r\\n */\\r\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\r\\n // benefit is lost if 'b' is also tested.\\r\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\r\\n if (a == 0) {\\r\\n return 0;\\r\\n }\\r\\n\\r\\n uint256 c = a * b;\\r\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n // Solidity only automatically asserts when dividing by 0\\r\\n require(b > 0, errorMessage);\\r\\n uint256 c = a / b;\\r\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts with custom message when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b != 0, errorMessage);\\r\\n return a % b;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x29ffa7ff59806a3add585615cc102b70b43049587dcc73649f77b427f35b009d\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Secondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../GSN/Context.sol\\\";\\r\\n/**\\r\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\r\\n */\\r\\nabstract contract Secondary is Context {\\r\\n address private _primary;\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the primary contract changes.\\r\\n */\\r\\n event PrimaryTransferred(\\r\\n address recipient\\r\\n );\\r\\n\\r\\n /**\\r\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\r\\n */\\r\\n constructor () {\\r\\n _primary = _msgSender();\\r\\n emit PrimaryTransferred(_primary);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Reverts if called from any account other than the primary.\\r\\n */\\r\\n modifier onlyPrimary() {\\r\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @return the address of the primary.\\r\\n */\\r\\n function primary() public view returns (address) {\\r\\n return _primary;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers contract to a new primary.\\r\\n * @param recipient The address of new primary.\\r\\n */\\r\\n function transferPrimary(address recipient) public onlyPrimary {\\r\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\r\\n _primary = recipient;\\r\\n emit PrimaryTransferred(_primary);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x9138d9f1c2d4b2b9d6fd72ceb5ef461ffcd2c26ade7b15a5ee86456ecda089ca\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\r\\n * the optional functions; to access them see {ERC20Detailed}.\\r\\n */\\r\\ninterface IERC20 {\\r\\n /**\\r\\n * @dev Returns the amount of tokens in existence.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens owned by `account`.\\r\\n */\\r\\n function balanceOf(address account) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transfer(address recipient, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Returns the remaining number of tokens that `spender` will be\\r\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\r\\n * zero by default.\\r\\n *\\r\\n * This value changes when {approve} or {transferFrom} are called.\\r\\n */\\r\\n function allowance(address owner, address spender) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\r\\n * that someone may use both the old and the new allowance by unfortunate\\r\\n * transaction ordering. One possible solution to mitigate this race\\r\\n * condition is to first reduce the spender's allowance to 0 and set the\\r\\n * desired value afterwards:\\r\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\r\\n *\\r\\n * Emits an {Approval} event.\\r\\n */\\r\\n function approve(address spender, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\r\\n * allowance mechanism. `amount` is then deducted from the caller's\\r\\n * allowance.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\r\\n * another (`to`).\\r\\n *\\r\\n * Note that `value` may be zero.\\r\\n */\\r\\n event Transfer(address indexed from, address indexed to, uint256 value);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\r\\n * a call to {approve}. `value` is the new allowance.\\r\\n */\\r\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\r\\n}\\r\\n\",\"keccak256\":\"0x7531f90b8a5a04fd225fb07a30e0792068438a7c82127a22db870c1849460dfc\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/ERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"./IERC777.sol\\\";\\r\\nimport \\\"./IERC777Recipient.sol\\\";\\r\\nimport \\\"./IERC777Sender.sol\\\";\\r\\nimport \\\"../../token/ERC20/IERC20.sol\\\";\\r\\nimport \\\"../../math/SafeMath.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\nimport \\\"../../introspection/IERC1820Registry.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Implementation of the {IERC777} interface.\\r\\n *\\r\\n * This implementation is agnostic to the way tokens are created. This means\\r\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\r\\n *\\r\\n * Support for ERC20 is included in this contract, as specified by the EIP: both\\r\\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\\r\\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\\r\\n * movements.\\r\\n *\\r\\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\\r\\n * are no special restrictions in the amount of tokens that created, moved, or\\r\\n * destroyed. This makes integration with ERC20 applications seamless.\\r\\n */\\r\\ncontract ERC777 is Context, IERC777, IERC20 {\\r\\n using SafeMath for uint256;\\r\\n using Address for address;\\r\\n\\r\\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\r\\n\\r\\n mapping(address => uint256) private _balances;\\r\\n\\r\\n uint256 private _totalSupply;\\r\\n\\r\\n string private _name;\\r\\n string private _symbol;\\r\\n\\r\\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\\r\\n // See https://github.com/ethereum/solidity/issues/4024.\\r\\n\\r\\n // keccak256(\\\"ERC777TokensSender\\\")\\r\\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\\r\\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\\r\\n\\r\\n // keccak256(\\\"ERC777TokensRecipient\\\")\\r\\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\\r\\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\\r\\n\\r\\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\\r\\n address[] private _defaultOperatorsArray;\\r\\n\\r\\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\\r\\n mapping(address => bool) private _defaultOperators;\\r\\n\\r\\n // For each account, a mapping of its operators and revoked default operators.\\r\\n mapping(address => mapping(address => bool)) private _operators;\\r\\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\\r\\n\\r\\n // ERC20-allowances\\r\\n mapping (address => mapping (address => uint256)) private _allowances;\\r\\n\\r\\n /**\\r\\n * @dev `defaultOperators` may be an empty array.\\r\\n */\\r\\n constructor(\\r\\n string memory aName,\\r\\n string memory aSymbol,\\r\\n address[] memory theDefaultOperators\\r\\n ) {\\r\\n _name = aName;\\r\\n _symbol = aSymbol;\\r\\n\\r\\n _defaultOperatorsArray = theDefaultOperators;\\r\\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\\r\\n _defaultOperators[_defaultOperatorsArray[i]] = true;\\r\\n }\\r\\n\\r\\n // register interfaces\\r\\n _erc1820.setInterfaceImplementer(address(this), keccak256(\\\"ERC777Token\\\"), address(this));\\r\\n _erc1820.setInterfaceImplementer(address(this), keccak256(\\\"ERC20Token\\\"), address(this));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-name}.\\r\\n */\\r\\n function name() public view override(IERC777) returns (string memory) {\\r\\n return _name;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-symbol}.\\r\\n */\\r\\n function symbol() public view override(IERC777) returns (string memory) {\\r\\n return _symbol;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {ERC20Detailed-decimals}.\\r\\n *\\r\\n * Always returns 18, as per the\\r\\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\\r\\n */\\r\\n function decimals() public pure override returns (uint8) {\\r\\n return 18;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-granularity}.\\r\\n *\\r\\n * This implementation always returns `1`.\\r\\n */\\r\\n function granularity() public view virtual override(IERC777) returns (uint256) {\\r\\n return 1;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-totalSupply}.\\r\\n */\\r\\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\\r\\n return _totalSupply;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\\r\\n */\\r\\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\\r\\n return _balances[tokenHolder];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-send}.\\r\\n *\\r\\n * Also emits a {Transfer} event for ERC20 compatibility.\\r\\n */\\r\\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\\r\\n _send(_msgSender(), _msgSender(), recipient, amount, data, \\\"\\\", true);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC20-transfer}.\\r\\n *\\r\\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\\r\\n * interface if it is a contract.\\r\\n *\\r\\n * Also emits a {Sent} event.\\r\\n */\\r\\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\\r\\n require(recipient != address(0), \\\"ERC777: transfer to zero address\\\");\\r\\n\\r\\n address from = _msgSender();\\r\\n\\r\\n _callTokensToSend(from, from, recipient, amount, \\\"\\\", \\\"\\\");\\r\\n\\r\\n _move(from, from, recipient, amount, \\\"\\\", \\\"\\\");\\r\\n\\r\\n _callTokensReceived(from, from, recipient, amount, \\\"\\\", \\\"\\\", false);\\r\\n\\r\\n return true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-burn}.\\r\\n *\\r\\n * Also emits a {Transfer} event for ERC20 compatibility.\\r\\n */\\r\\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\\r\\n _burn(_msgSender(), _msgSender(), amount, data, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-isOperatorFor}.\\r\\n */\\r\\n function isOperatorFor(\\r\\n address operator,\\r\\n address tokenHolder\\r\\n ) public view override(IERC777) returns (bool) {\\r\\n return operator == tokenHolder ||\\r\\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\\r\\n _operators[tokenHolder][operator];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-authorizeOperator}.\\r\\n */\\r\\n function authorizeOperator(address operator) external override(IERC777) {\\r\\n require(_msgSender() != operator, \\\"ERC777: authorizing self as operator\\\");\\r\\n\\r\\n if (_defaultOperators[operator]) {\\r\\n delete _revokedDefaultOperators[_msgSender()][operator];\\r\\n } else {\\r\\n _operators[_msgSender()][operator] = true;\\r\\n }\\r\\n\\r\\n emit AuthorizedOperator(operator, _msgSender());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-revokeOperator}.\\r\\n */\\r\\n function revokeOperator(address operator) external override(IERC777) {\\r\\n require(operator != _msgSender(), \\\"ERC777: revoking self as operator\\\");\\r\\n\\r\\n if (_defaultOperators[operator]) {\\r\\n _revokedDefaultOperators[_msgSender()][operator] = true;\\r\\n } else {\\r\\n delete _operators[_msgSender()][operator];\\r\\n }\\r\\n\\r\\n emit RevokedOperator(operator, _msgSender());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-defaultOperators}.\\r\\n */\\r\\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\\r\\n return _defaultOperatorsArray;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-operatorSend}.\\r\\n *\\r\\n * Emits {Sent} and {Transfer} events.\\r\\n */\\r\\n function operatorSend(\\r\\n address sender,\\r\\n address recipient,\\r\\n uint256 amount,\\r\\n bytes calldata data,\\r\\n bytes calldata operatorData\\r\\n )\\r\\n external override(IERC777)\\r\\n {\\r\\n require(isOperatorFor(_msgSender(), sender), \\\"ERC777: caller is not an operator\\\");\\r\\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-operatorBurn}.\\r\\n *\\r\\n * Emits {Burned} and {Transfer} events.\\r\\n */\\r\\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\\r\\n external override(IERC777) {\\r\\n require(isOperatorFor(_msgSender(), account), \\\"ERC777: caller is not an operator\\\");\\r\\n _burn(_msgSender(), account, amount, data, operatorData);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC20-allowance}.\\r\\n *\\r\\n * Note that operator and allowance concepts are orthogonal: operators may\\r\\n * not have allowance, and accounts with allowance may not be operators\\r\\n * themselves.\\r\\n */\\r\\n function allowance(address holder, address spender)\\r\\n public view override(IERC20) returns (uint256) {\\r\\n return _allowances[holder][spender];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC20-approve}.\\r\\n *\\r\\n * Note that accounts cannot have allowance issued by their operators.\\r\\n */\\r\\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\\r\\n address holder = _msgSender();\\r\\n _approve(holder, spender, value);\\r\\n return true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC20-transferFrom}.\\r\\n *\\r\\n * Note that operator and allowance concepts are orthogonal: operators cannot\\r\\n * call `transferFrom` (unless they have allowance), and accounts with\\r\\n * allowance cannot call `operatorSend` (unless they are operators).\\r\\n *\\r\\n * Emits {Sent}, {Transfer} and {Approval} events.\\r\\n */\\r\\n function transferFrom(address holder, address recipient, uint256 amount)\\r\\n external override(IERC20) returns (bool) {\\r\\n require(recipient != address(0), \\\"ERC777: transfer to zero address\\\");\\r\\n require(holder != address(0), \\\"ERC777: transfer from zero address\\\");\\r\\n\\r\\n address spender = _msgSender();\\r\\n\\r\\n _callTokensToSend(spender, holder, recipient, amount, \\\"\\\", \\\"\\\");\\r\\n\\r\\n _move(spender, holder, recipient, amount, \\\"\\\", \\\"\\\");\\r\\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \\\"ERC777: transfer amount exceeds allowance\\\"));\\r\\n\\r\\n _callTokensReceived(spender, holder, recipient, amount, \\\"\\\", \\\"\\\", false);\\r\\n\\r\\n return true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\\r\\n * the total supply.\\r\\n *\\r\\n * If a send hook is registered for `account`, the corresponding function\\r\\n * will be called with `operator`, `data` and `operatorData`.\\r\\n *\\r\\n * See {IERC777Sender} and {IERC777Recipient}.\\r\\n *\\r\\n * Emits {Minted} and {Transfer} events.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `account` cannot be the zero address.\\r\\n * - if `account` is a contract, it must implement the {IERC777Recipient}\\r\\n * interface.\\r\\n */\\r\\n function _mint(\\r\\n address operator,\\r\\n address account,\\r\\n uint256 amount,\\r\\n bytes memory userData,\\r\\n bytes memory operatorData\\r\\n )\\r\\n internal\\r\\n {\\r\\n require(account != address(0), \\\"ERC777: mint to zero address\\\");\\r\\n\\r\\n // Update state variables\\r\\n _totalSupply = _totalSupply.add(amount);\\r\\n _balances[account] = _balances[account].add(amount);\\r\\n\\r\\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\\r\\n\\r\\n emit Minted(operator, account, amount, userData, operatorData);\\r\\n emit Transfer(address(0), account, amount);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Send tokens\\r\\n * @param operator address operator requesting the transfer\\r\\n * @param from address token holder address\\r\\n * @param to address recipient address\\r\\n * @param amount uint256 amount of tokens to transfer\\r\\n * @param userData bytes extra information provided by the token holder (if any)\\r\\n * @param operatorData bytes extra information provided by the operator (if any)\\r\\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\\r\\n */\\r\\n function _send(\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint256 amount,\\r\\n bytes memory userData,\\r\\n bytes memory operatorData,\\r\\n bool requireReceptionAck\\r\\n )\\r\\n internal\\r\\n {\\r\\n require(from != address(0), \\\"ERC777: send from zero address\\\");\\r\\n require(to != address(0), \\\"ERC777: send to zero address\\\");\\r\\n\\r\\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\\r\\n\\r\\n _move(operator, from, to, amount, userData, operatorData);\\r\\n\\r\\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Burn tokens\\r\\n * @param operator address operator requesting the operation\\r\\n * @param from address token holder address\\r\\n * @param amount uint256 amount of tokens to burn\\r\\n * @param data bytes extra information provided by the token holder\\r\\n * @param operatorData bytes extra information provided by the operator (if any)\\r\\n */\\r\\n function _burn(\\r\\n address operator,\\r\\n address from,\\r\\n uint256 amount,\\r\\n bytes memory data,\\r\\n bytes memory operatorData\\r\\n )\\r\\n internal\\r\\n {\\r\\n require(from != address(0), \\\"ERC777: burn from zero address\\\");\\r\\n\\r\\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\\r\\n\\r\\n // Update state variables\\r\\n _balances[from] = _balances[from].sub(amount, \\\"ERC777: burn amount exceeds balance\\\");\\r\\n _totalSupply = _totalSupply.sub(amount);\\r\\n\\r\\n emit Burned(operator, from, amount, data, operatorData);\\r\\n emit Transfer(from, address(0), amount);\\r\\n }\\r\\n\\r\\n function _move(\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint256 amount,\\r\\n bytes memory userData,\\r\\n bytes memory operatorData\\r\\n )\\r\\n internal\\r\\n {\\r\\n _balances[from] = _balances[from].sub(amount, \\\"ERC777: transfer amount exceeds balance\\\");\\r\\n _balances[to] = _balances[to].add(amount);\\r\\n\\r\\n emit Sent(operator, from, to, amount, userData, operatorData);\\r\\n emit Transfer(from, to, amount);\\r\\n }\\r\\n\\r\\n function _approve(address holder, address spender, uint256 value) internal {\\r\\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\\r\\n // currently unnecessary.\\r\\n //require(holder != address(0), \\\"ERC777: approve from the zero address\\\");\\r\\n require(spender != address(0), \\\"ERC777: approve to zero address\\\");\\r\\n\\r\\n _allowances[holder][spender] = value;\\r\\n emit Approval(holder, spender, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Call from.tokensToSend() if the interface is registered\\r\\n * @param operator address operator requesting the transfer\\r\\n * @param from address token holder address\\r\\n * @param to address recipient address\\r\\n * @param amount uint256 amount of tokens to transfer\\r\\n * @param userData bytes extra information provided by the token holder (if any)\\r\\n * @param operatorData bytes extra information provided by the operator (if any)\\r\\n */\\r\\n function _callTokensToSend(\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint256 amount,\\r\\n bytes memory userData,\\r\\n bytes memory operatorData\\r\\n )\\r\\n internal\\r\\n {\\r\\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\\r\\n if (implementer != address(0)) {\\r\\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\\r\\n * tokensReceived() was not registered for the recipient\\r\\n * @param operator address operator requesting the transfer\\r\\n * @param from address token holder address\\r\\n * @param to address recipient address\\r\\n * @param amount uint256 amount of tokens to transfer\\r\\n * @param userData bytes extra information provided by the token holder (if any)\\r\\n * @param operatorData bytes extra information provided by the operator (if any)\\r\\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\\r\\n */\\r\\n function _callTokensReceived(\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint256 amount,\\r\\n bytes memory userData,\\r\\n bytes memory operatorData,\\r\\n bool requireReceptionAck\\r\\n )\\r\\n private\\r\\n {\\r\\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\\r\\n if (implementer != address(0)) {\\r\\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\\r\\n } else if (requireReceptionAck) {\\r\\n require(!to.isContract(), \\\"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\\\");\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xd113e66c8ecca27aa14ca2e6e7d0005220eb62d02f3f3b1e92930fd40797d5e4\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC777Token standard as defined in the EIP.\\r\\n *\\r\\n * This contract uses the\\r\\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\\r\\n * token holders and recipients react to token movements by using setting implementers\\r\\n * for the associated interfaces in said registry. See `IERC1820Registry` and\\r\\n * `ERC1820Implementer`.\\r\\n */\\r\\ninterface IERC777 {\\r\\n /**\\r\\n * @dev Returns the name of the token.\\r\\n */\\r\\n function name() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the symbol of the token, usually a shorter version of the\\r\\n * name.\\r\\n */\\r\\n function symbol() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the smallest part of the token that is not divisible. This\\r\\n * means all token operations (creation, movement and destruction) must have\\r\\n * amounts that are a multiple of this number.\\r\\n *\\r\\n * For most token contracts, this value will equal 1.\\r\\n */\\r\\n function granularity() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens in existence.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens owned by an account (`owner`).\\r\\n */\\r\\n function balanceOf(address owner) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\r\\n *\\r\\n * If send or receive hooks are registered for the caller and `recipient`,\\r\\n * the corresponding functions will be called with `data` and empty\\r\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\r\\n *\\r\\n * Emits a `Sent` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - the caller must have at least `amount` tokens.\\r\\n * - `recipient` cannot be the zero address.\\r\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\r\\n * interface.\\r\\n */\\r\\n function send(address recipient, uint256 amount, bytes calldata data) external;\\r\\n\\r\\n /**\\r\\n * @dev Destroys `amount` tokens from the caller's account, reducing the\\r\\n * total supply.\\r\\n *\\r\\n * If a send hook is registered for the caller, the corresponding function\\r\\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\\r\\n *\\r\\n * Emits a `Burned` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - the caller must have at least `amount` tokens.\\r\\n */\\r\\n function burn(uint256 amount, bytes calldata data) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns true if an account is an operator of `tokenHolder`.\\r\\n * Operators can send and burn tokens on behalf of their owners. All\\r\\n * accounts are their own operator.\\r\\n *\\r\\n * See `operatorSend` and `operatorBurn`.\\r\\n */\\r\\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Make an account an operator of the caller.\\r\\n *\\r\\n * See `isOperatorFor`.\\r\\n *\\r\\n * Emits an `AuthorizedOperator` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `operator` cannot be calling address.\\r\\n */\\r\\n function authorizeOperator(address operator) external;\\r\\n\\r\\n /**\\r\\n * @dev Make an account an operator of the caller.\\r\\n *\\r\\n * See `isOperatorFor` and `defaultOperators`.\\r\\n *\\r\\n * Emits a `RevokedOperator` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `operator` cannot be calling address.\\r\\n */\\r\\n function revokeOperator(address operator) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the list of default operators. These accounts are operators\\r\\n * for all token holders, even if `authorizeOperator` was never called on\\r\\n * them.\\r\\n *\\r\\n * This list is immutable, but individual holders may revoke these via\\r\\n * `revokeOperator`, in which case `isOperatorFor` will return false.\\r\\n */\\r\\n function defaultOperators() external view returns (address[] memory);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\\r\\n * be an operator of `sender`.\\r\\n *\\r\\n * If send or receive hooks are registered for `sender` and `recipient`,\\r\\n * the corresponding functions will be called with `data` and\\r\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\r\\n *\\r\\n * Emits a `Sent` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `sender` cannot be the zero address.\\r\\n * - `sender` must have at least `amount` tokens.\\r\\n * - the caller must be an operator for `sender`.\\r\\n * - `recipient` cannot be the zero address.\\r\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\r\\n * interface.\\r\\n */\\r\\n function operatorSend(\\r\\n address sender,\\r\\n address recipient,\\r\\n uint256 amount,\\r\\n bytes calldata data,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\\r\\n * The caller must be an operator of `account`.\\r\\n *\\r\\n * If a send hook is registered for `account`, the corresponding function\\r\\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\\r\\n *\\r\\n * Emits a `Burned` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `account` cannot be the zero address.\\r\\n * - `account` must have at least `amount` tokens.\\r\\n * - the caller must be an operator for `account`.\\r\\n */\\r\\n function operatorBurn(\\r\\n address account,\\r\\n uint256 amount,\\r\\n bytes calldata data,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n\\r\\n event Sent(\\r\\n address indexed operator,\\r\\n address indexed from,\\r\\n address indexed to,\\r\\n uint256 amount,\\r\\n bytes data,\\r\\n bytes operatorData\\r\\n );\\r\\n\\r\\n function decimals() external returns (uint8);\\r\\n\\r\\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\\r\\n\\r\\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\\r\\n\\r\\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\\r\\n\\r\\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\\r\\n}\\r\\n\",\"keccak256\":\"0xf9947f4f7572e74766fcb4de1d58c6c26cd31379fd5d4b885cdbdf14a16dbe94\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\r\\n *\\r\\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\\r\\n * contract implement this interface (contract holders can be their own\\r\\n * implementer) and registering it on the\\r\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\r\\n *\\r\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\r\\n */\\r\\ninterface IERC777Recipient {\\r\\n /**\\r\\n * @dev Called by an `IERC777` token contract whenever tokens are being\\r\\n * moved or created into a registered account (`to`). The type of operation\\r\\n * is conveyed by `from` being the zero address or not.\\r\\n *\\r\\n * This call occurs _after_ the token contract's state is updated, so\\r\\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\\r\\n *\\r\\n * This function may revert to prevent the operation from being executed.\\r\\n */\\r\\n function tokensReceived(\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n}\\r\\n\",\"keccak256\":\"0x1f43e427174c60bacb510e63053626e5b24d825333e9921bb7c1ea673b1c6e1e\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Sender.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\\r\\n *\\r\\n * `IERC777` Token holders can be notified of operations performed on their\\r\\n * tokens by having a contract implement this interface (contract holders can be\\r\\n * their own implementer) and registering it on the\\r\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\r\\n *\\r\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\r\\n */\\r\\ninterface IERC777Sender {\\r\\n /**\\r\\n * @dev Called by an `IERC777` token contract whenever a registered holder's\\r\\n * (`from`) tokens are about to be moved or destroyed. The type of operation\\r\\n * is conveyed by `to` being the zero address or not.\\r\\n *\\r\\n * This call occurs _before_ the token contract's state is updated, so\\r\\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\\r\\n *\\r\\n * This function may revert to prevent the operation from being executed.\\r\\n */\\r\\n function tokensToSend(\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n}\\r\\n\",\"keccak256\":\"0x6a963a46297ee065e14820a02556dee14da60684657d302387e31c50b0dff374\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50610019610074565b600080546001600160a01b0319166001600160a01b0392831617908190556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610067921690610078565b60405180910390a161008c565b3390565b6001600160a01b0391909116815260200190565b612d628061009b6000396000f3fe60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b57806326d9e9631462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002b8565b6200009d565b005b6200007b62000075366004620002e8565b6200016c565b6040516200008a91906200038a565b60405180910390f35b6200007b6200024d565b6000546001600160a01b0316620000b36200025c565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000458565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc906200040e565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992620001619216906200038a565b60405180910390a150565b600080546001600160a01b0316620001836200025c565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000458565b600086868686620001bc6200024d565b87604051620001cb9062000260565b620001dc969594939291906200039e565b604051809103906000f080158015620001f9573d6000803e3d6000fd5b509050806001600160a01b03167ff57d2ded8330a4affd2fa52378069be534fe22288536537d1a1cfc06151845078686866040516200023b93929190620003e8565b60405180910390a29695505050505050565b6000546001600160a01b031690565b3390565b61288880620004a583390190565b60008083601f84011262000280578182fd5b50813567ffffffffffffffff81111562000298578182fd5b602083019150836020828501011115620002b157600080fd5b9250929050565b600060208284031215620002ca578081fd5b81356001600160a01b0381168114620002e1578182fd5b9392505050565b60008060008060006060868803121562000300578081fd5b853567ffffffffffffffff8082111562000318578283fd5b6200032689838a016200026e565b909750955060208801359150808211156200033f578283fd5b506200034e888289016200026e565b96999598509660400135949350505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060808252620003b460808301888a62000360565b8281036020840152620003c981878962000360565b6001600160a01b03959095166040840152505060600152949350505050565b600060408252620003fe60408301858762000360565b9050826020830152949350505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b506040516200288838038062002888833981016040819052620000349162000561565b60408051600081526020808201909252855186928692916200005d9160029190860190620003c2565b50815162000073906003906020850190620003c2565b5080516200008990600490602084019062000457565b5060005b600454811015620000e95760016005600060048481548110620000ac57fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff19169115159190911790556001016200008d565b506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90620001479030907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054908290600401620005f0565b600060405180830381600087803b1580156200016257600080fd5b505af115801562000177573d6000803e3d6000fd5b50506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad2492506329965a1d9150620001d89030907faea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a908290600401620005f0565b600060405180830381600087803b158015620001f357600080fd5b505af115801562000208573d6000803e3d6000fd5b50505050506001600160a01b038416151591506200024590505760405162461bcd60e51b81526004016200023c9062000613565b60405180910390fd5b6001811015620002695760405162461bcd60e51b81526004016200023c906200064a565b600980546001600160a01b0319166001600160a01b038416179055600a81905546620002c562000298620002d4565b604051806040016040528060018152602001603160f81b81525083306200036b60201b62000fa41760201c565b600b5550620006819350505050565b60028054604080516020601f6000196101006001871615020190941685900493840181900481028201810190925282815260609390929091830182828015620003615780601f10620003355761010080835404028352916020019162000361565b820191906000526020600020905b8154815290600101906020018083116200034357829003601f168201915b5050505050905090565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620003fa576000855562000445565b82601f106200041557805160ff191683800117855562000445565b8280016001018555821562000445579182015b828111156200044557825182559160200191906001019062000428565b5062000453929150620004af565b5090565b82805482825590600052602060002090810192821562000445579160200282015b828111156200044557825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000478565b5b80821115620004535760008155600101620004b0565b600082601f830112620004d7578081fd5b81516001600160401b0380821115620004ec57fe5b6040516020601f8401601f19168201810183811183821017156200050c57fe5b604052838252858401810187101562000523578485fd5b8492505b8383101562000546578583018101518284018201529182019162000527565b838311156200055757848185840101525b5095945050505050565b6000806000806080858703121562000577578384fd5b84516001600160401b03808211156200058e578586fd5b6200059c88838901620004c6565b95506020870151915080821115620005b2578485fd5b50620005c187828801620004c6565b604087015190945090506001600160a01b0381168114620005e0578283fd5b6060959095015193969295505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b6020808252601a908201527f53696465546f6b656e3a204772616e756c6172697479203c2031000000000000604082015260600190565b6121f780620006916000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80637ecebe00116100de578063d95b637111610097578063f698da2511610071578063f698da2514610308578063fad8b32a14610310578063fc673c4f14610323578063fe9d93031461033657610173565b8063d95b6371146102cf578063dcdc7dd0146102e2578063dd62ed3e146102f557610173565b80637ecebe0014610268578063959b8c3f1461027b57806395d89b411461028e5780639bd9bbc614610296578063a9059cbb146102a9578063d505accf146102bc57610173565b806330adf81f1161013057806330adf81f14610208578063313ce567146102105780634000aea014610225578063556f0dc71461023857806362ad1b831461024057806370a082311461025557610173565b806306e485381461017857806306fdde031461019657806307546172146101ab578063095ea7b3146101c057806318160ddd146101e057806323b872dd146101f5575b600080fd5b610180610349565b60405161018d9190611c97565b60405180910390f35b61019e6103ab565b60405161018d9190611d4a565b6101b3610435565b60405161018d9190611b9f565b6101d36101ce3660046119d2565b610444565b60405161018d9190611ce4565b6101e8610466565b60405161018d9190611cef565b6101d3610203366004611881565b61046c565b6101e86105b4565b6102186105d8565b60405161018d9190612128565b6101d36102333660046119fd565b6105dd565b6101e86106eb565b61025361024e3660046118c1565b6106f1565b005b6101e8610263366004611811565b6107a8565b6101e8610276366004611811565b6107c3565b610253610289366004611811565b6107d5565b61019e610902565b6102536102a43660046119fd565b610963565b6101d36102b73660046119d2565b6109cb565b6102536102ca36600461195d565b610a85565b6101d36102dd366004611849565b610bd8565b6102536102f0366004611a57565b610c7a565b6101e8610303366004611849565b610d39565b6101e8610d64565b61025361031e366004611811565b610d6a565b610253610331366004611a57565b610e97565b610253610344366004611ae0565b610f41565b606060048054806020026020016040519081016040528092919081815260200182805480156103a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610383575b5050505050905090565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b820191906000526020600020905b81548152906001019060200180831161041757509395945050505050565b6009546001600160a01b031681565b60008061044f610ffb565b905061045c818585610fff565b5060019392505050565b60015490565b60006001600160a01b03831661049d5760405162461bcd60e51b815260040161049490611e50565b60405180910390fd5b6001600160a01b0384166104c35760405162461bcd60e51b815260040161049490612043565b60006104cd610ffb565b90506104fb81868686604051806020016040528060008152506040518060200160405280600081525061108d565b6105278186868660405180602001604052806000815250604051806020016040528060008152506111bb565b61057b858261057686604051806060016040528060298152602001612176602991396001600160a01b03808c166000908152600860209081526040808320938b168352929052205491906112db565b610fff565b6105a98186868660405180602001604052806000815250604051806020016040528060008152506000611307565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601290565b6000806105e8610ffb565b905061063c8182888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060408051602081019091528181529350915061146e9050565b7fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c168187878787604051610673959493929190611c0d565b60405180910390a1604051635260769b60e11b81526001600160a01b0387169063a4c0ed36906106ad908490899089908990600401611c65565b600060405180830381600087803b1580156106c757600080fd5b505af11580156106db573d6000803e3d6000fd5b5060019998505050505050505050565b600a5490565b6107026106fc610ffb565b88610bd8565b61071e5760405162461bcd60e51b815260040161049490612085565b61079f610729610ffb565b88888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a91508990819084018382808284376000920191909152506001925061146e915050565b50505050505050565b6001600160a01b031660009081526020819052604090205490565b600c6020526000908152604090205481565b806001600160a01b03166107e7610ffb565b6001600160a01b0316141561080e5760405162461bcd60e51b815260040161049490611dcb565b6001600160a01b03811660009081526005602052604090205460ff1615610871576007600061083b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690556108b8565b60016006600061087f610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b6108c0610ffb565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b6109c561096e610ffb565b610976610ffb565b868686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604080516020810190915290815292506001915061146e9050565b50505050565b60006001600160a01b0383166109f35760405162461bcd60e51b815260040161049490611e50565b60006109fd610ffb565b9050610a2b81828686604051806020016040528060008152506040518060200160405280600081525061108d565b610a578182868660405180602001604052806000815250604051806020016040528060008152506111bb565b61045c8182868660405180602001604052806000815250604051806020016040528060008152506000611307565b42841015610aa55760405162461bcd60e51b815260040161049490611fa9565b600b546001600160a01b0388166000908152600c6020908152604080832080546001810190915590519293610b27939092610b0c927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928e928e928e9290918e9101611cf8565b604051602081830303815290604052805190602001206114e5565b9050600060018286868660405160008152602001604052604051610b4e9493929190611d2c565b6020604051602081039080840390855afa158015610b70573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610ba65750886001600160a01b0316816001600160a01b0316145b610bc25760405162461bcd60e51b815260040161049490611f2f565b610bcd898989610fff565b505050505050505050565b6000816001600160a01b0316836001600160a01b03161480610c4357506001600160a01b03831660009081526005602052604090205460ff168015610c4357506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b80610c7357506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b6009546001600160a01b0316610c8e610ffb565b6001600160a01b031614610cb45760405162461bcd60e51b815260040161049490611f66565b610d31610cbf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061150492505050565b505050505050565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b600b5481565b610d72610ffb565b6001600160a01b0316816001600160a01b03161415610da35760405162461bcd60e51b815260040161049490611e0f565b6001600160a01b03811660009081526005602052604090205460ff1615610e0f57600160076000610dd2610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055610e4d565b60066000610e1b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b610e55610ffb565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b610ea8610ea2610ffb565b87610bd8565b610ec45760405162461bcd60e51b815260040161049490612085565b610d31610ecf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061162c92505050565b610f9f610f4c610ffb565b610f54610ffb565b8585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805160208101909152908152925061162c915050565b505050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b3390565b6001600160a01b0382166110255760405162461bcd60e51b8152600401610494906120c6565b6001600160a01b0380841660008181526008602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611080908590611cef565b60405180910390a3505050565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906110e99089907f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89590600401611c4c565b60206040518083038186803b15801561110157600080fd5b505afa158015611115573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611139919061182d565b90506001600160a01b0381161561079f57604051633ad5cbc160e11b81526001600160a01b038216906375ab978290611180908a908a908a908a908a908a90600401611bb3565b600060405180830381600087803b15801561119a57600080fd5b505af11580156111ae573d6000803e3d6000fd5b5050505050505050505050565b6111f88360405180606001604052806027815260200161214f602791396001600160a01b03881660009081526020819052604090205491906112db565b6001600160a01b038087166000908152602081905260408082209390935590861681522054611227908461175d565b6001600160a01b0380861660008181526020819052604090819020939093559151878216918916907f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc8261467798790611280908890889088906120fd565b60405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516112cb9190611cef565b60405180910390a3505050505050565b600081848411156112ff5760405162461bcd60e51b81526004016104949190611d4a565b505050900390565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906113639089907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b90600401611c4c565b60206040518083038186803b15801561137b57600080fd5b505afa15801561138f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b3919061182d565b90506001600160a01b0381161561142f576040516223de2960e01b81526001600160a01b038216906223de29906113f8908b908b908b908b908b908b90600401611bb3565b600060405180830381600087803b15801561141257600080fd5b505af1158015611426573d6000803e3d6000fd5b50505050611464565b811561146457611447866001600160a01b0316611782565b156114645760405162461bcd60e51b815260040161049490611ebc565b5050505050505050565b6001600160a01b0386166114945760405162461bcd60e51b815260040161049490611fd5565b6001600160a01b0385166114ba5760405162461bcd60e51b81526004016104949061200c565b6114c887878787878761108d565b6114d68787878787876111bb565b61079f87878787878787611307565b60405161190160f01b8152600281019290925260228201526042902090565b6001600160a01b03841661152a5760405162461bcd60e51b815260040161049490611e85565b600154611537908461175d565b6001556001600160a01b03841660009081526020819052604090205461155d908461175d565b6001600160a01b03851660009081526020819052604081209190915561158a908690868686866001611307565b836001600160a01b0316856001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d8585856040516115d1939291906120fd565b60405180910390a3836001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b60405180910390a35050505050565b6001600160a01b0384166116525760405162461bcd60e51b815260040161049490611d94565b6116618585600086868661108d565b61169e8360405180606001604052806023815260200161219f602391396001600160a01b03871660009081526020819052604090205491906112db565b6001600160a01b0385166000908152602081905260409020556001546116c49084611788565b600181905550836001600160a01b0316856001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098858585604051611711939291906120fd565b60405180910390a360006001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b600082820183811015610c735760405162461bcd60e51b815260040161049490611d5d565b3b151590565b6000610c7383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506112db565b60008083601f8401126117db578182fd5b50813567ffffffffffffffff8111156117f2578182fd5b60208301915083602082850101111561180a57600080fd5b9250929050565b600060208284031215611822578081fd5b8135610c7381612136565b60006020828403121561183e578081fd5b8151610c7381612136565b6000806040838503121561185b578081fd5b823561186681612136565b9150602083013561187681612136565b809150509250929050565b600080600060608486031215611895578081fd5b83356118a081612136565b925060208401356118b081612136565b929592945050506040919091013590565b600080600080600080600060a0888a0312156118db578283fd5b87356118e681612136565b965060208801356118f681612136565b955060408801359450606088013567ffffffffffffffff80821115611919578485fd5b6119258b838c016117ca565b909650945060808a013591508082111561193d578384fd5b5061194a8a828b016117ca565b989b979a50959850939692959293505050565b600080600080600080600060e0888a031215611977578283fd5b873561198281612136565b9650602088013561199281612136565b95506040880135945060608801359350608088013560ff811681146119b5578384fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156119e4578182fd5b82356119ef81612136565b946020939093013593505050565b60008060008060608587031215611a12578384fd5b8435611a1d81612136565b935060208501359250604085013567ffffffffffffffff811115611a3f578283fd5b611a4b878288016117ca565b95989497509550505050565b60008060008060008060808789031215611a6f578182fd5b8635611a7a81612136565b955060208701359450604087013567ffffffffffffffff80821115611a9d578384fd5b611aa98a838b016117ca565b90965094506060890135915080821115611ac1578384fd5b50611ace89828a016117ca565b979a9699509497509295939492505050565b600080600060408486031215611af4578283fd5b83359250602084013567ffffffffffffffff811115611b11578283fd5b611b1d868287016117ca565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b81811015611b7957602081850181015186830182015201611b5d565b81811115611b8a5782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0387811682528681166020830152851660408201526060810184905260c060808201819052600090611bee90830185611b54565b82810360a0840152611c008185611b54565b9998505050505050505050565b6001600160a01b0386811682528516602082015260408101849052608060608201819052600090611c419083018486611b2a565b979650505050505050565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038616825284602083015260606040830152611c8d606083018486611b2a565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611cd85783516001600160a01b031683529284019291840191600101611cb3565b50909695505050505050565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610c736020830184611b54565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f4552433737373a206275726e2066726f6d207a65726f20616464726573730000604082015260600190565b60208082526024908201527f4552433737373a20617574686f72697a696e672073656c66206173206f70657260408201526330ba37b960e11b606082015260800190565b60208082526021908201527f4552433737373a207265766f6b696e672073656c66206173206f70657261746f6040820152603960f91b606082015260800190565b6020808252818101527f4552433737373a207472616e7366657220746f207a65726f2061646472657373604082015260600190565b6020808252601c908201527f4552433737373a206d696e7420746f207a65726f206164647265737300000000604082015260600190565b6020808252604d908201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460408201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60608201526c1ad95b9cd49958da5c1a595b9d609a1b608082015260a00190565b6020808252601c908201527f53696465546f6b656e3a20494e56414c49445f5349474e415455524500000000604082015260600190565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b60208082526012908201527114da5919551bdad95b8e881156141254915160721b604082015260600190565b6020808252601e908201527f4552433737373a2073656e642066726f6d207a65726f20616464726573730000604082015260600190565b6020808252601c908201527f4552433737373a2073656e6420746f207a65726f206164647265737300000000604082015260600190565b60208082526022908201527f4552433737373a207472616e736665722066726f6d207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526021908201527f4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f6040820152603960f91b606082015260800190565b6020808252601f908201527f4552433737373a20617070726f766520746f207a65726f206164647265737300604082015260600190565b6000848252606060208301526121166060830185611b54565b8281036040840152611c8d8185611b54565b60ff91909116815260200190565b6001600160a01b038116811461214b57600080fd5b5056fe4552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a206275726e20616d6f756e7420657863656564732062616c616e6365a2646970667358221220e50313b8f4599486bdf7f8664f20e7ac280c8c35bbfd6cde681392ecbb37f14d64736f6c63430007060033a26469706673582212208c32c0735adbbf4ac7cf06584e89be0c8b8a258182daeed841b15ec41b72036764736f6c63430007060033",
+ "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b57806326d9e9631462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002b8565b6200009d565b005b6200007b62000075366004620002e8565b6200016c565b6040516200008a91906200038a565b60405180910390f35b6200007b6200024d565b6000546001600160a01b0316620000b36200025c565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000458565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc906200040e565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992620001619216906200038a565b60405180910390a150565b600080546001600160a01b0316620001836200025c565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000458565b600086868686620001bc6200024d565b87604051620001cb9062000260565b620001dc969594939291906200039e565b604051809103906000f080158015620001f9573d6000803e3d6000fd5b509050806001600160a01b03167ff57d2ded8330a4affd2fa52378069be534fe22288536537d1a1cfc06151845078686866040516200023b93929190620003e8565b60405180910390a29695505050505050565b6000546001600160a01b031690565b3390565b61288880620004a583390190565b60008083601f84011262000280578182fd5b50813567ffffffffffffffff81111562000298578182fd5b602083019150836020828501011115620002b157600080fd5b9250929050565b600060208284031215620002ca578081fd5b81356001600160a01b0381168114620002e1578182fd5b9392505050565b60008060008060006060868803121562000300578081fd5b853567ffffffffffffffff8082111562000318578283fd5b6200032689838a016200026e565b909750955060208801359150808211156200033f578283fd5b506200034e888289016200026e565b96999598509660400135949350505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060808252620003b460808301888a62000360565b8281036020840152620003c981878962000360565b6001600160a01b03959095166040840152505060600152949350505050565b600060408252620003fe60408301858762000360565b9050826020830152949350505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b506040516200288838038062002888833981016040819052620000349162000561565b60408051600081526020808201909252855186928692916200005d9160029190860190620003c2565b50815162000073906003906020850190620003c2565b5080516200008990600490602084019062000457565b5060005b600454811015620000e95760016005600060048481548110620000ac57fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff19169115159190911790556001016200008d565b506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90620001479030907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054908290600401620005f0565b600060405180830381600087803b1580156200016257600080fd5b505af115801562000177573d6000803e3d6000fd5b50506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad2492506329965a1d9150620001d89030907faea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a908290600401620005f0565b600060405180830381600087803b158015620001f357600080fd5b505af115801562000208573d6000803e3d6000fd5b50505050506001600160a01b038416151591506200024590505760405162461bcd60e51b81526004016200023c9062000613565b60405180910390fd5b6001811015620002695760405162461bcd60e51b81526004016200023c906200064a565b600980546001600160a01b0319166001600160a01b038416179055600a81905546620002c562000298620002d4565b604051806040016040528060018152602001603160f81b81525083306200036b60201b62000fa41760201c565b600b5550620006819350505050565b60028054604080516020601f6000196101006001871615020190941685900493840181900481028201810190925282815260609390929091830182828015620003615780601f10620003355761010080835404028352916020019162000361565b820191906000526020600020905b8154815290600101906020018083116200034357829003601f168201915b5050505050905090565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620003fa576000855562000445565b82601f106200041557805160ff191683800117855562000445565b8280016001018555821562000445579182015b828111156200044557825182559160200191906001019062000428565b5062000453929150620004af565b5090565b82805482825590600052602060002090810192821562000445579160200282015b828111156200044557825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000478565b5b80821115620004535760008155600101620004b0565b600082601f830112620004d7578081fd5b81516001600160401b0380821115620004ec57fe5b6040516020601f8401601f19168201810183811183821017156200050c57fe5b604052838252858401810187101562000523578485fd5b8492505b8383101562000546578583018101518284018201529182019162000527565b838311156200055757848185840101525b5095945050505050565b6000806000806080858703121562000577578384fd5b84516001600160401b03808211156200058e578586fd5b6200059c88838901620004c6565b95506020870151915080821115620005b2578485fd5b50620005c187828801620004c6565b604087015190945090506001600160a01b0381168114620005e0578283fd5b6060959095015193969295505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b6020808252601a908201527f53696465546f6b656e3a204772616e756c6172697479203c2031000000000000604082015260600190565b6121f780620006916000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80637ecebe00116100de578063d95b637111610097578063f698da2511610071578063f698da2514610308578063fad8b32a14610310578063fc673c4f14610323578063fe9d93031461033657610173565b8063d95b6371146102cf578063dcdc7dd0146102e2578063dd62ed3e146102f557610173565b80637ecebe0014610268578063959b8c3f1461027b57806395d89b411461028e5780639bd9bbc614610296578063a9059cbb146102a9578063d505accf146102bc57610173565b806330adf81f1161013057806330adf81f14610208578063313ce567146102105780634000aea014610225578063556f0dc71461023857806362ad1b831461024057806370a082311461025557610173565b806306e485381461017857806306fdde031461019657806307546172146101ab578063095ea7b3146101c057806318160ddd146101e057806323b872dd146101f5575b600080fd5b610180610349565b60405161018d9190611c97565b60405180910390f35b61019e6103ab565b60405161018d9190611d4a565b6101b3610435565b60405161018d9190611b9f565b6101d36101ce3660046119d2565b610444565b60405161018d9190611ce4565b6101e8610466565b60405161018d9190611cef565b6101d3610203366004611881565b61046c565b6101e86105b4565b6102186105d8565b60405161018d9190612128565b6101d36102333660046119fd565b6105dd565b6101e86106eb565b61025361024e3660046118c1565b6106f1565b005b6101e8610263366004611811565b6107a8565b6101e8610276366004611811565b6107c3565b610253610289366004611811565b6107d5565b61019e610902565b6102536102a43660046119fd565b610963565b6101d36102b73660046119d2565b6109cb565b6102536102ca36600461195d565b610a85565b6101d36102dd366004611849565b610bd8565b6102536102f0366004611a57565b610c7a565b6101e8610303366004611849565b610d39565b6101e8610d64565b61025361031e366004611811565b610d6a565b610253610331366004611a57565b610e97565b610253610344366004611ae0565b610f41565b606060048054806020026020016040519081016040528092919081815260200182805480156103a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610383575b5050505050905090565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b820191906000526020600020905b81548152906001019060200180831161041757509395945050505050565b6009546001600160a01b031681565b60008061044f610ffb565b905061045c818585610fff565b5060019392505050565b60015490565b60006001600160a01b03831661049d5760405162461bcd60e51b815260040161049490611e50565b60405180910390fd5b6001600160a01b0384166104c35760405162461bcd60e51b815260040161049490612043565b60006104cd610ffb565b90506104fb81868686604051806020016040528060008152506040518060200160405280600081525061108d565b6105278186868660405180602001604052806000815250604051806020016040528060008152506111bb565b61057b858261057686604051806060016040528060298152602001612176602991396001600160a01b03808c166000908152600860209081526040808320938b168352929052205491906112db565b610fff565b6105a98186868660405180602001604052806000815250604051806020016040528060008152506000611307565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601290565b6000806105e8610ffb565b905061063c8182888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060408051602081019091528181529350915061146e9050565b7fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c168187878787604051610673959493929190611c0d565b60405180910390a1604051635260769b60e11b81526001600160a01b0387169063a4c0ed36906106ad908490899089908990600401611c65565b600060405180830381600087803b1580156106c757600080fd5b505af11580156106db573d6000803e3d6000fd5b5060019998505050505050505050565b600a5490565b6107026106fc610ffb565b88610bd8565b61071e5760405162461bcd60e51b815260040161049490612085565b61079f610729610ffb565b88888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a91508990819084018382808284376000920191909152506001925061146e915050565b50505050505050565b6001600160a01b031660009081526020819052604090205490565b600c6020526000908152604090205481565b806001600160a01b03166107e7610ffb565b6001600160a01b0316141561080e5760405162461bcd60e51b815260040161049490611dcb565b6001600160a01b03811660009081526005602052604090205460ff1615610871576007600061083b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690556108b8565b60016006600061087f610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b6108c0610ffb565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b6109c561096e610ffb565b610976610ffb565b868686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604080516020810190915290815292506001915061146e9050565b50505050565b60006001600160a01b0383166109f35760405162461bcd60e51b815260040161049490611e50565b60006109fd610ffb565b9050610a2b81828686604051806020016040528060008152506040518060200160405280600081525061108d565b610a578182868660405180602001604052806000815250604051806020016040528060008152506111bb565b61045c8182868660405180602001604052806000815250604051806020016040528060008152506000611307565b42841015610aa55760405162461bcd60e51b815260040161049490611fa9565b600b546001600160a01b0388166000908152600c6020908152604080832080546001810190915590519293610b27939092610b0c927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928e928e928e9290918e9101611cf8565b604051602081830303815290604052805190602001206114e5565b9050600060018286868660405160008152602001604052604051610b4e9493929190611d2c565b6020604051602081039080840390855afa158015610b70573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610ba65750886001600160a01b0316816001600160a01b0316145b610bc25760405162461bcd60e51b815260040161049490611f2f565b610bcd898989610fff565b505050505050505050565b6000816001600160a01b0316836001600160a01b03161480610c4357506001600160a01b03831660009081526005602052604090205460ff168015610c4357506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b80610c7357506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b6009546001600160a01b0316610c8e610ffb565b6001600160a01b031614610cb45760405162461bcd60e51b815260040161049490611f66565b610d31610cbf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061150492505050565b505050505050565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b600b5481565b610d72610ffb565b6001600160a01b0316816001600160a01b03161415610da35760405162461bcd60e51b815260040161049490611e0f565b6001600160a01b03811660009081526005602052604090205460ff1615610e0f57600160076000610dd2610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055610e4d565b60066000610e1b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b610e55610ffb565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b610ea8610ea2610ffb565b87610bd8565b610ec45760405162461bcd60e51b815260040161049490612085565b610d31610ecf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061162c92505050565b610f9f610f4c610ffb565b610f54610ffb565b8585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805160208101909152908152925061162c915050565b505050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b3390565b6001600160a01b0382166110255760405162461bcd60e51b8152600401610494906120c6565b6001600160a01b0380841660008181526008602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611080908590611cef565b60405180910390a3505050565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906110e99089907f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89590600401611c4c565b60206040518083038186803b15801561110157600080fd5b505afa158015611115573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611139919061182d565b90506001600160a01b0381161561079f57604051633ad5cbc160e11b81526001600160a01b038216906375ab978290611180908a908a908a908a908a908a90600401611bb3565b600060405180830381600087803b15801561119a57600080fd5b505af11580156111ae573d6000803e3d6000fd5b5050505050505050505050565b6111f88360405180606001604052806027815260200161214f602791396001600160a01b03881660009081526020819052604090205491906112db565b6001600160a01b038087166000908152602081905260408082209390935590861681522054611227908461175d565b6001600160a01b0380861660008181526020819052604090819020939093559151878216918916907f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc8261467798790611280908890889088906120fd565b60405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516112cb9190611cef565b60405180910390a3505050505050565b600081848411156112ff5760405162461bcd60e51b81526004016104949190611d4a565b505050900390565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906113639089907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b90600401611c4c565b60206040518083038186803b15801561137b57600080fd5b505afa15801561138f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b3919061182d565b90506001600160a01b0381161561142f576040516223de2960e01b81526001600160a01b038216906223de29906113f8908b908b908b908b908b908b90600401611bb3565b600060405180830381600087803b15801561141257600080fd5b505af1158015611426573d6000803e3d6000fd5b50505050611464565b811561146457611447866001600160a01b0316611782565b156114645760405162461bcd60e51b815260040161049490611ebc565b5050505050505050565b6001600160a01b0386166114945760405162461bcd60e51b815260040161049490611fd5565b6001600160a01b0385166114ba5760405162461bcd60e51b81526004016104949061200c565b6114c887878787878761108d565b6114d68787878787876111bb565b61079f87878787878787611307565b60405161190160f01b8152600281019290925260228201526042902090565b6001600160a01b03841661152a5760405162461bcd60e51b815260040161049490611e85565b600154611537908461175d565b6001556001600160a01b03841660009081526020819052604090205461155d908461175d565b6001600160a01b03851660009081526020819052604081209190915561158a908690868686866001611307565b836001600160a01b0316856001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d8585856040516115d1939291906120fd565b60405180910390a3836001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b60405180910390a35050505050565b6001600160a01b0384166116525760405162461bcd60e51b815260040161049490611d94565b6116618585600086868661108d565b61169e8360405180606001604052806023815260200161219f602391396001600160a01b03871660009081526020819052604090205491906112db565b6001600160a01b0385166000908152602081905260409020556001546116c49084611788565b600181905550836001600160a01b0316856001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098858585604051611711939291906120fd565b60405180910390a360006001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b600082820183811015610c735760405162461bcd60e51b815260040161049490611d5d565b3b151590565b6000610c7383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506112db565b60008083601f8401126117db578182fd5b50813567ffffffffffffffff8111156117f2578182fd5b60208301915083602082850101111561180a57600080fd5b9250929050565b600060208284031215611822578081fd5b8135610c7381612136565b60006020828403121561183e578081fd5b8151610c7381612136565b6000806040838503121561185b578081fd5b823561186681612136565b9150602083013561187681612136565b809150509250929050565b600080600060608486031215611895578081fd5b83356118a081612136565b925060208401356118b081612136565b929592945050506040919091013590565b600080600080600080600060a0888a0312156118db578283fd5b87356118e681612136565b965060208801356118f681612136565b955060408801359450606088013567ffffffffffffffff80821115611919578485fd5b6119258b838c016117ca565b909650945060808a013591508082111561193d578384fd5b5061194a8a828b016117ca565b989b979a50959850939692959293505050565b600080600080600080600060e0888a031215611977578283fd5b873561198281612136565b9650602088013561199281612136565b95506040880135945060608801359350608088013560ff811681146119b5578384fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156119e4578182fd5b82356119ef81612136565b946020939093013593505050565b60008060008060608587031215611a12578384fd5b8435611a1d81612136565b935060208501359250604085013567ffffffffffffffff811115611a3f578283fd5b611a4b878288016117ca565b95989497509550505050565b60008060008060008060808789031215611a6f578182fd5b8635611a7a81612136565b955060208701359450604087013567ffffffffffffffff80821115611a9d578384fd5b611aa98a838b016117ca565b90965094506060890135915080821115611ac1578384fd5b50611ace89828a016117ca565b979a9699509497509295939492505050565b600080600060408486031215611af4578283fd5b83359250602084013567ffffffffffffffff811115611b11578283fd5b611b1d868287016117ca565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b81811015611b7957602081850181015186830182015201611b5d565b81811115611b8a5782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0387811682528681166020830152851660408201526060810184905260c060808201819052600090611bee90830185611b54565b82810360a0840152611c008185611b54565b9998505050505050505050565b6001600160a01b0386811682528516602082015260408101849052608060608201819052600090611c419083018486611b2a565b979650505050505050565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038616825284602083015260606040830152611c8d606083018486611b2a565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611cd85783516001600160a01b031683529284019291840191600101611cb3565b50909695505050505050565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610c736020830184611b54565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f4552433737373a206275726e2066726f6d207a65726f20616464726573730000604082015260600190565b60208082526024908201527f4552433737373a20617574686f72697a696e672073656c66206173206f70657260408201526330ba37b960e11b606082015260800190565b60208082526021908201527f4552433737373a207265766f6b696e672073656c66206173206f70657261746f6040820152603960f91b606082015260800190565b6020808252818101527f4552433737373a207472616e7366657220746f207a65726f2061646472657373604082015260600190565b6020808252601c908201527f4552433737373a206d696e7420746f207a65726f206164647265737300000000604082015260600190565b6020808252604d908201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460408201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60608201526c1ad95b9cd49958da5c1a595b9d609a1b608082015260a00190565b6020808252601c908201527f53696465546f6b656e3a20494e56414c49445f5349474e415455524500000000604082015260600190565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b60208082526012908201527114da5919551bdad95b8e881156141254915160721b604082015260600190565b6020808252601e908201527f4552433737373a2073656e642066726f6d207a65726f20616464726573730000604082015260600190565b6020808252601c908201527f4552433737373a2073656e6420746f207a65726f206164647265737300000000604082015260600190565b60208082526022908201527f4552433737373a207472616e736665722066726f6d207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526021908201527f4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f6040820152603960f91b606082015260800190565b6020808252601f908201527f4552433737373a20617070726f766520746f207a65726f206164647265737300604082015260600190565b6000848252606060208301526121166060830185611b54565b8281036040840152611c8d8185611b54565b60ff91909116815260200190565b6001600160a01b038116811461214b57600080fd5b5056fe4552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a206275726e20616d6f756e7420657863656564732062616c616e6365a2646970667358221220e50313b8f4599486bdf7f8664f20e7ac280c8c35bbfd6cde681392ecbb37f14d64736f6c63430007060033a26469706673582212208c32c0735adbbf4ac7cf06584e89be0c8b8a258182daeed841b15ec41b72036764736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 11018,
+ "contract": "contracts/SideTokenFactory/SideTokenFactory.sol:SideTokenFactory",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/WRBTC.json b/bridge/deployments/rinkeby/WRBTC.json
new file mode 100644
index 000000000..85da34087
--- /dev/null
+++ b/bridge/deployments/rinkeby/WRBTC.json
@@ -0,0 +1,400 @@
+{
+ "address": "0x1664Bd54e994C04bD0f9F7B7e9Ad7CC45d1537B1",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "guy",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposit",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Withdrawal",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "guy",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "deposit",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdraw",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x89073e5c6ef6b61526dddee2edb7f075ebbb4642403d661bc17df8f46526670f",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0x1664Bd54e994C04bD0f9F7B7e9Ad7CC45d1537B1",
+ "transactionIndex": 1,
+ "gasUsed": "556602",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xc1e7e25cbaaaff0b6030f0744c899f01b89b37f26340a0cc169d2e63de238a32",
+ "transactionHash": "0x89073e5c6ef6b61526dddee2edb7f075ebbb4642403d661bc17df8f46526670f",
+ "logs": [],
+ "blockNumber": 9269449,
+ "cumulativeGasUsed": "607736",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/test/WRBTC.sol\":\"WRBTC\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interface/IWrapped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IWrapped {\\r\\n function balanceOf(address) external returns(uint);\\r\\n\\r\\n function deposit() external payable;\\r\\n\\r\\n function withdraw(uint wad) external;\\r\\n\\r\\n function totalSupply() external view returns (uint);\\r\\n\\r\\n function approve(address guy, uint wad) external returns (bool);\\r\\n\\r\\n function transfer(address dst, uint wad) external returns (bool);\\r\\n\\r\\n function transferFrom(address src, address dst, uint wad)\\r\\n external\\r\\n returns (bool);\\r\\n}\",\"keccak256\":\"0xb79b74797d9b4102d4ba69d452ed04bae742e34240c3aa72f654de525b29a5c7\",\"license\":\"MIT\"},\"contracts/test/WRBTC.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../interface/IWrapped.sol\\\";\\r\\n\\r\\ncontract WRBTC is IWrapped {\\r\\n string public name = \\\"Wrapped RBTC\\\";\\r\\n string public symbol = \\\"WRBTC\\\";\\r\\n uint8 public decimals = 18;\\r\\n\\r\\n event Approval(address indexed src, address indexed guy, uint wad);\\r\\n event Transfer(address indexed src, address indexed dst, uint wad);\\r\\n event Deposit(address indexed dst, uint wad);\\r\\n event Withdrawal(address indexed src, uint wad);\\r\\n\\r\\n mapping (address => uint) override public balanceOf;\\r\\n mapping (address => mapping (address => uint)) public allowance;\\r\\n\\r\\n receive () external payable {\\r\\n deposit();\\r\\n }\\r\\n function deposit() override public payable {\\r\\n balanceOf[msg.sender] += msg.value;\\r\\n emit Deposit(msg.sender, msg.value);\\r\\n }\\r\\n function withdraw(uint wad) override public {\\r\\n require(balanceOf[msg.sender] >= wad, \\\"WRBTC: Balance less than wad\\\");\\r\\n balanceOf[msg.sender] -= wad;\\r\\n msg.sender.transfer(wad);\\r\\n emit Withdrawal(msg.sender, wad);\\r\\n }\\r\\n\\r\\n function totalSupply() override public view returns (uint) {\\r\\n return address(this).balance;\\r\\n }\\r\\n\\r\\n function approve(address guy, uint wad) override public returns (bool) {\\r\\n allowance[msg.sender][guy] = wad;\\r\\n emit Approval(msg.sender, guy, wad);\\r\\n return true;\\r\\n }\\r\\n\\r\\n function transfer(address dst, uint wad) override public returns (bool) {\\r\\n return transferFrom(msg.sender, dst, wad);\\r\\n }\\r\\n\\r\\n function transferFrom(address src, address dst, uint wad)\\r\\n override public\\r\\n returns (bool)\\r\\n {\\r\\n require(balanceOf[src] >= wad, \\\"WRBTC: Balance less than wad\\\");\\r\\n\\r\\n if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\\r\\n require(allowance[src][msg.sender] >= wad, \\\"WRBTC: Allowance less than wad\\\");\\r\\n allowance[src][msg.sender] -= wad;\\r\\n }\\r\\n\\r\\n balanceOf[src] -= wad;\\r\\n balanceOf[dst] += wad;\\r\\n\\r\\n emit Transfer(src, dst, wad);\\r\\n\\r\\n return true;\\r\\n }\\r\\n}\",\"keccak256\":\"0x4ff3e4b0e827349d96db7a36afe0f00b27cb5145b5f4df613884e89c516fd19a\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x60c0604052600c60808190526b57726170706564205242544360a01b60a090815261002d916000919061007a565b5060408051808201909152600580825264575242544360d81b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b5061011b565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826100b057600085556100f6565b82601f106100c957805160ff19168380011785556100f6565b828001600101855582156100f6579182015b828111156100f65782518255916020019190600101906100db565b50610102929150610106565b5090565b5b808211156101025760008155600101610107565b6107d28061012a6000396000f3fe6080604052600436106100a05760003560e01c8063313ce56711610064578063313ce5671461021f57806370a082311461024a57806395d89b411461027d578063a9059cbb14610292578063d0e30db0146102cb578063dd62ed3e146102d3576100af565b806306fdde03146100b4578063095ea7b31461013e57806318160ddd1461018b57806323b872dd146101b25780632e1a7d4d146101f5576100af565b366100af576100ad61030e565b005b600080fd5b3480156100c057600080fd5b506100c961035d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101035781810151838201526020016100eb565b50505050905090810190601f1680156101305780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014a57600080fd5b506101776004803603604081101561016157600080fd5b506001600160a01b0381351690602001356103eb565b604080519115158252519081900360200190f35b34801561019757600080fd5b506101a0610451565b60408051918252519081900360200190f35b3480156101be57600080fd5b50610177600480360360608110156101d557600080fd5b506001600160a01b03813581169160208101359091169060400135610455565b34801561020157600080fd5b506100ad6004803603602081101561021857600080fd5b5035610619565b34801561022b57600080fd5b506102346106f6565b6040805160ff9092168252519081900360200190f35b34801561025657600080fd5b506101a06004803603602081101561026d57600080fd5b50356001600160a01b03166106ff565b34801561028957600080fd5b506100c9610711565b34801561029e57600080fd5b50610177600480360360408110156102b557600080fd5b506001600160a01b03813516906020013561076b565b6100ad61030e565b3480156102df57600080fd5b506101a0600480360360408110156102f657600080fd5b506001600160a01b038135811691602001351661077f565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b820191906000526020600020905b8154815290600101906020018083116103c657829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b6001600160a01b0383166000908152600360205260408120548211156104c2576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b6001600160a01b038416331480159061050057506001600160a01b038416600090815260046020908152604080832033845290915290205460001914155b156105a8576001600160a01b038416600090815260046020908152604080832033845290915290205482111561057d576040805162461bcd60e51b815260206004820152601e60248201527f57524254433a20416c6c6f77616e6365206c657373207468616e207761640000604482015290519081900360640190fd5b6001600160a01b03841660009081526004602090815260408083203384529091529020805483900390555b6001600160a01b03808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561067d576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106bc573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b6000610778338484610455565b9392505050565b60046020908152600092835260408084209091529082529020548156fea26469706673582212203b131c7fbf6de964569d9ecd97f25396768cf2baaa7b608974f782e731298d4464736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106100a05760003560e01c8063313ce56711610064578063313ce5671461021f57806370a082311461024a57806395d89b411461027d578063a9059cbb14610292578063d0e30db0146102cb578063dd62ed3e146102d3576100af565b806306fdde03146100b4578063095ea7b31461013e57806318160ddd1461018b57806323b872dd146101b25780632e1a7d4d146101f5576100af565b366100af576100ad61030e565b005b600080fd5b3480156100c057600080fd5b506100c961035d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101035781810151838201526020016100eb565b50505050905090810190601f1680156101305780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014a57600080fd5b506101776004803603604081101561016157600080fd5b506001600160a01b0381351690602001356103eb565b604080519115158252519081900360200190f35b34801561019757600080fd5b506101a0610451565b60408051918252519081900360200190f35b3480156101be57600080fd5b50610177600480360360608110156101d557600080fd5b506001600160a01b03813581169160208101359091169060400135610455565b34801561020157600080fd5b506100ad6004803603602081101561021857600080fd5b5035610619565b34801561022b57600080fd5b506102346106f6565b6040805160ff9092168252519081900360200190f35b34801561025657600080fd5b506101a06004803603602081101561026d57600080fd5b50356001600160a01b03166106ff565b34801561028957600080fd5b506100c9610711565b34801561029e57600080fd5b50610177600480360360408110156102b557600080fd5b506001600160a01b03813516906020013561076b565b6100ad61030e565b3480156102df57600080fd5b506101a0600480360360408110156102f657600080fd5b506001600160a01b038135811691602001351661077f565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b820191906000526020600020905b8154815290600101906020018083116103c657829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b6001600160a01b0383166000908152600360205260408120548211156104c2576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b6001600160a01b038416331480159061050057506001600160a01b038416600090815260046020908152604080832033845290915290205460001914155b156105a8576001600160a01b038416600090815260046020908152604080832033845290915290205482111561057d576040805162461bcd60e51b815260206004820152601e60248201527f57524254433a20416c6c6f77616e6365206c657373207468616e207761640000604482015290519081900360640190fd5b6001600160a01b03841660009081526004602090815260408083203384529091529020805483900390555b6001600160a01b03808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561067d576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106bc573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b6000610778338484610455565b9392505050565b60046020908152600092835260408084209091529082529020548156fea26469706673582212203b131c7fbf6de964569d9ecd97f25396768cf2baaa7b608974f782e731298d4464736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {},
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 9312,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "name",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 9315,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "symbol",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 9318,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "decimals",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint8"
+ },
+ {
+ "astId": 9351,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "balanceOf",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_mapping(t_address,t_uint256)"
+ },
+ {
+ "astId": 9357,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "allowance",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_uint256))": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_uint256)"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "encoding": "inplace",
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/solcInputs/ac84b9a231dc57cb70373cf629ffea6c.json b/bridge/deployments/rinkeby/solcInputs/ac84b9a231dc57cb70373cf629ffea6c.json
new file mode 100644
index 000000000..3d31a3b4e
--- /dev/null
+++ b/bridge/deployments/rinkeby/solcInputs/ac84b9a231dc57cb70373cf629ffea6c.json
@@ -0,0 +1,36 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/MultiSigWallet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.\r\n/// @author Stefan George - \r\ncontract MultiSigWallet {\r\n\r\n /*\r\n * Events\r\n */\r\n event Confirmation(address indexed sender, uint indexed transactionId);\r\n event Revocation(address indexed sender, uint indexed transactionId);\r\n event Submission(uint indexed transactionId);\r\n event Execution(uint indexed transactionId);\r\n event ExecutionFailure(uint indexed transactionId);\r\n event Deposit(address indexed sender, uint value);\r\n event OwnerAddition(address indexed owner);\r\n event OwnerRemoval(address indexed owner);\r\n event RequirementChange(uint required);\r\n\r\n /*\r\n * views\r\n */\r\n uint constant public MAX_OWNER_COUNT = 50;\r\n\r\n /*\r\n * Storage\r\n */\r\n mapping (uint => Transaction) public transactions;\r\n mapping (uint => mapping (address => bool)) public confirmations;\r\n mapping (address => bool) public isOwner;\r\n address[] public owners;\r\n uint public required;\r\n uint public transactionCount;\r\n\r\n struct Transaction {\r\n address destination;\r\n uint value;\r\n bytes data;\r\n bool executed;\r\n }\r\n\r\n /*\r\n * Modifiers\r\n */\r\n modifier onlyWallet() {\r\n require(msg.sender == address(this), \"Only wallet allowed\");\r\n _;\r\n }\r\n\r\n modifier ownerDoesNotExist(address owner) {\r\n require(!isOwner[owner], \"The owner already exists\");\r\n _;\r\n }\r\n\r\n modifier ownerExists(address owner) {\r\n require(isOwner[owner], \"The owner does not exist\");\r\n _;\r\n }\r\n\r\n modifier transactionExists(uint transactionId) {\r\n require(transactions[transactionId].destination != address(0), \"Transaction does not exist\");\r\n _;\r\n }\r\n\r\n modifier confirmed(uint transactionId, address owner) {\r\n require(confirmations[transactionId][owner], \"Transaction is not confirmed by owner\");\r\n _;\r\n }\r\n\r\n modifier notConfirmed(uint transactionId, address owner) {\r\n require(!confirmations[transactionId][owner], \"Transaction is already confirmed by owner\");\r\n _;\r\n }\r\n\r\n modifier notExecuted(uint transactionId) {\r\n require(!transactions[transactionId].executed, \"Transaction was already executed\");\r\n _;\r\n }\r\n\r\n modifier notNull(address _address) {\r\n require(_address != address(0), \"Address cannot be empty\");\r\n _;\r\n }\r\n\r\n modifier validRequirement(uint ownerCount, uint _required) {\r\n // solium-disable-next-line max-len\r\n require(ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && _required != 0 && ownerCount != 0, \"Required value is invalid for the current owners count\");\r\n _;\r\n }\r\n\r\n /// @dev Fallback function allows to deposit ether.\r\n receive ()\r\n external\r\n payable\r\n {\r\n if (msg.value > 0)\r\n emit Deposit(msg.sender, msg.value);\r\n }\r\n\r\n /*\r\n * Public functions\r\n */\r\n /// @dev Contract constructor sets initial owners and required number of confirmations.\r\n /// @param _owners List of initial owners.\r\n /// @param _required Number of required confirmations.\r\n constructor(address[] memory _owners, uint _required)\r\n validRequirement(_owners.length, _required)\r\n {\r\n for (uint i = 0; i < _owners.length; i++) {\r\n require(!isOwner[_owners[i]] && _owners[i] != address(0), \"Owners addresses are invalid\");\r\n isOwner[_owners[i]] = true;\r\n }\r\n owners = _owners;\r\n required = _required;\r\n }\r\n\r\n /// @dev Allows to add a new owner. Transaction has to be sent by wallet.\r\n /// @param owner Address of new owner.\r\n function addOwner(address owner)\r\n public\r\n onlyWallet\r\n ownerDoesNotExist(owner)\r\n notNull(owner)\r\n validRequirement(owners.length + 1, required)\r\n {\r\n isOwner[owner] = true;\r\n owners.push(owner);\r\n emit OwnerAddition(owner);\r\n }\r\n\r\n /// @dev Allows to remove an owner. Transaction has to be sent by wallet.\r\n /// @param owner Address of owner.\r\n function removeOwner(address owner)\r\n public\r\n onlyWallet\r\n ownerExists(owner)\r\n {\r\n isOwner[owner] = false;\r\n for (uint i = 0; i < owners.length - 1; i++)\r\n if (owners[i] == owner) {\r\n owners[i] = owners[owners.length - 1];\r\n break;\r\n }\r\n owners.pop(); // remove an element from the end of the array.\r\n if (required > owners.length)\r\n changeRequirement(owners.length);\r\n emit OwnerRemoval(owner);\r\n }\r\n\r\n /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\r\n /// @param owner Address of owner to be replaced.\r\n /// @param newOwner Address of new owner.\r\n function replaceOwner(address owner, address newOwner)\r\n public\r\n onlyWallet\r\n ownerExists(owner)\r\n ownerDoesNotExist(newOwner)\r\n {\r\n for (uint i = 0; i < owners.length; i++)\r\n if (owners[i] == owner) {\r\n owners[i] = newOwner;\r\n break;\r\n }\r\n isOwner[owner] = false;\r\n isOwner[newOwner] = true;\r\n emit OwnerRemoval(owner);\r\n emit OwnerAddition(newOwner);\r\n }\r\n\r\n /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.\r\n /// @param _required Number of required confirmations.\r\n function changeRequirement(uint _required)\r\n public\r\n onlyWallet\r\n validRequirement(owners.length, _required)\r\n {\r\n required = _required;\r\n emit RequirementChange(_required);\r\n }\r\n\r\n /// @dev Allows an owner to submit and confirm a transaction.\r\n /// @param destination Transaction target address.\r\n /// @param value Transaction ether value.\r\n /// @param data Transaction data payload.\r\n /// @return transactionId Returns transaction ID.\r\n function submitTransaction(address destination, uint value, bytes memory data)\r\n public\r\n returns (uint transactionId)\r\n {\r\n transactionId = addTransaction(destination, value, data);\r\n confirmTransaction(transactionId);\r\n }\r\n\r\n /// @dev Allows an owner to confirm a transaction.\r\n /// @param transactionId Transaction ID.\r\n function confirmTransaction(uint transactionId)\r\n public\r\n ownerExists(msg.sender)\r\n transactionExists(transactionId)\r\n notConfirmed(transactionId, msg.sender)\r\n {\r\n confirmations[transactionId][msg.sender] = true;\r\n emit Confirmation(msg.sender, transactionId);\r\n executeTransaction(transactionId);\r\n }\r\n\r\n /// @dev Allows an owner to revoke a confirmation for a transaction.\r\n /// @param transactionId Transaction ID.\r\n function revokeConfirmation(uint transactionId)\r\n public\r\n ownerExists(msg.sender)\r\n confirmed(transactionId, msg.sender)\r\n notExecuted(transactionId)\r\n {\r\n confirmations[transactionId][msg.sender] = false;\r\n emit Revocation(msg.sender, transactionId);\r\n }\r\n\r\n /// @dev Allows anyone to execute a confirmed transaction.\r\n /// @param transactionId Transaction ID.\r\n function executeTransaction(uint transactionId)\r\n public\r\n ownerExists(msg.sender)\r\n confirmed(transactionId, msg.sender)\r\n notExecuted(transactionId)\r\n {\r\n if (isConfirmed(transactionId)) {\r\n Transaction storage txn = transactions[transactionId];\r\n txn.executed = true;\r\n if (external_call(txn.destination, txn.value, txn.data.length, txn.data))\r\n emit Execution(transactionId);\r\n else {\r\n emit ExecutionFailure(transactionId);\r\n txn.executed = false;\r\n }\r\n }\r\n }\r\n\r\n // call has been separated into its own function in order to take advantage\r\n // of the Solidity's code generator to produce a loop that copies tx.data into memory.\r\n function external_call(address destination, uint value, uint dataLength, bytes memory data) internal returns (bool) {\r\n bool result;\r\n // solium-disable-next-line security/no-inline-assembly\r\n assembly {\r\n let x := mload(0x40) // \"Allocate\" memory for output (0x40 is where \"free memory\" pointer is stored by convention)\r\n let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that\r\n result := call(\r\n sub(gas(), 34710), // 34710 is the value that solidity is currently emitting\r\n // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +\r\n // callNewAccountGas (25000, in case the destination address does not exist and needs creating)\r\n destination,\r\n value,\r\n d,\r\n dataLength, // Size of the input (in bytes) - this is what fixes the padding problem\r\n x,\r\n 0 // Output is ignored, therefore the output size is zero\r\n )\r\n }\r\n return result;\r\n }\r\n\r\n /// @dev Returns the confirmation status of a transaction.\r\n /// @param transactionId Transaction ID.\r\n /// @return Confirmation status.\r\n function isConfirmed(uint transactionId)\r\n public\r\n view\r\n returns (bool)\r\n {\r\n uint count = 0;\r\n for (uint i = 0; i < owners.length; i++) {\r\n if (confirmations[transactionId][owners[i]])\r\n count += 1;\r\n if (count == required)\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /*\r\n * Internal functions\r\n */\r\n /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.\r\n /// @param destination Transaction target address.\r\n /// @param value Transaction ether value.\r\n /// @param data Transaction data payload.\r\n /// @return transactionId Returns transaction ID.\r\n function addTransaction(address destination, uint value, bytes memory data)\r\n internal\r\n notNull(destination)\r\n returns (uint transactionId)\r\n {\r\n transactionId = transactionCount;\r\n transactions[transactionId] = Transaction({\r\n destination: destination,\r\n value: value,\r\n data: data,\r\n executed: false\r\n });\r\n transactionCount += 1;\r\n emit Submission(transactionId);\r\n }\r\n\r\n /*\r\n * Web3 call functions\r\n */\r\n /// @dev Returns number of confirmations of a transaction.\r\n /// @param transactionId Transaction ID.\r\n /// @return count Number of confirmations.\r\n function getConfirmationCount(uint transactionId)\r\n public\r\n view\r\n returns (uint count)\r\n {\r\n for (uint i = 0; i < owners.length; i++) {\r\n if (confirmations[transactionId][owners[i]]) {\r\n count += 1;\r\n }\r\n }\r\n }\r\n\r\n /// @dev Returns total number of transactions after filers are applied.\r\n /// @param pending Include pending transactions.\r\n /// @param executed Include executed transactions.\r\n /// @return count Total number of transactions after filters are applied.\r\n function getTransactionCount(bool pending, bool executed)\r\n public\r\n view\r\n returns (uint count)\r\n {\r\n for (uint i = 0; i < transactionCount; i++) {\r\n if ( pending && !transactions[i].executed || executed && transactions[i].executed) {\r\n count += 1;\r\n }\r\n }\r\n }\r\n\r\n /// @dev Returns list of owners.\r\n /// @return List of owner addresses.\r\n function getOwners()\r\n public\r\n view\r\n returns (address[] memory)\r\n {\r\n return owners;\r\n }\r\n\r\n /// @dev Returns array with owner addresses, which confirmed transaction.\r\n /// @param transactionId Transaction ID.\r\n /// @return _confirmations Returns array of owner addresses.\r\n function getConfirmations(uint transactionId)\r\n public\r\n view\r\n returns (address[] memory _confirmations)\r\n {\r\n address[] memory confirmationsTemp = new address[](owners.length);\r\n uint count = 0;\r\n uint i;\r\n for (i = 0; i < owners.length; i++)\r\n if (confirmations[transactionId][owners[i]]) {\r\n confirmationsTemp[count] = owners[i];\r\n count += 1;\r\n }\r\n _confirmations = new address[](count);\r\n for (i = 0; i < count; i++)\r\n _confirmations[i] = confirmationsTemp[i];\r\n }\r\n\r\n /// @dev Returns list of transaction IDs in defined range.\r\n /// @param from Index start position of transaction array.\r\n /// @param to Index end position of transaction array.\r\n /// @param pending Include pending transactions.\r\n /// @param executed Include executed transactions.\r\n /// @return _transactionIds Returns array of transaction IDs.\r\n function getTransactionIds(uint from, uint to, bool pending, bool executed)\r\n public\r\n view\r\n returns (uint[] memory _transactionIds)\r\n {\r\n uint[] memory transactionIdsTemp = new uint[](transactionCount);\r\n uint count = 0;\r\n uint i;\r\n for (i = 0; i < transactionCount; i++)\r\n if ( pending && !transactions[i].executed || executed && transactions[i].executed)\r\n {\r\n transactionIdsTemp[count] = i;\r\n count += 1;\r\n }\r\n _transactionIds = new uint[](to - from);\r\n for (i = from; i < to; i++)\r\n _transactionIds[i - from] = transactionIdsTemp[i];\r\n }\r\n}"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rinkeby/solcInputs/f57b3a626f709a0447a665aac92698b7.json b/bridge/deployments/rinkeby/solcInputs/f57b3a626f709a0447a665aac92698b7.json
new file mode 100644
index 000000000..de6b9b893
--- /dev/null
+++ b/bridge/deployments/rinkeby/solcInputs/f57b3a626f709a0447a665aac92698b7.json
@@ -0,0 +1,297 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../zeppelin/math/SafeMath.sol\";\r\n// Upgradables\r\nimport \"../zeppelin/upgradable/Initializable.sol\";\r\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\r\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\r\n\r\nimport \"../interface/IAllowTokens.sol\";\r\n\r\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\r\n using SafeMath for uint256;\r\n\r\n address constant private NULL_ADDRESS = address(0);\r\n uint256 constant public MAX_TYPES = 250;\r\n mapping (address => TokenInfo) public allowedTokens;\r\n mapping (uint256 => Limits) public typeLimits;\r\n uint256 public smallAmountConfirmations;\r\n uint256 public mediumAmountConfirmations;\r\n uint256 public largeAmountConfirmations;\r\n string[] public typeDescriptions;\r\n\r\n event SetToken(address indexed _tokenAddress, uint256 _typeId);\r\n event AllowedTokenRemoved(address indexed _tokenAddress);\r\n event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\r\n event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\r\n event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\r\n event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\r\n\r\n\r\n modifier notNull(address _address) {\r\n require(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\r\n _;\r\n }\r\n\r\n function initialize(\r\n address _manager,\r\n address _primary,\r\n uint256 _smallAmountConfirmations,\r\n uint256 _mediumAmountConfirmations,\r\n uint256 _largeAmountConfirmations,\r\n TypeInfo[] memory typesInfo) public initializer {\r\n UpgradableOwnable.initialize(_manager);\r\n UpgradableSecondary.__Secondary_init(_primary);\r\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\r\n for(uint i = 0; i < typesInfo.length; i = i + 1) {\r\n _addTokenType(typesInfo[i].description, typesInfo[i].limits);\r\n }\r\n }\r\n\r\n function version() override external pure returns (string memory) {\r\n return \"v1\";\r\n }\r\n\r\n function getInfoAndLimits(address token) override public view\r\n returns (TokenInfo memory info, Limits memory limit) {\r\n info = allowedTokens[token];\r\n limit = typeLimits[info.typeId];\r\n return (info, limit);\r\n }\r\n function calcMaxWithdraw(address token) override public view returns (uint256 maxWithdraw) {\r\n (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\r\n return _calcMaxWithdraw(info, limits);\r\n }\r\n\r\n function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\r\n // solium-disable-next-line security/no-block-members\r\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\r\n info.spentToday = 0;\r\n }\r\n if (limits.daily <= info.spentToday)\r\n return 0;\r\n maxWithdraw = limits.daily - info.spentToday;\r\n if(maxWithdraw > limits.max)\r\n maxWithdraw = limits.max;\r\n return maxWithdraw;\r\n }\r\n\r\n // solium-disable-next-line max-len\r\n function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\r\n (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\r\n require(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\r\n require(amount >= limit.min, \"AllowTokens: Lower than limit\");\r\n\r\n // solium-disable-next-line security/no-block-members\r\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\r\n // solium-disable-next-line security/no-block-members\r\n info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\r\n info.spentToday = 0;\r\n }\r\n uint maxWithdraw = _calcMaxWithdraw(info, limit);\r\n require(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\r\n info.spentToday = info.spentToday.add(amount);\r\n allowedTokens[token] = info;\r\n\r\n emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\r\n }\r\n\r\n function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\r\n require(bytes(description).length > 0, \"AllowTokens: Empty description\");\r\n len = typeDescriptions.length;\r\n require(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\r\n typeDescriptions.push(description);\r\n _setTypeLimits(len, limits);\r\n emit TokenTypeAdded(len, description);\r\n return len;\r\n }\r\n\r\n function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\r\n return _addTokenType(description, limits);\r\n }\r\n\r\n function _setTypeLimits(uint256 typeId, Limits memory limits) private {\r\n require(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\r\n require(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\r\n require(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\r\n require(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\r\n require(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\r\n typeLimits[typeId] = limits;\r\n emit TypeLimitsChanged(typeId, limits);\r\n }\r\n\r\n function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\r\n _setTypeLimits(typeId, limits);\r\n }\r\n\r\n function getTypesLimits() external view override returns(Limits[] memory limits) {\r\n limits = new Limits[](typeDescriptions.length);\r\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\r\n limits[i] = typeLimits[i];\r\n }\r\n return limits;\r\n }\r\n\r\n function getTypeDescriptionsLength() external view override returns(uint256) {\r\n return typeDescriptions.length;\r\n }\r\n\r\n function getTypeDescriptions() external view override returns(string[] memory descriptions) {\r\n descriptions = new string[](typeDescriptions.length);\r\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\r\n descriptions[i] = typeDescriptions[i];\r\n }\r\n return descriptions;\r\n }\r\n\r\n function isTokenAllowed(address token) public view notNull(token) override returns (bool) {\r\n return allowedTokens[token].allowed;\r\n }\r\n\r\n function setToken(address token, uint256 typeId) override public notNull(token) {\r\n require(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\r\n require(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\r\n TokenInfo memory info = allowedTokens[token];\r\n info.allowed = true;\r\n info.typeId = typeId;\r\n allowedTokens[token] = info;\r\n emit SetToken(token, typeId);\r\n }\r\n\r\n function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\r\n require(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\r\n for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\r\n setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\r\n }\r\n }\r\n\r\n function removeAllowedToken(address token) external notNull(token) onlyOwner {\r\n TokenInfo memory info = allowedTokens[token];\r\n require(info.allowed, \"AllowTokens: Not Allowed\");\r\n info.allowed = false;\r\n allowedTokens[token] = info;\r\n emit AllowedTokenRemoved(token);\r\n }\r\n\r\n function setConfirmations(\r\n uint256 _smallAmountConfirmations,\r\n uint256 _mediumAmountConfirmations,\r\n uint256 _largeAmountConfirmations) external onlyOwner {\r\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\r\n }\r\n\r\n function _setConfirmations(\r\n uint256 _smallAmountConfirmations,\r\n uint256 _mediumAmountConfirmations,\r\n uint256 _largeAmountConfirmations) private {\r\n require(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\r\n require(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\r\n smallAmountConfirmations = _smallAmountConfirmations;\r\n mediumAmountConfirmations = _mediumAmountConfirmations;\r\n largeAmountConfirmations = _largeAmountConfirmations;\r\n emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\r\n }\r\n\r\n function getConfirmations() external view override\r\n returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount) {\r\n return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\r\n * checks.\r\n *\r\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\r\n * in bugs, because programmers usually assume that an overflow raises an\r\n * error, which is the standard behavior in high level programming languages.\r\n * `SafeMath` restores this intuition by reverting the transaction when an\r\n * operation overflows.\r\n *\r\n * Using this library instead of the unchecked operations eliminates an entire\r\n * class of bugs, so it's recommended to use it always.\r\n */\r\nlibrary SafeMath {\r\n /**\r\n * @dev Returns the addition of two unsigned integers, reverting on\r\n * overflow.\r\n *\r\n * Counterpart to Solidity's `+` operator.\r\n *\r\n * Requirements:\r\n * - Addition cannot overflow.\r\n */\r\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\r\n uint256 c = a + b;\r\n require(c >= a, \"SafeMath: addition overflow\");\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the subtraction of two unsigned integers, reverting on\r\n * overflow (when the result is negative).\r\n *\r\n * Counterpart to Solidity's `-` operator.\r\n *\r\n * Requirements:\r\n * - Subtraction cannot overflow.\r\n */\r\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\r\n return sub(a, b, \"SafeMath: subtraction overflow\");\r\n }\r\n\r\n /**\r\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\r\n * overflow (when the result is negative).\r\n *\r\n * Counterpart to Solidity's `-` operator.\r\n *\r\n * Requirements:\r\n * - Subtraction cannot overflow.\r\n *\r\n * _Available since v2.4.0._\r\n */\r\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\r\n require(b <= a, errorMessage);\r\n uint256 c = a - b;\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the multiplication of two unsigned integers, reverting on\r\n * overflow.\r\n *\r\n * Counterpart to Solidity's `*` operator.\r\n *\r\n * Requirements:\r\n * - Multiplication cannot overflow.\r\n */\r\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\r\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\r\n // benefit is lost if 'b' is also tested.\r\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\r\n if (a == 0) {\r\n return 0;\r\n }\r\n\r\n uint256 c = a * b;\r\n require(c / a == b, \"SafeMath: multiplication overflow\");\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the integer division of two unsigned integers. Reverts on\r\n * division by zero. The result is rounded towards zero.\r\n *\r\n * Counterpart to Solidity's `/` operator. Note: this function uses a\r\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\r\n * uses an invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n * - The divisor cannot be zero.\r\n */\r\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\r\n return div(a, b, \"SafeMath: division by zero\");\r\n }\r\n\r\n /**\r\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\r\n * division by zero. The result is rounded towards zero.\r\n *\r\n * Counterpart to Solidity's `/` operator. Note: this function uses a\r\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\r\n * uses an invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n * - The divisor cannot be zero.\r\n *\r\n * _Available since v2.4.0._\r\n */\r\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\r\n // Solidity only automatically asserts when dividing by 0\r\n require(b > 0, errorMessage);\r\n uint256 c = a / b;\r\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\r\n * Reverts when dividing by zero.\r\n *\r\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\r\n * opcode (which leaves remaining gas untouched) while Solidity uses an\r\n * invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n * - The divisor cannot be zero.\r\n */\r\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\r\n return mod(a, b, \"SafeMath: modulo by zero\");\r\n }\r\n\r\n /**\r\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\r\n * Reverts with custom message when dividing by zero.\r\n *\r\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\r\n * opcode (which leaves remaining gas untouched) while Solidity uses an\r\n * invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n * - The divisor cannot be zero.\r\n *\r\n * _Available since v2.4.0._\r\n */\r\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\r\n require(b != 0, errorMessage);\r\n return a % b;\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @title Initializable\r\n *\r\n * @dev Helper contract to support initializer functions. To use it, replace\r\n * the constructor with a function that has the `initializer` modifier.\r\n * WARNING: Unlike constructors, initializer functions must be manually\r\n * invoked. This applies both to deploying an Initializable contract, as well\r\n * as extending an Initializable contract via inheritance.\r\n * WARNING: When used with inheritance, manual care must be taken to not invoke\r\n * a parent initializer twice, or ensure that all initializers are idempotent,\r\n * because this is not dealt with automatically as with constructors.\r\n */\r\ncontract Initializable {\r\n\r\n /**\r\n * @dev Indicates that the contract has been initialized.\r\n */\r\n bool private initialized;\r\n\r\n /**\r\n * @dev Indicates that the contract is in the process of being initialized.\r\n */\r\n bool private initializing;\r\n\r\n /**\r\n * @dev Modifier to use in the initializer function of a contract.\r\n */\r\n modifier initializer() {\r\n require(initializing || !initialized, \"Contract instance is already initialized\");\r\n\r\n bool isTopLevelCall = !initializing;\r\n if (isTopLevelCall) {\r\n initializing = true;\r\n initialized = true;\r\n }\r\n\r\n _;\r\n\r\n if (isTopLevelCall) {\r\n initializing = false;\r\n }\r\n }\r\n\r\n // Reserved storage space to allow for layout changes in the future.\r\n uint256[50] private ______gap;\r\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../Initializable.sol\";\r\n\r\nimport \"../../GSN/Context.sol\";\r\n\r\n/**\r\n * @dev Contract module which provides a basic access control mechanism, where\r\n * there is an account (an owner) that can be granted exclusive access to\r\n * specific functions.\r\n *\r\n * This module is used through inheritance. It will make available the modifier\r\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\r\n * the owner.\r\n */\r\ncontract UpgradableOwnable is Initializable, Context {\r\n address private _owner;\r\n\r\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\r\n\r\n /**\r\n * @dev Initializes the contract setting the deployer as the initial owner.\r\n */\r\n function initialize(address sender) public initializer {\r\n _owner = sender;\r\n emit OwnershipTransferred(address(0), _owner);\r\n }\r\n\r\n /**\r\n * @dev Returns the address of the current owner.\r\n */\r\n function owner() public view returns (address) {\r\n return _owner;\r\n }\r\n\r\n /**\r\n * @dev Throws if called by any account other than the owner.\r\n */\r\n modifier onlyOwner() {\r\n require(isOwner(), \"Ownable: caller is not the owner\");\r\n _;\r\n }\r\n\r\n /**\r\n * @dev Returns true if the caller is the current owner.\r\n */\r\n function isOwner() public view returns (bool) {\r\n return _msgSender() == _owner;\r\n }\r\n\r\n /**\r\n * @dev Leaves the contract without owner. It will not be possible to call\r\n * `onlyOwner` functions anymore. Can only be called by the current owner.\r\n *\r\n * > Note: Renouncing ownership will leave the contract without an owner,\r\n * thereby removing any functionality that is only available to the owner.\r\n */\r\n function renounceOwnership() public onlyOwner {\r\n emit OwnershipTransferred(_owner, address(0));\r\n _owner = address(0);\r\n }\r\n\r\n /**\r\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n * Can only be called by the current owner.\r\n */\r\n function transferOwnership(address newOwner) public onlyOwner {\r\n _transferOwnership(newOwner);\r\n }\r\n\r\n /**\r\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n */\r\n function _transferOwnership(address newOwner) internal {\r\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\r\n emit OwnershipTransferred(_owner, newOwner);\r\n _owner = newOwner;\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../Initializable.sol\";\r\n\r\nimport \"../../GSN/Context.sol\";\r\n\r\n/**\r\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\r\n */\r\ncontract UpgradableSecondary is Initializable, Context {\r\n address private _primary;\r\n\r\n /**\r\n * @dev Emitted when the primary contract changes.\r\n */\r\n event PrimaryTransferred(\r\n address recipient\r\n );\r\n\r\n /**\r\n * @dev Sets the primary account to the one that is creating the Secondary contract.\r\n */\r\n function __Secondary_init(address sender) public initializer {\r\n _primary = sender;\r\n emit PrimaryTransferred(_primary);\r\n }\r\n\r\n /**\r\n * @dev Reverts if called from any account other than the primary.\r\n */\r\n modifier onlyPrimary() {\r\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\r\n _;\r\n }\r\n\r\n /**\r\n * @return the address of the primary.\r\n */\r\n function primary() public view returns (address) {\r\n return _primary;\r\n }\r\n\r\n /**\r\n * @dev Transfers contract to a new primary.\r\n * @param recipient The address of new primary.\r\n */\r\n function transferPrimary(address recipient) public onlyPrimary {\r\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\r\n _primary = recipient;\r\n emit PrimaryTransferred(recipient);\r\n }\r\n\r\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\ninterface IAllowTokens {\r\n\r\n struct Limits {\r\n uint256 min;\r\n uint256 max;\r\n uint256 daily;\r\n uint256 mediumAmount;\r\n uint256 largeAmount;\r\n }\r\n\r\n struct TokenInfo {\r\n bool allowed;\r\n uint256 typeId;\r\n uint256 spentToday;\r\n uint256 lastDay;\r\n }\r\n\r\n struct TypeInfo {\r\n string description;\r\n Limits limits;\r\n }\r\n\r\n struct TokensAndType {\r\n address token;\r\n uint256 typeId;\r\n }\r\n\r\n function version() external pure returns (string memory);\r\n\r\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\r\n\r\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\r\n\r\n function getTypesLimits() external view returns(Limits[] memory limits);\r\n\r\n function getTypeDescriptionsLength() external view returns(uint256);\r\n\r\n function getTypeDescriptions() external view returns(string[] memory descriptions);\r\n\r\n function setToken(address token, uint256 typeId) external;\r\n\r\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\r\n\r\n function isTokenAllowed(address token) external view returns (bool);\r\n\r\n function updateTokenTransfer(address token, uint256 amount) external;\r\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/*\r\n * @dev Provides information about the current execution context, including the\r\n * sender of the transaction and its data. While these are generally available\r\n * via msg.sender and msg.data, they should not be accessed in such a direct\r\n * manner, since when dealing with GSN meta-transactions the account sending and\r\n * paying for execution may not be the actual sender (as far as an application\r\n * is concerned).\r\n *\r\n * This contract is only required for intermediate, library-like contracts.\r\n */\r\nabstract contract Context {\r\n\r\n function _msgSender() internal view returns (address payable) {\r\n return msg.sender;\r\n }\r\n\r\n function _msgData() internal view returns (bytes memory) {\r\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\r\n return msg.data;\r\n }\r\n}\r\n"
+ },
+ "contracts/nftbridge/NFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n// Import base Initializable contract\r\nimport \"../zeppelin/upgradable/Initializable.sol\";\r\n// Import interface and library from OpenZeppelin contracts\r\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\r\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\r\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\r\n\r\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\r\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\r\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\r\nimport \"../zeppelin/token/ERC721/IERC721.sol\";\r\nimport \"../zeppelin/token/ERC721/IERC721Metadata.sol\";\r\nimport \"../zeppelin/token/ERC721/IERC721Enumerable.sol\";\r\nimport \"../zeppelin/token/ERC721/IERC721Receiver.sol\";\r\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\r\nimport \"../zeppelin/utils/Address.sol\";\r\nimport \"../zeppelin/math/SafeMath.sol\";\r\n\r\nimport \"../lib/LibEIP712.sol\";\r\nimport \"../lib/LibUtils.sol\";\r\n\r\nimport \"./INFTBridge.sol\";\r\nimport \"./ISideNFTToken.sol\";\r\nimport \"./ISideNFTTokenFactory.sol\";\r\nimport \"../interface/IAllowTokens.sol\";\r\nimport \"../interface/IWrapped.sol\";\r\n\r\n// solhint-disable-next-line max-states-count\r\ncontract NFTBridge is\r\n Initializable,\r\n INFTBridge,\r\n UpgradablePausable,\r\n UpgradableOwnable,\r\n ReentrancyGuard,\r\n IERC721Receiver {\r\n using SafeMath for uint256;\r\n using SafeERC20 for IERC20;\r\n using Address for address;\r\n\r\n address internal constant NULL_ADDRESS = address(0);\r\n bytes32 internal constant NULL_HASH = bytes32(0);\r\n IERC1820Registry internal constant ERC1820 =\r\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\r\n\r\n address payable internal federation;\r\n uint256 internal fixedFee;\r\n string public symbolPrefix;\r\n\r\n mapping(address => address) public sideTokenAddressByOriginalTokenAddress;\r\n mapping(address => address) public originalTokenAddressBySideTokenAddress;\r\n mapping(address => bool) public isAddressFromCrossedOriginalToken; // address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\r\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\r\n IAllowTokens public allowTokens;\r\n ISideNFTTokenFactory public sideTokenFactory;\r\n bool public isUpgrading;\r\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\r\n\r\n event AllowTokensChanged(address _newAllowTokens);\r\n event FederationChanged(address _newFederation);\r\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\r\n event Upgrading(bool _isUpgrading);\r\n\r\n function initialize(\r\n address _manager,\r\n address payable _federation,\r\n address _allowTokens,\r\n address _sideTokenFactory,\r\n string memory _symbolPrefix\r\n ) public initializer {\r\n UpgradableOwnable.initialize(_manager);\r\n UpgradablePausable.__Pausable_init(_manager);\r\n symbolPrefix = _symbolPrefix;\r\n allowTokens = IAllowTokens(_allowTokens);\r\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\r\n federation = _federation;\r\n ERC1820.setInterfaceImplementer(\r\n address(this),\r\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\r\n address(this)\r\n );\r\n }\r\n\r\n function version() external pure override returns (string memory) {\r\n return \"v1\";\r\n }\r\n\r\n modifier whenNotUpgrading() {\r\n require(!isUpgrading, \"Bridge: Upgrading\");\r\n _;\r\n }\r\n\r\n function acceptTransfer(\r\n address _tokenAddress,\r\n address payable _from,\r\n address payable _to,\r\n uint256 _tokenId,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n ) external whenNotPaused nonReentrant override {\r\n require(_msgSender() == federation, \"NFTBridge: Not Federation\");\r\n require(\r\n isAddressFromCrossedOriginalToken[_tokenAddress] ||\r\n sideTokenAddressByOriginalTokenAddress[_tokenAddress] != NULL_ADDRESS,\r\n \"NFTBridge: Unknown token\"\r\n );\r\n require(_to != NULL_ADDRESS, \"NFTBridge: Null To\");\r\n require(_from != NULL_ADDRESS, \"NFTBridge: Null From\");\r\n require(_blockHash != NULL_HASH, \"NFTBridge: Null BlockHash\");\r\n require(_transactionHash != NULL_HASH, \"NFTBridge: Null TxHash\");\r\n require(\r\n transactionDataHashes[_transactionHash] == bytes32(0),\r\n \"NFTBridge: Already accepted\"\r\n );\r\n\r\n bytes32 _transactionDataHash = getTransactionDataHash(\r\n _to,\r\n _from,\r\n _tokenId,\r\n _tokenAddress,\r\n _blockHash,\r\n _transactionHash,\r\n _logIndex\r\n );\r\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\r\n require(!claimed[_transactionDataHash], \"NFTBridge: Already claimed\");\r\n\r\n transactionDataHashes[_transactionHash] = _transactionDataHash;\r\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\r\n// senderAddresses[_transactionHash] = _from;\r\n\r\n emit AcceptedNFTCrossTransfer(\r\n _transactionHash,\r\n _tokenAddress,\r\n _to,\r\n _from,\r\n _tokenId,\r\n _blockHash,\r\n _logIndex\r\n );\r\n }\r\n\r\n function createSideNFTToken(\r\n address _originalTokenAddress,\r\n string calldata _originalTokenSymbol,\r\n string calldata _originalTokenName,\r\n string calldata _baseURI,\r\n string calldata _contractURI\r\n ) external onlyOwner {\r\n require(_originalTokenAddress != NULL_ADDRESS, \"NFTBridge: Null original token address\");\r\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[_originalTokenAddress];\r\n require(sideTokenAddress == NULL_ADDRESS, \"NFTBridge: Side token already exists\");\r\n string memory sideTokenSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\r\n\r\n // Create side token\r\n sideTokenAddress = sideTokenFactory.createSideNFTToken(_originalTokenName, sideTokenSymbol, _baseURI, _contractURI);\r\n\r\n sideTokenAddressByOriginalTokenAddress[_originalTokenAddress] = sideTokenAddress;\r\n originalTokenAddressBySideTokenAddress[sideTokenAddress] = _originalTokenAddress;\r\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, sideTokenSymbol);\r\n }\r\n\r\n function claim(NFTClaimData calldata _claimData) external override {\r\n _claim(_claimData, _claimData.to);\r\n }\r\n\r\n function claimFallback(NFTClaimData calldata _claimData) external override {\r\n require(_msgSender() == _claimData.from, \"NFTBridge: invalid sender\");\r\n _claim(_claimData, _msgSender());\r\n }\r\n\r\n function _claim(\r\n NFTClaimData calldata _claimData,\r\n address payable _receiver\r\n ) internal {\r\n address tokenAddress = _claimData.tokenAddress;\r\n uint256 tokenId = _claimData.tokenId;\r\n\r\n bytes32 transactionDataHash = getTransactionDataHash(\r\n _claimData.to,\r\n _claimData.from,\r\n tokenId,\r\n tokenAddress,\r\n _claimData.blockHash,\r\n _claimData.transactionHash,\r\n _claimData.logIndex\r\n );\r\n require(\r\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\r\n \"NFTBridge: Wrong txDataHash\"\r\n );\r\n require(!claimed[transactionDataHash], \"NFTBridge: Already claimed\");\r\n\r\n claimed[transactionDataHash] = true;\r\n bool isClaimBeingRequestedInMainChain = isAddressFromCrossedOriginalToken[tokenAddress];\r\n if (isClaimBeingRequestedInMainChain) {\r\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\r\n } else {\r\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[tokenAddress];\r\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\r\n }\r\n\r\n emit ClaimedNFTToken(\r\n _claimData.transactionHash,\r\n tokenAddress,\r\n _claimData.to,\r\n _claimData.from,\r\n _claimData.tokenId,\r\n _claimData.blockHash,\r\n _claimData.logIndex,\r\n _receiver\r\n );\r\n }\r\n\r\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\r\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\"creator()\"));\r\n if (success) {\r\n return abi.decode(data, (address));\r\n }\r\n\r\n return IERC721(tokenAddress).ownerOf(tokenId);\r\n }\r\n\r\n /**\r\n * ERC-20 tokens approve and transferFrom pattern\r\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\r\n */\r\n function receiveTokensTo(\r\n address tokenAddress,\r\n address to,\r\n uint256 tokenId\r\n ) public payable override {\r\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\r\n\r\n address payable sender = _msgSender();\r\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\r\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\r\n\r\n crossTokens(tokenAddress, to, tokenCreator, \"\", tokenId);\r\n\r\n if (fixedFee > 0) {\r\n require(msg.value >= fixedFee, \"NFTBridge: value is smaller than fixed fee\");\r\n\r\n // Send the payment to the MultiSig of the Federation\r\n federation.transfer(fixedFee);\r\n if (msg.value > fixedFee) { // refund of unused value\r\n sender.transfer(msg.value.sub(fixedFee));\r\n }\r\n }\r\n }\r\n\r\n function crossTokens(\r\n address tokenAddress,\r\n address to,\r\n address tokenCreator,\r\n bytes memory userData,\r\n uint256 tokenId\r\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\r\n isAddressFromCrossedOriginalToken[tokenAddress] = true;\r\n\r\n IERC721Enumerable enumerable = IERC721Enumerable(tokenAddress);\r\n IERC721Metadata metadataIERC = IERC721Metadata(tokenAddress);\r\n string memory tokenURI = metadataIERC.tokenURI(tokenId);\r\n\r\n address originalTokenAddress = tokenAddress;\r\n if (originalTokenAddressBySideTokenAddress[tokenAddress] != NULL_ADDRESS) {\r\n originalTokenAddress = originalTokenAddressBySideTokenAddress[tokenAddress];\r\n ERC721Burnable(tokenAddress).burn(tokenId);\r\n }\r\n\r\n emit Cross(\r\n originalTokenAddress,\r\n _msgSender(),\r\n to,\r\n tokenCreator,\r\n userData,\r\n enumerable.totalSupply(),\r\n tokenId,\r\n tokenURI\r\n );\r\n }\r\n\r\n function getTransactionDataHash(\r\n address _to,\r\n address _from,\r\n uint256 _tokenId,\r\n address _tokenAddress,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n ) public pure override returns (bytes32) {\r\n return keccak256(\r\n abi.encodePacked(\r\n _blockHash,\r\n _transactionHash,\r\n _to,\r\n _from,\r\n _tokenId,\r\n _tokenAddress,\r\n _logIndex\r\n )\r\n );\r\n }\r\n\r\n function setFixedFee(uint256 amount) external onlyOwner {\r\n fixedFee = amount;\r\n emit FixedFeeNFTChanged(fixedFee);\r\n }\r\n\r\n function getFixedFee() external view override returns (uint256) {\r\n return fixedFee;\r\n }\r\n\r\n function changeFederation(address payable newFederation) external onlyOwner {\r\n require(newFederation != NULL_ADDRESS, \"NFTBridge: Federation is empty\");\r\n federation = newFederation;\r\n emit FederationChanged(federation);\r\n }\r\n\r\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\r\n require(newAllowTokens != NULL_ADDRESS, \"NFTBridge: AllowTokens is empty\");\r\n allowTokens = IAllowTokens(newAllowTokens);\r\n emit AllowTokensChanged(newAllowTokens);\r\n }\r\n\r\n function getFederation() external view returns (address) {\r\n return federation;\r\n }\r\n\r\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\r\n require(\r\n newSideNFTTokenFactory != NULL_ADDRESS,\r\n \"NFTBridge: empty SideTokenFactory\"\r\n );\r\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\r\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\r\n }\r\n\r\n function setUpgrading(bool _isUpgrading) external onlyOwner {\r\n isUpgrading = _isUpgrading;\r\n emit Upgrading(isUpgrading);\r\n }\r\n\r\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\r\n return transactionDataHashes[transactionHash] != bytes32(0);\r\n }\r\n\r\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\r\n return claimed[transactionDataHashes[transactionHash]];\r\n }\r\n\r\n /**\r\n * Always returns `IERC721Receiver.onERC721Received.selector`.\r\n */\r\n function onERC721Received(\r\n address,\r\n address,\r\n uint256,\r\n bytes memory\r\n ) public virtual override returns (bytes4) {\r\n return this.onERC721Received.selector;\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../Initializable.sol\";\r\n\r\n/**\r\n * @title Helps contracts guard against reentrancy attacks.\r\n * @author Remco Bloemen , Eenae \r\n * @dev If you mark a function `nonReentrant`, you should also\r\n * mark it `external`.\r\n */\r\ncontract ReentrancyGuard is Initializable {\r\n /// @dev counter to allow mutex lock with only one SSTORE operation\r\n uint256 private _guardCounter;\r\n\r\n function initialize() public initializer {\r\n // The counter starts at one to prevent changing it from zero to a non-zero\r\n // value, which is a more expensive operation.\r\n _guardCounter = 1;\r\n }\r\n\r\n /**\r\n * @dev Prevents a contract from calling itself, directly or indirectly.\r\n * Calling a `nonReentrant` function from another `nonReentrant`\r\n * function is not supported. It is possible to prevent this from happening\r\n * by making the `nonReentrant` function external, and make it call a\r\n * `private` function that does the actual work.\r\n */\r\n modifier nonReentrant() {\r\n _guardCounter += 1;\r\n uint256 localCounter = _guardCounter;\r\n _;\r\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\r\n }\r\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../Initializable.sol\";\r\n\r\nimport \"../../GSN/Context.sol\";\r\nimport \"../access/roles/UpgradablePauserRole.sol\";\r\n\r\n/**\r\n * @dev Contract module which allows children to implement an emergency stop\r\n * mechanism that can be triggered by an authorized account.\r\n *\r\n * This module is used through inheritance. It will make available the\r\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\r\n * the functions of your contract. Note that they will not be pausable by\r\n * simply including this module, only once the modifiers are put in place.\r\n */\r\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\r\n /**\r\n * @dev Emitted when the pause is triggered by a pauser (`account`).\r\n */\r\n event Paused(address account);\r\n\r\n /**\r\n * @dev Emitted when the pause is lifted by a pauser (`account`).\r\n */\r\n event Unpaused(address account);\r\n\r\n bool private _paused;\r\n\r\n /**\r\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\r\n * to the deployer.\r\n */\r\n function __Pausable_init(address sender) public initializer {\r\n UpgradablePauserRole.__PauserRol_init(sender);\r\n\r\n _paused = false;\r\n }\r\n\r\n /**\r\n * @dev Returns true if the contract is paused, and false otherwise.\r\n */\r\n function paused() public view returns (bool) {\r\n return _paused;\r\n }\r\n\r\n /**\r\n * @dev Modifier to make a function callable only when the contract is not paused.\r\n */\r\n modifier whenNotPaused() {\r\n require(!_paused, \"Pausable: paused\");\r\n _;\r\n }\r\n\r\n /**\r\n * @dev Modifier to make a function callable only when the contract is paused.\r\n */\r\n modifier whenPaused() {\r\n require(_paused, \"Pausable: not paused\");\r\n _;\r\n }\r\n\r\n /**\r\n * @dev Called by a pauser to pause, triggers stopped state.\r\n */\r\n function pause() public onlyPauser whenNotPaused {\r\n _paused = true;\r\n emit Paused(_msgSender());\r\n }\r\n\r\n /**\r\n * @dev Called by a pauser to unpause, returns to normal state.\r\n */\r\n function unpause() public onlyPauser whenPaused {\r\n _paused = false;\r\n emit Unpaused(_msgSender());\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev Interface of the global ERC1820 Registry, as defined in the\r\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\r\n * implementers for interfaces in this registry, as well as query support.\r\n *\r\n * Implementers may be shared by multiple accounts, and can also implement more\r\n * than a single interface for each account. Contracts can implement interfaces\r\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\r\n * contract.\r\n *\r\n * {IERC165} interfaces can also be queried via the registry.\r\n *\r\n * For an in-depth explanation and source code analysis, see the EIP text.\r\n */\r\ninterface IERC1820Registry {\r\n /**\r\n * @dev Sets `newManager` as the manager for `account`. A manager of an\r\n * account is able to set interface implementers for it.\r\n *\r\n * By default, each account is its own manager. Passing a value of `0x0` in\r\n * `newManager` will reset the manager to this initial state.\r\n *\r\n * Emits a {ManagerChanged} event.\r\n *\r\n * Requirements:\r\n *\r\n * - the caller must be the current manager for `account`.\r\n */\r\n function setManager(address account, address newManager) external;\r\n\r\n /**\r\n * @dev Returns the manager for `account`.\r\n *\r\n * See {setManager}.\r\n */\r\n function getManager(address account) external view returns (address);\r\n\r\n /**\r\n * @dev Sets the `implementer` contract as `account`'s implementer for\r\n * `interfaceHash`.\r\n *\r\n * `account` being the zero address is an alias for the caller's address.\r\n * The zero address can also be used in `implementer` to remove an old one.\r\n *\r\n * See {interfaceHash} to learn how these are created.\r\n *\r\n * Emits an {InterfaceImplementerSet} event.\r\n *\r\n * Requirements:\r\n *\r\n * - the caller must be the current manager for `_account`.\r\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\r\n * end in 28 zeroes).\r\n * - `_implementer` must implement {IERC1820Implementer} and return true when\r\n * queried for support, unless `implementer` is the caller. See\r\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\r\n */\r\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\r\n\r\n /**\r\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\r\n * implementer is registered, returns the zero address.\r\n *\r\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\r\n * zeroes), `_account` will be queried for support of it.\r\n *\r\n * `account` being the zero address is an alias for the caller's address.\r\n */\r\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\r\n\r\n /**\r\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\r\n * corresponding\r\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\r\n */\r\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\r\n\r\n /**\r\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\r\n * @param account Address of the contract for which to update the cache.\r\n * @param interfaceId ERC165 interface for which to update the cache.\r\n */\r\n function updateERC165Cache(address account, bytes4 interfaceId) external;\r\n\r\n /**\r\n * @notice Checks whether a contract implements an ERC165 interface or not.\r\n * If the result is not cached a direct lookup on the contract address is performed.\r\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\r\n * {updateERC165Cache} with the contract address.\r\n * @param account Address of the contract to check.\r\n * @param interfaceId ERC165 interface to check.\r\n * @return True if `account` implements `interfaceId`, false otherwise.\r\n */\r\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\r\n\r\n /**\r\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\r\n * @param account Address of the contract to check.\r\n * @param interfaceId ERC165 interface to check.\r\n * @return True if `account` implements `interfaceId`, false otherwise.\r\n */\r\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\r\n\r\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\r\n\r\n event ManagerChanged(address indexed account, address indexed newManager);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\r\n * the optional functions; to access them see {ERC20Detailed}.\r\n */\r\ninterface IERC20 {\r\n /**\r\n * @dev Returns the amount of tokens in existence.\r\n */\r\n function totalSupply() external view returns (uint256);\r\n\r\n /**\r\n * @dev Returns the amount of tokens owned by `account`.\r\n */\r\n function balanceOf(address account) external view returns (uint256);\r\n\r\n /**\r\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\r\n *\r\n * Returns a boolean value indicating whether the operation succeeded.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function transfer(address recipient, uint256 amount) external returns (bool);\r\n\r\n /**\r\n * @dev Returns the remaining number of tokens that `spender` will be\r\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\r\n * zero by default.\r\n *\r\n * This value changes when {approve} or {transferFrom} are called.\r\n */\r\n function allowance(address owner, address spender) external view returns (uint256);\r\n\r\n /**\r\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\r\n *\r\n * Returns a boolean value indicating whether the operation succeeded.\r\n *\r\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\r\n * that someone may use both the old and the new allowance by unfortunate\r\n * transaction ordering. One possible solution to mitigate this race\r\n * condition is to first reduce the spender's allowance to 0 and set the\r\n * desired value afterwards:\r\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\r\n *\r\n * Emits an {Approval} event.\r\n */\r\n function approve(address spender, uint256 amount) external returns (bool);\r\n\r\n /**\r\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\r\n * allowance mechanism. `amount` is then deducted from the caller's\r\n * allowance.\r\n *\r\n * Returns a boolean value indicating whether the operation succeeded.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\r\n\r\n /**\r\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\r\n * another (`to`).\r\n *\r\n * Note that `value` may be zero.\r\n */\r\n event Transfer(address indexed from, address indexed to, uint256 value);\r\n\r\n /**\r\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\r\n * a call to {approve}. `value` is the new allowance.\r\n */\r\n event Approval(address indexed owner, address indexed spender, uint256 value);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"./IERC20.sol\";\r\nimport \"../../math/SafeMath.sol\";\r\nimport \"../../utils/Address.sol\";\r\n\r\n/**\r\n * @title SafeERC20\r\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\r\n * contract returns false). Tokens that return no value (and instead revert or\r\n * throw on failure) are also supported, non-reverting calls are assumed to be\r\n * successful.\r\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\r\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\r\n */\r\nlibrary SafeERC20 {\r\n using SafeMath for uint256;\r\n using Address for address;\r\n\r\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\r\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\r\n }\r\n\r\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\r\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\r\n }\r\n\r\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\r\n // safeApprove should only be called when setting an initial allowance,\r\n // or when resetting it to zero. To increase and decrease it, use\r\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\r\n // solhint-disable-next-line max-line-length\r\n require((value == 0) || (token.allowance(address(this), spender) == 0),\r\n \"SafeERC20: approve non-zero to non-zero allowance\"\r\n );\r\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\r\n }\r\n\r\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\r\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\r\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\r\n }\r\n\r\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\r\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\r\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\r\n }\r\n\r\n /**\r\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\r\n * on the return value: the return value is optional (but if data is returned, it must not be false).\r\n * @param token The token targeted by the call.\r\n * @param data The call data (encoded using abi.encode or one of its variants).\r\n */\r\n function callOptionalReturn(IERC20 token, bytes memory data) private {\r\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\r\n // we're implementing it ourselves.\r\n\r\n // A Solidity high level call has three parts:\r\n // 1. The target address is checked to verify it contains contract code\r\n // 2. The call itself is made, and success asserted\r\n // 3. The return value is decoded, which in turn checks the size of the returned data.\r\n // solhint-disable-next-line max-line-length\r\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\r\n\r\n // solhint-disable-next-line avoid-low-level-calls\r\n (bool success, bytes memory returndata) = address(token).call(data);\r\n require(success, \"SafeERC20: low-level call failed\");\r\n\r\n if (returndata.length > 0) { // Return data is optional\r\n // solhint-disable-next-line max-line-length\r\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\r\n }\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../../introspection/IERC165.sol\";\r\n\r\n/**\r\n * @dev Required interface of an ERC721 compliant contract.\r\n */\r\ninterface IERC721 is IERC165 {\r\n /**\r\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\r\n */\r\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\r\n\r\n /**\r\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\r\n */\r\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\r\n\r\n /**\r\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\r\n */\r\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\r\n\r\n /**\r\n * @dev Returns the number of tokens in ``owner``'s account.\r\n */\r\n function balanceOf(address owner) external view returns (uint256 balance);\r\n\r\n /**\r\n * @dev Returns the owner of the `tokenId` token.\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must exist.\r\n */\r\n function ownerOf(uint256 tokenId) external view returns (address owner);\r\n\r\n /**\r\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\r\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must exist and be owned by `from`.\r\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\r\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\r\n\r\n /**\r\n * @dev Transfers `tokenId` token from `from` to `to`.\r\n *\r\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must be owned by `from`.\r\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function transferFrom(address from, address to, uint256 tokenId) external;\r\n\r\n /**\r\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\r\n * The approval is cleared when the token is transferred.\r\n *\r\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\r\n *\r\n * Requirements:\r\n *\r\n * - The caller must own the token or be an approved operator.\r\n * - `tokenId` must exist.\r\n *\r\n * Emits an {Approval} event.\r\n */\r\n function approve(address to, uint256 tokenId) external;\r\n\r\n /**\r\n * @dev Returns the account approved for `tokenId` token.\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must exist.\r\n */\r\n function getApproved(uint256 tokenId) external view returns (address operator);\r\n\r\n /**\r\n * @dev Approve or remove `operator` as an operator for the caller.\r\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\r\n *\r\n * Requirements:\r\n *\r\n * - The `operator` cannot be the caller.\r\n *\r\n * Emits an {ApprovalForAll} event.\r\n */\r\n function setApprovalForAll(address operator, bool _approved) external;\r\n\r\n /**\r\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\r\n *\r\n * See {setApprovalForAll}\r\n */\r\n function isApprovedForAll(address owner, address operator) external view returns (bool);\r\n\r\n /**\r\n * @dev Safely transfers `tokenId` token from `from` to `to`.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must exist and be owned by `from`.\r\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\r\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./IERC721.sol\";\r\n\r\n/**\r\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\r\n * @dev See https://eips.ethereum.org/EIPS/eip-721\r\n */\r\ninterface IERC721Metadata is IERC721 {\r\n\r\n /**\r\n * @dev Returns the token collection name.\r\n */\r\n function name() external view returns (string memory);\r\n\r\n /**\r\n * @dev Returns the token collection symbol.\r\n */\r\n function symbol() external view returns (string memory);\r\n\r\n /**\r\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\r\n */\r\n function tokenURI(uint256 tokenId) external view returns (string memory);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./IERC721.sol\";\r\n\r\n/**\r\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\r\n * @dev See https://eips.ethereum.org/EIPS/eip-721\r\n */\r\ninterface IERC721Enumerable is IERC721 {\r\n\r\n /**\r\n * @dev Returns the total amount of tokens stored by the contract.\r\n */\r\n function totalSupply() external view returns (uint256);\r\n\r\n /**\r\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\r\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\r\n */\r\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\r\n\r\n /**\r\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\r\n * Use along with {totalSupply} to enumerate all tokens.\r\n */\r\n function tokenByIndex(uint256 index) external view returns (uint256);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\n/**\r\n * @title ERC721 token receiver interface\r\n * @dev Interface for any contract that wants to support safeTransfers\r\n * from ERC721 asset contracts.\r\n */\r\ninterface IERC721Receiver {\r\n /**\r\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\r\n * by `operator` from `from`, this function is called.\r\n *\r\n * It must return its Solidity selector to confirm the token transfer.\r\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\r\n *\r\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\r\n */\r\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../../GSN/Context.sol\";\r\nimport \"./ERC721.sol\";\r\n\r\n/**\r\n * @title ERC721 Burnable Token\r\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\r\n */\r\nabstract contract ERC721Burnable is Context, ERC721 {\r\n /**\r\n * @dev Burns `tokenId`. See {ERC721-_burn}.\r\n *\r\n * Requirements:\r\n *\r\n * - The caller must own `tokenId` or be an approved operator.\r\n */\r\n function burn(uint256 tokenId) public virtual {\r\n //solhint-disable-next-line max-line-length\r\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\r\n _burn(tokenId);\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev Collection of functions related to the address type\r\n */\r\nlibrary Address {\r\n /**\r\n * @dev Returns true if `account` is a contract.\r\n *\r\n * [IMPORTANT]\r\n * ====\r\n * It is unsafe to assume that an address for which this function returns\r\n * false is an externally-owned account (EOA) and not a contract.\r\n *\r\n * Among others, `isContract` will return false for the following\r\n * types of addresses:\r\n *\r\n * - an externally-owned account\r\n * - a contract in construction\r\n * - an address where a contract will be created\r\n * - an address where a contract lived, but was destroyed\r\n * ====\r\n */\r\n function isContract(address account) internal view returns (bool) {\r\n // This method relies on extcodesize, which returns 0 for contracts in\r\n // construction, since the code is only stored at the end of the\r\n // constructor execution.\r\n\r\n uint256 size;\r\n // solhint-disable-next-line no-inline-assembly\r\n assembly { size := extcodesize(account) }\r\n return size > 0;\r\n }\r\n\r\n /**\r\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\r\n * `recipient`, forwarding all available gas and reverting on errors.\r\n *\r\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\r\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\r\n * imposed by `transfer`, making them unable to receive funds via\r\n * `transfer`. {sendValue} removes this limitation.\r\n *\r\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\r\n *\r\n * IMPORTANT: because control is transferred to `recipient`, care must be\r\n * taken to not create reentrancy vulnerabilities. Consider using\r\n * {ReentrancyGuard} or the\r\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\r\n */\r\n function sendValue(address payable recipient, uint256 amount) internal {\r\n require(address(this).balance >= amount, \"Address: insufficient balance\");\r\n\r\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\r\n (bool success, ) = recipient.call{ value: amount }(\"\");\r\n require(success, \"Address: unable to send value, recipient may have reverted\");\r\n }\r\n\r\n /**\r\n * @dev Performs a Solidity function call using a low level `call`. A\r\n * plain`call` is an unsafe replacement for a function call: use this\r\n * function instead.\r\n *\r\n * If `target` reverts with a revert reason, it is bubbled up by this\r\n * function (like regular Solidity function calls).\r\n *\r\n * Returns the raw returned data. To convert to the expected return value,\r\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\r\n *\r\n * Requirements:\r\n *\r\n * - `target` must be a contract.\r\n * - calling `target` with `data` must not revert.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\r\n return functionCall(target, data, \"Address: low-level call failed\");\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\r\n * `errorMessage` as a fallback revert reason when `target` reverts.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\r\n return functionCallWithValue(target, data, 0, errorMessage);\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\r\n * but also transferring `value` wei to `target`.\r\n *\r\n * Requirements:\r\n *\r\n * - the calling contract must have an ETH balance of at least `value`.\r\n * - the called Solidity function must be `payable`.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\r\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\r\n * with `errorMessage` as a fallback revert reason when `target` reverts.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\r\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\r\n require(isContract(target), \"Address: call to non-contract\");\r\n\r\n // solhint-disable-next-line avoid-low-level-calls\r\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\r\n return _verifyCallResult(success, returndata, errorMessage);\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\r\n * but performing a static call.\r\n *\r\n * _Available since v3.3._\r\n */\r\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\r\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\r\n * but performing a static call.\r\n *\r\n * _Available since v3.3._\r\n */\r\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\r\n require(isContract(target), \"Address: static call to non-contract\");\r\n\r\n // solhint-disable-next-line avoid-low-level-calls\r\n (bool success, bytes memory returndata) = target.staticcall(data);\r\n return _verifyCallResult(success, returndata, errorMessage);\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\r\n * but performing a delegate call.\r\n *\r\n * _Available since v3.4._\r\n */\r\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\r\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\r\n * but performing a delegate call.\r\n *\r\n * _Available since v3.4._\r\n */\r\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\r\n require(isContract(target), \"Address: delegate call to non-contract\");\r\n\r\n // solhint-disable-next-line avoid-low-level-calls\r\n (bool success, bytes memory returndata) = target.delegatecall(data);\r\n return _verifyCallResult(success, returndata, errorMessage);\r\n }\r\n\r\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\r\n if (success) {\r\n return returndata;\r\n } else {\r\n // Look for revert reason and bubble it up if present\r\n if (returndata.length > 0) {\r\n // The easiest way to bubble the revert reason is using memory via assembly\r\n\r\n // solhint-disable-next-line no-inline-assembly\r\n assembly {\r\n let returndata_size := mload(returndata)\r\n revert(add(32, returndata), returndata_size)\r\n }\r\n } else {\r\n revert(errorMessage);\r\n }\r\n }\r\n }\r\n}\r\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\r\nlibrary LibEIP712 {\r\n\r\n // Hash of the EIP712 Domain Separator Schema\r\n // keccak256(abi.encodePacked(\r\n // \"EIP712Domain(\",\r\n // \"string name,\",\r\n // \"string version,\",\r\n // \"uint256 chainId,\",\r\n // \"address verifyingContract\",\r\n // \")\"\r\n // ))\r\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\r\n\r\n /// @dev Calculates a EIP712 domain separator.\r\n /// @param name The EIP712 domain name.\r\n /// @param version The EIP712 domain version.\r\n /// @param verifyingContract The EIP712 verifying contract.\r\n /// @return result EIP712 domain separator.\r\n function hashEIP712Domain(\r\n string memory name,\r\n string memory version,\r\n uint256 chainId,\r\n address verifyingContract\r\n )\r\n internal\r\n pure\r\n returns (bytes32 result)\r\n {\r\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\r\n\r\n // Assembly for more efficient computing:\r\n // keccak256(abi.encodePacked(\r\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\r\n // keccak256(bytes(name)),\r\n // keccak256(bytes(version)),\r\n // chainId,\r\n // uint256(verifyingContract)\r\n // ))\r\n\r\n // solium-disable-next-line security/no-inline-assembly\r\n assembly {\r\n // Calculate hashes of dynamic data\r\n let nameHash := keccak256(add(name, 32), mload(name))\r\n let versionHash := keccak256(add(version, 32), mload(version))\r\n\r\n // Load free memory pointer\r\n let memPtr := mload(64)\r\n\r\n // Store params in memory\r\n mstore(memPtr, schemaHash)\r\n mstore(add(memPtr, 32), nameHash)\r\n mstore(add(memPtr, 64), versionHash)\r\n mstore(add(memPtr, 96), chainId)\r\n mstore(add(memPtr, 128), verifyingContract)\r\n\r\n // Compute hash\r\n result := keccak256(memPtr, 160)\r\n }\r\n return result;\r\n }\r\n\r\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\r\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\r\n /// with getDomainHash().\r\n /// @param hashStruct The EIP712 hash struct.\r\n /// @return result EIP712 hash applied to the given EIP712 Domain.\r\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\r\n internal\r\n pure\r\n returns (bytes32 result)\r\n {\r\n // Assembly for more efficient computing:\r\n // keccak256(abi.encodePacked(\r\n // EIP191_HEADER,\r\n // EIP712_DOMAIN_HASH,\r\n // hashStruct\r\n // ));\r\n\r\n // solium-disable-next-line security/no-inline-assembly\r\n assembly {\r\n // Load free memory pointer\r\n let memPtr := mload(64)\r\n\r\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\r\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\r\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\r\n\r\n // Compute hash\r\n result := keccak256(memPtr, 66)\r\n }\r\n return result;\r\n }\r\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nlibrary LibUtils {\r\n\r\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\r\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\r\n return uint256(10)**(18-decimals);\r\n }\r\n\r\n function getDecimals(address tokenToUse) internal view returns (uint8) {\r\n //support decimals as uint256 or uint8\r\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\r\n require(success, \"LibUtils: No decimals\");\r\n // uint: enc(X) is the big-endian encoding of X,\r\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\r\n return uint8(abi.decode(data, (uint256)));\r\n }\r\n\r\n function getGranularity(address tokenToUse) internal view returns (uint256) {\r\n //support granularity if ERC777\r\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\r\n require(success, \"LibUtils: No granularity\");\r\n\r\n return abi.decode(data, (uint256));\r\n }\r\n\r\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\r\n // solium-disable-next-line security/no-inline-assembly\r\n assembly {\r\n addr := mload(add(bys,20))\r\n }\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/nftbridge/INFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\ninterface INFTBridge {\r\n struct NFTClaimData {\r\n address payable to;\r\n address from;\r\n uint256 tokenId;\r\n address tokenAddress;\r\n bytes32 blockHash;\r\n bytes32 transactionHash;\r\n uint32 logIndex;\r\n }\r\n\r\n function version() external pure returns (string memory);\r\n\r\n function getFixedFee() external view returns (uint256);\r\n\r\n function receiveTokensTo(\r\n address tokenAddress,\r\n address to,\r\n uint256 tokenId\r\n ) external payable;\r\n\r\n /**\r\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\r\n */\r\n function acceptTransfer(\r\n address _originalTokenAddress,\r\n address payable _from,\r\n address payable _to,\r\n uint256 _tokenId,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n ) external;\r\n\r\n /**\r\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\r\n */\r\n function claim(NFTClaimData calldata _claimData) external;\r\n\r\n function claimFallback(NFTClaimData calldata _claimData) external;\r\n\r\n function getTransactionDataHash(\r\n address _to,\r\n address _from,\r\n uint256 _tokenId,\r\n address _tokenAddress,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n ) external returns (bytes32);\r\n\r\n event Cross(\r\n address indexed _originalTokenAddress,\r\n address indexed _from,\r\n address indexed _to,\r\n address _tokenCreator,\r\n bytes _userData,\r\n uint256 _totalSupply,\r\n uint256 _tokenId,\r\n string _tokenURI\r\n );\r\n event NewSideNFTToken(\r\n address indexed _newSideNFTTokenAddress,\r\n address indexed _originalTokenAddress,\r\n string _newSymbol\r\n );\r\n event AcceptedNFTCrossTransfer(\r\n bytes32 indexed _transactionHash,\r\n address indexed _originalTokenAddress,\r\n address indexed _to,\r\n address _from,\r\n uint256 _tokenId,\r\n bytes32 _blockHash,\r\n uint256 _logIndex\r\n );\r\n event FixedFeeNFTChanged(uint256 _amount);\r\n event ClaimedNFTToken(\r\n bytes32 indexed _transactionHash,\r\n address indexed _originalTokenAddress,\r\n address indexed _to,\r\n address _sender,\r\n uint256 _tokenId,\r\n bytes32 _blockHash,\r\n uint256 _logIndex,\r\n address _receiver\r\n );\r\n}\r\n"
+ },
+ "contracts/nftbridge/ISideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\ninterface ISideNFTToken {\r\n function mint(address account, uint256 tokenId) external;\r\n}"
+ },
+ "contracts/nftbridge/ISideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\ninterface ISideNFTTokenFactory {\r\n\r\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\r\n string calldata contractURI) external returns(address);\r\n\r\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\r\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\ninterface IWrapped {\r\n function balanceOf(address) external returns(uint);\r\n\r\n function deposit() external payable;\r\n\r\n function withdraw(uint wad) external;\r\n\r\n function totalSupply() external view returns (uint);\r\n\r\n function approve(address guy, uint wad) external returns (bool);\r\n\r\n function transfer(address dst, uint wad) external returns (bool);\r\n\r\n function transferFrom(address src, address dst, uint wad)\r\n external\r\n returns (bool);\r\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../../Initializable.sol\";\r\n\r\nimport \"../../../GSN/Context.sol\";\r\nimport \"../../../access/Roles.sol\";\r\n\r\ncontract UpgradablePauserRole is Initializable, Context {\r\n using Roles for Roles.Role;\r\n\r\n event PauserAdded(address indexed account);\r\n event PauserRemoved(address indexed account);\r\n\r\n Roles.Role private _pausers;\r\n\r\n function __PauserRol_init(address sender) public initializer {\r\n if (!isPauser(sender)) {\r\n _addPauser(sender);\r\n }\r\n }\r\n\r\n modifier onlyPauser() {\r\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\r\n _;\r\n }\r\n\r\n function isPauser(address account) public view returns (bool) {\r\n return _pausers.has(account);\r\n }\r\n\r\n function addPauser(address account) public onlyPauser {\r\n _addPauser(account);\r\n }\r\n\r\n function renouncePauser() public {\r\n _removePauser(_msgSender());\r\n }\r\n\r\n function _addPauser(address account) internal {\r\n _pausers.add(account);\r\n emit PauserAdded(account);\r\n }\r\n\r\n function _removePauser(address account) internal {\r\n _pausers.remove(account);\r\n emit PauserRemoved(account);\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @title Roles\r\n * @dev Library for managing addresses assigned to a Role.\r\n */\r\nlibrary Roles {\r\n struct Role {\r\n mapping (address => bool) bearer;\r\n }\r\n\r\n /**\r\n * @dev Give an account access to this role.\r\n */\r\n function add(Role storage role, address account) internal {\r\n require(!has(role, account), \"Roles: account already has role\");\r\n role.bearer[account] = true;\r\n }\r\n\r\n /**\r\n * @dev Remove an account's access to this role.\r\n */\r\n function remove(Role storage role, address account) internal {\r\n require(has(role, account), \"Roles: account doesn't have role\");\r\n role.bearer[account] = false;\r\n }\r\n\r\n /**\r\n * @dev Check if an account has this role.\r\n * @return bool\r\n */\r\n function has(Role storage role, address account) internal view returns (bool) {\r\n require(account != address(0), \"Roles: account is the zero address\");\r\n return role.bearer[account];\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\n/**\r\n * @dev Interface of the ERC165 standard, as defined in the\r\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\r\n *\r\n * Implementers can declare support of contract interfaces, which can then be\r\n * queried by others ({ERC165Checker}).\r\n *\r\n * For an implementation, see {ERC165}.\r\n */\r\ninterface IERC165 {\r\n /**\r\n * @dev Returns true if this contract implements the interface defined by\r\n * `interfaceId`. See the corresponding\r\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\r\n * to learn more about how these ids are created.\r\n *\r\n * This function call must use less than 30 000 gas.\r\n */\r\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../../GSN/Context.sol\";\r\nimport \"./IERC721.sol\";\r\nimport \"./IERC721Metadata.sol\";\r\nimport \"./IERC721Enumerable.sol\";\r\nimport \"./IERC721Receiver.sol\";\r\nimport \"../../introspection/ERC165.sol\";\r\nimport \"../../math/SafeMath.sol\";\r\nimport \"../../utils/Address.sol\";\r\nimport \"../../utils/EnumerableSet.sol\";\r\nimport \"../../utils/EnumerableMap.sol\";\r\nimport \"../../utils/Strings.sol\";\r\n\r\n/**\r\n * @title ERC721 Non-Fungible Token Standard basic implementation\r\n * @dev see https://eips.ethereum.org/EIPS/eip-721\r\n */\r\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\r\n using SafeMath for uint256;\r\n using Address for address;\r\n using EnumerableSet for EnumerableSet.UintSet;\r\n using EnumerableMap for EnumerableMap.UintToAddressMap;\r\n using Strings for uint256;\r\n\r\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\r\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\r\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\r\n\r\n // Mapping from holder address to their (enumerable) set of owned tokens\r\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\r\n\r\n // Enumerable mapping from token ids to their owners\r\n EnumerableMap.UintToAddressMap private _tokenOwners;\r\n\r\n // Mapping from token ID to approved address\r\n mapping (uint256 => address) private _tokenApprovals;\r\n\r\n // Mapping from owner to operator approvals\r\n mapping (address => mapping (address => bool)) private _operatorApprovals;\r\n\r\n // Token name\r\n string private _name;\r\n\r\n // Token symbol\r\n string private _symbol;\r\n\r\n // Optional mapping for token URIs\r\n mapping (uint256 => string) private _tokenURIs;\r\n\r\n // Base URI\r\n string private _baseURI;\r\n\r\n /*\r\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\r\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\r\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\r\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\r\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\r\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\r\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\r\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\r\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\r\n *\r\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\r\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\r\n */\r\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\r\n\r\n /*\r\n * bytes4(keccak256('name()')) == 0x06fdde03\r\n * bytes4(keccak256('symbol()')) == 0x95d89b41\r\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\r\n *\r\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\r\n */\r\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\r\n\r\n /*\r\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\r\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\r\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\r\n *\r\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\r\n */\r\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\r\n\r\n /**\r\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\r\n */\r\n constructor (string memory name_, string memory symbol_) {\r\n _name = name_;\r\n _symbol = symbol_;\r\n\r\n // register the supported interfaces to conform to ERC721 via ERC165\r\n _registerInterface(_INTERFACE_ID_ERC721);\r\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\r\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-balanceOf}.\r\n */\r\n function balanceOf(address owner) public view virtual override returns (uint256) {\r\n require(owner != address(0), \"ERC721: balance query for the zero address\");\r\n return _holderTokens[owner].length();\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-ownerOf}.\r\n */\r\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\r\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\r\n }\r\n\r\n /**\r\n * @dev See {IERC721Metadata-name}.\r\n */\r\n function name() public view virtual override returns (string memory) {\r\n return _name;\r\n }\r\n\r\n /**\r\n * @dev See {IERC721Metadata-symbol}.\r\n */\r\n function symbol() public view virtual override returns (string memory) {\r\n return _symbol;\r\n }\r\n\r\n /**\r\n * @dev See {IERC721Metadata-tokenURI}.\r\n */\r\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\r\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\r\n\r\n string memory _tokenURI = _tokenURIs[tokenId];\r\n string memory base = baseURI();\r\n\r\n // If there is no base URI, return the token URI.\r\n if (bytes(base).length == 0) {\r\n return _tokenURI;\r\n }\r\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\r\n if (bytes(_tokenURI).length > 0) {\r\n return string(abi.encodePacked(base, _tokenURI));\r\n }\r\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\r\n return string(abi.encodePacked(base, tokenId.toString()));\r\n }\r\n\r\n /**\r\n * @dev Returns the base URI set via {_setBaseURI}. This will be\r\n * automatically added as a prefix in {tokenURI} to each token's URI, or\r\n * to the token ID if no specific URI is set for that token ID.\r\n */\r\n function baseURI() public view virtual returns (string memory) {\r\n return _baseURI;\r\n }\r\n\r\n /**\r\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\r\n */\r\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\r\n return _holderTokens[owner].at(index);\r\n }\r\n\r\n /**\r\n * @dev See {IERC721Enumerable-totalSupply}.\r\n */\r\n function totalSupply() public view virtual override returns (uint256) {\r\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\r\n return _tokenOwners.length();\r\n }\r\n\r\n /**\r\n * @dev See {IERC721Enumerable-tokenByIndex}.\r\n */\r\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\r\n (uint256 tokenId, ) = _tokenOwners.at(index);\r\n return tokenId;\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-approve}.\r\n */\r\n function approve(address to, uint256 tokenId) public virtual override {\r\n address owner = ERC721.ownerOf(tokenId);\r\n require(to != owner, \"ERC721: approval to current owner\");\r\n\r\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\r\n \"ERC721: approve caller is not owner nor approved for all\"\r\n );\r\n\r\n _approve(to, tokenId);\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-getApproved}.\r\n */\r\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\r\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\r\n\r\n return _tokenApprovals[tokenId];\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-setApprovalForAll}.\r\n */\r\n function setApprovalForAll(address operator, bool approved) public virtual override {\r\n require(operator != _msgSender(), \"ERC721: approve to caller\");\r\n\r\n _operatorApprovals[_msgSender()][operator] = approved;\r\n emit ApprovalForAll(_msgSender(), operator, approved);\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-isApprovedForAll}.\r\n */\r\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\r\n return _operatorApprovals[owner][operator];\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-transferFrom}.\r\n */\r\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\r\n //solhint-disable-next-line max-line-length\r\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\r\n\r\n _transfer(from, to, tokenId);\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-safeTransferFrom}.\r\n */\r\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\r\n safeTransferFrom(from, to, tokenId, \"\");\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-safeTransferFrom}.\r\n */\r\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\r\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\r\n _safeTransfer(from, to, tokenId, _data);\r\n }\r\n\r\n /**\r\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\r\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\r\n *\r\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\r\n *\r\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\r\n * implement alternative mechanisms to perform token transfer, such as signature-based.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must exist and be owned by `from`.\r\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\r\n _transfer(from, to, tokenId);\r\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\r\n }\r\n\r\n /**\r\n * @dev Returns whether `tokenId` exists.\r\n *\r\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\r\n *\r\n * Tokens start existing when they are minted (`_mint`),\r\n * and stop existing when they are burned (`_burn`).\r\n */\r\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\r\n return _tokenOwners.contains(tokenId);\r\n }\r\n\r\n /**\r\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must exist.\r\n */\r\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\r\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\r\n address owner = ERC721.ownerOf(tokenId);\r\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\r\n }\r\n\r\n /**\r\n * @dev Safely mints `tokenId` and transfers it to `to`.\r\n *\r\n * Requirements:\r\n d*\r\n * - `tokenId` must not exist.\r\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function _safeMint(address to, uint256 tokenId) internal virtual {\r\n _safeMint(to, tokenId, \"\");\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\r\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\r\n */\r\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\r\n _mint(to, tokenId);\r\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\r\n }\r\n\r\n /**\r\n * @dev Mints `tokenId` and transfers it to `to`.\r\n *\r\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must not exist.\r\n * - `to` cannot be the zero address.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function _mint(address to, uint256 tokenId) internal virtual {\r\n require(to != address(0), \"ERC721: mint to the zero address\");\r\n require(!_exists(tokenId), \"ERC721: token already minted\");\r\n\r\n _beforeTokenTransfer(address(0), to, tokenId);\r\n\r\n _holderTokens[to].add(tokenId);\r\n\r\n _tokenOwners.set(tokenId, to);\r\n\r\n emit Transfer(address(0), to, tokenId);\r\n }\r\n\r\n /**\r\n * @dev Destroys `tokenId`.\r\n * The approval is cleared when the token is burned.\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must exist.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function _burn(uint256 tokenId) internal virtual {\r\n address owner = ERC721.ownerOf(tokenId); // internal owner\r\n\r\n _beforeTokenTransfer(owner, address(0), tokenId);\r\n\r\n // Clear approvals\r\n _approve(address(0), tokenId);\r\n\r\n // Clear metadata (if any)\r\n if (bytes(_tokenURIs[tokenId]).length != 0) {\r\n delete _tokenURIs[tokenId];\r\n }\r\n\r\n _holderTokens[owner].remove(tokenId);\r\n\r\n _tokenOwners.remove(tokenId);\r\n\r\n emit Transfer(owner, address(0), tokenId);\r\n }\r\n\r\n /**\r\n * @dev Transfers `tokenId` from `from` to `to`.\r\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\r\n *\r\n * Requirements:\r\n *\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must be owned by `from`.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\r\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\r\n require(to != address(0), \"ERC721: transfer to the zero address\");\r\n\r\n _beforeTokenTransfer(from, to, tokenId);\r\n\r\n // Clear approvals from the previous owner\r\n _approve(address(0), tokenId);\r\n\r\n _holderTokens[from].remove(tokenId);\r\n _holderTokens[to].add(tokenId);\r\n\r\n _tokenOwners.set(tokenId, to);\r\n\r\n emit Transfer(from, to, tokenId);\r\n }\r\n\r\n /**\r\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must exist.\r\n */\r\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\r\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\r\n _tokenURIs[tokenId] = _tokenURI;\r\n }\r\n\r\n /**\r\n * @dev Internal function to set the base URI for all token IDs. It is\r\n * automatically added as a prefix to the value returned in {tokenURI},\r\n * or to the token ID if {tokenURI} is empty.\r\n */\r\n function _setBaseURI(string memory baseURI_) internal virtual {\r\n _baseURI = baseURI_;\r\n }\r\n\r\n /**\r\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\r\n * The call is not executed if the target address is not a contract.\r\n *\r\n * @param from address representing the previous owner of the given token ID\r\n * @param to target address that will receive the tokens\r\n * @param tokenId uint256 ID of the token to be transferred\r\n * @param _data bytes optional data to send along with the call\r\n * @return bool whether the call correctly returned the expected magic value\r\n */\r\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\r\n private returns (bool)\r\n {\r\n if (!to.isContract()) {\r\n return true;\r\n }\r\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\r\n IERC721Receiver(to).onERC721Received.selector,\r\n _msgSender(),\r\n from,\r\n tokenId,\r\n _data\r\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\r\n bytes4 retval = abi.decode(returndata, (bytes4));\r\n return (retval == _ERC721_RECEIVED);\r\n }\r\n\r\n function _approve(address to, uint256 tokenId) private {\r\n _tokenApprovals[tokenId] = to;\r\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\r\n }\r\n\r\n /**\r\n * @dev Hook that is called before any token transfer. This includes minting\r\n * and burning.\r\n *\r\n * Calling conditions:\r\n *\r\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\r\n * transferred to `to`.\r\n * - When `from` is zero, `tokenId` will be minted for `to`.\r\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n *\r\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\r\n */\r\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\r\n}\r\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./IERC165.sol\";\r\n\r\n/**\r\n * @dev Implementation of the {IERC165} interface.\r\n *\r\n * Contracts may inherit from this and call {_registerInterface} to declare\r\n * their support of an interface.\r\n */\r\nabstract contract ERC165 is IERC165 {\r\n /*\r\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\r\n */\r\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\r\n\r\n /**\r\n * @dev Mapping of interface ids to whether or not it's supported.\r\n */\r\n mapping(bytes4 => bool) private _supportedInterfaces;\r\n\r\n constructor () {\r\n // Derived contracts need only register support for their own interfaces,\r\n // we register support for ERC165 itself here\r\n _registerInterface(_INTERFACE_ID_ERC165);\r\n }\r\n\r\n /**\r\n * @dev See {IERC165-supportsInterface}.\r\n *\r\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\r\n */\r\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\r\n return _supportedInterfaces[interfaceId];\r\n }\r\n\r\n /**\r\n * @dev Registers the contract as an implementer of the interface defined by\r\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\r\n * registering its interface id is not required.\r\n *\r\n * See {IERC165-supportsInterface}.\r\n *\r\n * Requirements:\r\n *\r\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\r\n */\r\n function _registerInterface(bytes4 interfaceId) internal virtual {\r\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\r\n _supportedInterfaces[interfaceId] = true;\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\n/**\r\n * @dev Library for managing\r\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\r\n * types.\r\n *\r\n * Sets have the following properties:\r\n *\r\n * - Elements are added, removed, and checked for existence in constant time\r\n * (O(1)).\r\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\r\n *\r\n * ```\r\n * contract Example {\r\n * // Add the library methods\r\n * using EnumerableSet for EnumerableSet.AddressSet;\r\n *\r\n * // Declare a set state variable\r\n * EnumerableSet.AddressSet private mySet;\r\n * }\r\n * ```\r\n *\r\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\r\n * and `uint256` (`UintSet`) are supported.\r\n */\r\nlibrary EnumerableSet {\r\n // To implement this library for multiple types with as little code\r\n // repetition as possible, we write it in terms of a generic Set type with\r\n // bytes32 values.\r\n // The Set implementation uses private functions, and user-facing\r\n // implementations (such as AddressSet) are just wrappers around the\r\n // underlying Set.\r\n // This means that we can only create new EnumerableSets for types that fit\r\n // in bytes32.\r\n\r\n struct Set {\r\n // Storage of set values\r\n bytes32[] _values;\r\n\r\n // Position of the value in the `values` array, plus 1 because index 0\r\n // means a value is not in the set.\r\n mapping (bytes32 => uint256) _indexes;\r\n }\r\n\r\n /**\r\n * @dev Add a value to a set. O(1).\r\n *\r\n * Returns true if the value was added to the set, that is if it was not\r\n * already present.\r\n */\r\n function _add(Set storage set, bytes32 value) private returns (bool) {\r\n if (!_contains(set, value)) {\r\n set._values.push(value);\r\n // The value is stored at length-1, but we add 1 to all indexes\r\n // and use 0 as a sentinel value\r\n set._indexes[value] = set._values.length;\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * @dev Removes a value from a set. O(1).\r\n *\r\n * Returns true if the value was removed from the set, that is if it was\r\n * present.\r\n */\r\n function _remove(Set storage set, bytes32 value) private returns (bool) {\r\n // We read and store the value's index to prevent multiple reads from the same storage slot\r\n uint256 valueIndex = set._indexes[value];\r\n\r\n if (valueIndex != 0) { // Equivalent to contains(set, value)\r\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\r\n // the array, and then remove the last element (sometimes called as 'swap and pop').\r\n // This modifies the order of the array, as noted in {at}.\r\n\r\n uint256 toDeleteIndex = valueIndex - 1;\r\n uint256 lastIndex = set._values.length - 1;\r\n\r\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\r\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\r\n\r\n bytes32 lastvalue = set._values[lastIndex];\r\n\r\n // Move the last value to the index where the value to delete is\r\n set._values[toDeleteIndex] = lastvalue;\r\n // Update the index for the moved value\r\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\r\n\r\n // Delete the slot where the moved value was stored\r\n set._values.pop();\r\n\r\n // Delete the index for the deleted slot\r\n delete set._indexes[value];\r\n\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * @dev Returns true if the value is in the set. O(1).\r\n */\r\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\r\n return set._indexes[value] != 0;\r\n }\r\n\r\n /**\r\n * @dev Returns the number of values on the set. O(1).\r\n */\r\n function _length(Set storage set) private view returns (uint256) {\r\n return set._values.length;\r\n }\r\n\r\n /**\r\n * @dev Returns the value stored at position `index` in the set. O(1).\r\n *\r\n * Note that there are no guarantees on the ordering of values inside the\r\n * array, and it may change when more values are added or removed.\r\n *\r\n * Requirements:\r\n *\r\n * - `index` must be strictly less than {length}.\r\n */\r\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\r\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\r\n return set._values[index];\r\n }\r\n\r\n // Bytes32Set\r\n\r\n struct Bytes32Set {\r\n Set _inner;\r\n }\r\n\r\n /**\r\n * @dev Add a value to a set. O(1).\r\n *\r\n * Returns true if the value was added to the set, that is if it was not\r\n * already present.\r\n */\r\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\r\n return _add(set._inner, value);\r\n }\r\n\r\n /**\r\n * @dev Removes a value from a set. O(1).\r\n *\r\n * Returns true if the value was removed from the set, that is if it was\r\n * present.\r\n */\r\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\r\n return _remove(set._inner, value);\r\n }\r\n\r\n /**\r\n * @dev Returns true if the value is in the set. O(1).\r\n */\r\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\r\n return _contains(set._inner, value);\r\n }\r\n\r\n /**\r\n * @dev Returns the number of values in the set. O(1).\r\n */\r\n function length(Bytes32Set storage set) internal view returns (uint256) {\r\n return _length(set._inner);\r\n }\r\n\r\n /**\r\n * @dev Returns the value stored at position `index` in the set. O(1).\r\n *\r\n * Note that there are no guarantees on the ordering of values inside the\r\n * array, and it may change when more values are added or removed.\r\n *\r\n * Requirements:\r\n *\r\n * - `index` must be strictly less than {length}.\r\n */\r\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\r\n return _at(set._inner, index);\r\n }\r\n\r\n // AddressSet\r\n\r\n struct AddressSet {\r\n Set _inner;\r\n }\r\n\r\n /**\r\n * @dev Add a value to a set. O(1).\r\n *\r\n * Returns true if the value was added to the set, that is if it was not\r\n * already present.\r\n */\r\n function add(AddressSet storage set, address value) internal returns (bool) {\r\n return _add(set._inner, bytes32(uint256(uint160(value))));\r\n }\r\n\r\n /**\r\n * @dev Removes a value from a set. O(1).\r\n *\r\n * Returns true if the value was removed from the set, that is if it was\r\n * present.\r\n */\r\n function remove(AddressSet storage set, address value) internal returns (bool) {\r\n return _remove(set._inner, bytes32(uint256(uint160(value))));\r\n }\r\n\r\n /**\r\n * @dev Returns true if the value is in the set. O(1).\r\n */\r\n function contains(AddressSet storage set, address value) internal view returns (bool) {\r\n return _contains(set._inner, bytes32(uint256(uint160(value))));\r\n }\r\n\r\n /**\r\n * @dev Returns the number of values in the set. O(1).\r\n */\r\n function length(AddressSet storage set) internal view returns (uint256) {\r\n return _length(set._inner);\r\n }\r\n\r\n /**\r\n * @dev Returns the value stored at position `index` in the set. O(1).\r\n *\r\n * Note that there are no guarantees on the ordering of values inside the\r\n * array, and it may change when more values are added or removed.\r\n *\r\n * Requirements:\r\n *\r\n * - `index` must be strictly less than {length}.\r\n */\r\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\r\n return address(uint160(uint256(_at(set._inner, index))));\r\n }\r\n\r\n\r\n // UintSet\r\n\r\n struct UintSet {\r\n Set _inner;\r\n }\r\n\r\n /**\r\n * @dev Add a value to a set. O(1).\r\n *\r\n * Returns true if the value was added to the set, that is if it was not\r\n * already present.\r\n */\r\n function add(UintSet storage set, uint256 value) internal returns (bool) {\r\n return _add(set._inner, bytes32(value));\r\n }\r\n\r\n /**\r\n * @dev Removes a value from a set. O(1).\r\n *\r\n * Returns true if the value was removed from the set, that is if it was\r\n * present.\r\n */\r\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\r\n return _remove(set._inner, bytes32(value));\r\n }\r\n\r\n /**\r\n * @dev Returns true if the value is in the set. O(1).\r\n */\r\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\r\n return _contains(set._inner, bytes32(value));\r\n }\r\n\r\n /**\r\n * @dev Returns the number of values on the set. O(1).\r\n */\r\n function length(UintSet storage set) internal view returns (uint256) {\r\n return _length(set._inner);\r\n }\r\n\r\n /**\r\n * @dev Returns the value stored at position `index` in the set. O(1).\r\n *\r\n * Note that there are no guarantees on the ordering of values inside the\r\n * array, and it may change when more values are added or removed.\r\n *\r\n * Requirements:\r\n *\r\n * - `index` must be strictly less than {length}.\r\n */\r\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\r\n return uint256(_at(set._inner, index));\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\n/**\r\n * @dev Library for managing an enumerable variant of Solidity's\r\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\r\n * type.\r\n *\r\n * Maps have the following properties:\r\n *\r\n * - Entries are added, removed, and checked for existence in constant time\r\n * (O(1)).\r\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\r\n *\r\n * ```\r\n * contract Example {\r\n * // Add the library methods\r\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\r\n *\r\n * // Declare a set state variable\r\n * EnumerableMap.UintToAddressMap private myMap;\r\n * }\r\n * ```\r\n *\r\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\r\n * supported.\r\n */\r\nlibrary EnumerableMap {\r\n // To implement this library for multiple types with as little code\r\n // repetition as possible, we write it in terms of a generic Map type with\r\n // bytes32 keys and values.\r\n // The Map implementation uses private functions, and user-facing\r\n // implementations (such as Uint256ToAddressMap) are just wrappers around\r\n // the underlying Map.\r\n // This means that we can only create new EnumerableMaps for types that fit\r\n // in bytes32.\r\n\r\n struct MapEntry {\r\n bytes32 _key;\r\n bytes32 _value;\r\n }\r\n\r\n struct Map {\r\n // Storage of map keys and values\r\n MapEntry[] _entries;\r\n\r\n // Position of the entry defined by a key in the `entries` array, plus 1\r\n // because index 0 means a key is not in the map.\r\n mapping (bytes32 => uint256) _indexes;\r\n }\r\n\r\n /**\r\n * @dev Adds a key-value pair to a map, or updates the value for an existing\r\n * key. O(1).\r\n *\r\n * Returns true if the key was added to the map, that is if it was not\r\n * already present.\r\n */\r\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\r\n // We read and store the key's index to prevent multiple reads from the same storage slot\r\n uint256 keyIndex = map._indexes[key];\r\n\r\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\r\n map._entries.push(MapEntry({ _key: key, _value: value }));\r\n // The entry is stored at length-1, but we add 1 to all indexes\r\n // and use 0 as a sentinel value\r\n map._indexes[key] = map._entries.length;\r\n return true;\r\n } else {\r\n map._entries[keyIndex - 1]._value = value;\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * @dev Removes a key-value pair from a map. O(1).\r\n *\r\n * Returns true if the key was removed from the map, that is if it was present.\r\n */\r\n function _remove(Map storage map, bytes32 key) private returns (bool) {\r\n // We read and store the key's index to prevent multiple reads from the same storage slot\r\n uint256 keyIndex = map._indexes[key];\r\n\r\n if (keyIndex != 0) { // Equivalent to contains(map, key)\r\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\r\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\r\n // This modifies the order of the array, as noted in {at}.\r\n\r\n uint256 toDeleteIndex = keyIndex - 1;\r\n uint256 lastIndex = map._entries.length - 1;\r\n\r\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\r\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\r\n\r\n MapEntry storage lastEntry = map._entries[lastIndex];\r\n\r\n // Move the last entry to the index where the entry to delete is\r\n map._entries[toDeleteIndex] = lastEntry;\r\n // Update the index for the moved entry\r\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\r\n\r\n // Delete the slot where the moved entry was stored\r\n map._entries.pop();\r\n\r\n // Delete the index for the deleted slot\r\n delete map._indexes[key];\r\n\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * @dev Returns true if the key is in the map. O(1).\r\n */\r\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\r\n return map._indexes[key] != 0;\r\n }\r\n\r\n /**\r\n * @dev Returns the number of key-value pairs in the map. O(1).\r\n */\r\n function _length(Map storage map) private view returns (uint256) {\r\n return map._entries.length;\r\n }\r\n\r\n /**\r\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\r\n *\r\n * Note that there are no guarantees on the ordering of entries inside the\r\n * array, and it may change when more entries are added or removed.\r\n *\r\n * Requirements:\r\n *\r\n * - `index` must be strictly less than {length}.\r\n */\r\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\r\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\r\n\r\n MapEntry storage entry = map._entries[index];\r\n return (entry._key, entry._value);\r\n }\r\n\r\n /**\r\n * @dev Tries to returns the value associated with `key`. O(1).\r\n * Does not revert if `key` is not in the map.\r\n */\r\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\r\n uint256 keyIndex = map._indexes[key];\r\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\r\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\r\n }\r\n\r\n /**\r\n * @dev Returns the value associated with `key`. O(1).\r\n *\r\n * Requirements:\r\n *\r\n * - `key` must be in the map.\r\n */\r\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\r\n uint256 keyIndex = map._indexes[key];\r\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\r\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\r\n }\r\n\r\n /**\r\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\r\n *\r\n * CAUTION: This function is deprecated because it requires allocating memory for the error\r\n * message unnecessarily. For custom revert reasons use {_tryGet}.\r\n */\r\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\r\n uint256 keyIndex = map._indexes[key];\r\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\r\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\r\n }\r\n\r\n // UintToAddressMap\r\n\r\n struct UintToAddressMap {\r\n Map _inner;\r\n }\r\n\r\n /**\r\n * @dev Adds a key-value pair to a map, or updates the value for an existing\r\n * key. O(1).\r\n *\r\n * Returns true if the key was added to the map, that is if it was not\r\n * already present.\r\n */\r\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\r\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\r\n }\r\n\r\n /**\r\n * @dev Removes a value from a set. O(1).\r\n *\r\n * Returns true if the key was removed from the map, that is if it was present.\r\n */\r\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\r\n return _remove(map._inner, bytes32(key));\r\n }\r\n\r\n /**\r\n * @dev Returns true if the key is in the map. O(1).\r\n */\r\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\r\n return _contains(map._inner, bytes32(key));\r\n }\r\n\r\n /**\r\n * @dev Returns the number of elements in the map. O(1).\r\n */\r\n function length(UintToAddressMap storage map) internal view returns (uint256) {\r\n return _length(map._inner);\r\n }\r\n\r\n /**\r\n * @dev Returns the element stored at position `index` in the set. O(1).\r\n * Note that there are no guarantees on the ordering of values inside the\r\n * array, and it may change when more values are added or removed.\r\n *\r\n * Requirements:\r\n *\r\n * - `index` must be strictly less than {length}.\r\n */\r\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\r\n (bytes32 key, bytes32 value) = _at(map._inner, index);\r\n return (uint256(key), address(uint160(uint256(value))));\r\n }\r\n\r\n /**\r\n * @dev Tries to returns the value associated with `key`. O(1).\r\n * Does not revert if `key` is not in the map.\r\n *\r\n * _Available since v3.4._\r\n */\r\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\r\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\r\n return (success, address(uint160(uint256(value))));\r\n }\r\n\r\n /**\r\n * @dev Returns the value associated with `key`. O(1).\r\n *\r\n * Requirements:\r\n *\r\n * - `key` must be in the map.\r\n */\r\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\r\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\r\n }\r\n\r\n /**\r\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\r\n *\r\n * CAUTION: This function is deprecated because it requires allocating memory for the error\r\n * message unnecessarily. For custom revert reasons use {tryGet}.\r\n */\r\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\r\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\n/**\r\n * @dev String operations.\r\n */\r\nlibrary Strings {\r\n /**\r\n * @dev Converts a `uint256` to its ASCII `string` representation.\r\n */\r\n function toString(uint256 value) internal pure returns (string memory) {\r\n // Inspired by OraclizeAPI's implementation - MIT licence\r\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\r\n\r\n if (value == 0) {\r\n return \"0\";\r\n }\r\n uint256 temp = value;\r\n uint256 digits;\r\n while (temp != 0) {\r\n digits++;\r\n temp /= 10;\r\n }\r\n bytes memory buffer = new bytes(digits);\r\n uint256 index = digits - 1;\r\n temp = value;\r\n while (temp != 0) {\r\n buffer[index--] = bytes1(uint8(48 + temp % 10));\r\n temp /= 10;\r\n }\r\n return string(buffer);\r\n }\r\n}\r\n"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../interface/IWrapped.sol\";\r\n\r\ncontract WRBTC is IWrapped {\r\n string public name = \"Wrapped RBTC\";\r\n string public symbol = \"WRBTC\";\r\n uint8 public decimals = 18;\r\n\r\n event Approval(address indexed src, address indexed guy, uint wad);\r\n event Transfer(address indexed src, address indexed dst, uint wad);\r\n event Deposit(address indexed dst, uint wad);\r\n event Withdrawal(address indexed src, uint wad);\r\n\r\n mapping (address => uint) override public balanceOf;\r\n mapping (address => mapping (address => uint)) public allowance;\r\n\r\n receive () external payable {\r\n deposit();\r\n }\r\n function deposit() override public payable {\r\n balanceOf[msg.sender] += msg.value;\r\n emit Deposit(msg.sender, msg.value);\r\n }\r\n function withdraw(uint wad) override public {\r\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\r\n balanceOf[msg.sender] -= wad;\r\n msg.sender.transfer(wad);\r\n emit Withdrawal(msg.sender, wad);\r\n }\r\n\r\n function totalSupply() override public view returns (uint) {\r\n return address(this).balance;\r\n }\r\n\r\n function approve(address guy, uint wad) override public returns (bool) {\r\n allowance[msg.sender][guy] = wad;\r\n emit Approval(msg.sender, guy, wad);\r\n return true;\r\n }\r\n\r\n function transfer(address dst, uint wad) override public returns (bool) {\r\n return transferFrom(msg.sender, dst, wad);\r\n }\r\n\r\n function transferFrom(address src, address dst, uint wad)\r\n override public\r\n returns (bool)\r\n {\r\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\r\n\r\n if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\r\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\r\n allowance[src][msg.sender] -= wad;\r\n }\r\n\r\n balanceOf[src] -= wad;\r\n balanceOf[dst] += wad;\r\n\r\n emit Transfer(src, dst, wad);\r\n\r\n return true;\r\n }\r\n}"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n// Import base Initializable contract\r\nimport \"../zeppelin/upgradable/Initializable.sol\";\r\n// Import interface and library from OpenZeppelin contracts\r\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\r\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\r\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\r\n\r\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\r\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\r\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\r\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\r\nimport \"../zeppelin/utils/Address.sol\";\r\nimport \"../zeppelin/math/SafeMath.sol\";\r\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\r\n\r\nimport \"../lib/LibEIP712.sol\";\r\nimport \"../lib/LibUtils.sol\";\r\n\r\nimport \"../interface/IBridge.sol\";\r\nimport \"../interface/ISideToken.sol\";\r\nimport \"../interface/ISideTokenFactory.sol\";\r\nimport \"../interface/IAllowTokens.sol\";\r\nimport \"../interface/IWrapped.sol\";\r\n\r\n// solhint-disable-next-line max-states-count\r\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\r\n using SafeMath for uint256;\r\n using SafeERC20 for IERC20;\r\n using Address for address;\r\n\r\n address constant internal NULL_ADDRESS = address(0);\r\n bytes32 constant internal NULL_HASH = bytes32(0);\r\n IERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\r\n\r\n address internal federation;\r\n uint256 internal feePercentage;\r\n string public symbolPrefix;\r\n // replaces uint256 internal _depprecatedLastDay;\r\n bytes32 public domainSeparator;\r\n uint256 internal _deprecatedSpentToday;\r\n\r\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\r\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\r\n mapping (address => bool) public knownTokens; // OriginalToken => true\r\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\r\n IAllowTokens public allowTokens;\r\n ISideTokenFactory public sideTokenFactory;\r\n //Bridge_v1 variables\r\n bool public isUpgrading;\r\n // Percentage with up to 2 decimals\r\n uint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\r\n //Bridge_v3 variables\r\n bytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\r\n IWrapped public wrappedCurrency;\r\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\r\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\r\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\r\n\r\n // keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\r\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\r\n mapping(address => uint) public nonces;\r\n\r\n event AllowTokensChanged(address _newAllowTokens);\r\n event FederationChanged(address _newFederation);\r\n event SideTokenFactoryChanged(address _newSideTokenFactory);\r\n event Upgrading(bool _isUpgrading);\r\n event WrappedCurrencyChanged(address _wrappedCurrency);\r\n\r\n function initialize(\r\n address _manager,\r\n address _federation,\r\n address _allowTokens,\r\n address _sideTokenFactory,\r\n string memory _symbolPrefix\r\n ) public initializer {\r\n UpgradableOwnable.initialize(_manager);\r\n UpgradablePausable.__Pausable_init(_manager);\r\n symbolPrefix = _symbolPrefix;\r\n allowTokens = IAllowTokens(_allowTokens);\r\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\r\n federation = _federation;\r\n //keccak256(\"ERC777TokensRecipient\")\r\n ERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\r\n initDomainSeparator();\r\n }\r\n\r\n receive () external payable {\r\n // The fallback function is needed to use WRBTC\r\n require(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\r\n }\r\n\r\n function version() override external pure returns (string memory) {\r\n return \"v3\";\r\n }\r\n\r\n function initDomainSeparator() public {\r\n uint chainId;\r\n // solium-disable-next-line security/no-inline-assembly\r\n assembly {\r\n chainId := chainid()\r\n }\r\n domainSeparator = LibEIP712.hashEIP712Domain(\r\n \"RSK Token Bridge\",\r\n \"1\",\r\n chainId,\r\n address(this)\r\n );\r\n }\r\n\r\n modifier whenNotUpgrading() {\r\n require(!isUpgrading, \"Bridge: Upgrading\");\r\n _;\r\n }\r\n\r\n function acceptTransfer(\r\n address _originalTokenAddress,\r\n address payable _from,\r\n address payable _to,\r\n uint256 _amount,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n ) external whenNotPaused nonReentrant override {\r\n require(_msgSender() == federation, \"Bridge: Not Federation\");\r\n require(knownTokens[_originalTokenAddress] ||\r\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\r\n \"Bridge: Unknown token\"\r\n );\r\n require(_to != NULL_ADDRESS, \"Bridge: Null To\");\r\n require(_amount > 0, \"Bridge: Amount 0\");\r\n require(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\r\n require(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\r\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\r\n\r\n bytes32 _transactionDataHash = getTransactionDataHash(\r\n _to,\r\n _amount,\r\n _blockHash,\r\n _transactionHash,\r\n _logIndex\r\n );\r\n // Do not remove, claimed also has the previously processed using the older bridge version\r\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\r\n require(!claimed[_transactionDataHash], \"Bridge: Already claimed\");\r\n\r\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\r\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\r\n senderAddresses[_transactionHash] = _from;\r\n\r\n emit AcceptedCrossTransfer(\r\n _transactionHash,\r\n _originalTokenAddress,\r\n _to,\r\n _from,\r\n _amount,\r\n _blockHash,\r\n _logIndex\r\n );\r\n }\r\n\r\n\r\n function createSideToken(\r\n uint256 _typeId,\r\n address _originalTokenAddress,\r\n uint8 _originalTokenDecimals,\r\n string calldata _originalTokenSymbol,\r\n string calldata _originalTokenName\r\n ) external onlyOwner {\r\n require(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\r\n address sideToken = mappedTokens[_originalTokenAddress];\r\n require(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\r\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\r\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\r\n\r\n // Create side token\r\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\r\n\r\n mappedTokens[_originalTokenAddress] = sideToken;\r\n originalTokens[sideToken] = _originalTokenAddress;\r\n allowTokens.setToken(sideToken, _typeId);\r\n\r\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\r\n }\r\n\r\n function claim(ClaimData calldata _claimData)\r\n external override returns (uint256 receivedAmount) {\r\n\r\n receivedAmount = _claim(\r\n _claimData,\r\n _claimData.to,\r\n payable(address(0)),\r\n 0\r\n );\r\n return receivedAmount;\r\n }\r\n\r\n function claimFallback(ClaimData calldata _claimData)\r\n external override returns (uint256 receivedAmount) {\r\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\r\n receivedAmount = _claim(\r\n _claimData,\r\n _msgSender(),\r\n payable(address(0)),\r\n 0\r\n );\r\n return receivedAmount;\r\n }\r\n\r\n function getDigest(\r\n ClaimData memory _claimData,\r\n address payable _relayer,\r\n uint256 _fee,\r\n uint256 _deadline\r\n ) internal returns (bytes32) {\r\n return LibEIP712.hashEIP712Message(\r\n domainSeparator,\r\n keccak256(\r\n abi.encode(\r\n CLAIM_TYPEHASH,\r\n _claimData.to,\r\n _claimData.amount,\r\n _claimData.transactionHash,\r\n _relayer,\r\n _fee,\r\n nonces[_claimData.to]++,\r\n _deadline\r\n )\r\n )\r\n );\r\n }\r\n\r\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\r\n function claimGasless(\r\n ClaimData calldata _claimData,\r\n address payable _relayer,\r\n uint256 _fee,\r\n uint256 _deadline,\r\n uint8 _v,\r\n bytes32 _r,\r\n bytes32 _s\r\n ) external override returns (uint256 receivedAmount) {\r\n require(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\r\n\r\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\r\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\r\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\r\n\r\n receivedAmount = _claim(\r\n _claimData,\r\n _claimData.to,\r\n _relayer,\r\n _fee\r\n );\r\n return receivedAmount;\r\n }\r\n\r\n function _claim(\r\n ClaimData calldata _claimData,\r\n address payable _reciever,\r\n address payable _relayer,\r\n uint256 _fee\r\n ) internal nonReentrant returns (uint256 receivedAmount) {\r\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\r\n require(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\r\n\r\n bytes32 transactionDataHash = getTransactionDataHash(\r\n _claimData.to,\r\n _claimData.amount,\r\n _claimData.blockHash,\r\n _claimData.transactionHash,\r\n _claimData.logIndex\r\n );\r\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\r\n require(!claimed[transactionDataHash], \"Bridge: Already claimed\");\r\n\r\n claimed[transactionDataHash] = true;\r\n if (knownTokens[originalTokenAddress]) {\r\n receivedAmount =_claimCrossBackToToken(\r\n originalTokenAddress,\r\n _reciever,\r\n _claimData.amount,\r\n _relayer,\r\n _fee\r\n );\r\n } else {\r\n receivedAmount =_claimCrossToSideToken(\r\n originalTokenAddress,\r\n _reciever,\r\n _claimData.amount,\r\n _relayer,\r\n _fee\r\n );\r\n }\r\n emit Claimed(\r\n _claimData.transactionHash,\r\n originalTokenAddress,\r\n _claimData.to,\r\n senderAddresses[_claimData.transactionHash],\r\n _claimData.amount,\r\n _claimData.blockHash,\r\n _claimData.logIndex,\r\n _reciever,\r\n _relayer,\r\n _fee\r\n );\r\n return receivedAmount;\r\n }\r\n\r\n function _claimCrossToSideToken(\r\n address _originalTokenAddress,\r\n address payable _receiver,\r\n uint256 _amount,\r\n address payable _relayer,\r\n uint256 _fee\r\n ) internal returns (uint256 receivedAmount) {\r\n address sideToken = mappedTokens[_originalTokenAddress];\r\n uint256 granularity = IERC777(sideToken).granularity();\r\n uint256 formattedAmount = _amount.mul(granularity);\r\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\r\n receivedAmount = formattedAmount - _fee;\r\n ISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\r\n if(_fee > 0) {\r\n ISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\r\n }\r\n return receivedAmount;\r\n }\r\n\r\n function _claimCrossBackToToken(\r\n address _originalTokenAddress,\r\n address payable _receiver,\r\n uint256 _amount,\r\n address payable _relayer,\r\n uint256 _fee\r\n ) internal returns (uint256 receivedAmount) {\r\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\r\n //As side tokens are ERC777 they will always have 18 decimals\r\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\r\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\r\n receivedAmount = formattedAmount - _fee;\r\n if(address(wrappedCurrency) == _originalTokenAddress) {\r\n wrappedCurrency.withdraw(formattedAmount);\r\n _receiver.transfer(receivedAmount);\r\n if(_fee > 0) {\r\n _relayer.transfer(_fee);\r\n }\r\n } else {\r\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\r\n if(_fee > 0) {\r\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\r\n }\r\n }\r\n return receivedAmount;\r\n }\r\n\r\n /**\r\n * ERC-20 tokens approve and transferFrom pattern\r\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\r\n */\r\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\r\n address sender = _msgSender();\r\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\r\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\r\n crossTokens(tokenToUse, sender, to, amount, \"\");\r\n }\r\n\r\n /**\r\n * Use network currency and cross it.\r\n */\r\n function depositTo(address to) override external payable {\r\n address sender = _msgSender();\r\n require(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\r\n wrappedCurrency.deposit{ value: msg.value }();\r\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \"\");\r\n }\r\n\r\n /**\r\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\r\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\r\n */\r\n function tokensReceived (\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes calldata userData,\r\n bytes calldata\r\n ) external override(IBridge, IERC777Recipient){\r\n //Hook from ERC777address\r\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\r\n require(to == address(this), \"Bridge: Not to this address\");\r\n address tokenToUse = _msgSender();\r\n require(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\r\n require(userData.length != 0 || !from.isContract(), \"Bridge: Specify receiver address in data\");\r\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\r\n crossTokens(tokenToUse, from, receiver, amount, userData);\r\n }\r\n\r\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\r\n internal whenNotUpgrading whenNotPaused nonReentrant {\r\n knownTokens[tokenToUse] = true;\r\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\r\n uint256 amountMinusFees = amount.sub(fee);\r\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\r\n uint formattedAmount = amount;\r\n if(decimals != 18) {\r\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\r\n }\r\n // We consider the amount before fees converted to 18 decimals to check the limits\r\n // updateTokenTransfer revert if token not allowed\r\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\r\n address originalTokenAddress = tokenToUse;\r\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\r\n //Side Token Crossing\r\n originalTokenAddress = originalTokens[tokenToUse];\r\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\r\n uint256 modulo = amountMinusFees.mod(granularity);\r\n fee = fee.add(modulo);\r\n amountMinusFees = amountMinusFees.sub(modulo);\r\n IERC777(tokenToUse).burn(amountMinusFees, userData);\r\n }\r\n\r\n emit Cross(\r\n originalTokenAddress,\r\n from,\r\n to,\r\n amountMinusFees,\r\n userData\r\n );\r\n\r\n if (fee > 0) {\r\n //Send the payment to the MultiSig of the Federation\r\n IERC20(tokenToUse).safeTransfer(owner(), fee);\r\n }\r\n }\r\n\r\n function getTransactionDataHash(\r\n address _to,\r\n uint256 _amount,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n )\r\n public pure override returns(bytes32)\r\n {\r\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\r\n }\r\n\r\n function setFeePercentage(uint amount) external onlyOwner {\r\n require(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\r\n feePercentage = amount;\r\n emit FeePercentageChanged(feePercentage);\r\n }\r\n\r\n function getFeePercentage() external view override returns(uint) {\r\n return feePercentage;\r\n }\r\n\r\n function changeFederation(address newFederation) external onlyOwner {\r\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\r\n federation = newFederation;\r\n emit FederationChanged(federation);\r\n }\r\n\r\n\r\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\r\n require(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\r\n allowTokens = IAllowTokens(newAllowTokens);\r\n emit AllowTokensChanged(newAllowTokens);\r\n }\r\n\r\n function getFederation() external view returns(address) {\r\n return federation;\r\n }\r\n\r\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\r\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\r\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\r\n emit SideTokenFactoryChanged(newSideTokenFactory);\r\n }\r\n\r\n function setUpgrading(bool _isUpgrading) external onlyOwner {\r\n isUpgrading = _isUpgrading;\r\n emit Upgrading(isUpgrading);\r\n }\r\n\r\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\r\n require(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\r\n wrappedCurrency = IWrapped(_wrappedCurrency);\r\n emit WrappedCurrencyChanged(_wrappedCurrency);\r\n }\r\n\r\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\r\n return transactionsDataHashes[transactionHash] != bytes32(0);\r\n }\r\n\r\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\r\n return claimed[transactionsDataHashes[transactionHash]];\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\r\n *\r\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\r\n * contract implement this interface (contract holders can be their own\r\n * implementer) and registering it on the\r\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\r\n *\r\n * See `IERC1820Registry` and `ERC1820Implementer`.\r\n */\r\ninterface IERC777Recipient {\r\n /**\r\n * @dev Called by an `IERC777` token contract whenever tokens are being\r\n * moved or created into a registered account (`to`). The type of operation\r\n * is conveyed by `from` being the zero address or not.\r\n *\r\n * This call occurs _after_ the token contract's state is updated, so\r\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\r\n *\r\n * This function may revert to prevent the operation from being executed.\r\n */\r\n function tokensReceived(\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes calldata userData,\r\n bytes calldata operatorData\r\n ) external;\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev Interface of the ERC777Token standard as defined in the EIP.\r\n *\r\n * This contract uses the\r\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\r\n * token holders and recipients react to token movements by using setting implementers\r\n * for the associated interfaces in said registry. See `IERC1820Registry` and\r\n * `ERC1820Implementer`.\r\n */\r\ninterface IERC777 {\r\n /**\r\n * @dev Returns the name of the token.\r\n */\r\n function name() external view returns (string memory);\r\n\r\n /**\r\n * @dev Returns the symbol of the token, usually a shorter version of the\r\n * name.\r\n */\r\n function symbol() external view returns (string memory);\r\n\r\n /**\r\n * @dev Returns the smallest part of the token that is not divisible. This\r\n * means all token operations (creation, movement and destruction) must have\r\n * amounts that are a multiple of this number.\r\n *\r\n * For most token contracts, this value will equal 1.\r\n */\r\n function granularity() external view returns (uint256);\r\n\r\n /**\r\n * @dev Returns the amount of tokens in existence.\r\n */\r\n function totalSupply() external view returns (uint256);\r\n\r\n /**\r\n * @dev Returns the amount of tokens owned by an account (`owner`).\r\n */\r\n function balanceOf(address owner) external view returns (uint256);\r\n\r\n /**\r\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\r\n *\r\n * If send or receive hooks are registered for the caller and `recipient`,\r\n * the corresponding functions will be called with `data` and empty\r\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\r\n *\r\n * Emits a `Sent` event.\r\n *\r\n * Requirements\r\n *\r\n * - the caller must have at least `amount` tokens.\r\n * - `recipient` cannot be the zero address.\r\n * - if `recipient` is a contract, it must implement the `tokensReceived`\r\n * interface.\r\n */\r\n function send(address recipient, uint256 amount, bytes calldata data) external;\r\n\r\n /**\r\n * @dev Destroys `amount` tokens from the caller's account, reducing the\r\n * total supply.\r\n *\r\n * If a send hook is registered for the caller, the corresponding function\r\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\r\n *\r\n * Emits a `Burned` event.\r\n *\r\n * Requirements\r\n *\r\n * - the caller must have at least `amount` tokens.\r\n */\r\n function burn(uint256 amount, bytes calldata data) external;\r\n\r\n /**\r\n * @dev Returns true if an account is an operator of `tokenHolder`.\r\n * Operators can send and burn tokens on behalf of their owners. All\r\n * accounts are their own operator.\r\n *\r\n * See `operatorSend` and `operatorBurn`.\r\n */\r\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\r\n\r\n /**\r\n * @dev Make an account an operator of the caller.\r\n *\r\n * See `isOperatorFor`.\r\n *\r\n * Emits an `AuthorizedOperator` event.\r\n *\r\n * Requirements\r\n *\r\n * - `operator` cannot be calling address.\r\n */\r\n function authorizeOperator(address operator) external;\r\n\r\n /**\r\n * @dev Make an account an operator of the caller.\r\n *\r\n * See `isOperatorFor` and `defaultOperators`.\r\n *\r\n * Emits a `RevokedOperator` event.\r\n *\r\n * Requirements\r\n *\r\n * - `operator` cannot be calling address.\r\n */\r\n function revokeOperator(address operator) external;\r\n\r\n /**\r\n * @dev Returns the list of default operators. These accounts are operators\r\n * for all token holders, even if `authorizeOperator` was never called on\r\n * them.\r\n *\r\n * This list is immutable, but individual holders may revoke these via\r\n * `revokeOperator`, in which case `isOperatorFor` will return false.\r\n */\r\n function defaultOperators() external view returns (address[] memory);\r\n\r\n /**\r\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\r\n * be an operator of `sender`.\r\n *\r\n * If send or receive hooks are registered for `sender` and `recipient`,\r\n * the corresponding functions will be called with `data` and\r\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\r\n *\r\n * Emits a `Sent` event.\r\n *\r\n * Requirements\r\n *\r\n * - `sender` cannot be the zero address.\r\n * - `sender` must have at least `amount` tokens.\r\n * - the caller must be an operator for `sender`.\r\n * - `recipient` cannot be the zero address.\r\n * - if `recipient` is a contract, it must implement the `tokensReceived`\r\n * interface.\r\n */\r\n function operatorSend(\r\n address sender,\r\n address recipient,\r\n uint256 amount,\r\n bytes calldata data,\r\n bytes calldata operatorData\r\n ) external;\r\n\r\n /**\r\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\r\n * The caller must be an operator of `account`.\r\n *\r\n * If a send hook is registered for `account`, the corresponding function\r\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\r\n *\r\n * Emits a `Burned` event.\r\n *\r\n * Requirements\r\n *\r\n * - `account` cannot be the zero address.\r\n * - `account` must have at least `amount` tokens.\r\n * - the caller must be an operator for `account`.\r\n */\r\n function operatorBurn(\r\n address account,\r\n uint256 amount,\r\n bytes calldata data,\r\n bytes calldata operatorData\r\n ) external;\r\n\r\n event Sent(\r\n address indexed operator,\r\n address indexed from,\r\n address indexed to,\r\n uint256 amount,\r\n bytes data,\r\n bytes operatorData\r\n );\r\n\r\n function decimals() external returns (uint8);\r\n\r\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\r\n\r\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\r\n\r\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\r\n\r\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\r\n}\r\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\ninterface IBridge {\r\n\r\n struct ClaimData {\r\n address payable to;\r\n uint256 amount;\r\n bytes32 blockHash;\r\n bytes32 transactionHash;\r\n uint32 logIndex;\r\n }\r\n\r\n function version() external pure returns (string memory);\r\n\r\n function getFeePercentage() external view returns(uint);\r\n\r\n /**\r\n * ERC-20 tokens approve and transferFrom pattern\r\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\r\n */\r\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\r\n\r\n /**\r\n * Use network currency and cross it.\r\n */\r\n function depositTo(address to) external payable;\r\n\r\n /**\r\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\r\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\r\n */\r\n function tokensReceived (\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes calldata userData,\r\n bytes calldata operatorData\r\n ) external;\r\n\r\n /**\r\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\r\n */\r\n function acceptTransfer(\r\n address _originalTokenAddress,\r\n address payable _from,\r\n address payable _to,\r\n uint256 _amount,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n ) external;\r\n\r\n /**\r\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\r\n */\r\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\r\n\r\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\r\n\r\n function claimGasless(\r\n ClaimData calldata _claimData,\r\n address payable _relayer,\r\n uint256 _fee,\r\n uint256 _deadline,\r\n uint8 _v,\r\n bytes32 _r,\r\n bytes32 _s\r\n ) external returns (uint256 receivedAmount);\r\n\r\n function getTransactionDataHash(\r\n address _to,\r\n uint256 _amount,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n ) external returns(bytes32);\r\n\r\n event Cross(\r\n address indexed _tokenAddress,\r\n address indexed _from,\r\n address indexed _to,\r\n uint256 _amount,\r\n bytes _userData\r\n );\r\n event NewSideToken(\r\n address indexed _newSideTokenAddress,\r\n address indexed _originalTokenAddress,\r\n string _newSymbol,\r\n uint256 _granularity\r\n );\r\n event AcceptedCrossTransfer(\r\n bytes32 indexed _transactionHash,\r\n address indexed _originalTokenAddress,\r\n address indexed _to,\r\n address _from,\r\n uint256 _amount,\r\n bytes32 _blockHash,\r\n uint256 _logIndex\r\n );\r\n event FeePercentageChanged(uint256 _amount);\r\n event Claimed(\r\n bytes32 indexed _transactionHash,\r\n address indexed _originalTokenAddress,\r\n address indexed _to,\r\n address _sender,\r\n uint256 _amount,\r\n bytes32 _blockHash,\r\n uint256 _logIndex,\r\n address _reciever,\r\n address _relayer,\r\n uint256 _fee\r\n );\r\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\ninterface ISideToken {\r\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\r\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\ninterface ISideTokenFactory {\r\n\r\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\r\n\r\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\r\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../zeppelin/ownership/Secondary.sol\";\r\nimport \"../interface/ISideTokenFactory.sol\";\r\nimport \"../SideToken/SideToken.sol\";\r\n\r\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\r\n\r\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\r\n external onlyPrimary override returns(address) {\r\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\r\n emit SideTokenCreated(sideToken, symbol, granularity);\r\n return sideToken;\r\n }\r\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../GSN/Context.sol\";\r\n/**\r\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\r\n */\r\nabstract contract Secondary is Context {\r\n address private _primary;\r\n\r\n /**\r\n * @dev Emitted when the primary contract changes.\r\n */\r\n event PrimaryTransferred(\r\n address recipient\r\n );\r\n\r\n /**\r\n * @dev Sets the primary account to the one that is creating the Secondary contract.\r\n */\r\n constructor () {\r\n _primary = _msgSender();\r\n emit PrimaryTransferred(_primary);\r\n }\r\n\r\n /**\r\n * @dev Reverts if called from any account other than the primary.\r\n */\r\n modifier onlyPrimary() {\r\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\r\n _;\r\n }\r\n\r\n /**\r\n * @return the address of the primary.\r\n */\r\n function primary() public view returns (address) {\r\n return _primary;\r\n }\r\n\r\n /**\r\n * @dev Transfers contract to a new primary.\r\n * @param recipient The address of new primary.\r\n */\r\n function transferPrimary(address recipient) public onlyPrimary {\r\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\r\n _primary = recipient;\r\n emit PrimaryTransferred(_primary);\r\n }\r\n}\r\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\r\nimport \"../interface/IERC677Receiver.sol\";\r\nimport \"../interface/ISideToken.sol\";\r\nimport \"../lib/LibEIP712.sol\";\r\n\r\ncontract SideToken is ISideToken, ERC777 {\r\n using Address for address;\r\n using SafeMath for uint256;\r\n\r\n address public minter;\r\n uint256 private _granularity;\r\n\r\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\r\n bytes32 public domainSeparator;\r\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\r\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\r\n mapping(address => uint) public nonces;\r\n\r\n // ERC677 Transfer Event\r\n event Transfer(address,address,uint256,bytes);\r\n\r\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\r\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\r\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\r\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\r\n minter = _minterAddr;\r\n _granularity = _newGranularity;\r\n\r\n uint chainId;\r\n // solium-disable-next-line security/no-inline-assembly\r\n assembly {\r\n chainId := chainid()\r\n }\r\n domainSeparator = LibEIP712.hashEIP712Domain(\r\n name(),\r\n \"1\",\r\n chainId,\r\n address(this)\r\n );\r\n }\r\n\r\n modifier onlyMinter() {\r\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\r\n _;\r\n }\r\n\r\n function mint(\r\n address account,\r\n uint256 amount,\r\n bytes calldata userData,\r\n bytes calldata operatorData\r\n )\r\n external onlyMinter override\r\n {\r\n _mint(_msgSender(), account, amount, userData, operatorData);\r\n }\r\n\r\n /**\r\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\r\n * @param recipient The address to transfer to.\r\n * @param amount The amount to be transferred.\r\n * @param data The extra data to be passed to the receiving contract.\r\n */\r\n function transferAndCall(address recipient, uint amount, bytes calldata data)\r\n external returns (bool success)\r\n {\r\n address from = _msgSender();\r\n\r\n _send(from, from, recipient, amount, data, \"\", false);\r\n emit Transfer(from, recipient, amount, data);\r\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\r\n return true;\r\n }\r\n\r\n function granularity() public view override returns (uint256) {\r\n return _granularity;\r\n }\r\n\r\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\r\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\r\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\r\n bytes32 digest = LibEIP712.hashEIP712Message(\r\n domainSeparator,\r\n keccak256(\r\n abi.encode(\r\n PERMIT_TYPEHASH,\r\n owner,\r\n spender,\r\n value,\r\n nonces[owner]++,\r\n deadline\r\n )\r\n )\r\n );\r\n address recoveredAddress = ecrecover(digest, v, r, s);\r\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\r\n _approve(owner, spender, value);\r\n }\r\n\r\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../../GSN/Context.sol\";\r\nimport \"./IERC777.sol\";\r\nimport \"./IERC777Recipient.sol\";\r\nimport \"./IERC777Sender.sol\";\r\nimport \"../../token/ERC20/IERC20.sol\";\r\nimport \"../../math/SafeMath.sol\";\r\nimport \"../../utils/Address.sol\";\r\nimport \"../../introspection/IERC1820Registry.sol\";\r\n\r\n/**\r\n * @dev Implementation of the {IERC777} interface.\r\n *\r\n * This implementation is agnostic to the way tokens are created. This means\r\n * that a supply mechanism has to be added in a derived contract using {_mint}.\r\n *\r\n * Support for ERC20 is included in this contract, as specified by the EIP: both\r\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\r\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\r\n * movements.\r\n *\r\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\r\n * are no special restrictions in the amount of tokens that created, moved, or\r\n * destroyed. This makes integration with ERC20 applications seamless.\r\n */\r\ncontract ERC777 is Context, IERC777, IERC20 {\r\n using SafeMath for uint256;\r\n using Address for address;\r\n\r\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\r\n\r\n mapping(address => uint256) private _balances;\r\n\r\n uint256 private _totalSupply;\r\n\r\n string private _name;\r\n string private _symbol;\r\n\r\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\r\n // See https://github.com/ethereum/solidity/issues/4024.\r\n\r\n // keccak256(\"ERC777TokensSender\")\r\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\r\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\r\n\r\n // keccak256(\"ERC777TokensRecipient\")\r\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\r\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\r\n\r\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\r\n address[] private _defaultOperatorsArray;\r\n\r\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\r\n mapping(address => bool) private _defaultOperators;\r\n\r\n // For each account, a mapping of its operators and revoked default operators.\r\n mapping(address => mapping(address => bool)) private _operators;\r\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\r\n\r\n // ERC20-allowances\r\n mapping (address => mapping (address => uint256)) private _allowances;\r\n\r\n /**\r\n * @dev `defaultOperators` may be an empty array.\r\n */\r\n constructor(\r\n string memory aName,\r\n string memory aSymbol,\r\n address[] memory theDefaultOperators\r\n ) {\r\n _name = aName;\r\n _symbol = aSymbol;\r\n\r\n _defaultOperatorsArray = theDefaultOperators;\r\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\r\n _defaultOperators[_defaultOperatorsArray[i]] = true;\r\n }\r\n\r\n // register interfaces\r\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\r\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-name}.\r\n */\r\n function name() public view override(IERC777) returns (string memory) {\r\n return _name;\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-symbol}.\r\n */\r\n function symbol() public view override(IERC777) returns (string memory) {\r\n return _symbol;\r\n }\r\n\r\n /**\r\n * @dev See {ERC20Detailed-decimals}.\r\n *\r\n * Always returns 18, as per the\r\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\r\n */\r\n function decimals() public pure override returns (uint8) {\r\n return 18;\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-granularity}.\r\n *\r\n * This implementation always returns `1`.\r\n */\r\n function granularity() public view virtual override(IERC777) returns (uint256) {\r\n return 1;\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-totalSupply}.\r\n */\r\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\r\n return _totalSupply;\r\n }\r\n\r\n /**\r\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\r\n */\r\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\r\n return _balances[tokenHolder];\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-send}.\r\n *\r\n * Also emits a {Transfer} event for ERC20 compatibility.\r\n */\r\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\r\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-transfer}.\r\n *\r\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\r\n * interface if it is a contract.\r\n *\r\n * Also emits a {Sent} event.\r\n */\r\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\r\n require(recipient != address(0), \"ERC777: transfer to zero address\");\r\n\r\n address from = _msgSender();\r\n\r\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\r\n\r\n _move(from, from, recipient, amount, \"\", \"\");\r\n\r\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-burn}.\r\n *\r\n * Also emits a {Transfer} event for ERC20 compatibility.\r\n */\r\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\r\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-isOperatorFor}.\r\n */\r\n function isOperatorFor(\r\n address operator,\r\n address tokenHolder\r\n ) public view override(IERC777) returns (bool) {\r\n return operator == tokenHolder ||\r\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\r\n _operators[tokenHolder][operator];\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-authorizeOperator}.\r\n */\r\n function authorizeOperator(address operator) external override(IERC777) {\r\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\r\n\r\n if (_defaultOperators[operator]) {\r\n delete _revokedDefaultOperators[_msgSender()][operator];\r\n } else {\r\n _operators[_msgSender()][operator] = true;\r\n }\r\n\r\n emit AuthorizedOperator(operator, _msgSender());\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-revokeOperator}.\r\n */\r\n function revokeOperator(address operator) external override(IERC777) {\r\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\r\n\r\n if (_defaultOperators[operator]) {\r\n _revokedDefaultOperators[_msgSender()][operator] = true;\r\n } else {\r\n delete _operators[_msgSender()][operator];\r\n }\r\n\r\n emit RevokedOperator(operator, _msgSender());\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-defaultOperators}.\r\n */\r\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\r\n return _defaultOperatorsArray;\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-operatorSend}.\r\n *\r\n * Emits {Sent} and {Transfer} events.\r\n */\r\n function operatorSend(\r\n address sender,\r\n address recipient,\r\n uint256 amount,\r\n bytes calldata data,\r\n bytes calldata operatorData\r\n )\r\n external override(IERC777)\r\n {\r\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\r\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-operatorBurn}.\r\n *\r\n * Emits {Burned} and {Transfer} events.\r\n */\r\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\r\n external override(IERC777) {\r\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\r\n _burn(_msgSender(), account, amount, data, operatorData);\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-allowance}.\r\n *\r\n * Note that operator and allowance concepts are orthogonal: operators may\r\n * not have allowance, and accounts with allowance may not be operators\r\n * themselves.\r\n */\r\n function allowance(address holder, address spender)\r\n public view override(IERC20) returns (uint256) {\r\n return _allowances[holder][spender];\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-approve}.\r\n *\r\n * Note that accounts cannot have allowance issued by their operators.\r\n */\r\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\r\n address holder = _msgSender();\r\n _approve(holder, spender, value);\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-transferFrom}.\r\n *\r\n * Note that operator and allowance concepts are orthogonal: operators cannot\r\n * call `transferFrom` (unless they have allowance), and accounts with\r\n * allowance cannot call `operatorSend` (unless they are operators).\r\n *\r\n * Emits {Sent}, {Transfer} and {Approval} events.\r\n */\r\n function transferFrom(address holder, address recipient, uint256 amount)\r\n external override(IERC20) returns (bool) {\r\n require(recipient != address(0), \"ERC777: transfer to zero address\");\r\n require(holder != address(0), \"ERC777: transfer from zero address\");\r\n\r\n address spender = _msgSender();\r\n\r\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\r\n\r\n _move(spender, holder, recipient, amount, \"\", \"\");\r\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\r\n\r\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\r\n * the total supply.\r\n *\r\n * If a send hook is registered for `account`, the corresponding function\r\n * will be called with `operator`, `data` and `operatorData`.\r\n *\r\n * See {IERC777Sender} and {IERC777Recipient}.\r\n *\r\n * Emits {Minted} and {Transfer} events.\r\n *\r\n * Requirements\r\n *\r\n * - `account` cannot be the zero address.\r\n * - if `account` is a contract, it must implement the {IERC777Recipient}\r\n * interface.\r\n */\r\n function _mint(\r\n address operator,\r\n address account,\r\n uint256 amount,\r\n bytes memory userData,\r\n bytes memory operatorData\r\n )\r\n internal\r\n {\r\n require(account != address(0), \"ERC777: mint to zero address\");\r\n\r\n // Update state variables\r\n _totalSupply = _totalSupply.add(amount);\r\n _balances[account] = _balances[account].add(amount);\r\n\r\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\r\n\r\n emit Minted(operator, account, amount, userData, operatorData);\r\n emit Transfer(address(0), account, amount);\r\n }\r\n\r\n /**\r\n * @dev Send tokens\r\n * @param operator address operator requesting the transfer\r\n * @param from address token holder address\r\n * @param to address recipient address\r\n * @param amount uint256 amount of tokens to transfer\r\n * @param userData bytes extra information provided by the token holder (if any)\r\n * @param operatorData bytes extra information provided by the operator (if any)\r\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\r\n */\r\n function _send(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256 amount,\r\n bytes memory userData,\r\n bytes memory operatorData,\r\n bool requireReceptionAck\r\n )\r\n internal\r\n {\r\n require(from != address(0), \"ERC777: send from zero address\");\r\n require(to != address(0), \"ERC777: send to zero address\");\r\n\r\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\r\n\r\n _move(operator, from, to, amount, userData, operatorData);\r\n\r\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\r\n }\r\n\r\n /**\r\n * @dev Burn tokens\r\n * @param operator address operator requesting the operation\r\n * @param from address token holder address\r\n * @param amount uint256 amount of tokens to burn\r\n * @param data bytes extra information provided by the token holder\r\n * @param operatorData bytes extra information provided by the operator (if any)\r\n */\r\n function _burn(\r\n address operator,\r\n address from,\r\n uint256 amount,\r\n bytes memory data,\r\n bytes memory operatorData\r\n )\r\n internal\r\n {\r\n require(from != address(0), \"ERC777: burn from zero address\");\r\n\r\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\r\n\r\n // Update state variables\r\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\r\n _totalSupply = _totalSupply.sub(amount);\r\n\r\n emit Burned(operator, from, amount, data, operatorData);\r\n emit Transfer(from, address(0), amount);\r\n }\r\n\r\n function _move(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256 amount,\r\n bytes memory userData,\r\n bytes memory operatorData\r\n )\r\n internal\r\n {\r\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\r\n _balances[to] = _balances[to].add(amount);\r\n\r\n emit Sent(operator, from, to, amount, userData, operatorData);\r\n emit Transfer(from, to, amount);\r\n }\r\n\r\n function _approve(address holder, address spender, uint256 value) internal {\r\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\r\n // currently unnecessary.\r\n //require(holder != address(0), \"ERC777: approve from the zero address\");\r\n require(spender != address(0), \"ERC777: approve to zero address\");\r\n\r\n _allowances[holder][spender] = value;\r\n emit Approval(holder, spender, value);\r\n }\r\n\r\n /**\r\n * @dev Call from.tokensToSend() if the interface is registered\r\n * @param operator address operator requesting the transfer\r\n * @param from address token holder address\r\n * @param to address recipient address\r\n * @param amount uint256 amount of tokens to transfer\r\n * @param userData bytes extra information provided by the token holder (if any)\r\n * @param operatorData bytes extra information provided by the operator (if any)\r\n */\r\n function _callTokensToSend(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256 amount,\r\n bytes memory userData,\r\n bytes memory operatorData\r\n )\r\n internal\r\n {\r\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\r\n if (implementer != address(0)) {\r\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\r\n }\r\n }\r\n\r\n /**\r\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\r\n * tokensReceived() was not registered for the recipient\r\n * @param operator address operator requesting the transfer\r\n * @param from address token holder address\r\n * @param to address recipient address\r\n * @param amount uint256 amount of tokens to transfer\r\n * @param userData bytes extra information provided by the token holder (if any)\r\n * @param operatorData bytes extra information provided by the operator (if any)\r\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\r\n */\r\n function _callTokensReceived(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256 amount,\r\n bytes memory userData,\r\n bytes memory operatorData,\r\n bool requireReceptionAck\r\n )\r\n private\r\n {\r\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\r\n if (implementer != address(0)) {\r\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\r\n } else if (requireReceptionAck) {\r\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\r\n }\r\n }\r\n}\r\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\ninterface IERC677Receiver {\r\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\r\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\r\n *\r\n * `IERC777` Token holders can be notified of operations performed on their\r\n * tokens by having a contract implement this interface (contract holders can be\r\n * their own implementer) and registering it on the\r\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\r\n *\r\n * See `IERC1820Registry` and `ERC1820Implementer`.\r\n */\r\ninterface IERC777Sender {\r\n /**\r\n * @dev Called by an `IERC777` token contract whenever a registered holder's\r\n * (`from`) tokens are about to be moved or destroyed. The type of operation\r\n * is conveyed by `to` being the zero address or not.\r\n *\r\n * This call occurs _before_ the token contract's state is updated, so\r\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\r\n *\r\n * This function may revert to prevent the operation from being executed.\r\n */\r\n function tokensToSend(\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes calldata userData,\r\n bytes calldata operatorData\r\n ) external;\r\n}\r\n"
+ },
+ "contracts/Bridge/BridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\n// Import base Initializable contract\r\nimport \"../zeppelin/upgradable/Initializable.sol\";\r\n// Import interface and library from OpenZeppelin contracts\r\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\r\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\r\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\r\n\r\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\r\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\r\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\r\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\r\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\r\nimport \"../zeppelin/utils/Address.sol\";\r\nimport \"../zeppelin/math/SafeMath.sol\";\r\n\r\nimport \"./IBridgeV2.sol\";\r\nimport \"../interface/ISideToken.sol\";\r\nimport \"../interface/ISideTokenFactory.sol\";\r\nimport \"../AllowTokens/AllowTokensV0.sol\";\r\nimport \"../Utils/UtilsV1.sol\";\r\n\r\ncontract BridgeV2 is Initializable, IBridgeV2, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\r\n using SafeMath for uint256;\r\n using SafeERC20 for IERC20;\r\n using Address for address;\r\n\r\n address constant private NULL_ADDRESS = address(0);\r\n bytes32 constant private NULL_HASH = bytes32(0);\r\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\r\n\r\n address private federation;\r\n uint256 private feePercentage;\r\n string public symbolPrefix;\r\n uint256 public lastDay;\r\n uint256 public spentToday;\r\n\r\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\r\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\r\n mapping (address => bool) public knownTokens; // OriginalToken => true\r\n mapping(bytes32 => bool) public processed; // ProcessedHash => true\r\n AllowTokensV0 public allowTokens;\r\n ISideTokenFactory public sideTokenFactory;\r\n //Bridge_v1 variables\r\n bool public isUpgrading;\r\n uint256 constant public FEE_PERCENTAGE_DIVIDER = 10000; // Percentage with up to 2 decimals\r\n bool private alreadyRun;\r\n\r\n event FederationChanged(address _newFederation);\r\n event SideTokenFactoryChanged(address _newSideTokenFactory);\r\n event Upgrading(bool isUpgrading);\r\n function initialize(\r\n address _manager,\r\n address _federation,\r\n address _allowTokens,\r\n address _sideTokenFactory,\r\n string memory _symbolPrefix\r\n ) public initializer {\r\n UpgradableOwnable.initialize(_manager);\r\n UpgradablePausable.__Pausable_init(_manager);\r\n symbolPrefix = _symbolPrefix;\r\n allowTokens = AllowTokensV0(_allowTokens);\r\n _changeSideTokenFactory(_sideTokenFactory);\r\n _changeFederation(_federation);\r\n //keccak256(\"ERC777TokensRecipient\")\r\n ERC_1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\r\n }\r\n\r\n function version() external pure override returns (string memory) {\r\n return \"v2\";\r\n }\r\n\r\n modifier onlyFederation() {\r\n require(msg.sender == federation, \"Bridge: Sender not Federation\");\r\n _;\r\n }\r\n\r\n modifier whenNotUpgrading() {\r\n require(!isUpgrading, \"Bridge: Upgrading\");\r\n _;\r\n }\r\n\r\n function acceptTransfer(\r\n address tokenAddress,\r\n address receiver,\r\n uint256 amount,\r\n string calldata symbol,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex,\r\n uint8 decimals,\r\n uint256 granularity\r\n ) external onlyFederation whenNotPaused nonReentrant override returns(bool) {\r\n require(tokenAddress != NULL_ADDRESS, \"Bridge: Token is null\");\r\n require(receiver != NULL_ADDRESS, \"Bridge: Receiver is null\");\r\n require(amount > 0, \"Bridge: Amount 0\");\r\n require(bytes(symbol).length > 0, \"Bridge: Empty symbol\");\r\n require(blockHash != NULL_HASH, \"Bridge: BlockHash is null\");\r\n require(transactionHash != NULL_HASH, \"Bridge: Transaction is null\");\r\n require(decimals <= 18, \"Bridge: Decimals bigger 18\");\r\n require(UtilsV1.granularityToDecimals(granularity) <= 18, \"Bridge: invalid granularity\");\r\n\r\n _processTransaction(blockHash, transactionHash, receiver, amount, logIndex);\r\n\r\n if (knownTokens[tokenAddress]) {\r\n _acceptCrossBackToToken(receiver, tokenAddress, decimals, granularity, amount);\r\n } else {\r\n _acceptCrossToSideToken(receiver, tokenAddress, decimals, granularity, amount, symbol);\r\n }\r\n return true;\r\n }\r\n\r\n function _acceptCrossToSideToken(\r\n address receiver,\r\n address tokenAddress,\r\n uint8 decimals,\r\n uint256 granularity,\r\n uint256 amount,\r\n string memory symbol\r\n ) private {\r\n\r\n (uint256 calculatedGranularity,uint256 formattedAmount) = UtilsV1.calculateGranularityAndAmount(decimals, granularity, amount);\r\n address sideToken = mappedTokens[tokenAddress];\r\n if (sideToken == NULL_ADDRESS) {\r\n sideToken = _createSideToken(tokenAddress, symbol, calculatedGranularity);\r\n } else {\r\n require(calculatedGranularity == IERC777(sideToken).granularity(), \"Bridge: Granularity differ from side token\");\r\n }\r\n ISideToken(sideToken).mint(receiver, formattedAmount, \"\", \"\");\r\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, 18, calculatedGranularity);\r\n }\r\n\r\n function _acceptCrossBackToToken(address receiver, address tokenAddress, uint8 decimals, uint256 granularity, uint256 amount) private {\r\n require(decimals == 18, \"Bridge: Invalid decimals cross back\");\r\n //As side tokens are ERC777 we need to convert granularity to decimals\r\n (uint8 calculatedDecimals, uint256 formattedAmount) = UtilsV1.calculateDecimalsAndAmount(tokenAddress, granularity, amount);\r\n IERC20(tokenAddress).safeTransfer(receiver, formattedAmount);\r\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, calculatedDecimals, 1);\r\n }\r\n\r\n /**\r\n * ERC-20 tokens approve and transferFrom pattern\r\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\r\n */\r\n function receiveTokens(address tokenToUse, uint256 amount) override external whenNotUpgrading whenNotPaused nonReentrant returns(bool) {\r\n address sender = _msgSender();\r\n require(!sender.isContract(), \"Bridge: Sender can't be a contract\");\r\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\r\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\r\n crossTokens(tokenToUse, sender, amount, \"\");\r\n return true;\r\n }\r\n\r\n /**\r\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\r\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\r\n */\r\n function tokensReceived (\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes calldata userData,\r\n bytes calldata\r\n ) external whenNotPaused whenNotUpgrading override(IBridgeV2, IERC777Recipient) {\r\n //Hook from ERC777address\r\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\r\n require(to == address(this), \"Bridge: Not to address\");\r\n address tokenToUse = _msgSender();\r\n //This can only be used with trusted contracts\r\n crossTokens(tokenToUse, from, amount, userData);\r\n }\r\n\r\n function crossTokens(address tokenToUse, address from, uint256 amount, bytes memory userData) private {\r\n bool isASideToken = originalTokens[tokenToUse] != NULL_ADDRESS;\r\n //Send the payment to the MultiSig of the Federation\r\n uint256 fee = amount.mul(feePercentage).div(FEE_PERCENTAGE_DIVIDER);\r\n uint256 amountMinusFees = amount.sub(fee);\r\n if (isASideToken) {\r\n uint256 modulo = amountMinusFees.mod(IERC777(tokenToUse).granularity());\r\n fee = fee.add(modulo);\r\n amountMinusFees = amountMinusFees.sub(modulo);\r\n }\r\n if(fee > 0) {\r\n IERC20(tokenToUse).safeTransfer(owner(), fee);\r\n }\r\n if (isASideToken) {\r\n verifyWithAllowTokens(tokenToUse, amount, isASideToken);\r\n //Side Token Crossing\r\n IERC777(tokenToUse).burn(amountMinusFees, userData);\r\n // solium-disable-next-line max-len\r\n emit Cross(originalTokens[tokenToUse], from, amountMinusFees, IERC777(tokenToUse).symbol(), userData, IERC777(tokenToUse).decimals(), IERC777(tokenToUse).granularity());\r\n } else {\r\n //Main Token Crossing\r\n knownTokens[tokenToUse] = true;\r\n (uint8 decimals, uint256 granularity, string memory symbol) = UtilsV1.getTokenInfo(tokenToUse);\r\n uint formattedAmount = amount;\r\n if(decimals != 18) {\r\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\r\n }\r\n //We consider the amount before fees converted to 18 decimals to check the limits\r\n verifyWithAllowTokens(tokenToUse, formattedAmount, isASideToken);\r\n emit Cross(tokenToUse, from, amountMinusFees, symbol, userData, decimals, granularity);\r\n }\r\n }\r\n\r\n function _createSideToken(address token, string memory symbol, uint256 granularity) private returns (address sideToken){\r\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, symbol));\r\n address sideTokenAddress = sideTokenFactory.createSideToken(newSymbol, newSymbol, granularity);\r\n sideToken = sideTokenAddress;\r\n mappedTokens[token] = sideToken;\r\n originalTokens[sideTokenAddress] = token;\r\n emit NewSideToken(sideTokenAddress, token, newSymbol, granularity);\r\n return sideToken;\r\n }\r\n\r\n function verifyWithAllowTokens(address tokenToUse, uint256 amount, bool isASideToken) private {\r\n // solium-disable-next-line security/no-block-members\r\n if (block.timestamp > lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\r\n // solium-disable-next-line security/no-block-members\r\n lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\r\n spentToday = 0;\r\n }\r\n require(allowTokens.isValidTokenTransfer(tokenToUse, amount, spentToday, isASideToken), \"Bridge: Bigger than limit\");\r\n spentToday = spentToday.add(amount);\r\n }\r\n\r\n function getTransactionId(\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n address _receiver,\r\n uint256 _amount,\r\n uint32 _logIndex\r\n )\r\n public pure returns(bytes32)\r\n {\r\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _receiver, _amount, _logIndex));\r\n }\r\n\r\n function _processTransaction(\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n address _receiver,\r\n uint256 _amount,\r\n uint32 _logIndex\r\n )\r\n private\r\n {\r\n bytes32 compiledId = getTransactionId(_blockHash, _transactionHash, _receiver, _amount, _logIndex);\r\n require(!processed[compiledId], \"Bridge: Already processed\");\r\n processed[compiledId] = true;\r\n }\r\n\r\n function setFeePercentage(uint amount) external onlyOwner whenNotPaused {\r\n require(amount < (FEE_PERCENTAGE_DIVIDER/10), \"Bridge: bigger than 10%\");\r\n feePercentage = amount;\r\n emit FeePercentageChanged(feePercentage);\r\n }\r\n\r\n function getFeePercentage() override external view returns(uint) {\r\n return feePercentage;\r\n }\r\n\r\n function calcMaxWithdraw() override external view returns (uint) {\r\n uint spent = spentToday;\r\n // solium-disable-next-line security/no-block-members\r\n if (block.timestamp > lastDay + 24 hours) // solhint-disable-line not-rely-on-time\r\n spent = 0;\r\n return allowTokens.calcMaxWithdraw(spent);\r\n }\r\n\r\n function changeFederation(address newFederation) external onlyOwner returns(bool) {\r\n _changeFederation(newFederation);\r\n return true;\r\n }\r\n\r\n function _changeFederation(address newFederation) internal {\r\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\r\n federation = newFederation;\r\n emit FederationChanged(federation);\r\n }\r\n\r\n function getFederation() external view returns(address) {\r\n return federation;\r\n }\r\n\r\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner returns(bool) {\r\n _changeSideTokenFactory(newSideTokenFactory);\r\n return true;\r\n }\r\n\r\n function _changeSideTokenFactory(address newSideTokenFactory) internal {\r\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\r\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\r\n emit SideTokenFactoryChanged(newSideTokenFactory);\r\n }\r\n\r\n function startUpgrade() external onlyOwner {\r\n isUpgrading = true;\r\n emit Upgrading(isUpgrading);\r\n }\r\n\r\n function endUpgrade() external onlyOwner {\r\n isUpgrading = false;\r\n emit Upgrading(isUpgrading);\r\n }\r\n\r\n //This method is only to recreate the USDT and USDC tokens on rsk without granularity restrictions.\r\n function clearSideToken() external onlyOwner returns(bool) {\r\n require(!alreadyRun, \"already done\");\r\n alreadyRun = true;\r\n address payable[4] memory sideTokens = [\r\n 0xe506F698b31a66049BD4653ed934E7a07Cbc5549,\r\n 0x5a42221D7AaE8e185BC0054Bb036D9757eC18857,\r\n 0xcdc8ccBbFB6407c53118fE47259e8d00C81F42CD,\r\n 0x6117C9529F15c52e2d3188d5285C745B757b5825\r\n ];\r\n for (uint i = 0; i < sideTokens.length; i++) {\r\n address originalToken = address(originalTokens[sideTokens[i]]);\r\n originalTokens[sideTokens[i]] = NULL_ADDRESS;\r\n mappedTokens[originalToken] = address(NULL_ADDRESS);\r\n }\r\n return true;\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/Bridge/IBridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\ninterface IBridgeV2 {function version() external pure returns (string memory);\r\n\r\n function getFeePercentage() external view returns(uint);\r\n\r\n function calcMaxWithdraw() external view returns (uint);\r\n\r\n /**\r\n * ERC-20 tokens approve and transferFrom pattern\r\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\r\n */\r\n function receiveTokens(address tokenToUse, uint256 amount) external returns(bool);\r\n\r\n /**\r\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\r\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\r\n */\r\n function tokensReceived (\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes calldata userData,\r\n bytes calldata operatorData\r\n ) external;\r\n\r\n /**\r\n * Accepts the transaction from the other chain that was voted and sent by the federation contract\r\n */\r\n function acceptTransfer(\r\n address originalTokenAddress,\r\n address receiver,\r\n uint256 amount,\r\n string calldata symbol,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex,\r\n uint8 decimals,\r\n uint256 granularity\r\n ) external returns(bool);\r\n\r\n event Cross(address indexed _tokenAddress, address indexed _to, uint256 _amount, string _symbol, bytes _userData,\r\n uint8 _decimals, uint256 _granularity);\r\n event NewSideToken(address indexed _newSideTokenAddress, address indexed _originalTokenAddress, string _newSymbol, uint256 _granularity);\r\n event AcceptedCrossTransfer(address indexed _tokenAddress, address indexed _to, uint256 _amount, uint8 _decimals, uint256 _granularity,\r\n uint256 _formattedAmount, uint8 _calculatedDecimals, uint256 _calculatedGranularity);\r\n event FeePercentageChanged(uint256 _amount);\r\n}"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/math/SafeMath.sol\";\r\nimport \"../zeppelin/ownership/Ownable.sol\";\r\n\r\ncontract AllowTokensV0 is Ownable {\r\n using SafeMath for uint256;\r\n\r\n address constant private NULL_ADDRESS = address(0);\r\n\r\n mapping (address => bool) public allowedTokens;\r\n bool private validateAllowedTokens;\r\n uint256 private maxTokensAllowed;\r\n uint256 private minTokensAllowed;\r\n uint256 public dailyLimit;\r\n\r\n event AllowedTokenAdded(address indexed _tokenAddress);\r\n event AllowedTokenRemoved(address indexed _tokenAddress);\r\n event AllowedTokenValidation(bool _enabled);\r\n event MaxTokensAllowedChanged(uint256 _maxTokens);\r\n event MinTokensAllowedChanged(uint256 _minTokens);\r\n event DailyLimitChanged(uint256 dailyLimit);\r\n\r\n modifier notNull(address _address) {\r\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\r\n _;\r\n }\r\n\r\n constructor(address _manager) {\r\n transferOwnership(_manager);\r\n validateAllowedTokens = true;\r\n maxTokensAllowed = 10000 ether;\r\n minTokensAllowed = 1 ether;\r\n dailyLimit = 100000 ether;\r\n }\r\n\r\n function isValidatingAllowedTokens() external view returns(bool) {\r\n return validateAllowedTokens;\r\n }\r\n\r\n function getMaxTokensAllowed() external view returns(uint256) {\r\n return maxTokensAllowed;\r\n }\r\n\r\n function getMinTokensAllowed() external view returns(uint256) {\r\n return minTokensAllowed;\r\n }\r\n\r\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\r\n return allowedTokens[token];\r\n }\r\n\r\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\r\n if (validateAllowedTokens) {\r\n return allowedTokenExist(token);\r\n }\r\n return true;\r\n }\r\n\r\n function addAllowedToken(address token) external onlyOwner {\r\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\r\n allowedTokens[token] = true;\r\n emit AllowedTokenAdded(token);\r\n }\r\n\r\n function removeAllowedToken(address token) external onlyOwner {\r\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\r\n allowedTokens[token] = false;\r\n emit AllowedTokenRemoved(token);\r\n }\r\n\r\n function enableAllowedTokensValidation() external onlyOwner {\r\n validateAllowedTokens = true;\r\n emit AllowedTokenValidation(validateAllowedTokens);\r\n }\r\n\r\n function disableAllowedTokensValidation() external onlyOwner {\r\n // Before disabling Allowed Tokens Validations some kind of contract validation system\r\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\r\n validateAllowedTokens = false;\r\n emit AllowedTokenValidation(validateAllowedTokens);\r\n }\r\n\r\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\r\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\r\n maxTokensAllowed = maxTokens;\r\n emit MaxTokensAllowedChanged(maxTokensAllowed);\r\n }\r\n\r\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\r\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\r\n minTokensAllowed = minTokens;\r\n emit MinTokensAllowedChanged(minTokensAllowed);\r\n }\r\n\r\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\r\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\r\n dailyLimit = _dailyLimit;\r\n emit DailyLimitChanged(_dailyLimit);\r\n }\r\n\r\n // solium-disable-next-line max-len\r\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\r\n if(amount > maxTokensAllowed)\r\n return false;\r\n if(amount < minTokensAllowed)\r\n return false;\r\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\r\n return false;\r\n if(!isSideToken && !isTokenAllowed(tokenToUse))\r\n return false;\r\n return true;\r\n }\r\n\r\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\r\n uint maxWithrow = dailyLimit - spentToday;\r\n if (dailyLimit < spentToday)\r\n return 0;\r\n if(maxWithrow > maxTokensAllowed)\r\n maxWithrow = maxTokensAllowed;\r\n return maxWithrow;\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/Utils/UtilsV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/math/SafeMath.sol\";\r\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\r\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\r\n\r\nlibrary UtilsV1 {\r\n using SafeMath for uint256;\r\n\r\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\r\n // keccak256(\"ERC777Token\")\r\n bytes32 constant private TOKENS_ERC777_HASH = 0xac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054;\r\n\r\n function getTokenInfo(address tokenToUse) external view returns (uint8 decimals, uint256 granularity, string memory symbol) {\r\n decimals = getDecimals(tokenToUse);\r\n granularity = getGranularity(tokenToUse);\r\n symbol = getSymbol(tokenToUse);\r\n }\r\n\r\n function getSymbol(address tokenToUse) public view returns (string memory symbol) {\r\n //support 32 bytes or string symbol\r\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"symbol()\"));\r\n require(success, \"Utils: Token hasn't symbol()\");\r\n if (data.length == 32) {\r\n symbol = bytes32ToString(abi.decode(data, (bytes32)));\r\n } else {\r\n symbol = abi.decode(data, (string));\r\n }\r\n require(bytes(symbol).length > 0, \"Utils: Token empty symbol\");\r\n return symbol;\r\n }\r\n\r\n function getDecimals(address tokenToUse) public view returns (uint8) {\r\n //support decimals as uint256 or uint8\r\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\r\n require(success, \"Utils: No decimals\");\r\n require(data.length == 32, \"Utils: Decimals not uint\");\r\n // uint: enc(X) is the big-endian encoding of X,\r\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\r\n uint256 decimalsDecoded = abi.decode(data, (uint256));\r\n require(decimalsDecoded <= 18, \"Utils: Decimals not in 0 to 18\");\r\n return uint8(decimalsDecoded);\r\n }\r\n\r\n function getGranularity(address tokenToUse) public view returns (uint256 granularity) {\r\n granularity = 1;\r\n //support granularity if ERC777\r\n address implementer = ERC_1820.getInterfaceImplementer(tokenToUse, TOKENS_ERC777_HASH);\r\n if (implementer != address(0)) {\r\n granularity = IERC777(implementer).granularity();\r\n //Verify granularity is power of 10 to keep it compatible with ERC20 decimals\r\n granularityToDecimals(granularity);\r\n }\r\n return granularity;\r\n }\r\n\r\n /* bytes32 (fixed-size array) to string (dynamically-sized array) */\r\n function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) {\r\n uint8 i = 0;\r\n while(i < 32 && _bytes32[i] != 0) {\r\n i++;\r\n }\r\n bytes memory bytesArray = new bytes(i);\r\n for (i = 0; i < 32 && _bytes32[i] != 0; i++) {\r\n bytesArray[i] = _bytes32[i];\r\n }\r\n return string(bytesArray);\r\n }\r\n\r\n function decimalsToGranularity(uint8 decimals) public pure returns (uint256) {\r\n require(decimals <= 18, \"Utils: Decimals not in 0 to 18\");\r\n return uint256(10)**(18-decimals);\r\n }\r\n\r\n function granularityToDecimals(uint256 granularity) public pure returns (uint8) {\r\n if(granularity == 1) return 18;\r\n if(granularity == 10) return 17;\r\n if(granularity == 100) return 16;\r\n if(granularity == 1000) return 15;\r\n if(granularity == 10000) return 14;\r\n if(granularity == 100000) return 13;\r\n if(granularity == 1000000) return 12;\r\n if(granularity == 10000000) return 11;\r\n if(granularity == 100000000) return 10;\r\n if(granularity == 1000000000) return 9;\r\n if(granularity == 10000000000) return 8;\r\n if(granularity == 100000000000) return 7;\r\n if(granularity == 1000000000000) return 6;\r\n if(granularity == 10000000000000) return 5;\r\n if(granularity == 100000000000000) return 4;\r\n if(granularity == 1000000000000000) return 3;\r\n if(granularity == 10000000000000000) return 2;\r\n if(granularity == 100000000000000000) return 1;\r\n if(granularity == 1000000000000000000) return 0;\r\n require(false, \"Utils: invalid granularity\");\r\n return 0;\r\n }\r\n\r\n function calculateGranularityAndAmount(uint8 decimals, uint256 granularity, uint256 amount) external pure\r\n returns(uint256 calculatedGranularity, uint256 formattedAmount) {\r\n\r\n if(decimals == 18) {\r\n //tokenAddress is a ERC20 with 18 decimals should have 1 granularity\r\n //tokenAddress is a ERC777 token we give the same granularity\r\n calculatedGranularity = granularity;\r\n formattedAmount = amount;\r\n } else {\r\n //tokenAddress is a ERC20 with other than 18 decimals\r\n calculatedGranularity = decimalsToGranularity(decimals);\r\n formattedAmount = amount.mul(calculatedGranularity);\r\n }\r\n }\r\n\r\n function calculateDecimalsAndAmount(address tokenAddress, uint256 granularity, uint256 amount)\r\n external view returns (uint8 calculatedDecimals, uint256 formattedAmount) {\r\n uint8 tokenDecimals = getDecimals(tokenAddress);\r\n //As side tokens are ERC777 we need to convert granularity to decimals\r\n calculatedDecimals = granularityToDecimals(granularity);\r\n require(tokenDecimals == calculatedDecimals, \"Utils: Token decimals differ from decimals - granularity\");\r\n formattedAmount = amount.div(granularity);\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../GSN/Context.sol\";\r\n/**\r\n * @dev Contract module which provides a basic access control mechanism, where\r\n * there is an account (an owner) that can be granted exclusive access to\r\n * specific functions.\r\n *\r\n * This module is used through inheritance. It will make available the modifier\r\n * `onlyOwner`, which can be applied to your functions to restrict their use to\r\n * the owner.\r\n */\r\nabstract contract Ownable is Context {\r\n address private _owner;\r\n\r\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\r\n\r\n /**\r\n * @dev Initializes the contract setting the deployer as the initial owner.\r\n */\r\n constructor () {\r\n _owner = _msgSender();\r\n emit OwnershipTransferred(address(0), _owner);\r\n }\r\n\r\n /**\r\n * @dev Returns the address of the current owner.\r\n */\r\n function owner() public view returns (address) {\r\n return _owner;\r\n }\r\n\r\n /**\r\n * @dev Throws if called by any account other than the owner.\r\n */\r\n modifier onlyOwner() {\r\n require(isOwner(), \"Ownable: caller is not the owner\");\r\n _;\r\n }\r\n\r\n /**\r\n * @dev Returns true if the caller is the current owner.\r\n */\r\n function isOwner() public view returns (bool) {\r\n return _msgSender() == _owner;\r\n }\r\n\r\n /**\r\n * @dev Leaves the contract without owner. It will not be possible to call\r\n * `onlyOwner` functions anymore. Can only be called by the current owner.\r\n *\r\n * NOTE: Renouncing ownership will leave the contract without an owner,\r\n * thereby removing any functionality that is only available to the owner.\r\n */\r\n function renounceOwnership() public onlyOwner {\r\n emit OwnershipTransferred(_owner, address(0));\r\n _owner = address(0);\r\n }\r\n\r\n /**\r\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n * Can only be called by the current owner.\r\n */\r\n function transferOwnership(address newOwner) public onlyOwner {\r\n _transferOwnership(newOwner);\r\n }\r\n\r\n /**\r\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n */\r\n function _transferOwnership(address newOwner) internal {\r\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\r\n emit OwnershipTransferred(_owner, newOwner);\r\n _owner = newOwner;\r\n }\r\n}\r\n"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../interface/IBridge.sol\";\r\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\r\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\r\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\r\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\r\n\r\ncontract mockReceiveTokensCall is IERC777Recipient {\r\n address public bridge;\r\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\r\n\r\n constructor(address _bridge) {\r\n bridge = _bridge;\r\n //keccak256(\"ERC777TokensRecipient\")\r\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\r\n }\r\n\r\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount) external {\r\n IERC20(tokenToUse).approve(bridge, amount);\r\n IBridge(bridge).receiveTokensTo(tokenToUse, receiver, amount);\r\n }\r\n\r\n function callDepositTo(address receiver) external payable {\r\n IBridge(bridge).depositTo{ value: msg.value }(receiver);\r\n }\r\n\r\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\r\n IERC777(tokenToUse).send(bridge, amount, data);\r\n }\r\n\r\n // Mandatory for IERC777Recipient\r\n function tokensReceived(\r\n address,\r\n address,\r\n address,\r\n uint,\r\n bytes calldata,\r\n bytes calldata\r\n ) override external view {\r\n this;\r\n }\r\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\r\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\r\n\r\ncontract mockERC777Recipient is IERC777Recipient {\r\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\r\n\r\n constructor() {\r\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\r\n }\r\n\r\n event Success(\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes userData,\r\n bytes operatorData);\r\n\r\n /**\r\n * ERC-677's only method implementation\r\n * See https://github.com/ethereum/EIPs/issues/677 for details\r\n */\r\n function tokensReceived(\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes calldata userData,\r\n bytes calldata operatorData\r\n ) override external {\r\n emit Success(operator, from, to, amount, userData, operatorData);\r\n }\r\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\r\n\r\ncontract SideTokenV1 is ERC777 {\r\n address public minter;\r\n\r\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\r\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\r\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\r\n minter = _minterAddr;\r\n }\r\n\r\n modifier onlyMinter() {\r\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\r\n _;\r\n }\r\n function mint(\r\n address account,\r\n uint256 amount,\r\n bytes calldata userData,\r\n bytes calldata operatorData\r\n )\r\n external onlyMinter\r\n {\r\n _mint(_msgSender(), account, amount, userData, operatorData);\r\n }\r\n\r\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/ownership/Secondary.sol\";\r\nimport \"../SideToken/SideTokenV1.sol\";\r\n\r\ncontract SideTokenFactoryV1 is Secondary {\r\n event CreatedSideToken(address sideToken, string symbol);\r\n\r\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\r\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\r\n emit CreatedSideToken(address(sideToken), symbol);\r\n return sideToken;\r\n }\r\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./IERC1155.sol\";\r\nimport \"./IERC1155MetadataURI.sol\";\r\nimport \"./IERC1155Receiver.sol\";\r\nimport \"../../GSN/Context.sol\";\r\nimport \"../../introspection/ERC165.sol\";\r\nimport \"../../math/SafeMath.sol\";\r\nimport \"../../utils/Address.sol\";\r\n\r\n/**\r\n *\r\n * @dev Implementation of the basic standard multi-token.\r\n * See https://eips.ethereum.org/EIPS/eip-1155\r\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\r\n *\r\n * _Available since v3.1._\r\n */\r\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\r\n using SafeMath for uint256;\r\n using Address for address;\r\n\r\n // Mapping from token ID to account balances\r\n mapping (uint256 => mapping(address => uint256)) private _balances;\r\n\r\n // Mapping from account to operator approvals\r\n mapping (address => mapping(address => bool)) private _operatorApprovals;\r\n\r\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\r\n string private _uri;\r\n\r\n /*\r\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\r\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\r\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\r\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\r\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\r\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\r\n *\r\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\r\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\r\n */\r\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\r\n\r\n /*\r\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\r\n */\r\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\r\n\r\n /**\r\n * @dev See {_setURI}.\r\n */\r\n constructor (string memory uri_) {\r\n _setURI(uri_);\r\n\r\n // register the supported interfaces to conform to ERC1155 via ERC165\r\n _registerInterface(_INTERFACE_ID_ERC1155);\r\n\r\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\r\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\r\n }\r\n\r\n /**\r\n * @dev See {IERC1155MetadataURI-uri}.\r\n *\r\n * This implementation returns the same URI for *all* token types. It relies\r\n * on the token type ID substitution mechanism\r\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\r\n *\r\n * Clients calling this function must replace the `\\{id\\}` substring with the\r\n * actual token type ID.\r\n */\r\n function uri(uint256) external view virtual override returns (string memory) {\r\n return _uri;\r\n }\r\n\r\n /**\r\n * @dev See {IERC1155-balanceOf}.\r\n *\r\n * Requirements:\r\n *\r\n * - `account` cannot be the zero address.\r\n */\r\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\r\n require(account != address(0), \"ERC1155: balance query for the zero address\");\r\n return _balances[id][account];\r\n }\r\n\r\n /**\r\n * @dev See {IERC1155-balanceOfBatch}.\r\n *\r\n * Requirements:\r\n *\r\n * - `accounts` and `ids` must have the same length.\r\n */\r\n function balanceOfBatch(\r\n address[] memory accounts,\r\n uint256[] memory ids\r\n )\r\n public\r\n view\r\n virtual\r\n override\r\n returns (uint256[] memory)\r\n {\r\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\r\n\r\n uint256[] memory batchBalances = new uint256[](accounts.length);\r\n\r\n for (uint256 i = 0; i < accounts.length; ++i) {\r\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\r\n }\r\n\r\n return batchBalances;\r\n }\r\n\r\n /**\r\n * @dev See {IERC1155-setApprovalForAll}.\r\n */\r\n function setApprovalForAll(address operator, bool approved) public virtual override {\r\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\r\n\r\n _operatorApprovals[_msgSender()][operator] = approved;\r\n emit ApprovalForAll(_msgSender(), operator, approved);\r\n }\r\n\r\n /**\r\n * @dev See {IERC1155-isApprovedForAll}.\r\n */\r\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\r\n return _operatorApprovals[account][operator];\r\n }\r\n\r\n /**\r\n * @dev See {IERC1155-safeTransferFrom}.\r\n */\r\n function safeTransferFrom(\r\n address from,\r\n address to,\r\n uint256 id,\r\n uint256 amount,\r\n bytes memory data\r\n )\r\n public\r\n virtual\r\n override\r\n {\r\n require(to != address(0), \"ERC1155: transfer to the zero address\");\r\n require(\r\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\r\n \"ERC1155: caller is not owner nor approved\"\r\n );\r\n\r\n address operator = _msgSender();\r\n\r\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\r\n\r\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\r\n _balances[id][to] = _balances[id][to].add(amount);\r\n\r\n emit TransferSingle(operator, from, to, id, amount);\r\n\r\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\r\n }\r\n\r\n /**\r\n * @dev See {IERC1155-safeBatchTransferFrom}.\r\n */\r\n function safeBatchTransferFrom(\r\n address from,\r\n address to,\r\n uint256[] memory ids,\r\n uint256[] memory amounts,\r\n bytes memory data\r\n )\r\n public\r\n virtual\r\n override\r\n {\r\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\r\n require(to != address(0), \"ERC1155: transfer to the zero address\");\r\n require(\r\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\r\n \"ERC1155: transfer caller is not owner nor approved\"\r\n );\r\n\r\n address operator = _msgSender();\r\n\r\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\r\n\r\n for (uint256 i = 0; i < ids.length; ++i) {\r\n uint256 id = ids[i];\r\n uint256 amount = amounts[i];\r\n\r\n _balances[id][from] = _balances[id][from].sub(\r\n amount,\r\n \"ERC1155: insufficient balance for transfer\"\r\n );\r\n _balances[id][to] = _balances[id][to].add(amount);\r\n }\r\n\r\n emit TransferBatch(operator, from, to, ids, amounts);\r\n\r\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\r\n }\r\n\r\n /**\r\n * @dev Sets a new URI for all token types, by relying on the token type ID\r\n * substitution mechanism\r\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\r\n *\r\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\r\n * URI or any of the amounts in the JSON file at said URI will be replaced by\r\n * clients with the token type ID.\r\n *\r\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\r\n * interpreted by clients as\r\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\r\n * for token type ID 0x4cce0.\r\n *\r\n * See {uri}.\r\n *\r\n * Because these URIs cannot be meaningfully represented by the {URI} event,\r\n * this function emits no events.\r\n */\r\n function _setURI(string memory newuri) internal virtual {\r\n _uri = newuri;\r\n }\r\n\r\n /**\r\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\r\n *\r\n * Emits a {TransferSingle} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `account` cannot be the zero address.\r\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\r\n * acceptance magic value.\r\n */\r\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\r\n require(account != address(0), \"ERC1155: mint to the zero address\");\r\n\r\n address operator = _msgSender();\r\n\r\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\r\n\r\n _balances[id][account] = _balances[id][account].add(amount);\r\n emit TransferSingle(operator, address(0), account, id, amount);\r\n\r\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\r\n }\r\n\r\n /**\r\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\r\n *\r\n * Requirements:\r\n *\r\n * - `ids` and `amounts` must have the same length.\r\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\r\n * acceptance magic value.\r\n */\r\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\r\n require(to != address(0), \"ERC1155: mint to the zero address\");\r\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\r\n\r\n address operator = _msgSender();\r\n\r\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\r\n\r\n for (uint i = 0; i < ids.length; i++) {\r\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\r\n }\r\n\r\n emit TransferBatch(operator, address(0), to, ids, amounts);\r\n\r\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\r\n }\r\n\r\n /**\r\n * @dev Destroys `amount` tokens of token type `id` from `account`\r\n *\r\n * Requirements:\r\n *\r\n * - `account` cannot be the zero address.\r\n * - `account` must have at least `amount` tokens of token type `id`.\r\n */\r\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\r\n require(account != address(0), \"ERC1155: burn from the zero address\");\r\n\r\n address operator = _msgSender();\r\n\r\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\r\n\r\n _balances[id][account] = _balances[id][account].sub(\r\n amount,\r\n \"ERC1155: burn amount exceeds balance\"\r\n );\r\n\r\n emit TransferSingle(operator, account, address(0), id, amount);\r\n }\r\n\r\n /**\r\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\r\n *\r\n * Requirements:\r\n *\r\n * - `ids` and `amounts` must have the same length.\r\n */\r\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\r\n require(account != address(0), \"ERC1155: burn from the zero address\");\r\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\r\n\r\n address operator = _msgSender();\r\n\r\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\r\n\r\n for (uint i = 0; i < ids.length; i++) {\r\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\r\n amounts[i],\r\n \"ERC1155: burn amount exceeds balance\"\r\n );\r\n }\r\n\r\n emit TransferBatch(operator, account, address(0), ids, amounts);\r\n }\r\n\r\n /**\r\n * @dev Hook that is called before any token transfer. This includes minting\r\n * and burning, as well as batched variants.\r\n *\r\n * The same hook is called on both single and batched variants. For single\r\n * transfers, the length of the `id` and `amount` arrays will be 1.\r\n *\r\n * Calling conditions (for each `id` and `amount` pair):\r\n *\r\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\r\n * of token type `id` will be transferred to `to`.\r\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\r\n * for `to`.\r\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\r\n * will be burned.\r\n * - `from` and `to` are never both zero.\r\n * - `ids` and `amounts` have the same, non-zero length.\r\n *\r\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\r\n */\r\n function _beforeTokenTransfer(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256[] memory ids,\r\n uint256[] memory amounts,\r\n bytes memory data\r\n )\r\n internal\r\n virtual\r\n { }\r\n\r\n function _doSafeTransferAcceptanceCheck(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256 id,\r\n uint256 amount,\r\n bytes memory data\r\n )\r\n private\r\n {\r\n if (to.isContract()) {\r\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\r\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\r\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\r\n }\r\n } catch Error(string memory reason) {\r\n revert(reason);\r\n } catch {\r\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\r\n }\r\n }\r\n }\r\n\r\n function _doSafeBatchTransferAcceptanceCheck(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256[] memory ids,\r\n uint256[] memory amounts,\r\n bytes memory data\r\n )\r\n private\r\n {\r\n if (to.isContract()) {\r\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\r\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\r\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\r\n }\r\n } catch Error(string memory reason) {\r\n revert(reason);\r\n } catch {\r\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\r\n }\r\n }\r\n }\r\n\r\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\r\n uint256[] memory array = new uint256[](1);\r\n array[0] = element;\r\n\r\n return array;\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../../introspection/IERC165.sol\";\r\n\r\n/**\r\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\r\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\r\n *\r\n * _Available since v3.1._\r\n */\r\ninterface IERC1155 is IERC165 {\r\n /**\r\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\r\n */\r\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\r\n\r\n /**\r\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\r\n * transfers.\r\n */\r\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\r\n\r\n /**\r\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\r\n * `approved`.\r\n */\r\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\r\n\r\n /**\r\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\r\n *\r\n * If an {URI} event was emitted for `id`, the standard\r\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\r\n * returned by {IERC1155MetadataURI-uri}.\r\n */\r\n event URI(string value, uint256 indexed id);\r\n\r\n /**\r\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\r\n *\r\n * Requirements:\r\n *\r\n * - `account` cannot be the zero address.\r\n */\r\n function balanceOf(address account, uint256 id) external view returns (uint256);\r\n\r\n /**\r\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\r\n *\r\n * Requirements:\r\n *\r\n * - `accounts` and `ids` must have the same length.\r\n */\r\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\r\n\r\n /**\r\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\r\n *\r\n * Emits an {ApprovalForAll} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `operator` cannot be the caller.\r\n */\r\n function setApprovalForAll(address operator, bool approved) external;\r\n\r\n /**\r\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\r\n *\r\n * See {setApprovalForAll}.\r\n */\r\n function isApprovedForAll(address account, address operator) external view returns (bool);\r\n\r\n /**\r\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\r\n *\r\n * Emits a {TransferSingle} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `to` cannot be the zero address.\r\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\r\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\r\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\r\n * acceptance magic value.\r\n */\r\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\r\n\r\n /**\r\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\r\n *\r\n * Emits a {TransferBatch} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `ids` and `amounts` must have the same length.\r\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\r\n * acceptance magic value.\r\n */\r\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./IERC1155.sol\";\r\n\r\n/**\r\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\r\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\r\n *\r\n * _Available since v3.1._\r\n */\r\ninterface IERC1155MetadataURI is IERC1155 {\r\n /**\r\n * @dev Returns the URI for token type `id`.\r\n *\r\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\r\n * clients with the actual token type ID.\r\n */\r\n function uri(uint256 id) external view returns (string memory);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../../introspection/IERC165.sol\";\r\n\r\n/**\r\n * _Available since v3.1._\r\n */\r\ninterface IERC1155Receiver is IERC165 {\r\n\r\n /**\r\n @dev Handles the receipt of a single ERC1155 token type. This function is\r\n called at the end of a `safeTransferFrom` after the balance has been updated.\r\n To accept the transfer, this must return\r\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\r\n (i.e. 0xf23a6e61, or its own function selector).\r\n @param operator The address which initiated the transfer (i.e. msg.sender)\r\n @param from The address which previously owned the token\r\n @param id The ID of the token being transferred\r\n @param value The amount of tokens being transferred\r\n @param data Additional data with no specified format\r\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\r\n */\r\n function onERC1155Received(\r\n address operator,\r\n address from,\r\n uint256 id,\r\n uint256 value,\r\n bytes calldata data\r\n )\r\n external\r\n returns(bytes4);\r\n\r\n /**\r\n @dev Handles the receipt of a multiple ERC1155 token types. This function\r\n is called at the end of a `safeBatchTransferFrom` after the balances have\r\n been updated. To accept the transfer(s), this must return\r\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\r\n (i.e. 0xbc197c81, or its own function selector).\r\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\r\n @param from The address which previously owned the token\r\n @param ids An array containing ids of each token being transferred (order and length must match values array)\r\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\r\n @param data Additional data with no specified format\r\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\r\n */\r\n function onERC1155BatchReceived(\r\n address operator,\r\n address from,\r\n uint256[] calldata ids,\r\n uint256[] calldata values,\r\n bytes calldata data\r\n )\r\n external\r\n returns(bytes4);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./ERC1155.sol\";\r\nimport \"../../lifecycle/Pausable.sol\";\r\n\r\n/**\r\n * @dev ERC1155 token with pausable token transfers, minting and burning.\r\n *\r\n * Useful for scenarios such as preventing trades until the end of an evaluation\r\n * period, or having an emergency switch for freezing all token transfers in the\r\n * event of a large bug.\r\n *\r\n * _Available since v3.1._\r\n */\r\nabstract contract ERC1155Pausable is ERC1155, Pausable {\r\n /**\r\n * @dev See {ERC1155-_beforeTokenTransfer}.\r\n *\r\n * Requirements:\r\n *\r\n * - the contract must not be paused.\r\n */\r\n function _beforeTokenTransfer(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256[] memory ids,\r\n uint256[] memory amounts,\r\n bytes memory data\r\n )\r\n internal\r\n virtual\r\n override\r\n {\r\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\r\n\r\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../GSN/Context.sol\";\r\nimport \"../access/roles/PauserRole.sol\";\r\n\r\n/**\r\n * @dev Contract module which allows children to implement an emergency stop\r\n * mechanism that can be triggered by an authorized account.\r\n *\r\n * This module is used through inheritance. It will make available the\r\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\r\n * the functions of your contract. Note that they will not be pausable by\r\n * simply including this module, only once the modifiers are put in place.\r\n */\r\nabstract contract Pausable is Context, PauserRole {\r\n /**\r\n * @dev Emitted when the pause is triggered by a pauser (`account`).\r\n */\r\n event Paused(address account);\r\n\r\n /**\r\n * @dev Emitted when the pause is lifted by a pauser (`account`).\r\n */\r\n event Unpaused(address account);\r\n\r\n bool private _paused;\r\n\r\n /**\r\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\r\n * to the deployer.\r\n */\r\n constructor () {\r\n _paused = false;\r\n }\r\n\r\n /**\r\n * @dev Returns true if the contract is paused, and false otherwise.\r\n */\r\n function paused() public view returns (bool) {\r\n return _paused;\r\n }\r\n\r\n /**\r\n * @dev Modifier to make a function callable only when the contract is not paused.\r\n */\r\n modifier whenNotPaused() {\r\n require(!_paused, \"Pausable: paused\");\r\n _;\r\n }\r\n\r\n /**\r\n * @dev Modifier to make a function callable only when the contract is paused.\r\n */\r\n modifier whenPaused() {\r\n require(_paused, \"Pausable: not paused\");\r\n _;\r\n }\r\n\r\n /**\r\n * @dev Called by a pauser to pause, triggers stopped state.\r\n */\r\n function pause() public onlyPauser whenNotPaused {\r\n _paused = true;\r\n emit Paused(_msgSender());\r\n }\r\n\r\n /**\r\n * @dev Called by a pauser to unpause, returns to normal state.\r\n */\r\n function unpause() public onlyPauser whenPaused {\r\n _paused = false;\r\n emit Unpaused(_msgSender());\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../../GSN/Context.sol\";\r\nimport \"../Roles.sol\";\r\n\r\nabstract contract PauserRole is Context {\r\n using Roles for Roles.Role;\r\n\r\n event PauserAdded(address indexed account);\r\n event PauserRemoved(address indexed account);\r\n\r\n Roles.Role private _pausers;\r\n\r\n constructor () {\r\n _addPauser(_msgSender());\r\n }\r\n\r\n modifier onlyPauser() {\r\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\r\n _;\r\n }\r\n\r\n function isPauser(address account) public view returns (bool) {\r\n return _pausers.has(account);\r\n }\r\n\r\n function addPauser(address account) public onlyPauser {\r\n _addPauser(account);\r\n }\r\n\r\n function renouncePauser() public {\r\n _removePauser(_msgSender());\r\n }\r\n\r\n function _addPauser(address account) internal {\r\n _pausers.add(account);\r\n emit PauserAdded(account);\r\n }\r\n\r\n function _removePauser(address account) internal {\r\n _pausers.remove(account);\r\n emit PauserRemoved(account);\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./ERC721.sol\";\r\nimport \"../../lifecycle/Pausable.sol\";\r\n\r\n/**\r\n * @dev ERC721 token with pausable token transfers, minting and burning.\r\n *\r\n * Useful for scenarios such as preventing trades until the end of an evaluation\r\n * period, or having an emergency switch for freezing all token transfers in the\r\n * event of a large bug.\r\n */\r\nabstract contract ERC721Pausable is ERC721, Pausable {\r\n /**\r\n * @dev See {ERC721-_beforeTokenTransfer}.\r\n *\r\n * Requirements:\r\n *\r\n * - the contract must not be paused.\r\n */\r\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\r\n super._beforeTokenTransfer(from, to, tokenId);\r\n\r\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\r\n }\r\n}\r\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\r\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\r\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\r\nimport \"../../zeppelin/ownership/Ownable.sol\";\r\nimport \"../../zeppelin/math/SafeMath.sol\";\r\nimport \"../../zeppelin/utils/Strings.sol\";\r\nimport \"./OpenSeaEIP712Base.sol\";\r\n\r\n\r\n/**\r\n * @title OpenSea721\r\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\r\n */\r\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\r\n using SafeMath for uint256;\r\n\r\n uint256 private _currentTokenId = 0;\r\n\r\n constructor(\r\n string memory _name,\r\n string memory _symbol\r\n ) ERC721(_name, _symbol) {\r\n _initializeEIP712(_name);\r\n }\r\n\r\n function baseTokenURI() public pure returns (string memory) {\r\n return \"https://creatures-api.opensea.io/api/creature/\";\r\n }\r\n\r\n function contractURI() public pure returns (string memory) {\r\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\r\n }\r\n\r\n /**\r\n * @dev Mints a token to an address with a tokenURI.\r\n * @param _to address of the future owner of the token\r\n */\r\n function mintTo(address _to) public onlyOwner {\r\n uint256 newTokenId = _getNextTokenId();\r\n _mint(_to, newTokenId);\r\n _incrementTokenId();\r\n }\r\n\r\n /**\r\n * @dev calculates the next token ID based on value of _currentTokenId\r\n * @return uint256 for the next token ID\r\n */\r\n function _getNextTokenId() private view returns (uint256) {\r\n return _currentTokenId.add(1);\r\n }\r\n\r\n /**\r\n * @dev increments the value of _currentTokenId\r\n */\r\n function _incrementTokenId() private {\r\n _currentTokenId++;\r\n }\r\n\r\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\r\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\r\n }\r\n\r\n}"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../../zeppelin/upgradable/Initializable.sol\";\r\n\r\ncontract OpenSeaEIP712Base is Initializable {\r\n struct EIP712Domain {\r\n string name;\r\n string version;\r\n address verifyingContract;\r\n bytes32 salt;\r\n }\r\n\r\n string constant public ERC712_VERSION = \"1\";\r\n\r\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\r\n bytes(\r\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\r\n )\r\n );\r\n bytes32 internal domainSeperator;\r\n\r\n // supposed to be called once while initializing.\r\n // one of the contracts that inherits this contract follows proxy pattern\r\n // so it is not possible to do this in a constructor\r\n function _initializeEIP712(\r\n string memory name\r\n )\r\n internal\r\n initializer\r\n {\r\n _setDomainSeperator(name);\r\n }\r\n\r\n function _setDomainSeperator(string memory name) internal {\r\n domainSeperator = keccak256(\r\n abi.encode(\r\n EIP712_DOMAIN_TYPEHASH,\r\n keccak256(bytes(name)),\r\n keccak256(bytes(ERC712_VERSION)),\r\n address(this),\r\n bytes32(getChainId())\r\n )\r\n );\r\n }\r\n\r\n function getDomainSeperator() public view returns (bytes32) {\r\n return domainSeperator;\r\n }\r\n\r\n function getChainId() public pure returns (uint256) {\r\n uint256 id;\r\n assembly {\r\n id := chainid()\r\n }\r\n return id;\r\n }\r\n\r\n /**\r\n * Accept message hash and returns hash message in EIP712 compatible form\r\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\r\n * https://eips.ethereum.org/EIPS/eip-712\r\n * \"\\\\x19\" makes the encoding deterministic\r\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\r\n */\r\n function toTypedMessageHash(bytes32 messageHash)\r\n internal\r\n view\r\n returns (bytes32)\r\n {\r\n return\r\n keccak256(\r\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\r\n );\r\n }\r\n}\r\n"
+ },
+ "contracts/Federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n// Upgradables\r\nimport \"../zeppelin/upgradable/Initializable.sol\";\r\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\r\n\r\nimport \"../interface/IBridge.sol\";\r\n\r\ncontract FederationV2 is Initializable, UpgradableOwnable {\r\n uint constant public MAX_MEMBER_COUNT = 50;\r\n address constant private NULL_ADDRESS = address(0);\r\n\r\n IBridge public bridge;\r\n address[] public members;\r\n uint public required;\r\n\r\n mapping (address => bool) public isMember;\r\n mapping (bytes32 => mapping (address => bool)) public votes;\r\n mapping(bytes32 => bool) public processed;\r\n\r\n event Executed(\r\n address indexed federator,\r\n bytes32 indexed transactionHash,\r\n bytes32 indexed transactionId,\r\n address originalTokenAddress,\r\n address sender,\r\n address receiver,\r\n uint256 amount,\r\n bytes32 blockHash,\r\n uint32 logIndex\r\n );\r\n event MemberAddition(address indexed member);\r\n event MemberRemoval(address indexed member);\r\n event RequirementChange(uint required);\r\n event BridgeChanged(address bridge);\r\n event Voted(\r\n address indexed federator,\r\n bytes32 indexed transactionHash,\r\n bytes32 indexed transactionId,\r\n address originalTokenAddress,\r\n address sender,\r\n address receiver,\r\n uint256 amount,\r\n bytes32 blockHash,\r\n uint32 logIndex\r\n );\r\n event HeartBeat(\r\n address indexed sender,\r\n uint256 fedRskBlock,\r\n uint256 fedEthBlock,\r\n string federatorVersion,\r\n string nodeRskInfo,\r\n string nodeEthInfo\r\n );\r\n\r\n modifier onlyMember() {\r\n require(isMember[_msgSender()], \"Federation: Not Federator\");\r\n _;\r\n }\r\n\r\n modifier validRequirement(uint membersCount, uint _required) {\r\n // solium-disable-next-line max-len\r\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\r\n _;\r\n }\r\n\r\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\r\n public validRequirement(_members.length, _required) initializer {\r\n UpgradableOwnable.initialize(owner);\r\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\r\n members = _members;\r\n for (uint i = 0; i < _members.length; i++) {\r\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\r\n isMember[_members[i]] = true;\r\n emit MemberAddition(_members[i]);\r\n }\r\n required = _required;\r\n emit RequirementChange(required);\r\n _setBridge(_bridge);\r\n }\r\n\r\n function version() external pure returns (string memory) {\r\n return \"v2\";\r\n }\r\n\r\n function setBridge(address _bridge) external onlyOwner {\r\n _setBridge(_bridge);\r\n }\r\n\r\n function _setBridge(address _bridge) internal {\r\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\r\n bridge = IBridge(_bridge);\r\n emit BridgeChanged(_bridge);\r\n }\r\n\r\n function voteTransaction(\r\n address originalTokenAddress,\r\n address payable sender,\r\n address payable receiver,\r\n uint256 amount,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex\r\n )\r\n public onlyMember returns(bool)\r\n {\r\n bytes32 transactionId = getTransactionId(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n amount,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n );\r\n if (processed[transactionId])\r\n return true;\r\n\r\n if (votes[transactionId][_msgSender()])\r\n return true;\r\n\r\n votes[transactionId][_msgSender()] = true;\r\n emit Voted(\r\n _msgSender(),\r\n transactionHash,\r\n transactionId,\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n amount,\r\n blockHash,\r\n logIndex\r\n );\r\n\r\n uint transactionCount = getTransactionCount(transactionId);\r\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\r\n processed[transactionId] = true;\r\n bridge.acceptTransfer(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n amount,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n );\r\n emit Executed(\r\n _msgSender(),\r\n transactionHash,\r\n transactionId,\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n amount,\r\n blockHash,\r\n logIndex\r\n );\r\n return true;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\r\n uint count = 0;\r\n for (uint i = 0; i < members.length; i++) {\r\n if (votes[transactionId][members[i]])\r\n count += 1;\r\n }\r\n return count;\r\n }\r\n\r\n function hasVoted(bytes32 transactionId) external view returns(bool)\r\n {\r\n return votes[transactionId][_msgSender()];\r\n }\r\n\r\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\r\n {\r\n return processed[transactionId];\r\n }\r\n\r\n function getTransactionId(\r\n address originalTokenAddress,\r\n address sender,\r\n address receiver,\r\n uint256 amount,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex\r\n ) public pure returns(bytes32)\r\n {\r\n return keccak256(\r\n abi.encodePacked(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n amount,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n )\r\n );\r\n }\r\n\r\n function addMember(address _newMember) external onlyOwner\r\n {\r\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\r\n require(!isMember[_newMember], \"Federation: Member already exists\");\r\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\r\n\r\n isMember[_newMember] = true;\r\n members.push(_newMember);\r\n emit MemberAddition(_newMember);\r\n }\r\n\r\n function removeMember(address _oldMember) external onlyOwner\r\n {\r\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\r\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\r\n require(members.length > 1, \"Federation: Can't remove all the members\");\r\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\r\n\r\n isMember[_oldMember] = false;\r\n for (uint i = 0; i < members.length - 1; i++) {\r\n if (members[i] == _oldMember) {\r\n members[i] = members[members.length - 1];\r\n break;\r\n }\r\n }\r\n members.pop(); // remove an element from the end of the array.\r\n emit MemberRemoval(_oldMember);\r\n }\r\n\r\n function getMembers() external view returns (address[] memory)\r\n {\r\n return members;\r\n }\r\n\r\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\r\n {\r\n require(_required >= 2, \"Federation: Requires at least 2\");\r\n required = _required;\r\n emit RequirementChange(_required);\r\n }\r\n\r\n function emitHeartbeat(\r\n uint256 fedRskBlock,\r\n uint256 fedEthBlock,\r\n string calldata federatorVersion,\r\n string calldata nodeRskInfo,\r\n string calldata nodeEthInfo\r\n ) external onlyMember {\r\n emit HeartBeat(\r\n _msgSender(),\r\n fedRskBlock,\r\n fedEthBlock,\r\n federatorVersion,\r\n nodeRskInfo,\r\n nodeEthInfo\r\n );\r\n }\r\n}"
+ },
+ "contracts/Federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n// Upgradables\r\nimport \"../zeppelin/upgradable/Initializable.sol\";\r\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\r\n\r\nimport \"../nftbridge/INFTBridge.sol\";\r\nimport \"../interface/IBridge.sol\";\r\nimport \"../interface/IFederation.sol\";\r\n\r\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\r\n uint constant public MAX_MEMBER_COUNT = 50;\r\n address constant private NULL_ADDRESS = address(0);\r\n\r\n IBridge public bridge;\r\n address[] public members;\r\n\r\n /**\r\n @notice The minimum amount of votes to approve a transaction\r\n @dev It should have more members than the required amount\r\n */\r\n uint public required;\r\n\r\n /**\r\n @notice All the addresses that are members of the federation\r\n @dev The address should be a member to vote in transactions\r\n */\r\n mapping (address => bool) public isMember;\r\n\r\n /**\r\n (bytes32) transactionId = keccak256(\r\n abi.encodePacked(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n amount,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n )\r\n ) => (\r\n (address) members => (bool) voted\r\n )\r\n @notice Votes by members by the transaction ID\r\n @dev usually the members should approve the transaction by 50% + 1\r\n */\r\n mapping (bytes32 => mapping (address => bool)) public votes;\r\n\r\n /**\r\n (bytes32) transactionId => (bool) voted\r\n @notice Check if that transaction was already processed\r\n */\r\n mapping(bytes32 => bool) public processed;\r\n\r\n /** Federator v3 variables */\r\n INFTBridge public bridgeNFT;\r\n\r\n modifier onlyMember() {\r\n require(isMember[_msgSender()], \"Federation: Not Federator\");\r\n _;\r\n }\r\n\r\n modifier validRequirement(uint membersCount, uint _required) {\r\n // solium-disable-next-line max-len\r\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\r\n _;\r\n }\r\n\r\n function initialize(address[] memory _members, uint _required, address _bridge, address owner, address _bridgeNFT) public\r\n validRequirement(_members.length, _required) initializer {\r\n UpgradableOwnable.initialize(owner);\r\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\r\n members = _members;\r\n for (uint i = 0; i < _members.length; i++) {\r\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\r\n isMember[_members[i]] = true;\r\n emit MemberAddition(_members[i]);\r\n }\r\n required = _required;\r\n emit RequirementChange(required);\r\n _setBridge(_bridge);\r\n _setNFTBridge(_bridgeNFT);\r\n }\r\n\r\n /**\r\n @notice Current version of the contract\r\n @return version in v{Number}\r\n */\r\n function version() external pure override returns (string memory) {\r\n return \"v3\";\r\n }\r\n\r\n /**\r\n @notice Sets a new bridge contract\r\n @dev Emits BridgeChanged event\r\n @param _bridge the new bridge contract address that should implement the IBridge interface\r\n */\r\n function setBridge(address _bridge) external onlyOwner override {\r\n _setBridge(_bridge);\r\n }\r\n\r\n function _setBridge(address _bridge) internal {\r\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\r\n bridge = IBridge(_bridge);\r\n emit BridgeChanged(_bridge);\r\n }\r\n\r\n /**\r\n @notice Sets a new NFT bridge contract\r\n @dev Emits NFTBridgeChanged event\r\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\r\n */\r\n function setNFTBridge(address _bridgeNFT) external onlyOwner override {\r\n _setNFTBridge(_bridgeNFT);\r\n }\r\n\r\n function _setNFTBridge(address _bridgeNFT) internal {\r\n require(_bridgeNFT != NULL_ADDRESS, \"Federation: Empty NFT bridge\");\r\n bridgeNFT = INFTBridge(_bridgeNFT);\r\n emit NFTBridgeChanged(_bridgeNFT);\r\n }\r\n\r\n function validateTransaction(bytes32 transactionId) internal view returns(bool) {\r\n uint transactionCount = getTransactionCount(transactionId);\r\n return transactionCount >= required && transactionCount >= members.length / 2 + 1;\r\n }\r\n\r\n /**\r\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\r\n @param originalTokenAddress The address of the token in the origin (main) chain\r\n @param sender The address who solicited the cross token\r\n @param receiver Who is going to receive the token in the opposite chain\r\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\r\n @param blockHash The block hash in which the transaction with the cross event occurred\r\n @param transactionHash The transaction in which the cross event occurred\r\n @param logIndex Index of the event in the logs\r\n @param tokenType Is the type of bridge to be used\r\n */\r\n function voteTransaction(\r\n address originalTokenAddress,\r\n address payable sender,\r\n address payable receiver,\r\n uint256 value,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex,\r\n TokenType tokenType\r\n ) external onlyMember override {\r\n bytes32 transactionId = getTransactionId(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n value,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n );\r\n if (processed[transactionId])\r\n return;\r\n\r\n if (votes[transactionId][_msgSender()])\r\n return;\r\n\r\n votes[transactionId][_msgSender()] = true;\r\n emit Voted(\r\n _msgSender(),\r\n transactionHash,\r\n transactionId,\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n value,\r\n blockHash,\r\n logIndex\r\n );\r\n\r\n if (validateTransaction(transactionId)) {\r\n processed[transactionId] = true;\r\n acceptTransfer(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n value,\r\n blockHash,\r\n transactionHash,\r\n logIndex,\r\n tokenType\r\n );\r\n\r\n emit Executed(\r\n _msgSender(),\r\n transactionHash,\r\n transactionId,\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n value,\r\n blockHash,\r\n logIndex\r\n );\r\n return;\r\n }\r\n }\r\n\r\n function acceptTransfer(\r\n address originalTokenAddress,\r\n address payable sender,\r\n address payable receiver,\r\n uint256 value,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex,\r\n TokenType tokenType\r\n ) internal {\r\n if (tokenType == TokenType.NFT) {\r\n require(address(bridgeNFT) != NULL_ADDRESS, \"Federation: Empty NFTBridge\");\r\n bridgeNFT.acceptTransfer(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n value,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n );\r\n return;\r\n }\r\n\r\n bridge.acceptTransfer(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n value,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n );\r\n }\r\n\r\n /**\r\n @notice Get the amount of approved votes for that transactionId\r\n @param transactionId The transaction hashed from getTransactionId function\r\n */\r\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\r\n uint count = 0;\r\n for (uint i = 0; i < members.length; i++) {\r\n if (votes[transactionId][members[i]])\r\n count += 1;\r\n }\r\n return count;\r\n }\r\n\r\n function hasVoted(bytes32 transactionId) external view returns(bool)\r\n {\r\n return votes[transactionId][_msgSender()];\r\n }\r\n\r\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\r\n {\r\n return processed[transactionId];\r\n }\r\n\r\n /**\r\n @notice Gets the hash of transaction from the following parameters encoded and keccaked\r\n @dev It encodes and applies keccak256 to the parameters received in the same order\r\n @param originalTokenAddress The address of the token in the origin (main) chain\r\n @param sender The address who solicited the cross token\r\n @param receiver Who is going to receive the token in the opposite chain\r\n @param amount Could be the amount or the tokenId\r\n @param blockHash The block hash in which the transaction with the cross event occurred\r\n @param transactionHash The transaction in which the cross event occurred\r\n @param logIndex Index of the event in the logs\r\n @return The hash generated by the parameters.\r\n */\r\n function getTransactionId(\r\n address originalTokenAddress,\r\n address sender,\r\n address receiver,\r\n uint256 amount,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex\r\n ) public pure returns(bytes32) {\r\n return keccak256(\r\n abi.encodePacked(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n amount,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n )\r\n );\r\n }\r\n\r\n function addMember(address _newMember) external onlyOwner override\r\n {\r\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\r\n require(!isMember[_newMember], \"Federation: Member already exists\");\r\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\r\n\r\n isMember[_newMember] = true;\r\n members.push(_newMember);\r\n emit MemberAddition(_newMember);\r\n }\r\n\r\n function removeMember(address _oldMember) external onlyOwner override\r\n {\r\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\r\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\r\n require(members.length > 1, \"Federation: Can't remove all the members\");\r\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\r\n\r\n isMember[_oldMember] = false;\r\n for (uint i = 0; i < members.length - 1; i++) {\r\n if (members[i] == _oldMember) {\r\n members[i] = members[members.length - 1];\r\n break;\r\n }\r\n }\r\n members.pop(); // remove an element from the end of the array.\r\n emit MemberRemoval(_oldMember);\r\n }\r\n\r\n /**\r\n @notice Return all the current members of the federation\r\n @return Current members\r\n */\r\n function getMembers() external view override returns (address[] memory) {\r\n return members;\r\n }\r\n\r\n /**\r\n @notice Changes the number of required members to vote and approve an transaction\r\n @dev Emits the RequirementChange event\r\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\r\n */\r\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\r\n require(_required >= 2, \"Federation: Requires at least 2\");\r\n required = _required;\r\n emit RequirementChange(_required);\r\n }\r\n\r\n /**\r\n @notice It emits an HeartBeat like an health check\r\n @dev Emits HeartBeat event\r\n */\r\n function emitHeartbeat(\r\n uint256 fedRskBlock,\r\n uint256 fedEthBlock,\r\n string calldata federatorVersion,\r\n string calldata nodeRskInfo,\r\n string calldata nodeEthInfo\r\n ) external onlyMember override {\r\n emit HeartBeat(\r\n _msgSender(),\r\n fedRskBlock,\r\n fedEthBlock,\r\n federatorVersion,\r\n nodeRskInfo,\r\n nodeEthInfo\r\n );\r\n }\r\n}\r\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\ninterface IFederation {\r\n enum TokenType{ COIN, NFT }\r\n\r\n /**\r\n @notice Current version of the contract\r\n @return version in v{Number}\r\n */\r\n function version() external pure returns (string memory);\r\n\r\n /**\r\n @notice Sets a new bridge contract\r\n @param _bridge the new bridge contract address that should implement the IBridge interface\r\n */\r\n function setBridge(address _bridge) external;\r\n\r\n /**\r\n @notice Sets a new NFT bridge contract\r\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\r\n */\r\n function setNFTBridge(address _bridgeNFT) external;\r\n\r\n /**\r\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\r\n @param originalTokenAddress The address of the token in the origin (main) chain\r\n @param sender The address who solicited the cross token\r\n @param receiver Who is going to receive the token in the opposite chain\r\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\r\n @param blockHash The block hash in which the transaction with the cross event occurred\r\n @param transactionHash The transaction in which the cross event occurred\r\n @param logIndex Index of the event in the logs\r\n @param tokenType Is the type of bridge to be used\r\n */\r\n function voteTransaction(\r\n address originalTokenAddress,\r\n address payable sender,\r\n address payable receiver,\r\n uint256 value,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex,\r\n TokenType tokenType\r\n ) external;\r\n\r\n /**\r\n @notice Add a new member to the federation\r\n @param _newMember address of the new member\r\n */\r\n function addMember(address _newMember) external;\r\n\r\n /**\r\n @notice Remove a member of the federation\r\n @param _oldMember address of the member to be removed from federation\r\n */\r\n function removeMember(address _oldMember) external;\r\n\r\n /**\r\n @notice Return all the current members of the federation\r\n @return Current members\r\n */\r\n function getMembers() external view returns (address[] memory);\r\n\r\n /**\r\n @notice Changes the number of required members to vote and approve an transaction\r\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\r\n */\r\n function changeRequirement(uint _required) external;\r\n\r\n /**\r\n @notice It emmits an HeartBeat like an healthy check\r\n */\r\n function emitHeartbeat(\r\n uint256 fedRskBlock,\r\n uint256 fedEthBlock,\r\n string calldata federatorVersion,\r\n string calldata nodeRskInfo,\r\n string calldata nodeEthInfo\r\n ) external;\r\n\r\n event Executed(\r\n address indexed federator,\r\n bytes32 indexed transactionHash,\r\n bytes32 indexed transactionId,\r\n address originalTokenAddress,\r\n address sender,\r\n address receiver,\r\n uint256 amount,\r\n bytes32 blockHash,\r\n uint32 logIndex\r\n );\r\n event MemberAddition(address indexed member);\r\n event MemberRemoval(address indexed member);\r\n event RequirementChange(uint required);\r\n event BridgeChanged(address bridge);\r\n event NFTBridgeChanged(address bridgeNFT);\r\n event Voted(\r\n address indexed federator,\r\n bytes32 indexed transactionHash,\r\n bytes32 indexed transactionId,\r\n address originalTokenAddress,\r\n address sender,\r\n address receiver,\r\n uint256 amount,\r\n bytes32 blockHash,\r\n uint32 logIndex\r\n );\r\n event HeartBeat(\r\n address indexed sender,\r\n uint256 fedRskBlock,\r\n uint256 fedEthBlock,\r\n string federatorVersion,\r\n string nodeRskInfo,\r\n string nodeEthInfo\r\n );\r\n\r\n}\r\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../../GSN/Context.sol\";\r\nimport \"../Roles.sol\";\r\n\r\nabstract contract MinterRole is Context {\r\n using Roles for Roles.Role;\r\n\r\n event MinterAdded(address indexed account);\r\n event MinterRemoved(address indexed account);\r\n\r\n Roles.Role private _minters;\r\n\r\n constructor () {\r\n _addMinter(_msgSender());\r\n }\r\n\r\n modifier onlyMinter() {\r\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\r\n _;\r\n }\r\n\r\n function isMinter(address account) public view returns (bool) {\r\n return _minters.has(account);\r\n }\r\n\r\n function addMinter(address account) public onlyMinter {\r\n _addMinter(account);\r\n }\r\n\r\n function renounceMinter() public {\r\n _removeMinter(_msgSender());\r\n }\r\n\r\n function _addMinter(address account) internal {\r\n _minters.add(account);\r\n emit MinterAdded(account);\r\n }\r\n\r\n function _removeMinter(address account) internal {\r\n _minters.remove(account);\r\n emit MinterRemoved(account);\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../../GSN/Context.sol\";\r\nimport \"./IERC20.sol\";\r\nimport \"../../math/SafeMath.sol\";\r\n\r\n/**\r\n * @dev Implementation of the {IERC20} interface.\r\n *\r\n * This implementation is agnostic to the way tokens are created. This means\r\n * that a supply mechanism has to be added in a derived contract using {_mint}.\r\n * For a generic mechanism see {ERC20Mintable}.\r\n *\r\n * TIP: For a detailed writeup see our guide\r\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\r\n * to implement supply mechanisms].\r\n *\r\n * We have followed general OpenZeppelin guidelines: functions revert instead\r\n * of returning `false` on failure. This behavior is nonetheless conventional\r\n * and does not conflict with the expectations of ERC20 applications.\r\n *\r\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\r\n * This allows applications to reconstruct the allowance for all accounts just\r\n * by listening to said events. Other implementations of the EIP may not emit\r\n * these events, as it isn't required by the specification.\r\n *\r\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\r\n * functions have been added to mitigate the well-known issues around setting\r\n * allowances. See {IERC20-approve}.\r\n */\r\ncontract ERC20 is Context, IERC20 {\r\n using SafeMath for uint256;\r\n\r\n mapping (address => uint256) private _balances;\r\n\r\n mapping (address => mapping (address => uint256)) private _allowances;\r\n\r\n uint256 private _totalSupply;\r\n\r\n /**\r\n * @dev See {IERC20-totalSupply}.\r\n */\r\n function totalSupply() override public view returns (uint256) {\r\n return _totalSupply;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-balanceOf}.\r\n */\r\n function balanceOf(address account) override public view returns (uint256) {\r\n return _balances[account];\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-transfer}.\r\n *\r\n * Requirements:\r\n *\r\n * - `recipient` cannot be the zero address.\r\n * - the caller must have a balance of at least `amount`.\r\n */\r\n function transfer(address recipient, uint256 amount) override public returns (bool) {\r\n _transfer(_msgSender(), recipient, amount);\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-allowance}.\r\n */\r\n function allowance(address owner, address spender) override public view returns (uint256) {\r\n return _allowances[owner][spender];\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-approve}.\r\n *\r\n * Requirements:\r\n *\r\n * - `spender` cannot be the zero address.\r\n */\r\n function approve(address spender, uint256 amount) override public returns (bool) {\r\n _approve(_msgSender(), spender, amount);\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-transferFrom}.\r\n *\r\n * Emits an {Approval} event indicating the updated allowance. This is not\r\n * required by the EIP. See the note at the beginning of {ERC20};\r\n *\r\n * Requirements:\r\n * - `sender` and `recipient` cannot be the zero address.\r\n * - `sender` must have a balance of at least `amount`.\r\n * - the caller must have allowance for `sender`'s tokens of at least\r\n * `amount`.\r\n */\r\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\r\n _transfer(sender, recipient, amount);\r\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Atomically increases the allowance granted to `spender` by the caller.\r\n *\r\n * This is an alternative to {approve} that can be used as a mitigation for\r\n * problems described in {IERC20-approve}.\r\n *\r\n * Emits an {Approval} event indicating the updated allowance.\r\n *\r\n * Requirements:\r\n *\r\n * - `spender` cannot be the zero address.\r\n */\r\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\r\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\r\n *\r\n * This is an alternative to {approve} that can be used as a mitigation for\r\n * problems described in {IERC20-approve}.\r\n *\r\n * Emits an {Approval} event indicating the updated allowance.\r\n *\r\n * Requirements:\r\n *\r\n * - `spender` cannot be the zero address.\r\n * - `spender` must have allowance for the caller of at least\r\n * `subtractedValue`.\r\n */\r\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\r\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Moves tokens `amount` from `sender` to `recipient`.\r\n *\r\n * This is internal function is equivalent to {transfer}, and can be used to\r\n * e.g. implement automatic token fees, slashing mechanisms, etc.\r\n *\r\n * Emits a {Transfer} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `sender` cannot be the zero address.\r\n * - `recipient` cannot be the zero address.\r\n * - `sender` must have a balance of at least `amount`.\r\n */\r\n function _transfer(address sender, address recipient, uint256 amount) internal {\r\n require(sender != address(0), \"ERC20: transfer from zero address\");\r\n require(recipient != address(0), \"ERC20: transfer to zero address\");\r\n\r\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\r\n _balances[recipient] = _balances[recipient].add(amount);\r\n emit Transfer(sender, recipient, amount);\r\n }\r\n\r\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\r\n * the total supply.\r\n *\r\n * Emits a {Transfer} event with `from` set to the zero address.\r\n *\r\n * Requirements\r\n *\r\n * - `to` cannot be the zero address.\r\n */\r\n function _mint(address account, uint256 amount) internal {\r\n require(account != address(0), \"ERC20: mint to zero address\");\r\n\r\n _totalSupply = _totalSupply.add(amount);\r\n _balances[account] = _balances[account].add(amount);\r\n emit Transfer(address(0), account, amount);\r\n }\r\n\r\n /**\r\n * @dev Destroys `amount` tokens from `account`, reducing the\r\n * total supply.\r\n *\r\n * Emits a {Transfer} event with `to` set to the zero address.\r\n *\r\n * Requirements\r\n *\r\n * - `account` cannot be the zero address.\r\n * - `account` must have at least `amount` tokens.\r\n */\r\n function _burn(address account, uint256 amount) internal {\r\n require(account != address(0), \"ERC20: burn from zero address\");\r\n\r\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\r\n _totalSupply = _totalSupply.sub(amount);\r\n emit Transfer(account, address(0), amount);\r\n }\r\n\r\n /**\r\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\r\n *\r\n * This is internal function is equivalent to `approve`, and can be used to\r\n * e.g. set automatic allowances for certain subsystems, etc.\r\n *\r\n * Emits an {Approval} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `owner` cannot be the zero address.\r\n * - `spender` cannot be the zero address.\r\n */\r\n function _approve(address owner, address spender, uint256 amount) internal {\r\n require(owner != address(0), \"ERC20: approve from zero address\");\r\n require(spender != address(0), \"ERC20: approve to zero address\");\r\n\r\n _allowances[owner][spender] = amount;\r\n emit Approval(owner, spender, amount);\r\n }\r\n\r\n /**\r\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\r\n * from the caller's allowance.\r\n *\r\n * See {_burn} and {_approve}.\r\n */\r\n function _burnFrom(address account, uint256 amount) internal {\r\n _burn(account, amount);\r\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\r\n }\r\n}\r\n"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\r\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\r\nimport \"../interface/IERC677Receiver.sol\";\r\n\r\ncontract mockERC677Receiver is IERC677Receiver {\r\n event Success(address _sender, uint _value, bytes _data);\r\n /**\r\n * ERC-677's only method implementation\r\n * See https://github.com/ethereum/EIPs/issues/677 for details\r\n */\r\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\r\n emit Success(_sender, _value, _data);\r\n }\r\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"./IERC20.sol\";\r\n\r\n/**\r\n * @dev Optional functions from the ERC20 standard.\r\n */\r\nabstract contract ERC20Detailed is IERC20 {\r\n string private _name;\r\n string private _symbol;\r\n uint8 private _decimals;\r\n\r\n /**\r\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\r\n * these values are immutable: they can only be set once during\r\n * construction.\r\n */\r\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\r\n _name = aName;\r\n _symbol = aSymbol;\r\n _decimals = theDecimals;\r\n }\r\n\r\n /**\r\n * @dev Returns the name of the token.\r\n */\r\n function name() public view returns (string memory) {\r\n return _name;\r\n }\r\n\r\n /**\r\n * @dev Returns the symbol of the token, usually a shorter version of the\r\n * name.\r\n */\r\n function symbol() public view returns (string memory) {\r\n return _symbol;\r\n }\r\n\r\n /**\r\n * @dev Returns the number of decimals used to get its user representation.\r\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\r\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\r\n *\r\n * Tokens usually opt for a value of 18, imitating the relationship between\r\n * Ether and Wei.\r\n *\r\n * NOTE: This information is only used for _display_ purposes: it in\r\n * no way affects any of the arithmetic of the contract, including\r\n * {IERC20-balanceOf} and {IERC20-transfer}.\r\n */\r\n function decimals() public view returns (uint8) {\r\n return _decimals;\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"./Proxy.sol\";\r\nimport \"../../utils/Address.sol\";\r\n\r\n/**\r\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\r\n * implementation address that can be changed. This address is stored in storage in the location specified by\r\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\r\n * implementation behind the proxy.\r\n *\r\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\r\n * {TransparentUpgradeableProxy}.\r\n */\r\ncontract UpgradeableProxy is Proxy {\r\n /**\r\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\r\n *\r\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\r\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\r\n */\r\n constructor(address _logic, bytes memory _data) payable {\r\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\r\n _setImplementation(_logic);\r\n if(_data.length > 0) {\r\n Address.functionDelegateCall(_logic, _data);\r\n }\r\n }\r\n\r\n /**\r\n * @dev Emitted when the implementation is upgraded.\r\n */\r\n event Upgraded(address indexed implementation);\r\n\r\n /**\r\n * @dev Storage slot with the address of the current implementation.\r\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\r\n * validated in the constructor.\r\n */\r\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\r\n\r\n /**\r\n * @dev Returns the current implementation address.\r\n */\r\n function _implementation() internal view virtual override returns (address impl) {\r\n bytes32 slot = _IMPLEMENTATION_SLOT;\r\n // solhint-disable-next-line no-inline-assembly\r\n assembly {\r\n impl := sload(slot)\r\n }\r\n }\r\n\r\n /**\r\n * @dev Upgrades the proxy to a new implementation.\r\n *\r\n * Emits an {Upgraded} event.\r\n */\r\n function _upgradeTo(address newImplementation) internal virtual {\r\n _setImplementation(newImplementation);\r\n emit Upgraded(newImplementation);\r\n }\r\n\r\n /**\r\n * @dev Stores a new address in the EIP1967 implementation slot.\r\n */\r\n function _setImplementation(address newImplementation) private {\r\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\r\n\r\n bytes32 slot = _IMPLEMENTATION_SLOT;\r\n\r\n // solhint-disable-next-line no-inline-assembly\r\n assembly {\r\n sstore(slot, newImplementation)\r\n }\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\r\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\r\n * be specified by overriding the virtual {_implementation} function.\r\n *\r\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\r\n * different contract through the {_delegate} function.\r\n *\r\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\r\n */\r\nabstract contract Proxy {\r\n /**\r\n * @dev Delegates the current call to `implementation`.\r\n *\r\n * This function does not return to its internall call site, it will return directly to the external caller.\r\n */\r\n function _delegate(address implementation) internal virtual {\r\n // solhint-disable-next-line no-inline-assembly\r\n assembly {\r\n // Copy msg.data. We take full control of memory in this inline assembly\r\n // block because it will not return to Solidity code. We overwrite the\r\n // Solidity scratch pad at memory position 0.\r\n calldatacopy(0, 0, calldatasize())\r\n\r\n // Call the implementation.\r\n // out and outsize are 0 because we don't know the size yet.\r\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\r\n\r\n // Copy the returned data.\r\n returndatacopy(0, 0, returndatasize())\r\n\r\n switch result\r\n // delegatecall returns 0 on error.\r\n case 0 { revert(0, returndatasize()) }\r\n default { return(0, returndatasize()) }\r\n }\r\n }\r\n\r\n /**\r\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\r\n * and {_fallback} should delegate.\r\n */\r\n function _implementation() internal view virtual returns (address);\r\n\r\n /**\r\n * @dev Delegates the current call to the address returned by `_implementation()`.\r\n *\r\n * This function does not return to its internall call site, it will return directly to the external caller.\r\n */\r\n function _fallback() internal virtual {\r\n _beforeFallback();\r\n _delegate(_implementation());\r\n }\r\n\r\n /**\r\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\r\n * function in the contract matches the call data.\r\n */\r\n fallback () external payable virtual {\r\n _fallback();\r\n }\r\n\r\n /**\r\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\r\n * is empty.\r\n */\r\n receive () external payable virtual {\r\n _fallback();\r\n }\r\n\r\n /**\r\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\r\n * call, or as part of the Solidity `fallback` or `receive` functions.\r\n *\r\n * If overriden should call `super._beforeFallback()`.\r\n */\r\n function _beforeFallback() internal virtual {\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"./UpgradeableProxy.sol\";\r\n\r\n/**\r\n * @dev This contract implements a proxy that is upgradeable by an admin.\r\n *\r\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\r\n * clashing], which can potentially be used in an attack, this contract uses the\r\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\r\n * things that go hand in hand:\r\n *\r\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\r\n * that call matches one of the admin functions exposed by the proxy itself.\r\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\r\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\r\n * \"admin cannot fallback to proxy target\".\r\n *\r\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\r\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\r\n * to sudden errors when trying to call a function from the proxy implementation.\r\n *\r\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\r\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\r\n */\r\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\r\n /**\r\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\r\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\r\n */\r\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\r\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\r\n _setAdmin(admin_);\r\n }\r\n\r\n /**\r\n * @dev Emitted when the admin account has changed.\r\n */\r\n event AdminChanged(address previousAdmin, address newAdmin);\r\n\r\n /**\r\n * @dev Storage slot with the admin of the contract.\r\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\r\n * validated in the constructor.\r\n */\r\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\r\n\r\n /**\r\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\r\n */\r\n modifier ifAdmin() {\r\n if (msg.sender == _admin()) {\r\n _;\r\n } else {\r\n _fallback();\r\n }\r\n }\r\n\r\n /**\r\n * @dev Returns the current admin.\r\n *\r\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\r\n *\r\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\r\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\r\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\r\n */\r\n function admin() external ifAdmin returns (address admin_) {\r\n admin_ = _admin();\r\n }\r\n\r\n /**\r\n * @dev Returns the current implementation.\r\n *\r\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\r\n *\r\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\r\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\r\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\r\n */\r\n function implementation() external ifAdmin returns (address implementation_) {\r\n implementation_ = _implementation();\r\n }\r\n\r\n /**\r\n * @dev Changes the admin of the proxy.\r\n *\r\n * Emits an {AdminChanged} event.\r\n *\r\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\r\n */\r\n function changeAdmin(address newAdmin) external virtual ifAdmin {\r\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\r\n emit AdminChanged(_admin(), newAdmin);\r\n _setAdmin(newAdmin);\r\n }\r\n\r\n /**\r\n * @dev Upgrade the implementation of the proxy.\r\n *\r\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\r\n */\r\n function upgradeTo(address newImplementation) external virtual ifAdmin {\r\n _upgradeTo(newImplementation);\r\n }\r\n\r\n /**\r\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\r\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\r\n * proxied contract.\r\n *\r\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\r\n */\r\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\r\n _upgradeTo(newImplementation);\r\n Address.functionDelegateCall(newImplementation, data);\r\n }\r\n\r\n /**\r\n * @dev Returns the current admin.\r\n */\r\n function _admin() internal view virtual returns (address adm) {\r\n bytes32 slot = _ADMIN_SLOT;\r\n // solhint-disable-next-line no-inline-assembly\r\n assembly {\r\n adm := sload(slot)\r\n }\r\n }\r\n\r\n /**\r\n * @dev Stores a new address in the EIP1967 admin slot.\r\n */\r\n function _setAdmin(address newAdmin) private {\r\n bytes32 slot = _ADMIN_SLOT;\r\n\r\n // solhint-disable-next-line no-inline-assembly\r\n assembly {\r\n sstore(slot, newAdmin)\r\n }\r\n }\r\n\r\n /**\r\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\r\n */\r\n function _beforeFallback() internal virtual override {\r\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\r\n super._beforeFallback();\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../../ownership/Ownable.sol\";\r\nimport \"./TransparentUpgradeableProxy.sol\";\r\n\r\n/**\r\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\r\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\r\n */\r\ncontract ProxyAdmin is Ownable {\r\n\r\n /**\r\n * @dev Returns the current implementation of `proxy`.\r\n *\r\n * Requirements:\r\n *\r\n * - This contract must be the admin of `proxy`.\r\n */\r\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\r\n // We need to manually run the static call since the getter cannot be flagged as view\r\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\r\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\r\n require(success);\r\n return abi.decode(returndata, (address));\r\n }\r\n\r\n /**\r\n * @dev Returns the current admin of `proxy`.\r\n *\r\n * Requirements:\r\n *\r\n * - This contract must be the admin of `proxy`.\r\n */\r\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\r\n // We need to manually run the static call since the getter cannot be flagged as view\r\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\r\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\r\n require(success);\r\n return abi.decode(returndata, (address));\r\n }\r\n\r\n /**\r\n * @dev Changes the admin of `proxy` to `newAdmin`.\r\n *\r\n * Requirements:\r\n *\r\n * - This contract must be the current admin of `proxy`.\r\n */\r\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\r\n proxy.changeAdmin(newAdmin);\r\n }\r\n\r\n /**\r\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\r\n *\r\n * Requirements:\r\n *\r\n * - This contract must be the admin of `proxy`.\r\n */\r\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\r\n proxy.upgradeTo(implementation);\r\n }\r\n\r\n /**\r\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\r\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\r\n *\r\n * Requirements:\r\n *\r\n * - This contract must be the admin of `proxy`.\r\n */\r\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\r\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\r\n }\r\n}\r\n"
+ },
+ "contracts/Federation/FederationV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../Bridge/IBridgeV2.sol\";\r\nimport \"../zeppelin/ownership/Ownable.sol\";\r\n\r\ncontract FederationV1 is Ownable {\r\n uint constant public MAX_MEMBER_COUNT = 50;\r\n address constant private NULL_ADDRESS = address(0);\r\n\r\n IBridgeV2 public bridge;\r\n address[] public members;\r\n uint public required;\r\n\r\n mapping (address => bool) public isMember;\r\n mapping (bytes32 => mapping (address => bool)) public votes;\r\n mapping(bytes32 => bool) public processed;\r\n // solium-disable-next-line max-len\r\n event Voted(address indexed sender, bytes32 indexed transactionId, address originalTokenAddress, address receiver, uint256 amount, string symbol, bytes32 blockHash, bytes32 indexed transactionHash, uint32 logIndex, uint8 decimals, uint256 granularity);\r\n event Executed(bytes32 indexed transactionId);\r\n event MemberAddition(address indexed member);\r\n event MemberRemoval(address indexed member);\r\n event RequirementChange(uint required);\r\n event BridgeChanged(address bridge);\r\n\r\n modifier onlyMember() {\r\n require(isMember[_msgSender()], \"Federation: Caller not a Federator\");\r\n _;\r\n }\r\n\r\n modifier validRequirement(uint membersCount, uint _required) {\r\n // solium-disable-next-line max-len\r\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\r\n _;\r\n }\r\n\r\n constructor(address[] memory _members, uint _required) validRequirement(_members.length, _required) {\r\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Members larger than max allowed\");\r\n members = _members;\r\n for (uint i = 0; i < _members.length; i++) {\r\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\r\n isMember[_members[i]] = true;\r\n emit MemberAddition(_members[i]);\r\n }\r\n required = _required;\r\n emit RequirementChange(required);\r\n }\r\n\r\n function setBridge(address _bridge) external onlyOwner {\r\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\r\n bridge = IBridgeV2(_bridge);\r\n emit BridgeChanged(_bridge);\r\n }\r\n\r\n function voteTransaction(\r\n address originalTokenAddress,\r\n address receiver,\r\n uint256 amount,\r\n string calldata symbol,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex,\r\n uint8 decimals,\r\n uint256 granularity)\r\n external onlyMember returns(bool)\r\n {\r\n // solium-disable-next-line max-len\r\n bytes32 transactionId = getTransactionId(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\r\n if (processed[transactionId])\r\n return true;\r\n\r\n if (votes[transactionId][_msgSender()])\r\n return true;\r\n\r\n votes[transactionId][_msgSender()] = true;\r\n // solium-disable-next-line max-len\r\n emit Voted(_msgSender(), transactionId, originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\r\n\r\n uint transactionCount = getTransactionCount(transactionId);\r\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\r\n processed[transactionId] = true;\r\n bool acceptTransfer = bridge.acceptTransfer(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\r\n require(acceptTransfer, \"Federation: Bridge acceptTransfer error\");\r\n emit Executed(transactionId);\r\n return true;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\r\n uint count = 0;\r\n for (uint i = 0; i < members.length; i++) {\r\n if (votes[transactionId][members[i]])\r\n count += 1;\r\n }\r\n return count;\r\n }\r\n\r\n function hasVoted(bytes32 transactionId) external view returns(bool)\r\n {\r\n return votes[transactionId][_msgSender()];\r\n }\r\n\r\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\r\n {\r\n return processed[transactionId];\r\n }\r\n\r\n function getTransactionId(\r\n address originalTokenAddress,\r\n address receiver,\r\n uint256 amount,\r\n string memory symbol,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex,\r\n uint8 decimals,\r\n uint256 granularity)\r\n public pure returns(bytes32)\r\n {\r\n // solium-disable-next-line max-len\r\n return keccak256(abi.encodePacked(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity));\r\n }\r\n\r\n function addMember(address _newMember) external onlyOwner\r\n {\r\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\r\n require(!isMember[_newMember], \"Federation: Member already exists\");\r\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\r\n\r\n isMember[_newMember] = true;\r\n members.push(_newMember);\r\n emit MemberAddition(_newMember);\r\n }\r\n\r\n function removeMember(address _oldMember) external onlyOwner\r\n {\r\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\r\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\r\n require(members.length > 1, \"Federation: Can't remove all the members\");\r\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\r\n\r\n isMember[_oldMember] = false;\r\n for (uint i = 0; i < members.length - 1; i++) {\r\n if (members[i] == _oldMember) {\r\n members[i] = members[members.length - 1];\r\n break;\r\n }\r\n }\r\n members.pop(); // remove last element\r\n emit MemberRemoval(_oldMember);\r\n }\r\n\r\n function getMembers() external view returns (address[] memory)\r\n {\r\n return members;\r\n }\r\n\r\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\r\n {\r\n require(_required >= 2, \"Federation: Requires at least 2\");\r\n required = _required;\r\n emit RequirementChange(_required);\r\n }\r\n\r\n}"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\r\n\r\ncontract BridgeProxy is TransparentUpgradeableProxy {\r\n // solhint-disable-next-line no-empty-blocks\r\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\r\n}\r\n\r\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\r\n // solhint-disable-next-line no-empty-blocks\r\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\r\n}\r\n\r\ncontract FederationProxy is TransparentUpgradeableProxy {\r\n // solhint-disable-next-line no-empty-blocks\r\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\r\n}"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\r\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\r\n\r\ncontract MainToken is ERC20Detailed, ERC20 {\r\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\r\n ERC20Detailed(name, symbol, decimals)\r\n {\r\n _mint(msg.sender, totalSupply);\r\n }\r\n\r\n /**\r\n * ERC-677's only method implementation\r\n * See https://github.com/ethereum/EIPs/issues/677 for details\r\n */\r\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\r\n bool result = transfer(_to, _value);\r\n if (!result) return false;\r\n\r\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\r\n receiver.tokenFallback(msg.sender, _value, _data);\r\n\r\n // IMPORTANT: the ERC-677 specification does not say\r\n // anything about the use of the receiver contract's\r\n // tokenFallback method return value. Given\r\n // its return type matches with this method's return\r\n // type, returning it could be a possibility.\r\n // We here take the more conservative approach and\r\n // ignore the return value, returning true\r\n // to signal a succesful transfer despite tokenFallback's\r\n // return value -- fact being tokens are transferred\r\n // in any case.\r\n return true;\r\n }\r\n}\r\n\r\ninterface ERC677TransferReceiver {\r\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\r\n}"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\r\n\r\ncontract AlternativeERC20Detailed is ERC20 {\r\n string private _name;\r\n bytes32 private _symbol;\r\n uint256 private _decimals;\r\n\r\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\r\n {\r\n _name = aName;\r\n _symbol = aSymbol;\r\n _decimals = someDecimals;\r\n _mint(msg.sender, aTotalSupply);\r\n }\r\n\r\n function name() public view returns (string memory) {\r\n return _name;\r\n }\r\n\r\n function symbol() public view returns (bytes32) {\r\n return _symbol;\r\n }\r\n\r\n function decimals() public view returns (uint256) {\r\n return _decimals;\r\n }\r\n}"
+ },
+ "contracts/test/nftbridge/NFTERC721TestToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.7.6;\r\n\r\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\r\n\r\ncontract NFTERC721TestToken is ERC721 {\r\n\r\n string private _contractURI;\r\n\r\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\r\n\r\n function safeMint(address to, uint256 tokenId) public {\r\n _safeMint(to, tokenId);\r\n }\r\n\r\n function setBaseURI(string memory baseURI) public {\r\n _setBaseURI(baseURI);\r\n }\r\n\r\n function setContractURI(string memory contractURI_) public {\r\n _contractURI = contractURI_;\r\n }\r\n\r\n function contractURI() public view returns (string memory) {\r\n return _contractURI;\r\n }\r\n\r\n function setTokenURI(uint256 tokenId, string memory _tokenURI) public {\r\n _setTokenURI(tokenId, _tokenURI);\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/nftbridge/SideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"./ISideNFTToken.sol\";\r\nimport \"../zeppelin/token/ERC721/ERC721.sol\";\r\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\r\n\r\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\r\n address public minter;\r\n string private _contractURI;\r\n\r\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\r\n require(_minter != address(0), \"SideToken: Empty Minter\");\r\n minter = _minter;\r\n _setBaseURI(_baseURI);\r\n _setContractURI(contractURI_);\r\n }\r\n\r\n function _setContractURI(string memory contractURI_) internal {\r\n _contractURI = contractURI_;\r\n }\r\n\r\n function contractURI() public view returns (string memory) {\r\n return _contractURI;\r\n }\r\n\r\n modifier onlyMinter() {\r\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\r\n _;\r\n }\r\n\r\n function mint(address account, uint256 tokenId) external onlyMinter override {\r\n _mint(account, tokenId);\r\n }\r\n}"
+ },
+ "contracts/nftbridge/SideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../zeppelin/ownership/Secondary.sol\";\r\nimport \"./ISideNFTTokenFactory.sol\";\r\nimport \"./SideNFTToken.sol\";\r\n\r\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\r\n\r\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\r\n string calldata contractURI) external onlyPrimary override returns(address) {\r\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\r\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\r\n return sideTokenAddress;\r\n }\r\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./IERC1155Receiver.sol\";\r\nimport \"../../introspection/ERC165.sol\";\r\n\r\n/**\r\n * @dev _Available since v3.1._\r\n */\r\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\r\n constructor() {\r\n _registerInterface(\r\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\r\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\r\n );\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./ERC1155Receiver.sol\";\r\n\r\n/**\r\n * @dev _Available since v3.1._\r\n */\r\ncontract ERC1155Holder is ERC1155Receiver {\r\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\r\n return this.onERC1155Received.selector;\r\n }\r\n\r\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\r\n return this.onERC1155BatchReceived.selector;\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./IERC721Receiver.sol\";\r\n\r\n /**\r\n * @dev Implementation of the {IERC721Receiver} interface.\r\n *\r\n * Accepts all token transfers. \r\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\r\n */\r\ncontract ERC721Holder is IERC721Receiver {\r\n\r\n /**\r\n * @dev See {IERC721Receiver-onERC721Received}.\r\n *\r\n * Always returns `IERC721Receiver.onERC721Received.selector`.\r\n */\r\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\r\n return this.onERC721Received.selector;\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./ERC1155.sol\";\r\n\r\n/**\r\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\r\n * own tokens and those that they have been approved to use.\r\n *\r\n * _Available since v3.1._\r\n */\r\nabstract contract ERC1155Burnable is ERC1155 {\r\n function burn(address account, uint256 id, uint256 value) public virtual {\r\n require(\r\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\r\n \"ERC1155: caller is not owner nor approved\"\r\n );\r\n\r\n _burn(account, id, value);\r\n }\r\n\r\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\r\n require(\r\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\r\n \"ERC1155: caller is not owner nor approved\"\r\n );\r\n\r\n _burnBatch(account, ids, values);\r\n }\r\n}\r\n"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../lib/LibUtils.sol\";\r\n\r\ncontract LibUtilsHarness {\r\n\r\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\r\n return LibUtils.decimalsToGranularity(decimals);\r\n }\r\n\r\n function getDecimals(address tokenToUse) external view returns (uint8) {\r\n return LibUtils.getDecimals(tokenToUse);\r\n }\r\n\r\n function getGranularity(address tokenToUse) external view returns (uint256) {\r\n return LibUtils.getGranularity(tokenToUse);\r\n }\r\n\r\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\r\n return LibUtils.bytesToAddress(bys);\r\n }\r\n\r\n}\r\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/.chainId b/bridge/deployments/rsktestnet/.chainId
new file mode 100644
index 000000000..b74e882ae
--- /dev/null
+++ b/bridge/deployments/rsktestnet/.chainId
@@ -0,0 +1 @@
+31
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/AllowTokens.json b/bridge/deployments/rsktestnet/AllowTokens.json
new file mode 100644
index 000000000..cdea50fa4
--- /dev/null
+++ b/bridge/deployments/rsktestnet/AllowTokens.json
@@ -0,0 +1,1196 @@
+{
+ "address": "0xa39b89d1e36af95183cc09ab83e8fe374bd82f49",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ }
+ ],
+ "name": "AllowedTokenRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "ConfirmationsChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ }
+ ],
+ "name": "SetToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_typeDescription",
+ "type": "string"
+ }
+ ],
+ "name": "TokenTypeAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "indexed": false,
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "TypeLimitsChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_lastDay",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_spentToday",
+ "type": "uint256"
+ }
+ ],
+ "name": "UpdateTokensTransfered",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_TYPES",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Secondary_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "description",
+ "type": "string"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "addTokenType",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "len",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "allowedTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "calcMaxWithdraw",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "maxWithdraw",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "smallAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "getInfoAndLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokenInfo",
+ "name": "info",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limit",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypeDescriptions",
+ "outputs": [
+ {
+ "internalType": "string[]",
+ "name": "descriptions",
+ "type": "string[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypeDescriptionsLength",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypesLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits[]",
+ "name": "limits",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_primary",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "string",
+ "name": "description",
+ "type": "string"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TypeInfo[]",
+ "name": "typesInfo",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "isTokenAllowed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "largeAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "mediumAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "removeAllowedToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "setConfirmations",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokensAndType[]",
+ "name": "tokensAndTypes",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "setMultipleTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ }
+ ],
+ "name": "setToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "setTypeLimits",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "smallAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "typeDescriptions",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "typeLimits",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "updateTokenTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x2d1158799ed192bce68c3676ba7833a087251423290c4423e3a16134a6fa6978",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x11804f8DeADb1803603278156AA1e6602949e8b2",
+ "transactionIndex": 0,
+ "gasUsed": "2459902",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x09f2374a7b81dbe264dfb6095f10fe185c7c9a4e0cb0457a68f63b30f06121b2",
+ "transactionHash": "0x2d1158799ed192bce68c3676ba7833a087251423290c4423e3a16134a6fa6978",
+ "logs": [],
+ "blockNumber": 2152254,
+ "cumulativeGasUsed": "2459902",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"}],\"name\":\"AllowedTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"}],\"name\":\"ConfirmationsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"}],\"name\":\"SetToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_typeDescription\",\"type\":\"string\"}],\"name\":\"TokenTypeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"TypeLimitsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_lastDay\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_spentToday\",\"type\":\"uint256\"}],\"name\":\"UpdateTokensTransfered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_TYPES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__Secondary_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"addTokenType\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"len\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowedTokens\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"spentToday\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastDay\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"calcMaxWithdraw\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"maxWithdraw\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"smallAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getInfoAndLimits\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"spentToday\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastDay\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.TokenInfo\",\"name\":\"info\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limit\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypeDescriptions\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"descriptions\",\"type\":\"string[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypeDescriptionsLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypesLimits\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits[]\",\"name\":\"limits\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_primary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"internalType\":\"struct IAllowTokens.TypeInfo[]\",\"name\":\"typesInfo\",\"type\":\"tuple[]\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isTokenAllowed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"largeAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mediumAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"removeAllowedToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"}],\"name\":\"setConfirmations\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.TokensAndType[]\",\"name\":\"tokensAndTypes\",\"type\":\"tuple[]\"}],\"name\":\"setMultipleTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"}],\"name\":\"setToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"setTypeLimits\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"smallAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"typeDescriptions\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"typeLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"updateTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"__Secondary_init(address)\":{\"details\":\"Sets the primary account to the one that is creating the Secondary contract.\"},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/AllowTokens/AllowTokens.sol\":\"AllowTokens\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/AllowTokens/AllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../zeppelin/math/SafeMath.sol\\\";\\n// Upgradables\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\\\";\\n\\nimport \\\"../interface/IAllowTokens.sol\\\";\\n\\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\\n using SafeMath for uint256;\\n\\n address constant private NULL_ADDRESS = address(0);\\n uint256 constant public MAX_TYPES = 250;\\n mapping (address => TokenInfo) public allowedTokens;\\n mapping (uint256 => Limits) public typeLimits;\\n uint256 public smallAmountConfirmations;\\n uint256 public mediumAmountConfirmations;\\n uint256 public largeAmountConfirmations;\\n string[] public typeDescriptions;\\n\\n event SetToken(address indexed _tokenAddress, uint256 _typeId);\\n event AllowedTokenRemoved(address indexed _tokenAddress);\\n event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\\n event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\\n event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\\n event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\\n\\n\\n modifier notNull(address _address) {\\n require(_address != NULL_ADDRESS, \\\"AllowTokens: Null Address\\\");\\n _;\\n }\\n\\n function initialize(\\n address _manager,\\n address _primary,\\n uint256 _smallAmountConfirmations,\\n uint256 _mediumAmountConfirmations,\\n uint256 _largeAmountConfirmations,\\n TypeInfo[] memory typesInfo) public initializer {\\n UpgradableOwnable.initialize(_manager);\\n UpgradableSecondary.__Secondary_init(_primary);\\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\n for(uint i = 0; i < typesInfo.length; i = i + 1) {\\n _addTokenType(typesInfo[i].description, typesInfo[i].limits);\\n }\\n }\\n\\n function version() override external pure returns (string memory) {\\n return \\\"v1\\\";\\n }\\n\\n function getInfoAndLimits(address token) override public view\\n returns (TokenInfo memory info, Limits memory limit) {\\n info = allowedTokens[token];\\n limit = typeLimits[info.typeId];\\n return (info, limit);\\n }\\n function calcMaxWithdraw(address token) override public view returns (uint256 maxWithdraw) {\\n (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\\n return _calcMaxWithdraw(info, limits);\\n }\\n\\n function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\\n // solium-disable-next-line security/no-block-members\\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\\n info.spentToday = 0;\\n }\\n if (limits.daily <= info.spentToday)\\n return 0;\\n maxWithdraw = limits.daily - info.spentToday;\\n if(maxWithdraw > limits.max)\\n maxWithdraw = limits.max;\\n return maxWithdraw;\\n }\\n\\n // solium-disable-next-line max-len\\n function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\\n (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\\n require(isTokenAllowed(token), \\\"AllowTokens: Not whitelisted\\\");\\n require(amount >= limit.min, \\\"AllowTokens: Lower than limit\\\");\\n\\n // solium-disable-next-line security/no-block-members\\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\\n // solium-disable-next-line security/no-block-members\\n info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\\n info.spentToday = 0;\\n }\\n uint maxWithdraw = _calcMaxWithdraw(info, limit);\\n require(amount <= maxWithdraw, \\\"AllowTokens: Exceeded limit\\\");\\n info.spentToday = info.spentToday.add(amount);\\n allowedTokens[token] = info;\\n\\n emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\\n }\\n\\n function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\\n require(bytes(description).length > 0, \\\"AllowTokens: Empty description\\\");\\n len = typeDescriptions.length;\\n require(len + 1 <= MAX_TYPES, \\\"AllowTokens: Reached MAX_TYPES\\\");\\n typeDescriptions.push(description);\\n _setTypeLimits(len, limits);\\n emit TokenTypeAdded(len, description);\\n return len;\\n }\\n\\n function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\\n return _addTokenType(description, limits);\\n }\\n\\n function _setTypeLimits(uint256 typeId, Limits memory limits) private {\\n require(typeId < typeDescriptions.length, \\\"AllowTokens: bigger than typeDescriptions\\\");\\n require(limits.max >= limits.min, \\\"AllowTokens: maxTokens smaller than minTokens\\\");\\n require(limits.daily >= limits.max, \\\"AllowTokens: dailyLimit smaller than maxTokens\\\");\\n require(limits.mediumAmount > limits.min, \\\"AllowTokens: limits.mediumAmount smaller than min\\\");\\n require(limits.largeAmount > limits.mediumAmount, \\\"AllowTokens: limits.largeAmount smaller than mediumAmount\\\");\\n typeLimits[typeId] = limits;\\n emit TypeLimitsChanged(typeId, limits);\\n }\\n\\n function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\\n _setTypeLimits(typeId, limits);\\n }\\n\\n function getTypesLimits() external view override returns(Limits[] memory limits) {\\n limits = new Limits[](typeDescriptions.length);\\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\\n limits[i] = typeLimits[i];\\n }\\n return limits;\\n }\\n\\n function getTypeDescriptionsLength() external view override returns(uint256) {\\n return typeDescriptions.length;\\n }\\n\\n function getTypeDescriptions() external view override returns(string[] memory descriptions) {\\n descriptions = new string[](typeDescriptions.length);\\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\\n descriptions[i] = typeDescriptions[i];\\n }\\n return descriptions;\\n }\\n\\n function isTokenAllowed(address token) public view notNull(token) override returns (bool) {\\n return allowedTokens[token].allowed;\\n }\\n\\n function setToken(address token, uint256 typeId) override public notNull(token) {\\n require(isOwner() || _msgSender() == primary(), \\\"AllowTokens: unauthorized sender\\\");\\n require(typeId < typeDescriptions.length, \\\"AllowTokens: typeId does not exist\\\");\\n TokenInfo memory info = allowedTokens[token];\\n info.allowed = true;\\n info.typeId = typeId;\\n allowedTokens[token] = info;\\n emit SetToken(token, typeId);\\n }\\n\\n function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\\n require(tokensAndTypes.length > 0, \\\"AllowTokens: empty tokens\\\");\\n for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\\n setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\\n }\\n }\\n\\n function removeAllowedToken(address token) external notNull(token) onlyOwner {\\n TokenInfo memory info = allowedTokens[token];\\n require(info.allowed, \\\"AllowTokens: Not Allowed\\\");\\n info.allowed = false;\\n allowedTokens[token] = info;\\n emit AllowedTokenRemoved(token);\\n }\\n\\n function setConfirmations(\\n uint256 _smallAmountConfirmations,\\n uint256 _mediumAmountConfirmations,\\n uint256 _largeAmountConfirmations) external onlyOwner {\\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\n }\\n\\n function _setConfirmations(\\n uint256 _smallAmountConfirmations,\\n uint256 _mediumAmountConfirmations,\\n uint256 _largeAmountConfirmations) private {\\n require(_smallAmountConfirmations <= _mediumAmountConfirmations, \\\"AllowTokens: small bigger than medium confirmations\\\");\\n require(_mediumAmountConfirmations <= _largeAmountConfirmations, \\\"AllowTokens: medium bigger than large confirmations\\\");\\n smallAmountConfirmations = _smallAmountConfirmations;\\n mediumAmountConfirmations = _mediumAmountConfirmations;\\n largeAmountConfirmations = _largeAmountConfirmations;\\n emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\n }\\n\\n function getConfirmations() external view override\\n returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount) {\\n return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\\n }\\n\\n}\\n\",\"keccak256\":\"0x0d9f9d1c4e2185846e9c2f9aa41db513f647983d3497366ab327872f99010b65\",\"license\":\"MIT\"},\"contracts/interface/IAllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\ninterface IAllowTokens {\\n\\n struct Limits {\\n uint256 min;\\n uint256 max;\\n uint256 daily;\\n uint256 mediumAmount;\\n uint256 largeAmount;\\n }\\n\\n struct TokenInfo {\\n bool allowed;\\n uint256 typeId;\\n uint256 spentToday;\\n uint256 lastDay;\\n }\\n\\n struct TypeInfo {\\n string description;\\n Limits limits;\\n }\\n\\n struct TokensAndType {\\n address token;\\n uint256 typeId;\\n }\\n\\n function version() external pure returns (string memory);\\n\\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\\n\\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\\n\\n function getTypesLimits() external view returns(Limits[] memory limits);\\n\\n function getTypeDescriptionsLength() external view returns(uint256);\\n\\n function getTypeDescriptions() external view returns(string[] memory descriptions);\\n\\n function setToken(address token, uint256 typeId) external;\\n\\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\\n\\n function isTokenAllowed(address token) external view returns (bool);\\n\\n function updateTokenTransfer(address token, uint256 amount) external;\\n}\",\"keccak256\":\"0x5a2aaa285c400917cd72fafe61ce409f200c3fc13d984843bccfb97563489a61\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x09ca2716452528a6e69ac9f83f874292a1e547630473f3133038314a2f16029e\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\",\"keccak256\":\"0x3eeeb5ea6bf7d3458bb36acebd4268b406e6a1525e009d4d8a90626c277a37d1\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract UpgradableOwnable is Initializable, Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function initialize(address sender) public initializer {\\n _owner = sender;\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * > Note: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n\\n}\\n\",\"keccak256\":\"0x2e0e58f4a3991801550e6a52512a3c1bbcaa5cb824120c177cb6ec1b4fa0ce97\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\n */\\ncontract UpgradableSecondary is Initializable, Context {\\n address private _primary;\\n\\n /**\\n * @dev Emitted when the primary contract changes.\\n */\\n event PrimaryTransferred(\\n address recipient\\n );\\n\\n /**\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\n */\\n function __Secondary_init(address sender) public initializer {\\n _primary = sender;\\n emit PrimaryTransferred(_primary);\\n }\\n\\n /**\\n * @dev Reverts if called from any account other than the primary.\\n */\\n modifier onlyPrimary() {\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\n _;\\n }\\n\\n /**\\n * @return the address of the primary.\\n */\\n function primary() public view returns (address) {\\n return _primary;\\n }\\n\\n /**\\n * @dev Transfers contract to a new primary.\\n * @param recipient The address of new primary.\\n */\\n function transferPrimary(address recipient) public onlyPrimary {\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\n _primary = recipient;\\n emit PrimaryTransferred(recipient);\\n }\\n\\n}\",\"keccak256\":\"0x156eff0cfa1a0b99fcc5a710688fd8d3038552a380e3687a70e9d75e4bb59315\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50612331806100206000396000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80638f32d59b1161010f578063c4d66de8116100a2578063e4f89ae411610071578063e4f89ae4146103e3578063e744092e146103f6578063f2fde38b14610419578063f9eaee0d1461042c576101e5565b8063c4d66de8146103ad578063c6dbdf61146103c0578063d4164b5d146103c8578063d7516faa146103db576101e5565b8063adfeb5eb116100de578063adfeb5eb1461035d578063b348a29f14610370578063bb698dad14610383578063c361ce8314610396576101e5565b80638f32d59b1461030c57806390469a9d146103215780639d27d22614610334578063a81a8b1f14610355576101e5565b806354fd4d50116101875780637d496be9116101565780637d496be9146102d45780638c34bc55146102dc5780638da5cb5b146102ef5780638de52dd714610304576101e5565b806354fd4d501461029e578063601ad4c9146102a6578063715018a6146102b957806378bf2b53146102c1576101e5565b80632348238c116101c35780632348238c1461024c578063250540cf146102615780633777804f1461027457806353a8b57414610289576101e5565b806307fc9eb9146101ea5780630a9763d7146102175780631c21a08f1461022c575b600080fd5b6101fd6101f8366004611a65565b61043f565b60405161020e9594939291906122b4565b60405180910390f35b61021f61046e565b60405161020e9190612287565b61023f61023a366004611a65565b610473565b60405161020e9190611c39565b61025f61025a366004611725565b61051c565b005b61021f61026f366004611725565b6105db565b61027c610601565b60405161020e9190611bc3565b6102916106da565b60405161020e9190611b63565b61023f6107f9565b61025f6102b4366004611aa9565b610815565b61025f610849565b61025f6102cf366004611928565b6108b7565b61021f610a00565b61025f6102ea366004611928565b610a06565b6102f7610b7f565b60405161020e9190611b4f565b61021f610b8e565b610314610b94565b60405161020e9190611c11565b61025f61032f366004611725565b610bba565b610347610342366004611725565b610ce7565b60405161020e92919061224d565b61021f610d93565b61025f61036b366004611725565b610d99565b61025f61037e366004611a7d565b610e68565b61021f6103913660046119c1565b610e96565b61039e610f14565b60405161020e9392919061229e565b61025f6103bb366004611725565b610f22565b6102f7610fe6565b61025f6103d636600461173f565b610ff5565b61021f6110db565b61025f6103f1366004611951565b6110e1565b610409610404366004611725565b611175565b60405161020e9493929190611c1c565b61025f610427366004611725565b6111a0565b61031461043a366004611725565b6111d0565b603660205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b60fa81565b603a818154811061048357600080fd5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152935090918301828280156105145780601f106104e957610100808354040283529160200191610514565b820191906000526020600020905b8154815290600101906020018083116104f757829003601f168201915b505050505081565b6034546001600160a01b0316610530611219565b6001600160a01b03161461055f5760405162461bcd60e51b815260040161055690612143565b60405180910390fd5b6001600160a01b0381166105855760405162461bcd60e51b815260040161055690611f4b565b603480546001600160a01b0319166001600160a01b0383161790556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9906105d0908390611b4f565b60405180910390a150565b60008060006105e984610ce7565b915091506105f7828261121d565b925050505b919050565b603a5460609067ffffffffffffffff8111801561061d57600080fd5b5060405190808252806020026020018201604052801561065757816020015b6106446115b4565b81526020019060019003908161063c5790505b50905060005b603a548110156106d657603660008281526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250508282815181106106c357fe5b602090810291909101015260010161065d565b5090565b603a5460609067ffffffffffffffff811180156106f657600080fd5b5060405190808252806020026020018201604052801561072a57816020015b60608152602001906001900390816107155790505b50905060005b603a548110156106d657603a818154811061074757fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156107d55780601f106107aa576101008083540402835291602001916107d5565b820191906000526020600020905b8154815290600101906020018083116107b857829003601f168201915b50505050508282815181106107e657fe5b6020908102919091010152600101610730565b604080518082019091526002815261763160f01b602082015290565b61081d610b94565b6108395760405162461bcd60e51b815260040161055690611eb9565b610844838383611275565b505050565b610851610b94565b61086d5760405162461bcd60e51b815260040161055690611eb9565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b816001600160a01b0381166108de5760405162461bcd60e51b815260040161055690611e4d565b6108e6610b94565b8061091057506108f4610fe6565b6001600160a01b0316610905611219565b6001600160a01b0316145b61092c5760405162461bcd60e51b815260040161055690611e84565b603a54821061094d5760405162461bcd60e51b815260040161055690611cf1565b6001600160a01b038316600081815260356020818152604080842081516080810183528154600283018054838601908152600385018054606086019081526001808752868a018f81529b8d9052999098528451151560ff1990941693909317855597519690930195909555945190559051909155519091907f720764556647dd167f4229d6a4255ac86018e302a50fc29dd67a70edb7b314d0906109f2908690612287565b60405180910390a250505050565b60395481565b6034546001600160a01b0316610a1a611219565b6001600160a01b031614610a405760405162461bcd60e51b815260040161055690612143565b600080610a4c84610ce7565b91509150610a59846111d0565b610a755760405162461bcd60e51b8152600401610556906121d1565b8051831015610a965760405162461bcd60e51b815260040161055690612208565b81606001516201518001421115610ab557426060830152600060408301525b6000610ac1838361121d565b905080841115610ae35760405162461bcd60e51b815260040161055690611c4c565b6040830151610af29085611305565b60408481019182526001600160a01b038716600081815260356020908152908390208751815460ff191690151517815590870151600182015592516002840181905560608701516003909401849055915190927f84480cc6a063ffd72c3eddf21e3ffd30db3e2b8e386ec3abf09c98ee9e0e8d3492610b7092612290565b60405180910390a25050505050565b6033546001600160a01b031690565b60385481565b6033546000906001600160a01b0316610bab611219565b6001600160a01b031614905090565b806001600160a01b038116610be15760405162461bcd60e51b815260040161055690611e4d565b610be9610b94565b610c055760405162461bcd60e51b815260040161055690611eb9565b6001600160a01b0382166000908152603560209081526040918290208251608081018452815460ff161515808252600183015493820193909352600282015493810193909352600301546060830152610c705760405162461bcd60e51b815260040161055690612068565b60008082526001600160a01b0384168082526035602090815260408084208551815460ff191690151517815591850151600183015580850151600283015560608501516003909201919091555190917fbf996b4fd74f0c7159bb017b1db415b0d9a6f13129f46d0b93309d170b78df3191a2505050565b610cef6115e3565b610cf76115b4565b50506001600160a01b03166000908152603560209081526040808320815160808082018452825460ff1615158252600180840154838701819052600280860154858801526003958601546060808701919091529189526036885297869020865160a08101885281548152928101549783019790975296860154948101949094529184015494830194909452600490920154918101919091529091565b60375481565b600054610100900460ff1680610db2575060005460ff16155b610dce5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610df9576000805460ff1961ff0019909116610100171660011790555b603480546001600160a01b0319166001600160a01b0384811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610e4a921690611b4f565b60405180910390a18015610e64576000805461ff00191690555b5050565b610e70610b94565b610e8c5760405162461bcd60e51b815260040161055690611eb9565b610e64828261132a565b6000610ea0610b94565b610ebc5760405162461bcd60e51b815260040161055690611eb9565b610f0a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f059250505036859003850185611a4a565b61145c565b90505b9392505050565b603754603854603954909192565b600054610100900460ff1680610f3b575060005460ff16155b610f575760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610f82576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e64576000805461ff00191690555050565b6034546001600160a01b031690565b600054610100900460ff168061100e575060005460ff16155b61102a5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015611055576000805460ff1961ff0019909116610100171660011790555b61105e87610f22565b61106786610d99565b611072858585611275565b60005b82518110156110bf576110b683828151811061108d57fe5b6020026020010151600001518483815181106110a557fe5b60200260200101516020015161145c565b50600101611075565b5080156110d2576000805461ff00191690555b50505050505050565b603a5490565b6110e9610b94565b6111055760405162461bcd60e51b815260040161055690611eb9565b806111225760405162461bcd60e51b815260040161055690611dc8565b60005b818110156108445761116d83838381811061113c57fe5b6111529260206040909202019081019150611725565b84848481811061115e57fe5b905060400201602001356108b7565b600101611125565b603560205260009081526040902080546001820154600283015460039093015460ff90921692909184565b6111a8610b94565b6111c45760405162461bcd60e51b815260040161055690611eb9565b6111cd81611532565b50565b6000816001600160a01b0381166111f95760405162461bcd60e51b815260040161055690611e4d565b50506001600160a01b031660009081526035602052604090205460ff1690565b3390565b60008260600151620151800142111561123857600060408401525b826040015182604001511161124f5750600061126f565b82604001518260400151039050816020015181111561126f575060208101515b92915050565b818311156112955760405162461bcd60e51b815260040161055690611fde565b808211156112b55760405162461bcd60e51b8152600401610556906120f0565b6037839055603882905560398190556040517ffcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219906112f89085908590859061229e565b60405180910390a1505050565b600082820183811015610f0d5760405162461bcd60e51b815260040161055690611cba565b603a54821061134b5760405162461bcd60e51b815260040161055690611f95565b8051602082015110156113705760405162461bcd60e51b815260040161055690611d7b565b8060200151816040015110156113985760405162461bcd60e51b815260040161055690611dff565b80516060820151116113bc5760405162461bcd60e51b81526004016105569061209f565b80606001518160800151116113e35760405162461bcd60e51b815260040161055690611eee565b600082815260366020908152604091829020835181559083015160018201558183015160028201556060830151600382015560808301516004909101555182907f1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb9061145090849061223f565b60405180910390a25050565b60008083511161147e5760405162461bcd60e51b815260040161055690611c83565b50603a5460fa6001820111156114a65760405162461bcd60e51b815260040161055690612031565b603a805460018101825560009190915283516114e9917fa2999d817b6757290b50e8ecf3fa939673403dd35c97de392fdb343b4015ce9e0190602086019061160d565b506114f4818361132a565b807fb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0846040516115249190611c39565b60405180910390a292915050565b6001600160a01b0381166115585760405162461bcd60e51b81526004016105569061218f565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806000151581526020016000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826116435760008555611689565b82601f1061165c57805160ff1916838001178555611689565b82800160010185558215611689579182015b8281111561168957825182559160200191906001019061166e565b506106d69291505b808211156106d65760008155600101611691565b80356001600160a01b03811681146105fc57600080fd5b600060a082840312156116cd578081fd5b60405160a0810181811067ffffffffffffffff821117156116ea57fe5b806040525080915082358152602083013560208201526040830135604082015260608301356060820152608083013560808201525092915050565b600060208284031215611736578081fd5b610f0d826116a5565b60008060008060008060c08789031215611757578182fd5b611760876116a5565b955061176e602088016116a5565b945060408701359350606087013592506080870135915067ffffffffffffffff60a0880135111561179d578081fd5b60a0870135870188601f8201126117b2578182fd5b67ffffffffffffffff813511156117c557fe5b6117d4602080833502016122d7565b81358152602080820191908301845b84358110156119165760c0823586018e03601f19011215611802578586fd5b60405180604082011067ffffffffffffffff6040830111171561182157fe5b6040810160405267ffffffffffffffff60208435880101351115611843578687fd5b82358601602081013501603f018e1361185a578687fd5b67ffffffffffffffff60208435880181810135010135111561187857fe5b61189883358701602081810135909101810135601f01601f1916016122d7565b60208435880181810135019081013580835260409101018f10156118ba578788fd5b602084358801818101350180820135916040909101908301378335870160208181013582018101358301018990529082526118f9908f906040016116bc565b6020828101919091529085529384019391909101906001016117e3565b50508093505050509295509295509295565b6000806040838503121561193a578182fd5b611943836116a5565b946020939093013593505050565b60008060208385031215611963578182fd5b823567ffffffffffffffff8082111561197a578384fd5b818501915085601f83011261198d578384fd5b81358181111561199b578485fd5b8660206040830285010111156119af578485fd5b60209290920196919550909350505050565b600080600083850360c08112156119d6578384fd5b843567ffffffffffffffff808211156119ed578586fd5b818701915087601f830112611a00578586fd5b813581811115611a0e578687fd5b886020828501011115611a1f578687fd5b60209290920195509093505060a0601f1982011215611a3c578182fd5b506020840190509250925092565b600060a08284031215611a5b578081fd5b610f0d83836116bc565b600060208284031215611a76578081fd5b5035919050565b60008060c08385031215611a8f578182fd5b82359150611aa084602085016116bc565b90509250929050565b600080600060608486031215611abd578283fd5b505081359360208301359350604090920135919050565b60008151808452815b81811015611af957602081850181015186830182015201611add565b81811115611b0a5782602083870101525b50601f01601f19169290920160200192915050565b80518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b6001600160a01b0391909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611bb657603f19888603018452611ba4858351611ad4565b94509285019290850190600101611b88565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611c0557611bf2838551611b1f565b9284019260a09290920191600101611bdf565b50909695505050505050565b901515815260200190565b931515845260208401929092526040830152606082015260800190565b600060208252610f0d6020830184611ad4565b6020808252601b908201527f416c6c6f77546f6b656e733a204578636565646564206c696d69740000000000604082015260600190565b6020808252601e908201527f416c6c6f77546f6b656e733a20456d707479206465736372697074696f6e0000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526022908201527f416c6c6f77546f6b656e733a2074797065496420646f6573206e6f74206578696040820152611cdd60f21b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252602d908201527f416c6c6f77546f6b656e733a206d6178546f6b656e7320736d616c6c6572207460408201526c68616e206d696e546f6b656e7360981b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a20656d70747920746f6b656e7300000000000000604082015260600190565b6020808252602e908201527f416c6c6f77546f6b656e733a206461696c794c696d697420736d616c6c65722060408201526d7468616e206d6178546f6b656e7360901b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a204e756c6c204164647265737300000000000000604082015260600190565b6020808252818101527f416c6c6f77546f6b656e733a20756e617574686f72697a65642073656e646572604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526039908201527f416c6c6f77546f6b656e733a206c696d6974732e6c61726765416d6f756e742060408201527f736d616c6c6572207468616e206d656469756d416d6f756e7400000000000000606082015260800190565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f416c6c6f77546f6b656e733a20626967676572207468616e20747970654465736040820152686372697074696f6e7360b81b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a20736d616c6c20626967676572207468616e206d604082015272656469756d20636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252601e908201527f416c6c6f77546f6b656e733a2052656163686564204d41585f54595045530000604082015260600190565b60208082526018908201527f416c6c6f77546f6b656e733a204e6f7420416c6c6f7765640000000000000000604082015260600190565b60208082526031908201527f416c6c6f77546f6b656e733a206c696d6974732e6d656469756d416d6f756e746040820152701039b6b0b63632b9103a3430b71036b4b760791b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a206d656469756d20626967676572207468616e206040820152726c6172676520636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601c908201527f416c6c6f77546f6b656e733a204e6f742077686974656c697374656400000000604082015260600190565b6020808252601d908201527f416c6c6f77546f6b656e733a204c6f776572207468616e206c696d6974000000604082015260600190565b60a0810161126f8284611b1f565b600061012082019050835115158252602084015160208301526040840151604083015260608401516060830152610f0d6080830184611b1f565b90815260200190565b918252602082015260400190565b9283526020830191909152604082015260600190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff811182821017156122f357fe5b60405291905056fea26469706673582212201e8e7daaf66204df917383a3310c7fd1c18b921bb77f19ca1a9103a1dcd8335864736f6c63430007060033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101e55760003560e01c80638f32d59b1161010f578063c4d66de8116100a2578063e4f89ae411610071578063e4f89ae4146103e3578063e744092e146103f6578063f2fde38b14610419578063f9eaee0d1461042c576101e5565b8063c4d66de8146103ad578063c6dbdf61146103c0578063d4164b5d146103c8578063d7516faa146103db576101e5565b8063adfeb5eb116100de578063adfeb5eb1461035d578063b348a29f14610370578063bb698dad14610383578063c361ce8314610396576101e5565b80638f32d59b1461030c57806390469a9d146103215780639d27d22614610334578063a81a8b1f14610355576101e5565b806354fd4d50116101875780637d496be9116101565780637d496be9146102d45780638c34bc55146102dc5780638da5cb5b146102ef5780638de52dd714610304576101e5565b806354fd4d501461029e578063601ad4c9146102a6578063715018a6146102b957806378bf2b53146102c1576101e5565b80632348238c116101c35780632348238c1461024c578063250540cf146102615780633777804f1461027457806353a8b57414610289576101e5565b806307fc9eb9146101ea5780630a9763d7146102175780631c21a08f1461022c575b600080fd5b6101fd6101f8366004611a65565b61043f565b60405161020e9594939291906122b4565b60405180910390f35b61021f61046e565b60405161020e9190612287565b61023f61023a366004611a65565b610473565b60405161020e9190611c39565b61025f61025a366004611725565b61051c565b005b61021f61026f366004611725565b6105db565b61027c610601565b60405161020e9190611bc3565b6102916106da565b60405161020e9190611b63565b61023f6107f9565b61025f6102b4366004611aa9565b610815565b61025f610849565b61025f6102cf366004611928565b6108b7565b61021f610a00565b61025f6102ea366004611928565b610a06565b6102f7610b7f565b60405161020e9190611b4f565b61021f610b8e565b610314610b94565b60405161020e9190611c11565b61025f61032f366004611725565b610bba565b610347610342366004611725565b610ce7565b60405161020e92919061224d565b61021f610d93565b61025f61036b366004611725565b610d99565b61025f61037e366004611a7d565b610e68565b61021f6103913660046119c1565b610e96565b61039e610f14565b60405161020e9392919061229e565b61025f6103bb366004611725565b610f22565b6102f7610fe6565b61025f6103d636600461173f565b610ff5565b61021f6110db565b61025f6103f1366004611951565b6110e1565b610409610404366004611725565b611175565b60405161020e9493929190611c1c565b61025f610427366004611725565b6111a0565b61031461043a366004611725565b6111d0565b603660205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b60fa81565b603a818154811061048357600080fd5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152935090918301828280156105145780601f106104e957610100808354040283529160200191610514565b820191906000526020600020905b8154815290600101906020018083116104f757829003601f168201915b505050505081565b6034546001600160a01b0316610530611219565b6001600160a01b03161461055f5760405162461bcd60e51b815260040161055690612143565b60405180910390fd5b6001600160a01b0381166105855760405162461bcd60e51b815260040161055690611f4b565b603480546001600160a01b0319166001600160a01b0383161790556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9906105d0908390611b4f565b60405180910390a150565b60008060006105e984610ce7565b915091506105f7828261121d565b925050505b919050565b603a5460609067ffffffffffffffff8111801561061d57600080fd5b5060405190808252806020026020018201604052801561065757816020015b6106446115b4565b81526020019060019003908161063c5790505b50905060005b603a548110156106d657603660008281526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250508282815181106106c357fe5b602090810291909101015260010161065d565b5090565b603a5460609067ffffffffffffffff811180156106f657600080fd5b5060405190808252806020026020018201604052801561072a57816020015b60608152602001906001900390816107155790505b50905060005b603a548110156106d657603a818154811061074757fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156107d55780601f106107aa576101008083540402835291602001916107d5565b820191906000526020600020905b8154815290600101906020018083116107b857829003601f168201915b50505050508282815181106107e657fe5b6020908102919091010152600101610730565b604080518082019091526002815261763160f01b602082015290565b61081d610b94565b6108395760405162461bcd60e51b815260040161055690611eb9565b610844838383611275565b505050565b610851610b94565b61086d5760405162461bcd60e51b815260040161055690611eb9565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b816001600160a01b0381166108de5760405162461bcd60e51b815260040161055690611e4d565b6108e6610b94565b8061091057506108f4610fe6565b6001600160a01b0316610905611219565b6001600160a01b0316145b61092c5760405162461bcd60e51b815260040161055690611e84565b603a54821061094d5760405162461bcd60e51b815260040161055690611cf1565b6001600160a01b038316600081815260356020818152604080842081516080810183528154600283018054838601908152600385018054606086019081526001808752868a018f81529b8d9052999098528451151560ff1990941693909317855597519690930195909555945190559051909155519091907f720764556647dd167f4229d6a4255ac86018e302a50fc29dd67a70edb7b314d0906109f2908690612287565b60405180910390a250505050565b60395481565b6034546001600160a01b0316610a1a611219565b6001600160a01b031614610a405760405162461bcd60e51b815260040161055690612143565b600080610a4c84610ce7565b91509150610a59846111d0565b610a755760405162461bcd60e51b8152600401610556906121d1565b8051831015610a965760405162461bcd60e51b815260040161055690612208565b81606001516201518001421115610ab557426060830152600060408301525b6000610ac1838361121d565b905080841115610ae35760405162461bcd60e51b815260040161055690611c4c565b6040830151610af29085611305565b60408481019182526001600160a01b038716600081815260356020908152908390208751815460ff191690151517815590870151600182015592516002840181905560608701516003909401849055915190927f84480cc6a063ffd72c3eddf21e3ffd30db3e2b8e386ec3abf09c98ee9e0e8d3492610b7092612290565b60405180910390a25050505050565b6033546001600160a01b031690565b60385481565b6033546000906001600160a01b0316610bab611219565b6001600160a01b031614905090565b806001600160a01b038116610be15760405162461bcd60e51b815260040161055690611e4d565b610be9610b94565b610c055760405162461bcd60e51b815260040161055690611eb9565b6001600160a01b0382166000908152603560209081526040918290208251608081018452815460ff161515808252600183015493820193909352600282015493810193909352600301546060830152610c705760405162461bcd60e51b815260040161055690612068565b60008082526001600160a01b0384168082526035602090815260408084208551815460ff191690151517815591850151600183015580850151600283015560608501516003909201919091555190917fbf996b4fd74f0c7159bb017b1db415b0d9a6f13129f46d0b93309d170b78df3191a2505050565b610cef6115e3565b610cf76115b4565b50506001600160a01b03166000908152603560209081526040808320815160808082018452825460ff1615158252600180840154838701819052600280860154858801526003958601546060808701919091529189526036885297869020865160a08101885281548152928101549783019790975296860154948101949094529184015494830194909452600490920154918101919091529091565b60375481565b600054610100900460ff1680610db2575060005460ff16155b610dce5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610df9576000805460ff1961ff0019909116610100171660011790555b603480546001600160a01b0319166001600160a01b0384811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610e4a921690611b4f565b60405180910390a18015610e64576000805461ff00191690555b5050565b610e70610b94565b610e8c5760405162461bcd60e51b815260040161055690611eb9565b610e64828261132a565b6000610ea0610b94565b610ebc5760405162461bcd60e51b815260040161055690611eb9565b610f0a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f059250505036859003850185611a4a565b61145c565b90505b9392505050565b603754603854603954909192565b600054610100900460ff1680610f3b575060005460ff16155b610f575760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610f82576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e64576000805461ff00191690555050565b6034546001600160a01b031690565b600054610100900460ff168061100e575060005460ff16155b61102a5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015611055576000805460ff1961ff0019909116610100171660011790555b61105e87610f22565b61106786610d99565b611072858585611275565b60005b82518110156110bf576110b683828151811061108d57fe5b6020026020010151600001518483815181106110a557fe5b60200260200101516020015161145c565b50600101611075565b5080156110d2576000805461ff00191690555b50505050505050565b603a5490565b6110e9610b94565b6111055760405162461bcd60e51b815260040161055690611eb9565b806111225760405162461bcd60e51b815260040161055690611dc8565b60005b818110156108445761116d83838381811061113c57fe5b6111529260206040909202019081019150611725565b84848481811061115e57fe5b905060400201602001356108b7565b600101611125565b603560205260009081526040902080546001820154600283015460039093015460ff90921692909184565b6111a8610b94565b6111c45760405162461bcd60e51b815260040161055690611eb9565b6111cd81611532565b50565b6000816001600160a01b0381166111f95760405162461bcd60e51b815260040161055690611e4d565b50506001600160a01b031660009081526035602052604090205460ff1690565b3390565b60008260600151620151800142111561123857600060408401525b826040015182604001511161124f5750600061126f565b82604001518260400151039050816020015181111561126f575060208101515b92915050565b818311156112955760405162461bcd60e51b815260040161055690611fde565b808211156112b55760405162461bcd60e51b8152600401610556906120f0565b6037839055603882905560398190556040517ffcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219906112f89085908590859061229e565b60405180910390a1505050565b600082820183811015610f0d5760405162461bcd60e51b815260040161055690611cba565b603a54821061134b5760405162461bcd60e51b815260040161055690611f95565b8051602082015110156113705760405162461bcd60e51b815260040161055690611d7b565b8060200151816040015110156113985760405162461bcd60e51b815260040161055690611dff565b80516060820151116113bc5760405162461bcd60e51b81526004016105569061209f565b80606001518160800151116113e35760405162461bcd60e51b815260040161055690611eee565b600082815260366020908152604091829020835181559083015160018201558183015160028201556060830151600382015560808301516004909101555182907f1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb9061145090849061223f565b60405180910390a25050565b60008083511161147e5760405162461bcd60e51b815260040161055690611c83565b50603a5460fa6001820111156114a65760405162461bcd60e51b815260040161055690612031565b603a805460018101825560009190915283516114e9917fa2999d817b6757290b50e8ecf3fa939673403dd35c97de392fdb343b4015ce9e0190602086019061160d565b506114f4818361132a565b807fb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0846040516115249190611c39565b60405180910390a292915050565b6001600160a01b0381166115585760405162461bcd60e51b81526004016105569061218f565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806000151581526020016000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826116435760008555611689565b82601f1061165c57805160ff1916838001178555611689565b82800160010185558215611689579182015b8281111561168957825182559160200191906001019061166e565b506106d69291505b808211156106d65760008155600101611691565b80356001600160a01b03811681146105fc57600080fd5b600060a082840312156116cd578081fd5b60405160a0810181811067ffffffffffffffff821117156116ea57fe5b806040525080915082358152602083013560208201526040830135604082015260608301356060820152608083013560808201525092915050565b600060208284031215611736578081fd5b610f0d826116a5565b60008060008060008060c08789031215611757578182fd5b611760876116a5565b955061176e602088016116a5565b945060408701359350606087013592506080870135915067ffffffffffffffff60a0880135111561179d578081fd5b60a0870135870188601f8201126117b2578182fd5b67ffffffffffffffff813511156117c557fe5b6117d4602080833502016122d7565b81358152602080820191908301845b84358110156119165760c0823586018e03601f19011215611802578586fd5b60405180604082011067ffffffffffffffff6040830111171561182157fe5b6040810160405267ffffffffffffffff60208435880101351115611843578687fd5b82358601602081013501603f018e1361185a578687fd5b67ffffffffffffffff60208435880181810135010135111561187857fe5b61189883358701602081810135909101810135601f01601f1916016122d7565b60208435880181810135019081013580835260409101018f10156118ba578788fd5b602084358801818101350180820135916040909101908301378335870160208181013582018101358301018990529082526118f9908f906040016116bc565b6020828101919091529085529384019391909101906001016117e3565b50508093505050509295509295509295565b6000806040838503121561193a578182fd5b611943836116a5565b946020939093013593505050565b60008060208385031215611963578182fd5b823567ffffffffffffffff8082111561197a578384fd5b818501915085601f83011261198d578384fd5b81358181111561199b578485fd5b8660206040830285010111156119af578485fd5b60209290920196919550909350505050565b600080600083850360c08112156119d6578384fd5b843567ffffffffffffffff808211156119ed578586fd5b818701915087601f830112611a00578586fd5b813581811115611a0e578687fd5b886020828501011115611a1f578687fd5b60209290920195509093505060a0601f1982011215611a3c578182fd5b506020840190509250925092565b600060a08284031215611a5b578081fd5b610f0d83836116bc565b600060208284031215611a76578081fd5b5035919050565b60008060c08385031215611a8f578182fd5b82359150611aa084602085016116bc565b90509250929050565b600080600060608486031215611abd578283fd5b505081359360208301359350604090920135919050565b60008151808452815b81811015611af957602081850181015186830182015201611add565b81811115611b0a5782602083870101525b50601f01601f19169290920160200192915050565b80518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b6001600160a01b0391909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611bb657603f19888603018452611ba4858351611ad4565b94509285019290850190600101611b88565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611c0557611bf2838551611b1f565b9284019260a09290920191600101611bdf565b50909695505050505050565b901515815260200190565b931515845260208401929092526040830152606082015260800190565b600060208252610f0d6020830184611ad4565b6020808252601b908201527f416c6c6f77546f6b656e733a204578636565646564206c696d69740000000000604082015260600190565b6020808252601e908201527f416c6c6f77546f6b656e733a20456d707479206465736372697074696f6e0000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526022908201527f416c6c6f77546f6b656e733a2074797065496420646f6573206e6f74206578696040820152611cdd60f21b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252602d908201527f416c6c6f77546f6b656e733a206d6178546f6b656e7320736d616c6c6572207460408201526c68616e206d696e546f6b656e7360981b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a20656d70747920746f6b656e7300000000000000604082015260600190565b6020808252602e908201527f416c6c6f77546f6b656e733a206461696c794c696d697420736d616c6c65722060408201526d7468616e206d6178546f6b656e7360901b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a204e756c6c204164647265737300000000000000604082015260600190565b6020808252818101527f416c6c6f77546f6b656e733a20756e617574686f72697a65642073656e646572604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526039908201527f416c6c6f77546f6b656e733a206c696d6974732e6c61726765416d6f756e742060408201527f736d616c6c6572207468616e206d656469756d416d6f756e7400000000000000606082015260800190565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f416c6c6f77546f6b656e733a20626967676572207468616e20747970654465736040820152686372697074696f6e7360b81b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a20736d616c6c20626967676572207468616e206d604082015272656469756d20636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252601e908201527f416c6c6f77546f6b656e733a2052656163686564204d41585f54595045530000604082015260600190565b60208082526018908201527f416c6c6f77546f6b656e733a204e6f7420416c6c6f7765640000000000000000604082015260600190565b60208082526031908201527f416c6c6f77546f6b656e733a206c696d6974732e6d656469756d416d6f756e746040820152701039b6b0b63632b9103a3430b71036b4b760791b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a206d656469756d20626967676572207468616e206040820152726c6172676520636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601c908201527f416c6c6f77546f6b656e733a204e6f742077686974656c697374656400000000604082015260600190565b6020808252601d908201527f416c6c6f77546f6b656e733a204c6f776572207468616e206c696d6974000000604082015260600190565b60a0810161126f8284611b1f565b600061012082019050835115158252602084015160208301526040840151604083015260608401516060830152610f0d6080830184611b1f565b90815260200190565b918252602082015260400190565b9283526020830191909152604082015260600190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff811182821017156122f357fe5b60405291905056fea26469706673582212201e8e7daaf66204df917383a3310c7fd1c18b921bb77f19ca1a9103a1dcd8335864736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "__Secondary_init(address)": {
+ "details": "Sets the primary account to the one that is creating the Secondary contract."
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15785,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15788,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15828,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16072,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 16205,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_address"
+ },
+ {
+ "astId": 31,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "allowedTokens",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_mapping(t_address,t_struct(TokenInfo)7131_storage)"
+ },
+ {
+ "astId": 35,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeLimits",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_mapping(t_uint256,t_struct(Limits)7122_storage)"
+ },
+ {
+ "astId": 37,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "smallAmountConfirmations",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 39,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "mediumAmountConfirmations",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 41,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "largeAmountConfirmations",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 44,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeDescriptions",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_array(t_string_storage)dyn_storage"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "base": "t_string_storage",
+ "encoding": "dynamic_array",
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_struct(TokenInfo)7131_storage)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => struct IAllowTokens.TokenInfo)",
+ "numberOfBytes": "32",
+ "value": "t_struct(TokenInfo)7131_storage"
+ },
+ "t_mapping(t_uint256,t_struct(Limits)7122_storage)": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => struct IAllowTokens.Limits)",
+ "numberOfBytes": "32",
+ "value": "t_struct(Limits)7122_storage"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(Limits)7122_storage": {
+ "encoding": "inplace",
+ "label": "struct IAllowTokens.Limits",
+ "members": [
+ {
+ "astId": 7113,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "min",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7115,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "max",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7117,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "daily",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7119,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "mediumAmount",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7121,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "largeAmount",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "160"
+ },
+ "t_struct(TokenInfo)7131_storage": {
+ "encoding": "inplace",
+ "label": "struct IAllowTokens.TokenInfo",
+ "members": [
+ {
+ "astId": 7124,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "allowed",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 7126,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeId",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7128,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "spentToday",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7130,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "lastDay",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/AllowTokensProxy.json b/bridge/deployments/rsktestnet/AllowTokensProxy.json
new file mode 100644
index 000000000..30c6b939a
--- /dev/null
+++ b/bridge/deployments/rsktestnet/AllowTokensProxy.json
@@ -0,0 +1,426 @@
+{
+ "address": "0xc65bf0ae75dc1a5fc9e6f4215125692a548c773a",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "transactionIndex": 0,
+ "gasUsed": "1808069",
+ "logsBloom": "0x04000000000000000000000000010000000100000000200000800000000000000000000000000000000000000000000000002000020400000000000000040000000010000000000000000000000000000001000100040000000000000100000008000000020000000000800000000800000000000000000000000000000000400004000400000000000000000004001800000800000000000000000000000000000000000000000000000100000004000000000000c00000002000080000400000000000000004000000000000000000000008008000000000000000000060200000000080200000000000000000000000000000008000000000000000100000",
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f",
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ],
+ "data": "0x0000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf63",
+ "logIndex": 1,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xfcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 2,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "data": "0x00000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000015af1d78b58c400000000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a0000",
+ "logIndex": 3,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034254430000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 4,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000001"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000028a857425466f800000000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000429d069189e0000",
+ "logIndex": 5,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000001"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034554480000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 6,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000002"
+ ],
+ "data": "0x00000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000878678326eac90000000000000000000000000000000000000000000000000010f0cf064dd59200000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a0000",
+ "logIndex": 7,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000002"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000083c31303030757364000000000000000000000000000000000000000000000000",
+ "logIndex": 8,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000003"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000054b40b1f852bda00000000000000000000000000000000000000000000000000a968163f0a57b4000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000008ac7230489e80000",
+ "logIndex": 9,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000003"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000073c31303075736400000000000000000000000000000000000000000000000000",
+ "logIndex": 10,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000004"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000002116545850052128000000000000000000000000000000000000000000000000422ca8b0a00a4250000000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000056bc75e2d63100000",
+ "logIndex": 11,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000004"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000053d31757364000000000000000000000000000000000000000000000000000000",
+ "logIndex": 12,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000005"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000cecb8f27f4200f3a0000000000000000000000000000000000000000000000019d971e4fe8401e740000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea00000",
+ "logIndex": 13,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000005"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000053c31757364000000000000000000000000000000000000000000000000000000",
+ "logIndex": 14,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000006"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000050c783eb9b5c85f2a80000000000000000000000000000000000000000000000a18f07d736b90be5500000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea00000",
+ "logIndex": 15,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000006"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000063c3163656e740000000000000000000000000000000000000000000000000000",
+ "logIndex": 16,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ }
+ ],
+ "blockNumber": 2152255,
+ "cumulativeGasUsed": "1808069",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0x11804f8DeADb1803603278156AA1e6602949e8b2",
+ "0x8c35e166d2dea7a8a28aaea11ad7933cdae4b0ab",
+ "0xd4164b5d000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e80000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf6300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000015af1d78b58c400000000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000000003425443000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000028a857425466f800000000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000429d069189e00000000000000000000000000000000000000000000000000000000000000000003455448000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000878678326eac90000000000000000000000000000000000000000000000000010f0cf064dd59200000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000083c3130303075736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000054b40b1f852bda00000000000000000000000000000000000000000000000000a968163f0a57b4000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000073c3130307573640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000002116545850052128000000000000000000000000000000000000000000000000422ca8b0a00a4250000000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000053d3175736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000cecb8f27f4200f3a0000000000000000000000000000000000000000000000019d971e4fe8401e740000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000053c3175736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000050c783eb9b5c85f2a80000000000000000000000000000000000000000000000a18f07d736b90be5500000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000063c3163656e740000000000000000000000000000000000000000000000000000"
+ ],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"stateVariables\":{\"_ADMIN_SLOT\":{\"details\":\"Storage slot with the admin of the contract. This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0x590a4d952d39a99972cbcb691b472c5d58af9ae8fd142355ad26200affdd2a51\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x0d5202a38732881d576fe3831605fe2633e1bc9f981ebea9c3a368af027e0b71\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x53b00bc48bd4eac1e100195c494267c0ca082bd91ac3018e2ee6155fbcbbb14f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000c9f38038062000c9f83398101604081905262000026916200022e565b8281620000338262000071565b8051156200005457620000528282620000d360201b620002ca1760201c565b505b506200005d9050565b620000688262000102565b5050506200041d565b62000087816200012660201b620002f61760201c565b620000af5760405162461bcd60e51b8152600401620000a69062000347565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6060620000fb838360405180606001604052806027815260200162000c786027913962000130565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b60606200013d8462000126565b6200015c5760405162461bcd60e51b8152600401620000a690620003a4565b600080856001600160a01b031685604051620001799190620002f4565b600060405180830381855af49150503d8060008114620001b6576040519150601f19603f3d011682016040523d82523d6000602084013e620001bb565b606091505b509092509050620001ce828286620001d8565b9695505050505050565b60608315620001e9575081620000fb565b825115620001fa5782518084602001fd5b8160405162461bcd60e51b8152600401620000a6919062000312565b80516001600160a01b03811681146200012b57600080fd5b60008060006060848603121562000243578283fd5b6200024e8462000216565b92506200025e6020850162000216565b60408501519092506001600160401b03808211156200027b578283fd5b818601915086601f8301126200028f578283fd5b8151818111156200029c57fe5b604051601f8201601f191681016020018381118282101715620002bb57fe5b604052818152838201602001891015620002d3578485fd5b620002e6826020830160208701620003ea565b809450505050509250925092565b6000825162000308818460208701620003ea565b9190910192915050565b600060208252825180602084015262000333816040850160208701620003ea565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b8381101562000407578181015183820152602001620003ed565b8381111562000417576000848401525b50505050565b61084b806200042d6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fabbc30a04f636413f38ca4eda3e460473659576ddb6aaf9066d31235c793fc064736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fabbc30a04f636413f38ca4eda3e460473659576ddb6aaf9066d31235c793fc064736f6c63430007060033",
+ "devdoc": {
+ "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.",
+ "events": {
+ "AdminChanged(address,address)": {
+ "details": "Emitted when the admin account has changed."
+ }
+ },
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "constructor": {
+ "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "stateVariables": {
+ "_ADMIN_SLOT": {
+ "details": "Storage slot with the admin of the contract. This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/Bridge.json b/bridge/deployments/rsktestnet/Bridge.json
new file mode 100644
index 000000000..374eb4f57
--- /dev/null
+++ b/bridge/deployments/rsktestnet/Bridge.json
@@ -0,0 +1,2174 @@
+{
+ "address": "0x240731d9226001139b7782Fab4D261a633a0f273",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "AcceptedCrossTransfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "AllowTokensChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_reciever",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Claimed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "_userData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Cross",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "FederationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "FeePercentageChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_newSideTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_newSymbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_granularity",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_chainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "NewSideToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Paused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "SideTokenFactoryChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Unpaused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "Upgrading",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "WrappedCurrencyChanged",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "CLAIM_TYPEHASH",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Pausable_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__PauserRol_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "acceptTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "addPauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "allowTokens",
+ "outputs": [
+ {
+ "internalType": "contract IAllowTokens",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "changeAllowTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "changeFederation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "changeSideTokenFactory",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claim",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claimFallback",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_deadline",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_v",
+ "type": "uint8"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_r",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_s",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimGasless",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_originalTokenDecimals",
+ "type": "uint8"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenName",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.CreateSideTokenStruct[]",
+ "name": "createSideTokenStruct",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "createMultipleSideTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_originalTokenDecimals",
+ "type": "uint8"
+ },
+ {
+ "internalType": "string",
+ "name": "_tokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_tokenName",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deprecatedKnownTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deprecatedMappedTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deprecatedOriginalTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "deprecatedSymbolPrefix",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "domainSeparator",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "feePercentageDivider",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFederation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFeePercentage",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ }
+ ],
+ "name": "getOriginalTokenBySideToken",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.OriginalToken",
+ "name": "originalToken",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getTransactionDataHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasBeenClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasCrossed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initDomainSeparator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_federation",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_allowTokens",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_sideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionDataHashMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionDataHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionDataHashMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isPauser",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isUpgrading",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "originalToken",
+ "type": "address"
+ }
+ ],
+ "name": "knownToken",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "knownTokenByChain",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "nonces",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "originalTokenAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "originalTokenBySideToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "pause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "paused",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "tokenToUse",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "receiveTokensTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renouncePauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "senderAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "setFeePercentage",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ },
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IBridge.OriginalToken",
+ "name": "originalToken",
+ "type": "tuple"
+ }
+ ],
+ "name": "setOriginalTokenBySideTokenByChain",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "originalToken",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ }
+ ],
+ "name": "setSideTokenByOriginalAddressByChain",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "setUpgrading",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "setWrappedCurrency",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "originalToken",
+ "type": "address"
+ }
+ ],
+ "name": "sideTokenByOriginalToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "sideTokenByOriginalTokenByChain",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "sideTokenFactory",
+ "outputs": [
+ {
+ "internalType": "contract ISideTokenFactory",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "userData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "tokensReceived",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionsDataHashes",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unpause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "wrappedCurrency",
+ "outputs": [
+ {
+ "internalType": "contract IWrapped",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x10db0fdefb750e7e32f3c3e3dea628d1d6584dc76d1f24941e618f0c8a4b7fb6",
+ "receipt": {
+ "to": null,
+ "from": "0x9C95B0EF2D3E1D9ca479524Ba738C87BE28C1585",
+ "contractAddress": "0x240731d9226001139b7782Fab4D261a633a0f273",
+ "transactionIndex": 0,
+ "gasUsed": "5411353",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xe2edba6d0b6b853c15c3206742b4322f086dd5a434de732ca65d261ade275def",
+ "transactionHash": "0x10db0fdefb750e7e32f3c3e3dea628d1d6584dc76d1f24941e618f0c8a4b7fb6",
+ "logs": [],
+ "blockNumber": 2698017,
+ "cumulativeGasUsed": "5411353",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "numDeployments": 3,
+ "solcInputHash": "b19a85096471779fd79d66673cd8b3cb",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"}],\"name\":\"AcceptedCrossTransfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newAllowTokens\",\"type\":\"address\"}],\"name\":\"AllowTokensChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_reciever\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_relayer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"}],\"name\":\"Claimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_userData\",\"type\":\"bytes\"}],\"name\":\"Cross\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newFederation\",\"type\":\"address\"}],\"name\":\"FederationChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"FeePercentageChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newSideTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_newSymbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_granularity\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_chainId\",\"type\":\"uint256\"}],\"name\":\"NewSideToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newSideTokenFactory\",\"type\":\"address\"}],\"name\":\"SideTokenFactoryChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"Upgrading\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_wrappedCurrency\",\"type\":\"address\"}],\"name\":\"WrappedCurrencyChanged\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"CLAIM_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__Pausable_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__PauserRol_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"}],\"name\":\"acceptTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"addPauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allowTokens\",\"outputs\":[{\"internalType\":\"contract IAllowTokens\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAllowTokens\",\"type\":\"address\"}],\"name\":\"changeAllowTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFederation\",\"type\":\"address\"}],\"name\":\"changeFederation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newSideTokenFactory\",\"type\":\"address\"}],\"name\":\"changeSideTokenFactory\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claim\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claimFallback\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"},{\"internalType\":\"address payable\",\"name\":\"_relayer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_s\",\"type\":\"bytes32\"}],\"name\":\"claimGasless\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"claimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"_originalTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"_originalTokenSymbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_originalTokenName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.CreateSideTokenStruct[]\",\"name\":\"createSideTokenStruct\",\"type\":\"tuple[]\"}],\"name\":\"createMultipleSideTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"_originalTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"_tokenSymbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_tokenName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"}],\"name\":\"createSideToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deprecatedKnownTokens\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deprecatedMappedTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deprecatedOriginalTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deprecatedSymbolPrefix\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"domainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePercentageDivider\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFederation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeePercentage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"}],\"name\":\"getOriginalTokenBySideToken\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.OriginalToken\",\"name\":\"originalToken\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_originChainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_destinationChainId\",\"type\":\"uint256\"}],\"name\":\"getTransactionDataHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasBeenClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasCrossed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initDomainSeparator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_federation\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_allowTokens\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_sideTokenFactory\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"transactionDataHashMultichain\",\"type\":\"bytes32\"}],\"name\":\"isClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionDataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionDataHashMultichain\",\"type\":\"bytes32\"}],\"name\":\"isClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isPauser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUpgrading\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalToken\",\"type\":\"address\"}],\"name\":\"knownToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"knownTokenByChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"originalTokenAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"originalTokenBySideToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenToUse\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"receiveTokensTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renouncePauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"senderAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"setFeePercentage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"}],\"internalType\":\"struct IBridge.OriginalToken\",\"name\":\"originalToken\",\"type\":\"tuple\"}],\"name\":\"setOriginalTokenBySideTokenByChain\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"}],\"name\":\"setSideTokenByOriginalAddressByChain\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"setUpgrading\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_wrappedCurrency\",\"type\":\"address\"}],\"name\":\"setWrappedCurrency\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalToken\",\"type\":\"address\"}],\"name\":\"sideTokenByOriginalToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"sideTokenByOriginalTokenByChain\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sideTokenFactory\",\"outputs\":[{\"internalType\":\"contract ISideTokenFactory\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"userData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transactionsDataHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wrappedCurrency\",\"outputs\":[{\"internalType\":\"contract IWrapped\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"__Pausable_init(address)\":{\"details\":\"Initializes the contract in unpaused state. Assigns the Pauser role to the deployer.\"},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pause()\":{\"details\":\"Called by a pauser to pause, triggers stopped state.\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"params\":{\"userData\":\"it can be 2 options in the first one you can send the receiver and the chain id of the destination const userData = web3.eth.abi.encodeParameters( [\\\"address\\\", \\\"uint256\\\"], [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID] ); or you also can send only the destination chain id, and the receiver would be the same as the from parameter const userData = web3.eth.abi.encodeParameters([\\\"uint256\\\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"unpause()\":{\"details\":\"Called by a pauser to unpause, returns to normal state.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"acceptTransfer(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)\":{\"notice\":\"Accepts the transaction from the other chain that was voted and sent by the Federation contract\"},\"claim((address,uint256,bytes32,bytes32,uint32,uint256))\":{\"notice\":\"Claims the crossed transaction using the hash, this sends the funds to the address indicated in\"},\"depositTo(uint256,address)\":{\"notice\":\"Use network currency and cross it.\"},\"receiveTokensTo(uint256,address,address,uint256)\":{\"notice\":\"ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction See https://eips.ethereum.org/EIPS/eip-777#motivation for details\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Bridge/Bridge.sol\":\"Bridge\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Bridge/Bridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n// import \\\"hardhat/console.sol\\\";\\n// Import base Initializable contract\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\n// Import interface and library from OpenZeppelin contracts\\nimport \\\"../zeppelin/upgradable/utils/ReentrancyGuard.sol\\\";\\nimport \\\"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\n\\nimport \\\"../zeppelin/introspection/IERC1820Registry.sol\\\";\\nimport \\\"../zeppelin/token/ERC777/IERC777Recipient.sol\\\";\\nimport \\\"../zeppelin/token/ERC20/IERC20.sol\\\";\\nimport \\\"../zeppelin/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"../zeppelin/utils/Address.sol\\\";\\nimport \\\"../zeppelin/math/SafeMath.sol\\\";\\nimport \\\"../zeppelin/token/ERC777/IERC777.sol\\\";\\n\\nimport \\\"../lib/LibEIP712.sol\\\";\\nimport \\\"../lib/LibUtils.sol\\\";\\n\\nimport \\\"../interface/IBridge.sol\\\";\\nimport \\\"../interface/ISideToken.sol\\\";\\nimport \\\"../interface/ISideTokenFactory.sol\\\";\\nimport \\\"../interface/IAllowTokens.sol\\\";\\nimport \\\"../interface/IWrapped.sol\\\";\\n\\n// solhint-disable-next-line max-states-count\\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\\n\\tusing SafeMath for uint256;\\n\\tusing SafeERC20 for IERC20;\\n\\tusing Address for address;\\n\\n\\taddress constant internal NULL_ADDRESS = address(0);\\n\\tbytes32 constant internal NULL_HASH = bytes32(0);\\n\\tIERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\n\\n\\taddress internal federation;\\n\\tuint256 internal feePercentage;\\n\\tstring public deprecatedSymbolPrefix;\\n\\t// domainSeparator replaces uint256 internal _depprecatedLastDay;\\n\\tbytes32 public domainSeparator;\\n\\tuint256 internal _deprecatedSpentToday;\\n\\n\\tmapping (address => address) public deprecatedMappedTokens; // OriginalToken => SideToken\\n\\tmapping (address => address) public deprecatedOriginalTokens; // SideToken => OriginalToken\\n\\tmapping (address => bool) public deprecatedKnownTokens; // OriginalToken => true\\n\\n\\t// claimed can use the same of bytes32\\n\\tmapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\\n\\n\\tIAllowTokens public allowTokens;\\n\\tISideTokenFactory public sideTokenFactory;\\n\\t//Bridge_v1 variables\\n\\tbool public isUpgrading;\\n\\t// Percentage with up to 2 decimals\\n\\tuint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\\n\\t//Bridge_v2 variables\\n\\tbytes32 constant internal _erc777Interface = keccak256(\\\"ERC777Token\\\"); // solhint-disable-line const-name-snakecase\\n\\tIWrapped public wrappedCurrency;\\n\\tmapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\\n\\tmapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\\n\\tmapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\\n\\n\\t// keccak256(\\\"Claim(address to,uint256 amount,bytes32 transactionHash,uint256 originChainId,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\\\");\\n\\tbytes32 public constant CLAIM_TYPEHASH = 0xaf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c;\\n\\tmapping(address => uint) public nonces;\\n\\n\\t//Bridge_v3 variables multichain\\n\\tmapping (uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain; // chainId => OriginalToken Address => SideToken Address\\n\\tmapping (address => OriginalToken) public originalTokenBySideToken; // SideTokenAddress => struct {}\\n\\tmapping (uint256 => mapping(address => bool)) public knownTokenByChain; // chainId => OriginalToken Address => Know\\n\\n\\tevent AllowTokensChanged(address _newAllowTokens);\\n\\tevent FederationChanged(address _newFederation);\\n\\tevent SideTokenFactoryChanged(address _newSideTokenFactory);\\n\\tevent Upgrading(bool _isUpgrading);\\n\\tevent WrappedCurrencyChanged(address _wrappedCurrency);\\n\\n\\tfunction initialize(\\n\\t\\taddress _manager,\\n\\t\\taddress _federation,\\n\\t\\taddress _allowTokens,\\n\\t\\taddress _sideTokenFactory\\n\\t) public initializer {\\n\\t\\tUpgradableOwnable.initialize(_manager);\\n\\t\\tUpgradablePausable.__Pausable_init(_manager);\\n\\t\\tallowTokens = IAllowTokens(_allowTokens);\\n\\t\\tsideTokenFactory = ISideTokenFactory(_sideTokenFactory);\\n\\t\\tfederation = _federation;\\n\\t\\t//keccak256(\\\"ERC777TokensRecipient\\\")\\n\\t\\tERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\\n\\t\\tinitDomainSeparator();\\n\\t}\\n\\n\\treceive () external payable {\\n\\t\\t// The fallback function is needed to use WRBTC\\n\\t\\trequire(_msgSender() == address(wrappedCurrency), \\\"Bridge: not wrappedCurrency\\\");\\n\\t}\\n\\n\\tfunction version() override external pure returns (string memory) {\\n\\t\\treturn \\\"v4\\\";\\n\\t}\\n\\n\\tfunction initDomainSeparator() public {\\n\\t\\tdomainSeparator = LibEIP712.hashEIP712Domain(\\n\\t\\t\\t\\\"RSK Token Bridge\\\",\\n\\t\\t\\t\\\"1\\\",\\n\\t\\t\\tblock.chainid,\\n\\t\\t\\taddress(this)\\n\\t\\t);\\n\\t}\\n\\n\\tmodifier whenNotUpgrading() {\\n\\t\\trequire(!isUpgrading, \\\"Bridge: Upgrading\\\");\\n\\t\\t_;\\n\\t}\\n\\n\\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\\n\\t\\trequire(chainId == block.chainid, \\\"Bridge: Not block.chainid\\\");\\n\\t}\\n\\n\\tfunction sideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\\n\\t\\taddress sideTokenAddr = sideTokenByOriginalTokenByChain[chainId][originalToken];\\n\\n\\t\\tif (sideTokenAddr != NULL_ADDRESS) {\\n\\t\\t\\treturn sideTokenAddr;\\n\\t\\t}\\n\\n\\t\\t// specification for retrocompatibility\\n\\t\\treturn deprecatedMappedTokens[originalToken];\\n\\t}\\n\\n\\tfunction setSideTokenByOriginalAddressByChain(uint256 chainId, address originalToken, address sideToken) public onlyOwner {\\n\\t\\tsideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\\n\\t}\\n\\n\\tfunction getOriginalTokenBySideToken(address sideToken) public view returns(OriginalToken memory originalToken) {\\n\\t\\toriginalToken = originalTokenBySideToken[sideToken];\\n\\t\\tif (originalToken.tokenAddress != NULL_ADDRESS) {\\n\\t\\t\\treturn originalToken;\\n\\t\\t}\\n\\n\\t\\t// specification for retrocompatibility\\n\\t\\toriginalToken.originChainId = 1; // ethereum main chain id\\n\\t\\toriginalToken.tokenAddress = deprecatedOriginalTokens[sideToken];\\n\\t\\treturn originalToken;\\n\\t}\\n\\n\\tfunction setOriginalTokenBySideTokenByChain(address sideToken, OriginalToken memory originalToken) public onlyOwner {\\n\\t\\toriginalTokenBySideToken[sideToken] = originalToken;\\n\\t}\\n\\n\\tfunction knownToken(uint256 chainId, address originalToken) public view returns(bool) {\\n\\t\\tbool knowToken = knownTokenByChain[chainId][originalToken];\\n\\t\\tif (knowToken) {\\n\\t\\t\\treturn knowToken;\\n\\t\\t}\\n\\n\\t\\t// specification for retrocompatibility\\n\\t\\treturn deprecatedKnownTokens[originalToken];\\n\\t}\\n\\n\\tfunction _setKnownTokenByChain(uint256 chainId, address originalToken, bool knownTokenValue) internal {\\n\\t\\tknownTokenByChain[chainId][originalToken] = knownTokenValue;\\n\\t}\\n\\n\\tfunction acceptTransfer(\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _from,\\n\\t\\taddress payable _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t) external whenNotPaused nonReentrant override {\\n\\t\\trequire(_msgSender() == federation, \\\"Bridge: Not Federation\\\");\\n\\t\\tcheckChainId(_originChainId);\\n\\t\\tshouldBeCurrentChainId(_destinationChainId);\\n\\t\\trequire(knownToken(_originChainId, _originalTokenAddress) ||\\n\\t\\t\\tsideTokenByOriginalToken(_originChainId, _originalTokenAddress) != NULL_ADDRESS,\\n\\t\\t\\t\\\"Bridge: Unknown token\\\"\\n\\t\\t);\\n\\t\\trequire(_to != NULL_ADDRESS, \\\"Bridge: Null To\\\");\\n\\t\\trequire(_amount > 0, \\\"Bridge: Amount 0\\\");\\n\\t\\trequire(_blockHash != NULL_HASH, \\\"Bridge: Null BlockHash\\\");\\n\\t\\trequire(_transactionHash != NULL_HASH, \\\"Bridge: Null TxHash\\\");\\n\\t\\trequire(transactionsDataHashes[_transactionHash] == bytes32(0), \\\"Bridge: Already accepted\\\");\\n\\n\\t\\tbytes32 _transactionDataHash = getTransactionDataHash(\\n\\t\\t\\t_to,\\n\\t\\t\\t_amount,\\n\\t\\t\\t_blockHash,\\n\\t\\t\\t_transactionHash,\\n\\t\\t\\t_logIndex\\n\\t\\t);\\n\\n\\t\\tbytes32 _transactionDataHashMultichain = getTransactionDataHash(\\n\\t\\t\\t_to,\\n\\t\\t\\t_amount,\\n\\t\\t\\t_blockHash,\\n\\t\\t\\t_transactionHash,\\n\\t\\t\\t_logIndex,\\n\\t\\t\\t_originChainId,\\n\\t\\t\\t_destinationChainId\\n\\t\\t);\\n\\t\\t// Do not remove, claimed also has the previously processed using the older bridge version\\n\\t\\t// https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\\n\\t\\trequire(!isClaimed(_transactionDataHash, _transactionDataHashMultichain), \\\"Bridge: Already claimed\\\");\\n\\n\\t\\ttransactionsDataHashes[_transactionHash] = _transactionDataHashMultichain;\\n\\t\\toriginalTokenAddresses[_transactionHash] = _originalTokenAddress;\\n\\t\\tsenderAddresses[_transactionHash] = _from;\\n\\n\\t\\temit AcceptedCrossTransfer(\\n\\t\\t\\t_transactionHash,\\n\\t\\t\\t_originalTokenAddress,\\n\\t\\t\\t_to,\\n\\t\\t\\t_from,\\n\\t\\t\\t_amount,\\n\\t\\t\\t_blockHash,\\n\\t\\t\\t_logIndex,\\n\\t\\t\\t_originChainId,\\n\\t\\t\\t_destinationChainId\\n\\t\\t);\\n\\t}\\n\\n\\tfunction checkChainId(uint256 chainId) internal pure {\\n\\t\\trequire(chainId > 0, \\\"Bridge: ChainId is 0\\\");\\n\\t}\\n\\n\\tfunction _createSideToken(\\n\\t\\tuint256 _typeId,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\tuint8 _originalTokenDecimals,\\n\\t\\tstring calldata _tokenSymbol,\\n\\t\\tstring calldata _tokenName,\\n\\t\\tuint256 _originChainId\\n\\t) internal {\\n\\t\\trequire(_originalTokenAddress != NULL_ADDRESS, \\\"Bridge: Null token\\\");\\n\\t\\tcheckChainId(_originChainId);\\n\\t\\taddress sideToken = sideTokenByOriginalToken(_originChainId, _originalTokenAddress);\\n\\t\\trequire(sideToken == NULL_ADDRESS, \\\"Bridge: Already exists\\\");\\n\\n\\t\\tuint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\\n\\n\\t\\t// Create side token\\n\\t\\tsideToken = sideTokenFactory.createSideToken(_tokenName, _tokenSymbol, granularity);\\n\\n\\t\\tsetSideTokenByOriginalAddressByChain(_originChainId, _originalTokenAddress, sideToken);\\n\\n\\t\\tOriginalToken memory originalToken;\\n\\t\\toriginalToken.originChainId = _originChainId;\\n\\t\\toriginalToken.tokenAddress = _originalTokenAddress;\\n\\t\\tsetOriginalTokenBySideTokenByChain(sideToken, originalToken);\\n\\t\\tallowTokens.setToken(sideToken, _typeId);\\n\\n\\t\\temit NewSideToken(sideToken, _originalTokenAddress, _tokenSymbol, granularity, _originChainId);\\n\\t}\\n\\n\\tfunction createSideToken(\\n\\t\\tuint256 _typeId,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\tuint8 _originalTokenDecimals,\\n\\t\\tstring calldata _tokenSymbol,\\n\\t\\tstring calldata _tokenName,\\n\\t\\tuint256 _originChainId\\n\\t) external onlyOwner override {\\n\\t\\t_createSideToken(\\n\\t\\t\\t_typeId,\\n\\t\\t\\t_originalTokenAddress,\\n\\t\\t\\t_originalTokenDecimals,\\n\\t\\t\\t_tokenSymbol,\\n\\t\\t\\t_tokenName,\\n\\t\\t\\t_originChainId\\n\\t\\t);\\n\\t}\\n\\n\\tfunction createMultipleSideTokens(\\n\\t\\tCreateSideTokenStruct[] calldata createSideTokenStruct\\n\\t) external onlyOwner {\\n\\t\\tfor(uint256 i = 0; i < createSideTokenStruct.length; i++) {\\n\\t\\t\\t_createSideToken(\\n\\t\\t\\t\\tcreateSideTokenStruct[i]._typeId,\\n\\t\\t\\t\\tcreateSideTokenStruct[i]._originalTokenAddress,\\n\\t\\t\\t\\tcreateSideTokenStruct[i]._originalTokenDecimals,\\n\\t\\t\\t\\tcreateSideTokenStruct[i]._originalTokenSymbol,\\n\\t\\t\\t\\tcreateSideTokenStruct[i]._originalTokenName,\\n\\t\\t\\t\\tcreateSideTokenStruct[i]._originChainId\\n\\t\\t\\t);\\n\\t\\t}\\n\\t}\\n\\n\\tfunction claim(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\\n\\t\\treceivedAmount = _claim(\\n\\t\\t\\t_claimData,\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\tpayable(address(0)),\\n\\t\\t\\t0\\n\\t\\t);\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\tfunction claimFallback(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\\n\\t\\trequire(_msgSender() == senderAddresses[_claimData.transactionHash],\\\"Bridge: invalid sender\\\");\\n\\t\\treceivedAmount = _claim(\\n\\t\\t\\t_claimData,\\n\\t\\t\\t_msgSender(),\\n\\t\\t\\tpayable(address(0)),\\n\\t\\t\\t0\\n\\t\\t);\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\tfunction getDigest(\\n\\t\\tClaimData memory _claimData,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _deadline\\n\\t) internal returns (bytes32) {\\n\\t\\treturn LibEIP712.hashEIP712Message(\\n\\t\\t\\tdomainSeparator,\\n\\t\\t\\tkeccak256(\\n\\t\\t\\t\\tabi.encode(\\n\\t\\t\\t\\t\\tCLAIM_TYPEHASH,\\n\\t\\t\\t\\t\\t_claimData.to,\\n\\t\\t\\t\\t\\t_claimData.amount,\\n\\t\\t\\t\\t\\t_claimData.transactionHash,\\n\\t\\t\\t\\t\\t_claimData.originChainId,\\n\\t\\t\\t\\t\\t_relayer,\\n\\t\\t\\t\\t\\t_fee,\\n\\t\\t\\t\\t\\tnonces[_claimData.to]++,\\n\\t\\t\\t\\t\\t_deadline\\n\\t\\t\\t\\t)\\n\\t\\t\\t)\\n\\t\\t);\\n\\t}\\n\\n\\t// Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\\n\\tfunction claimGasless(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _deadline,\\n\\t\\tuint8 _v,\\n\\t\\tbytes32 _r,\\n\\t\\tbytes32 _s\\n\\t) external override returns (uint256 receivedAmount) {\\n\\t\\trequire(_deadline >= block.timestamp, \\\"Bridge: EXPIRED\\\"); // solhint-disable-line not-rely-on-time\\n\\n\\t\\tbytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\\n\\t\\taddress recoveredAddress = ecrecover(digest, _v, _r, _s);\\n\\t\\trequire(_claimData.to != address(0) && recoveredAddress == _claimData.to, \\\"Bridge: INVALID_SIGNATURE\\\");\\n\\n\\t\\treturn _claim(\\n\\t\\t\\t_claimData,\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\t_relayer,\\n\\t\\t\\t_fee\\n\\t\\t);\\n\\t}\\n\\n\\tfunction isClaimed(bytes32 transactionDataHash, bytes32 transactionDataHashMultichain) public view returns(bool) {\\n\\t\\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\\n\\t}\\n\\n\\tfunction isClaimed(ClaimData calldata _claimData, bytes32 transactionDataHashMultichain) public view returns(bool) {\\n\\t\\tbytes32 transactionDataHash = getTransactionDataHash(\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\t_claimData.amount,\\n\\t\\t\\t_claimData.blockHash,\\n\\t\\t\\t_claimData.transactionHash,\\n\\t\\t\\t_claimData.logIndex\\n\\t\\t);\\n\\n\\t\\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\\n\\t}\\n\\n\\tfunction _claim(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress payable _reciever,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal nonReentrant returns (uint256 receivedAmount) {\\n\\t\\taddress originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\\n\\t\\trequire(originalTokenAddress != NULL_ADDRESS, \\\"Bridge: Tx not crossed\\\");\\n\\n\\t\\tbytes32 transactionDataHash = getTransactionDataHash(\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\t_claimData.amount,\\n\\t\\t\\t_claimData.blockHash,\\n\\t\\t\\t_claimData.transactionHash,\\n\\t\\t\\t_claimData.logIndex,\\n\\t\\t\\t_claimData.originChainId,\\n\\t\\t\\tblock.chainid\\n\\t\\t);\\n\\n\\t\\trequire(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \\\"Bridge: Wrong transactionDataHash\\\");\\n\\t\\trequire(!isClaimed(_claimData, transactionDataHash), \\\"Bridge: Already claimed\\\");\\n\\t\\tclaimed[transactionDataHash] = true;\\n\\n\\t\\treceivedAmount = _claimCross(\\n\\t\\t\\t_claimData.originChainId,\\n\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t_reciever,\\n\\t\\t\\t_claimData.amount,\\n\\t\\t\\t_relayer,\\n\\t\\t\\t_fee\\n\\t\\t);\\n\\n\\t\\temitClaimed(_claimData, originalTokenAddress, _reciever, _relayer, _fee);\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\tfunction emitClaimed(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _reciever,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal {\\n\\t\\temit Claimed(\\n\\t\\t\\t_claimData.transactionHash,\\n\\t\\t\\t_originalTokenAddress,\\n\\t\\t\\t_claimData.to,\\n\\t\\t\\tsenderAddresses[_claimData.transactionHash],\\n\\t\\t\\t_claimData.amount,\\n\\t\\t\\t_claimData.blockHash,\\n\\t\\t\\t_claimData.logIndex,\\n\\t\\t\\t_reciever,\\n\\t\\t\\t_relayer,\\n\\t\\t\\t_fee,\\n\\t\\t\\t_claimData.originChainId,\\n\\t\\t\\tblock.chainid\\n\\t\\t);\\n\\t}\\n\\n\\tfunction _claimCross(\\n\\t\\tuint256 _originalChainId,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _reciever,\\n\\t\\tuint256 _amount,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal returns (uint256) {\\n\\t\\tcheckChainId(_originalChainId);\\n\\t\\tif (knownToken(_originalChainId, _originalTokenAddress)) {\\n\\t\\t\\treturn _claimCrossBackToToken(\\n\\t\\t\\t\\t_originalTokenAddress,\\n\\t\\t\\t\\t_reciever,\\n\\t\\t\\t\\t_amount,\\n\\t\\t\\t\\t_relayer,\\n\\t\\t\\t\\t_fee\\n\\t\\t\\t);\\n\\t\\t}\\n\\n\\t\\treturn _claimCrossToSideToken(\\n\\t\\t\\tsideTokenByOriginalToken(_originalChainId, _originalTokenAddress),\\n\\t\\t\\t_reciever,\\n\\t\\t\\t_amount,\\n\\t\\t\\t_relayer,\\n\\t\\t\\t_fee\\n\\t\\t);\\n\\t}\\n\\n\\tfunction _claimCrossToSideToken(\\n\\t\\taddress _sideToken,\\n\\t\\taddress payable _receiver,\\n\\t\\tuint256 _amount,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal returns (uint256 receivedAmount) {\\n\\t\\trequire(_sideToken != NULL_ADDRESS, \\\"Bridge: side token is null\\\");\\n\\t\\tuint256 granularity = IERC777(_sideToken).granularity();\\n\\t\\tuint256 formattedAmount = _amount.mul(granularity);\\n\\t\\trequire(_fee <= formattedAmount, \\\"Bridge: fee too high\\\");\\n\\t\\treceivedAmount = formattedAmount.sub(_fee);\\n\\t\\tISideToken(_sideToken).mint(_receiver, receivedAmount, \\\"\\\", \\\"\\\");\\n\\t\\tif (_fee > 0) {\\n\\t\\t\\tISideToken(_sideToken).mint(_relayer, _fee, \\\"\\\", \\\"relayer fee\\\");\\n\\t\\t}\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\tfunction _claimCrossBackToToken(\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _receiver,\\n\\t\\tuint256 _amount,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee\\n\\t) internal returns (uint256 receivedAmount) {\\n\\t\\tuint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\\n\\t\\t//As side tokens are ERC777 they will always have 18 decimals\\n\\t\\tuint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\\n\\t\\trequire(_fee <= formattedAmount, \\\"Bridge: fee too high\\\");\\n\\t\\treceivedAmount = formattedAmount.sub(_fee);\\n\\t\\tif (address(wrappedCurrency) == _originalTokenAddress) {\\n\\t\\t\\twrappedCurrency.withdraw(formattedAmount);\\n\\t\\t\\t_receiver.transfer(receivedAmount);\\n\\t\\t\\tif(_fee > 0) {\\n\\t\\t\\t\\t_relayer.transfer(_fee);\\n\\t\\t\\t}\\n\\t\\t} else {\\n\\t\\t\\tIERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\\n\\t\\t\\tif(_fee > 0) {\\n\\t\\t\\t\\tIERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\treturn receivedAmount;\\n\\t}\\n\\n\\t/**\\n\\t\\t* ERC-20 tokens approve and transferFrom pattern\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\n\\t\\t*/\\n\\tfunction receiveTokensTo(uint256 destinationChainId, address tokenToUse, address to, uint256 amount) external override {\\n\\t\\taddress sender = _msgSender();\\n\\t\\t//Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\\n\\t\\tIERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\\n\\t\\tcrossTokens(tokenToUse, sender, to, amount, \\\"\\\", destinationChainId);\\n\\t}\\n\\n\\t/**\\n\\t\\t* Use network currency and cross it.\\n\\t\\t*/\\n\\tfunction depositTo(uint256 chainId, address to) external payable override {\\n\\t\\taddress sender = _msgSender();\\n\\t\\trequire(address(wrappedCurrency) != NULL_ADDRESS, \\\"Bridge: wrappedCurrency empty\\\");\\n\\t\\twrappedCurrency.deposit{ value: msg.value }();\\n\\t\\tcrossTokens(address(wrappedCurrency), sender, to, msg.value, \\\"\\\", chainId);\\n\\t}\\n\\n\\t/**\\n\\t\\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\n\\t\\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\\n\\t\\t* const userData = web3.eth.abi.encodeParameters(\\n * [\\\"address\\\", \\\"uint256\\\"],\\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\\n * );\\n\\t\\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\\n\\t\\t* const userData = web3.eth.abi.encodeParameters([\\\"uint256\\\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\\n\\t\\t*/\\n\\tfunction tokensReceived(\\n\\t\\taddress operator,\\n\\t\\taddress from,\\n\\t\\taddress to,\\n\\t\\tuint amount,\\n\\t\\tbytes calldata userData, // [address,uint256] user addrest receiver, destinationChainId || [uint256] same as from, destinationChainId\\n\\t\\tbytes calldata\\n\\t) external override(IBridge, IERC777Recipient) {\\n\\t\\t//Hook from ERC777address\\n\\t\\tif(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\\n\\t\\trequire(to == address(this), \\\"Bridge: Not to this address\\\");\\n\\t\\taddress tokenToUse = _msgSender();\\n\\t\\trequire(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \\\"Bridge: Not ERC777 token\\\");\\n\\t\\trequire(userData.length >= 32, \\\"Bridge: user data with at least the destinationChainId\\\");\\n\\t\\trequire(userData.length == 64 || !from.isContract(), \\\"Bridge: Specify receiver address in data\\\");\\n\\t\\taddress receiver = userData.length == 32 ? from : LibUtils.toAddress(userData, 12);\\n\\t\\tuint256 destinationChainId = LibUtils.toUint256(userData, userData.length - 32);\\n\\t\\tcrossTokens(tokenToUse, from, receiver, amount, userData, destinationChainId);\\n\\t}\\n\\n\\tfunction crossTokens(\\n\\t\\taddress tokenToUse,\\n\\t\\taddress from,\\n\\t\\taddress to,\\n\\t\\tuint256 amount,\\n\\t\\tbytes memory userData,\\n\\t\\tuint256 destinationChainId\\n\\t) internal whenNotUpgrading whenNotPaused nonReentrant {\\n\\t\\trequire(block.chainid != destinationChainId, \\\"Bridge: destination chain id equal current chain id\\\");\\n\\t\\tcheckChainId(destinationChainId);\\n\\t\\t_setKnownTokenByChain(destinationChainId, tokenToUse, true);\\n\\t\\tuint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\\n\\t\\tuint256 amountMinusFees = amount.sub(fee);\\n\\t\\tuint8 decimals = LibUtils.getDecimals(tokenToUse);\\n\\t\\tuint formattedAmount = amount;\\n\\t\\tif (decimals != 18) {\\n\\t\\t\\tformattedAmount = amount.mul(uint256(10)**(18-decimals));\\n\\t\\t}\\n\\t\\t// We consider the amount before fees converted to 18 decimals to check the limits\\n\\t\\t// updateTokenTransfer revert if token not allowed\\n\\t\\tallowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\\n\\n\\t\\tOriginalToken memory sideToken = getOriginalTokenBySideToken(tokenToUse);\\n\\t\\tif (sideToken.tokenAddress != NULL_ADDRESS) {\\n\\t\\t\\t// Side Token Crossing back\\n\\t\\t\\t{ // Created scope to avoid stack too deep\\n\\t\\t\\t\\tuint256 granularity = LibUtils.getGranularity(tokenToUse);\\n\\t\\t\\t\\tuint256 modulo = amountMinusFees.mod(granularity);\\n\\t\\t\\t\\tfee = fee.add(modulo);\\n\\t\\t\\t\\tamountMinusFees = amountMinusFees.sub(modulo);\\n\\t\\t\\t\\tIERC777(tokenToUse).burn(amountMinusFees, userData);\\n\\t\\t\\t}\\n\\t\\t\\temit Cross(\\n\\t\\t\\t\\tsideToken.tokenAddress,\\n\\t\\t\\t\\tto,\\n\\t\\t\\t\\tdestinationChainId,\\n\\t\\t\\t\\tfrom,\\n\\t\\t\\t\\tblock.chainid,\\n\\t\\t\\t\\tamountMinusFees,\\n\\t\\t\\t\\tuserData\\n\\t\\t\\t);\\n\\t\\t} else {\\n\\t\\t\\temit Cross(\\n\\t\\t\\t\\ttokenToUse,\\n\\t\\t\\t\\tto,\\n\\t\\t\\t\\tdestinationChainId,\\n\\t\\t\\t\\tfrom,\\n\\t\\t\\t\\tblock.chainid,\\n\\t\\t\\t\\tamountMinusFees,\\n\\t\\t\\t\\tuserData\\n\\t\\t\\t);\\n\\t\\t}\\n\\n\\t\\tif (fee > 0) {\\n\\t\\t\\t//Send the payment to the MultiSig of the Federation\\n\\t\\t\\tIERC20(tokenToUse).safeTransfer(owner(), fee);\\n\\t\\t}\\n\\t}\\n\\n\\t// function for retrocompatibility\\n\\tfunction getTransactionDataHash(\\n\\t\\taddress _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex\\n\\t) internal pure returns(bytes32) {\\n\\t\\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\\n\\t}\\n\\n\\tfunction getTransactionDataHash(\\n\\t\\taddress _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t) public pure override returns(bytes32) {\\n\\t\\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex, _originChainId, _destinationChainId));\\n\\t}\\n\\n\\tfunction setFeePercentage(uint amount) external onlyOwner {\\n\\t\\trequire(amount < (feePercentageDivider/10), \\\"Bridge: bigger than 10%\\\");\\n\\t\\tfeePercentage = amount;\\n\\t\\temit FeePercentageChanged(feePercentage);\\n\\t}\\n\\n\\tfunction getFeePercentage() external view override returns(uint) {\\n\\t\\treturn feePercentage;\\n\\t}\\n\\n\\tfunction changeFederation(address newFederation) external onlyOwner {\\n\\t\\trequire(newFederation != NULL_ADDRESS, \\\"Bridge: Federation is empty\\\");\\n\\t\\tfederation = newFederation;\\n\\t\\temit FederationChanged(federation);\\n\\t}\\n\\n\\tfunction changeAllowTokens(address newAllowTokens) external onlyOwner {\\n\\t\\trequire(newAllowTokens != NULL_ADDRESS, \\\"Bridge: AllowTokens is empty\\\");\\n\\t\\tallowTokens = IAllowTokens(newAllowTokens);\\n\\t\\temit AllowTokensChanged(newAllowTokens);\\n\\t}\\n\\n\\tfunction getFederation() external view returns(address) {\\n\\t\\treturn federation;\\n\\t}\\n\\n\\tfunction changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\\n\\t\\trequire(newSideTokenFactory != NULL_ADDRESS, \\\"Bridge: SideTokenFactory is empty\\\");\\n\\t\\tsideTokenFactory = ISideTokenFactory(newSideTokenFactory);\\n\\t\\temit SideTokenFactoryChanged(newSideTokenFactory);\\n\\t}\\n\\n\\tfunction setUpgrading(bool _isUpgrading) external onlyOwner {\\n\\t\\tisUpgrading = _isUpgrading;\\n\\t\\temit Upgrading(isUpgrading);\\n\\t}\\n\\n\\tfunction setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\\n\\t\\trequire(_wrappedCurrency != NULL_ADDRESS, \\\"Bridge: wrapp is empty\\\");\\n\\t\\twrappedCurrency = IWrapped(_wrappedCurrency);\\n\\t\\temit WrappedCurrencyChanged(_wrappedCurrency);\\n\\t}\\n\\n\\tfunction hasCrossed(bytes32 transactionHash) public view returns (bool) {\\n\\t\\treturn transactionsDataHashes[transactionHash] != bytes32(0);\\n\\t}\\n\\n\\tfunction hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\\n\\t\\treturn claimed[transactionsDataHashes[transactionHash]];\\n\\t}\\n\\n}\\n\",\"keccak256\":\"0xb86625857e1fbf57abe4356692a4a550fbe53e1ead4ecc09de069cad3807706e\",\"license\":\"MIT\"},\"contracts/interface/IAllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\ninterface IAllowTokens {\\n\\n\\tstruct Limits {\\n\\t\\tuint256 min;\\n\\t\\tuint256 max;\\n\\t\\tuint256 daily;\\n\\t\\tuint256 mediumAmount;\\n\\t\\tuint256 largeAmount;\\n\\t}\\n\\n\\tstruct TokenInfo {\\n\\t\\tbool allowed;\\n\\t\\tuint256 typeId;\\n\\t\\tuint256 spentToday;\\n\\t\\tuint256 lastDay;\\n\\t}\\n\\n\\tstruct TypeInfo {\\n\\t\\tstring description;\\n\\t\\tLimits limits;\\n\\t}\\n\\n\\tstruct TokensAndType {\\n\\t\\taddress token;\\n\\t\\tuint256 typeId;\\n\\t}\\n\\n\\tfunction version() external pure returns (string memory);\\n\\n\\tfunction getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\\n\\n\\tfunction calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\\n\\n\\tfunction getTypesLimits() external view returns(Limits[] memory limits);\\n\\n\\tfunction getTypeDescriptionsLength() external view returns(uint256);\\n\\n\\tfunction getTypeDescriptions() external view returns(string[] memory descriptions);\\n\\n\\tfunction setToken(address token, uint256 typeId) external;\\n\\n\\tfunction getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\\n\\n\\tfunction isTokenAllowed(address token) external view returns (bool);\\n\\n\\tfunction updateTokenTransfer(address token, uint256 amount) external;\\n}\",\"keccak256\":\"0x7a68f098e5efaad2d9d84314b2df76897fa9dbbe65c64d629b02b1dc4d9d36b5\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\ninterface IBridge {\\n\\n\\tstruct ClaimData {\\n\\t\\taddress payable to;\\n\\t\\tuint256 amount;\\n\\t\\tbytes32 blockHash;\\n\\t\\tbytes32 transactionHash;\\n\\t\\tuint32 logIndex;\\n\\t\\tuint256 originChainId;\\n\\t}\\n\\n\\tstruct OriginalToken {\\n\\t\\taddress tokenAddress;\\n\\t\\tuint256 originChainId;\\n\\t}\\n\\t\\n\\tstruct CreateSideTokenStruct {\\n\\t\\tuint256 _typeId;\\n\\t\\taddress _originalTokenAddress;\\n\\t\\tuint8 _originalTokenDecimals;\\n\\t\\tstring _originalTokenSymbol;\\n\\t\\tstring _originalTokenName;\\n\\t\\tuint256 _originChainId;\\n\\t}\\n\\n\\tfunction version() external pure returns (string memory);\\n\\n\\tfunction getFeePercentage() external view returns(uint);\\n\\n\\t/**\\n\\t\\t* ERC-20 tokens approve and transferFrom pattern\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\n\\t\\t*/\\n\\tfunction receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;\\n\\n\\t/**\\n\\t\\t* Use network currency and cross it.\\n\\t\\t*/\\n\\tfunction depositTo(uint256 chainId, address to) external payable;\\n\\n\\t/**\\n\\t\\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\n\\t\\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\\n\\t\\t* const userData = web3.eth.abi.encodeParameters(\\n * [\\\"address\\\", \\\"uint256\\\"],\\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\\n * );\\n\\t\\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\\n\\t\\t* const userData = web3.eth.abi.encodeParameters([\\\"uint256\\\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\\n\\t\\t*/\\n\\tfunction tokensReceived (\\n\\t\\taddress operator,\\n\\t\\taddress from,\\n\\t\\taddress to,\\n\\t\\tuint amount,\\n\\t\\tbytes calldata userData,\\n\\t\\tbytes calldata operatorData\\n\\t) external;\\n\\n\\t/**\\n\\t\\t* Accepts the transaction from the other chain that was voted and sent by the Federation contract\\n\\t\\t*/\\n\\tfunction acceptTransfer(\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _from,\\n\\t\\taddress payable _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t) external;\\n\\n\\t/**\\n\\t\\t* Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\n\\t\\t*/\\n\\tfunction claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n\\tfunction claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n\\tfunction claimGasless(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _deadline,\\n\\t\\tuint8 _v,\\n\\t\\tbytes32 _r,\\n\\t\\tbytes32 _s\\n\\t) external returns (uint256 receivedAmount);\\n\\n\\tfunction createSideToken(\\n\\t\\tuint256 _typeId,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\tuint8 _originalTokenDecimals,\\n\\t\\tstring calldata _originalTokenSymbol,\\n\\t\\tstring calldata _originalTokenName,\\n\\t\\tuint256 _chainId\\n\\t) external;\\n\\n\\tfunction createMultipleSideTokens(\\n\\t\\tCreateSideTokenStruct[] calldata createSideTokenStruct\\n\\t) external;\\n\\n\\tfunction getTransactionDataHash(\\n\\t\\taddress _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256 _destinationChainId\\n\\t) external returns(bytes32);\\n\\n\\tevent Cross(\\n\\t\\taddress indexed _tokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\tuint256 indexed _destinationChainId,\\n\\t\\taddress _from,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes _userData\\n\\t);\\n\\n\\tevent NewSideToken(\\n\\t\\taddress indexed _newSideTokenAddress,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\tstring _newSymbol,\\n\\t\\tuint256 _granularity,\\n\\t\\tuint256 _chainId\\n\\t);\\n\\tevent AcceptedCrossTransfer(\\n\\t\\tbytes32 indexed _transactionHash,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\taddress _from,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tuint256 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t);\\n\\tevent FeePercentageChanged(uint256 _amount);\\n\\tevent Claimed(\\n\\t\\tbytes32 indexed _transactionHash,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\taddress _sender,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tuint256 _logIndex,\\n\\t\\taddress _reciever,\\n\\t\\taddress _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _destinationChainId,\\n\\t\\tuint256 _originChainId\\n\\t);\\n}\",\"keccak256\":\"0x1c5d6422edd509f1abc62bc29b41b1c6f80df08235ca289da81c661b8aa33044\",\"license\":\"MIT\"},\"contracts/interface/ISideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\ninterface ISideToken {\\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\\n}\",\"keccak256\":\"0x43d96442dcb622e7efbad6ff3fcfe109d9f881c18415b571511f326b39d7a70e\",\"license\":\"MIT\"},\"contracts/interface/ISideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\ninterface ISideTokenFactory {\\n\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\\n\\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\\n}\",\"keccak256\":\"0x5c3c0db3ad07c2cb9933ea8a37e01b83d4ec77c7bc0ac684de87f6b1e09d25dc\",\"license\":\"MIT\"},\"contracts/interface/IWrapped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\ninterface IWrapped {\\n function balanceOf(address) external returns(uint);\\n\\n function deposit() external payable;\\n\\n function withdraw(uint wad) external;\\n\\n function totalSupply() external view returns (uint);\\n\\n function approve(address guy, uint wad) external returns (bool);\\n\\n function transfer(address dst, uint wad) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint wad)\\n external\\n returns (bool);\\n}\",\"keccak256\":\"0xea9894370181d2b7a43d973e033d1ceb8d8d229fed2b775d267ca23b58836e7f\",\"license\":\"MIT\"},\"contracts/lib/LibEIP712.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\\nlibrary LibEIP712 {\\n\\n // Hash of the EIP712 Domain Separator Schema\\n // keccak256(abi.encodePacked(\\n // \\\"EIP712Domain(\\\",\\n // \\\"string name,\\\",\\n // \\\"string version,\\\",\\n // \\\"uint256 chainId,\\\",\\n // \\\"address verifyingContract\\\",\\n // \\\")\\\"\\n // ))\\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\\n\\n /// @dev Calculates a EIP712 domain separator.\\n /// @param name The EIP712 domain name.\\n /// @param version The EIP712 domain version.\\n /// @param verifyingContract The EIP712 verifying contract.\\n /// @return result EIP712 domain separator.\\n function hashEIP712Domain(\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract\\n )\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\\n\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\\n // keccak256(bytes(name)),\\n // keccak256(bytes(version)),\\n // chainId,\\n // uint256(verifyingContract)\\n // ))\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Calculate hashes of dynamic data\\n let nameHash := keccak256(add(name, 32), mload(name))\\n let versionHash := keccak256(add(version, 32), mload(version))\\n\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n // Store params in memory\\n mstore(memPtr, schemaHash)\\n mstore(add(memPtr, 32), nameHash)\\n mstore(add(memPtr, 64), versionHash)\\n mstore(add(memPtr, 96), chainId)\\n mstore(add(memPtr, 128), verifyingContract)\\n\\n // Compute hash\\n result := keccak256(memPtr, 160)\\n }\\n return result;\\n }\\n\\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\\n /// with getDomainHash().\\n /// @param hashStruct The EIP712 hash struct.\\n /// @return result EIP712 hash applied to the given EIP712 Domain.\\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // EIP191_HEADER,\\n // EIP712_DOMAIN_HASH,\\n // hashStruct\\n // ));\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\\n\\n // Compute hash\\n result := keccak256(memPtr, 66)\\n }\\n return result;\\n }\\n}\",\"keccak256\":\"0x0314f8cfcab5979a2d713b4863bf5783b1181151ac144091d23f802d3f8ac7c5\",\"license\":\"MIT\"},\"contracts/lib/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nlibrary LibUtils {\\n\\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\\n require(decimals <= 18, \\\"LibUtils: Decimals not <= 18\\\");\\n return uint256(10)**(18-decimals);\\n }\\n\\n function getDecimals(address tokenToUse) internal view returns (uint8) {\\n //support decimals as uint256 or uint8\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"decimals()\\\"));\\n require(success, \\\"LibUtils: No decimals\\\");\\n // uint: enc(X) is the big-endian encoding of X,\\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\\n return uint8(abi.decode(data, (uint256)));\\n }\\n\\n function getGranularity(address tokenToUse) internal view returns (uint256) {\\n //support granularity if ERC777\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"granularity()\\\"));\\n require(success, \\\"LibUtils: No granularity\\\");\\n\\n return abi.decode(data, (uint256));\\n }\\n\\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n addr := mload(add(bys,20))\\n }\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"LibUtils: toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"LibUtils: toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n\\t\\trequire(_bytes.length >= _start + 32, \\\"LibUtils: toUint256_outOfBounds\\\");\\n\\t\\tuint256 tempUint;\\n\\n // solium-disable-next-line security/no-inline-assembly\\n\\t\\tassembly {\\n\\t\\t\\ttempUint := mload(add(add(_bytes, 0x20), _start))\\n\\t\\t}\\n\\n\\t\\treturn tempUint;\\n\\t}\\n}\\n\",\"keccak256\":\"0xf9495f9e5371f47c7ae2a3ce423598414ee24e60983602d76563a782b2562104\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return payable(msg.sender);\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x6f3f274a2270bfe073339370edfa2485e2d515a2656039937f6b972fae96d297\",\"license\":\"MIT\"},\"contracts/zeppelin/access/Roles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Roles\\n * @dev Library for managing addresses assigned to a Role.\\n */\\nlibrary Roles {\\n struct Role {\\n mapping (address => bool) bearer;\\n }\\n\\n /**\\n * @dev Give an account access to this role.\\n */\\n function add(Role storage role, address account) internal {\\n require(!has(role, account), \\\"Roles: account already has role\\\");\\n role.bearer[account] = true;\\n }\\n\\n /**\\n * @dev Remove an account's access to this role.\\n */\\n function remove(Role storage role, address account) internal {\\n require(has(role, account), \\\"Roles: account doesn't have role\\\");\\n role.bearer[account] = false;\\n }\\n\\n /**\\n * @dev Check if an account has this role.\\n * @return bool\\n */\\n function has(Role storage role, address account) internal view returns (bool) {\\n require(account != address(0), \\\"Roles: account is the zero address\\\");\\n return role.bearer[account];\\n }\\n}\\n\",\"keccak256\":\"0x932fc31748c82142ad9f51abd8c9bbaa562c7e6183b967b78a61884ee18e3474\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC1820Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\n * implementers for interfaces in this registry, as well as query support.\\n *\\n * Implementers may be shared by multiple accounts, and can also implement more\\n * than a single interface for each account. Contracts can implement interfaces\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\n * contract.\\n *\\n * {IERC165} interfaces can also be queried via the registry.\\n *\\n * For an in-depth explanation and source code analysis, see the EIP text.\\n */\\ninterface IERC1820Registry {\\n /**\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\n * account is able to set interface implementers for it.\\n *\\n * By default, each account is its own manager. Passing a value of `0x0` in\\n * `newManager` will reset the manager to this initial state.\\n *\\n * Emits a {ManagerChanged} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `account`.\\n */\\n function setManager(address account, address newManager) external;\\n\\n /**\\n * @dev Returns the manager for `account`.\\n *\\n * See {setManager}.\\n */\\n function getManager(address account) external view returns (address);\\n\\n /**\\n * @dev Sets the `implementer` contract as `account`'s implementer for\\n * `interfaceHash`.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n * The zero address can also be used in `implementer` to remove an old one.\\n *\\n * See {interfaceHash} to learn how these are created.\\n *\\n * Emits an {InterfaceImplementerSet} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `_account`.\\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\n * end in 28 zeroes).\\n * - `_implementer` must implement {IERC1820Implementer} and return true when\\n * queried for support, unless `implementer` is the caller. See\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\n */\\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\\n\\n /**\\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\\n * implementer is registered, returns the zero address.\\n *\\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\n * zeroes), `_account` will be queried for support of it.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n */\\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\\n\\n /**\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\n * corresponding\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\n */\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\n\\n /**\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\n * @param account Address of the contract for which to update the cache.\\n * @param interfaceId ERC165 interface for which to update the cache.\\n */\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\n * If the result is not cached a direct lookup on the contract address is performed.\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\n * {updateERC165Cache} with the contract address.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\n\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\n\\n event ManagerChanged(address indexed account, address indexed newManager);\\n}\\n\",\"keccak256\":\"0x8877787cbe99ab8e2dcb85e9b22066b7e62bcea328091c1ff9ae462e54afa66e\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x8038a6eca31e013b0c7f248c7a4eb5846ab0d52bb3f7636fafcf00b075643afe\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {ERC20Detailed}.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xdb194e173849ac56dbc15eaf0c01848361748ff8e4679985c3d11013ee4fa4b6\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeERC20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeERC20: low-level call failed\\\");\\n\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb7197e89889e574b9774604c7583b7226b06f6ebf8327c462fb15d5f8465ab8b\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777Token standard as defined in the EIP.\\n *\\n * This contract uses the\\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\\n * token holders and recipients react to token movements by using setting implementers\\n * for the associated interfaces in said registry. See `IERC1820Registry` and\\n * `ERC1820Implementer`.\\n */\\ninterface IERC777 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the smallest part of the token that is not divisible. This\\n * means all token operations (creation, movement and destruction) must have\\n * amounts that are a multiple of this number.\\n *\\n * For most token contracts, this value will equal 1.\\n */\\n function granularity() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by an account (`owner`).\\n */\\n function balanceOf(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * If send or receive hooks are registered for the caller and `recipient`,\\n * the corresponding functions will be called with `data` and empty\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function send(address recipient, uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Destroys `amount` tokens from the caller's account, reducing the\\n * total supply.\\n *\\n * If a send hook is registered for the caller, the corresponding function\\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n */\\n function burn(uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Returns true if an account is an operator of `tokenHolder`.\\n * Operators can send and burn tokens on behalf of their owners. All\\n * accounts are their own operator.\\n *\\n * See `operatorSend` and `operatorBurn`.\\n */\\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor`.\\n *\\n * Emits an `AuthorizedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function authorizeOperator(address operator) external;\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor` and `defaultOperators`.\\n *\\n * Emits a `RevokedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function revokeOperator(address operator) external;\\n\\n /**\\n * @dev Returns the list of default operators. These accounts are operators\\n * for all token holders, even if `authorizeOperator` was never called on\\n * them.\\n *\\n * This list is immutable, but individual holders may revoke these via\\n * `revokeOperator`, in which case `isOperatorFor` will return false.\\n */\\n function defaultOperators() external view returns (address[] memory);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\\n * be an operator of `sender`.\\n *\\n * If send or receive hooks are registered for `sender` and `recipient`,\\n * the corresponding functions will be called with `data` and\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - `sender` cannot be the zero address.\\n * - `sender` must have at least `amount` tokens.\\n * - the caller must be an operator for `sender`.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function operatorSend(\\n address sender,\\n address recipient,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n /**\\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\\n * The caller must be an operator of `account`.\\n *\\n * If a send hook is registered for `account`, the corresponding function\\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n * - the caller must be an operator for `account`.\\n */\\n function operatorBurn(\\n address account,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n event Sent(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256 amount,\\n bytes data,\\n bytes operatorData\\n );\\n\\n function decimals() external returns (uint8);\\n\\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\\n\\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\\n\\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\\n\\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\\n}\\n\",\"keccak256\":\"0xd8fb2f5bda9acc32af1bc5ed8a64c67a42ac7f32dd1195387535e8e148d40421\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\n *\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an `IERC777` token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0xc1e6f2d257d4973a27a86e590e01a3289317bd4b44ea040a622b4823c7793875\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\",\"keccak256\":\"0x14063a689bff5eecf0f36cb519feb575f60349ecf0d425ead5b931b77dd599d4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../../Initializable.sol\\\";\\n\\nimport \\\"../../../GSN/Context.sol\\\";\\nimport \\\"../../../access/Roles.sol\\\";\\n\\ncontract UpgradablePauserRole is Initializable, Context {\\n using Roles for Roles.Role;\\n\\n event PauserAdded(address indexed account);\\n event PauserRemoved(address indexed account);\\n\\n Roles.Role private _pausers;\\n\\n function __PauserRol_init(address sender) public initializer {\\n if (!isPauser(sender)) {\\n _addPauser(sender);\\n }\\n }\\n\\n modifier onlyPauser() {\\n require(isPauser(_msgSender()), \\\"PauserRole: caller doesn't have the role\\\");\\n _;\\n }\\n\\n function isPauser(address account) public view returns (bool) {\\n return _pausers.has(account);\\n }\\n\\n function addPauser(address account) public onlyPauser {\\n _addPauser(account);\\n }\\n\\n function renouncePauser() public {\\n _removePauser(_msgSender());\\n }\\n\\n function _addPauser(address account) internal {\\n _pausers.add(account);\\n emit PauserAdded(account);\\n }\\n\\n function _removePauser(address account) internal {\\n _pausers.remove(account);\\n emit PauserRemoved(account);\\n }\\n}\\n\",\"keccak256\":\"0xb484fd9ca5d28b46ec2c0d765cd592786a5a2c796987b5a7000e0b3d8b2a0ac9\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"../access/roles/UpgradablePauserRole.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\\n /**\\n * @dev Emitted when the pause is triggered by a pauser (`account`).\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by a pauser (`account`).\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\\n * to the deployer.\\n */\\n function __Pausable_init(address sender) public initializer {\\n UpgradablePauserRole.__PauserRol_init(sender);\\n\\n _paused = false;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n */\\n modifier whenNotPaused() {\\n require(!_paused, \\\"Pausable: paused\\\");\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n */\\n modifier whenPaused() {\\n require(_paused, \\\"Pausable: not paused\\\");\\n _;\\n }\\n\\n /**\\n * @dev Called by a pauser to pause, triggers stopped state.\\n */\\n function pause() public onlyPauser whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Called by a pauser to unpause, returns to normal state.\\n */\\n function unpause() public onlyPauser whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n}\\n\",\"keccak256\":\"0xdc64aa92b0dd6c6d4dc898bee62b70ebf64449b8c27fac6dff027e2fb367e6c0\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract UpgradableOwnable is Initializable, Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function initialize(address sender) public initializer {\\n _owner = sender;\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * > Note: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n\\n}\\n\",\"keccak256\":\"0xdf439a167ae82e7e3dd241ea0c831a1bb0329432ceb4fa889778d1f2d196ce00\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\n/**\\n * @title Helps contracts guard against reentrancy attacks.\\n * @author Remco Bloemen , Eenae \\n * @dev If you mark a function `nonReentrant`, you should also\\n * mark it `external`.\\n */\\ncontract ReentrancyGuard is Initializable {\\n /// @dev counter to allow mutex lock with only one SSTORE operation\\n uint256 private _guardCounter;\\n\\n function initialize() public initializer {\\n // The counter starts at one to prevent changing it from zero to a non-zero\\n // value, which is a more expensive operation.\\n _guardCounter = 1;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n _guardCounter += 1;\\n uint256 localCounter = _guardCounter;\\n _;\\n require(localCounter == _guardCounter, \\\"ReentrancyGuard: no reentrant allowed\\\");\\n }\\n}\",\"keccak256\":\"0x56f7b326ffaf9484cbcad316cb3344153584065d5b33da5698e3eedce30565fa\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x04801fc2398ee3370f3903f95389ea3a8da65a8df01f24b352e499e44d492e9b\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50614e8d806100206000396000f3fe6080604052600436106103bb5760003560e01c806382a0b8cb116101f2578063c4d66de81161010d578063e4e5bbcb116100a0578063f2fde38b1161006f578063f2fde38b14610ce0578063f698da2514610d00578063f8c8765e14610d16578063fa0caa1614610d3657600080fd5b8063e4e5bbcb14610c6c578063e6fc774414610c8c578063ea21709114610ca2578063eb16136f14610cc057600080fd5b8063d12e825d116100dc578063d12e825d14610be8578063d3401a2214610bfd578063da67703714610c1d578063e07801d014610c4c57600080fd5b8063c4d66de814610b42578063ca07140c14610b62578063cbc7328014610b98578063cc3c0f0614610bb857600080fd5b8063a53d6e6e11610185578063b0e1268e11610154578063b0e1268e14610a9d578063b794726214610abd578063b86f60d214610ade578063b984a40414610afe57600080fd5b8063a53d6e6e14610a1d578063a89f298a14610a3d578063ae06c1b714610a5d578063b048c4fb14610a7d57600080fd5b80638ca01082116101c15780638ca010821461099f5780638da5cb5b146109b45780638f32d59b146109d7578063916dc59d146109fd57600080fd5b806382a0b8cb1461091a57806382dc1ec41461094a5780638456cb591461096a57806388710e2e1461097f57600080fd5b80633f4ba83a116102e25780636b0509b1116102755780637a0ab28f116102445780637a0ab28f146108435780637a98187b146108795780637ecebe00146108d85780638129fc1c1461090557600080fd5b80636b0509b1146107d25780636ef8d66d1461080657806370aff70f1461081b578063715018a61461082e57600080fd5b80634c739509116102b15780634c7395091461074657806354fd4d50146107665780635c975abb1461079a578063615bfd6e146107b257600080fd5b80633f4ba83a146106d157806342cdb2c6146106e657806346fbf68e1461070657806347f8bbd41461072657600080fd5b806322f89ba41161035a5780633a1cbbcb116103295780633a1cbbcb146105ec5780633c3f63f41461063a5780633c7e0cb71461067b5780633cf3058b1461069b57600080fd5b806322f89ba4146105245780632f3cca4e1461056f5780633500c1dc1461058f57806337e76109146105af57600080fd5b80630ed928af116103965780630ed928af146104af5780630ef1335c146104cf57806311efbf61146104ef578063122aa5d41461050457600080fd5b806223de291461042f578063026976191461044f57806307c8f7b01461048f57600080fd5b3661042a576041546001600160a01b0316336001600160a01b0316146104285760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a206e6f74207772617070656443757272656e6379000000000060448201526064015b60405180910390fd5b005b600080fd5b34801561043b57600080fd5b5061042861044a36600461424b565b610d56565b34801561045b57600080fd5b5061047c61046a3660046142fc565b60426020526000908152604090205481565b6040519081526020015b60405180910390f35b34801561049b57600080fd5b506104286104aa366004614323565b6110b1565b3480156104bb57600080fd5b5061047c6104ca366004614358565b611140565b3480156104db57600080fd5b5061047c6104ea366004614358565b611161565b3480156104fb57600080fd5b5060375461047c565b34801561051057600080fd5b5061042861051f36600461438d565b6111d8565b34801561053057600080fd5b5061055f61053f366004614418565b604860209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610486565b34801561057b57600080fd5b5061042861058a366004614448565b611616565b34801561059b57600080fd5b506104286105aa366004614448565b611696565b3480156105bb57600080fd5b5061055f6105ca3660046142fc565b6000908152604260209081526040808320548352603e90915290205460ff1690565b3480156105f857600080fd5b50610622610607366004614448565b603b602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610486565b34801561064657600080fd5b50610622610655366004614418565b60466020908152600092835260408084209091529082529020546001600160a01b031681565b34801561068757600080fd5b50610428610696366004614465565b611768565b3480156106a757600080fd5b506106226106b63660046142fc565b6044602052600090815260409020546001600160a01b031681565b3480156106dd57600080fd5b506104286118e2565b3480156106f257600080fd5b50610428610701366004614448565b61199a565b34801561071257600080fd5b5061055f610721366004614448565b611a7b565b34801561073257600080fd5b506104286107413660046144da565b611a88565b34801561075257600080fd5b50610428610761366004614565565b611af9565b34801561077257600080fd5b506040805180820190915260028152611d8d60f21b60208201525b60405161048691906145ff565b3480156107a657600080fd5b5060345460ff1661055f565b3480156107be57600080fd5b5061055f6107cd366004614612565b611b69565b3480156107de57600080fd5b5061047c7faf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c81565b34801561081257600080fd5b50610428611bd6565b610428610829366004614418565b611be1565b34801561083a57600080fd5b50610428611cd6565b34801561084f57600080fd5b5061062261085e366004614448565b603c602052600090815260409020546001600160a01b031681565b34801561088557600080fd5b506108b9610894366004614448565b604760205260009081526040902080546001909101546001600160a01b039091169082565b604080516001600160a01b039093168352602083019190915201610486565b3480156108e457600080fd5b5061047c6108f3366004614448565b60456020526000908152604090205481565b34801561091157600080fd5b50610428611d5b565b34801561092657600080fd5b5061055f610935366004614448565b603d6020526000908152604090205460ff1681565b34801561095657600080fd5b50610428610965366004614448565b611dcc565b34801561097657600080fd5b50610428611dfa565b34801561098b57600080fd5b5061047c61099a36600461464e565b611e77565b3480156109ab57600080fd5b5061078d611ff2565b3480156109c057600080fd5b5060345461010090046001600160a01b0316610622565b3480156109e357600080fd5b5061055f60345461010090046001600160a01b0316331490565b348015610a0957600080fd5b50610428610a18366004614448565b612080565b348015610a2957600080fd5b50603f54610622906001600160a01b031681565b348015610a4957600080fd5b5061047c610a583660046146c0565b612159565b348015610a6957600080fd5b50610428610a783660046142fc565b6121cb565b348015610a8957600080fd5b5061055f610a98366004614725565b612290565b348015610aa957600080fd5b50604154610622906001600160a01b031681565b348015610ac957600080fd5b5060405461055f90600160a01b900460ff1681565b348015610aea57600080fd5b50604054610622906001600160a01b031681565b348015610b0a57600080fd5b50610b1e610b19366004614448565b6122c2565b6040805182516001600160a01b031681526020928301519281019290925201610486565b348015610b4e57600080fd5b50610428610b5d366004614448565b612341565b348015610b6e57600080fd5b50610622610b7d3660046142fc565b6043602052600090815260409020546001600160a01b031681565b348015610ba457600080fd5b50610428610bb3366004614747565b612403565b348015610bc457600080fd5b5061055f610bd33660046142fc565b603e6020526000908152604090205460ff1681565b348015610bf457600080fd5b50610428612448565b348015610c0957600080fd5b50610622610c18366004614418565b6124ef565b348015610c2957600080fd5b5061055f610c383660046142fc565b600090815260426020526040902054151590565b348015610c5857600080fd5b5061055f610c67366004614418565b612542565b348015610c7857600080fd5b50610428610c873660046147eb565b612597565b348015610c9857600080fd5b5061047c61271081565b348015610cae57600080fd5b506036546001600160a01b0316610622565b348015610ccc57600080fd5b50610428610cdb366004614448565b6125d1565b348015610cec57600080fd5b50610428610cfb366004614448565b612653565b348015610d0c57600080fd5b5061047c60395481565b348015610d2257600080fd5b50610428610d31366004614833565b612691565b348015610d4257600080fd5b50610428610d51366004614448565b6127e6565b6001600160a01b038816301415610d6c576110a7565b6001600160a01b0386163014610dc45760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a204e6f7420746f207468697320616464726573730000000000604482015260640161041f565b60003360405163555ddc6560e11b81526001600160a01b03821660048201527fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce21770546024820152909150600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca9060440160206040518083038186803b158015610e4657600080fd5b505afa158015610e5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7e919061488f565b6001600160a01b03161415610ed55760405162461bcd60e51b815260206004820152601860248201527f4272696467653a204e6f742045524337373720746f6b656e0000000000000000604482015260640161041f565b6020841015610f455760405162461bcd60e51b815260206004820152603660248201527f4272696467653a207573657220646174612077697468206174206c65617374206044820152751d1a194819195cdd1a5b985d1a5bdb90da185a5b925960521b606482015260840161041f565b6040841480610f5c57506001600160a01b0388163b155b610fb95760405162461bcd60e51b815260206004820152602860248201527f4272696467653a2053706563696679207265636569766572206164647265737360448201526720696e206461746160c01b606482015260840161041f565b60006020851461100a5761100586868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600c92506128bf915050565b61100c565b885b9050600061105c87878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506110579250602091508a90506148c2565b61292c565b90506110a3838b848b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250899250612992915050565b5050505b5050505050505050565b6110ca60345461010090046001600160a01b0316331490565b6110e65760405162461bcd60e51b815260040161041f906148d9565b6040805460ff60a01b1916600160a01b831515810291909117808355915160ff9190920416151581527f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad9906020015b60405180910390a150565b600061115b826111536020820182614448565b600080612d52565b92915050565b60608101356000908152604460205260408120546001600160a01b0316336001600160a01b0316146111ce5760405162461bcd60e51b8152602060048201526016602482015275213934b233b29d1034b73b30b634b21039b2b73232b960511b604482015260640161041f565b61115b8233611153565b60345460ff16156111fb5760405162461bcd60e51b815260040161041f9061490e565b60016035600082825461120e9190614938565b90915550506035546036546001600160a01b0316336001600160a01b0316146112725760405162461bcd60e51b8152602060048201526016602482015275213934b233b29d102737ba102332b232b930ba34b7b760511b604482015260640161041f565b61127b83612f3d565b61128482612f84565b61128e838b612542565b806112ac575060006112a0848c6124ef565b6001600160a01b031614155b6112f05760405162461bcd60e51b8152602060048201526015602482015274213934b233b29d102ab735b737bbb7103a37b5b2b760591b604482015260640161041f565b6001600160a01b0388166113385760405162461bcd60e51b815260206004820152600f60248201526e4272696467653a204e756c6c20546f60881b604482015260640161041f565b6000871161137b5760405162461bcd60e51b815260206004820152601060248201526f04272696467653a20416d6f756e7420360841b604482015260640161041f565b856113c15760405162461bcd60e51b8152602060048201526016602482015275084e4d2c8ceca74409cead8d84084d8dec6d690c2e6d60531b604482015260640161041f565b846114045760405162461bcd60e51b8152602060048201526013602482015272084e4d2c8ceca74409cead8d840a8f090c2e6d606b1b604482015260640161041f565b600085815260426020526040902054156114605760405162461bcd60e51b815260206004820152601860248201527f4272696467653a20416c72656164792061636365707465640000000000000000604482015260640161041f565b600061146f8989898989612fd3565b905060006114828a8a8a8a8a8a8a612159565b905061148e8282612290565b156114d55760405162461bcd60e51b8152602060048201526017602482015276109c9a5919d94e88105b1c9958591e4818db185a5b5959604a1b604482015260640161041f565b8060426000898152602001908152602001600020819055508b6043600089815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508a6044600089815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550896001600160a01b03168c6001600160a01b0316887fddae5e892ad96ac0e35e9018a1a3e32ecd7f3dfe55ea34d9ab1e8faecd6ccb5a8e8d8d8c8c8c6040516115df969594939291906001600160a01b039690961686526020860194909452604085019290925263ffffffff166060840152608083015260a082015260c00190565b60405180910390a45050603554811461160a5760405162461bcd60e51b815260040161041f90614950565b50505050505050505050565b600054610100900460ff168061162f575060005460ff16155b61164b5760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff1615801561166d576000805461ffff19166101011790555b611676826125d1565b6034805460ff191690558015611692576000805461ff00191690555b5050565b6116af60345461010090046001600160a01b0316331490565b6116cb5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b03811661171a5760405162461bcd60e51b81526020600482015260166024820152754272696467653a20777261707020697320656d70747960501b604482015260640161041f565b604180546001600160a01b0319166001600160a01b0383169081179091556040519081527f0966c958966f6fac9ff807af074f8117eb2e9ce2b76390db7a158e9bdeb2485c90602001611135565b61178160345461010090046001600160a01b0316331490565b61179d5760405162461bcd60e51b815260040161041f906148d9565b60005b818110156118dd576118cb8383838181106117bd576117bd6149dd565b90506020028101906117cf91906149f3565b358484848181106117e2576117e26149dd565b90506020028101906117f491906149f3565b611805906040810190602001614448565b858585818110611817576118176149dd565b905060200281019061182991906149f3565b61183a906060810190604001614a13565b86868681811061184c5761184c6149dd565b905060200281019061185e91906149f3565b61186c906060810190614a2e565b88888881811061187e5761187e6149dd565b905060200281019061189091906149f3565b61189e906080810190614a2e565b8a8a8a8181106118b0576118b06149dd565b90506020028101906118c291906149f3565b60a0013561303e565b806118d581614a75565b9150506117a0565b505050565b6118eb33611a7b565b6119075760405162461bcd60e51b815260040161041f90614a90565b60345460ff166119505760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161041f565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6119b360345461010090046001600160a01b0316331490565b6119cf5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b038116611a2f5760405162461bcd60e51b815260206004820152602160248201527f4272696467653a2053696465546f6b656e466163746f727920697320656d70746044820152607960f81b606482015260840161041f565b604080546001600160a01b0319166001600160a01b038316908117825590519081527f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e318369252162590602001611135565b600061115b60338361327e565b611aa160345461010090046001600160a01b0316331490565b611abd5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b039182166000908152604760209081526040909120825181546001600160a01b03191694169390931783550151600190910155565b611b1260345461010090046001600160a01b0316331490565b611b2e5760405162461bcd60e51b815260040161041f906148d9565b60009283526046602090815260408085206001600160a01b0394851686529091529092208054919092166001600160a01b0319909116179055565b600080611ba0611b7c6020860186614448565b602086013560408701356060880135611b9b60a08a0160808b01614ad8565b612fd3565b6000818152603e602052604090205490915060ff1680611bce57506000838152603e602052604090205460ff165b949350505050565b611bdf33613301565b565b60415433906001600160a01b0316611c3b5760405162461bcd60e51b815260206004820152601d60248201527f4272696467653a207772617070656443757272656e637920656d707479000000604482015260640161041f565b604160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611c8b57600080fd5b505af1158015611c9f573d6000803e3d6000fd5b50505050506118dd604160009054906101000a90046001600160a01b03168284346040518060200160405280600081525088612992565b611cef60345461010090046001600160a01b0316331490565b611d0b5760405162461bcd60e51b815260040161041f906148d9565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b600054610100900460ff1680611d74575060005460ff16155b611d905760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff16158015611db2576000805461ffff19166101011790555b60016035558015611dc9576000805461ff00191690555b50565b611dd533611a7b565b611df15760405162461bcd60e51b815260040161041f90614a90565b611dc981613343565b611e0333611a7b565b611e1f5760405162461bcd60e51b815260040161041f90614a90565b60345460ff1615611e425760405162461bcd60e51b815260040161041f9061490e565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861197d3390565b600042851015611ebb5760405162461bcd60e51b815260206004820152600f60248201526e109c9a5919d94e8811561412549151608a1b604482015260640161041f565b6000611ed7611ecf368b90038b018b614af3565b898989613385565b6040805160008082526020820180845284905260ff89169282019290925260608101879052608081018690529192509060019060a0016020604051602081039080840390855afa158015611f2f573d6000803e3d6000fd5b5050604051601f190151915060009050611f4c60208c018c614448565b6001600160a01b031614158015611f805750611f6b60208b018b614448565b6001600160a01b0316816001600160a01b0316145b611fcc5760405162461bcd60e51b815260206004820152601960248201527f4272696467653a20494e56414c49445f5349474e415455524500000000000000604482015260640161041f565b611fe48a611fdd6020820182614448565b8b8b612d52565b9a9950505050505050505050565b60388054611fff90614b8b565b80601f016020809104026020016040519081016040528092919081815260200182805461202b90614b8b565b80156120785780601f1061204d57610100808354040283529160200191612078565b820191906000526020600020905b81548152906001019060200180831161205b57829003601f168201915b505050505081565b61209960345461010090046001600160a01b0316331490565b6120b55760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b03811661210b5760405162461bcd60e51b815260206004820152601c60248201527f4272696467653a20416c6c6f77546f6b656e7320697320656d70747900000000604482015260640161041f565b603f80546001600160a01b0319166001600160a01b0383169081179091556040519081527f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e390602001611135565b6040805160208082019790975280820195909552606097881b6bffffffffffffffffffffffff191697850197909752607484019590955260e09190911b6001600160e01b0319166094830152609882015260b8808201939093528351808203909301835260d801909252805191012090565b6121e460345461010090046001600160a01b0316331490565b6122005760405162461bcd60e51b815260040161041f906148d9565b61220d600a612710614bd6565b811061225b5760405162461bcd60e51b815260206004820152601760248201527f4272696467653a20626967676572207468616e20313025000000000000000000604482015260640161041f565b60378190556040518181527f97e97c577f03bda90e2c9739011ec065ed5fbfb36ae217d20bb0d9be95e160cd90602001611135565b6000828152603e602052604081205460ff16806122bb57506000828152603e602052604090205460ff165b9392505050565b604080518082018252600080825260209182018190526001600160a01b038481168252604783529083902083518085019094528054909116808452600190910154918301919091521561231457919050565b60016020808301919091526001600160a01b039283166000908152603c9091526040902054909116815290565b600054610100900460ff168061235a575060005460ff16155b6123765760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff16158015612398576000805461ffff19166101011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015611692576000805461ff00191690555050565b61241c60345461010090046001600160a01b0316331490565b6124385760405162461bcd60e51b815260040161041f906148d9565b6110a7888888888888888861303e565b604080518082018252601081526f52534b20546f6b656e2042726964676560801b60208083019182528351808501855260018152603160f81b908201529151902082517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8152918201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc69181019190915246606082015230608082015260a09020603955565b60008281526046602090815260408083206001600160a01b038086168552925282205416801561252057905061115b565b50506001600160a01b039081166000908152603b602052604090205416919050565b60008281526048602090815260408083206001600160a01b038516845290915281205460ff16801561257557905061115b565b50506001600160a01b03166000908152603d602052604090205460ff16919050565b336125ad6001600160a01b038516823085613489565b6125ca84828585604051806020016040528060008152508a612992565b5050505050565b600054610100900460ff16806125ea575060005460ff16155b6126065760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff16158015612628576000805461ffff19166101011790555b61263182611a7b565b61263e5761263e82613343565b8015611692576000805461ff00191690555050565b61266c60345461010090046001600160a01b0316331490565b6126885760405162461bcd60e51b815260040161041f906148d9565b611dc9816134fa565b600054610100900460ff16806126aa575060005460ff16155b6126c65760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff161580156126e8576000805461ffff19166101011790555b6126f185612341565b6126fa85611616565b603f80546001600160a01b038581166001600160a01b031992831617909255604080548584169083161781556036805493881693909216929092179055516329965a1d60e01b815230600482018190527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b60248301526044820152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90606401600060405180830381600087803b1580156127ae57600080fd5b505af11580156127c2573d6000803e3d6000fd5b505050506127ce612448565b80156125ca576000805461ff00191690555050505050565b6127ff60345461010090046001600160a01b0316331490565b61281b5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b0381166128715760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a2046656465726174696f6e20697320656d7074790000000000604482015260640161041f565b603680546001600160a01b0319166001600160a01b0383169081179091556040519081527f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb90602001611135565b60006128cc826014614938565b8351101561291c5760405162461bcd60e51b815260206004820152601f60248201527f4c69625574696c733a20746f416464726573735f6f75744f66426f756e647300604482015260640161041f565b500160200151600160601b900490565b6000612939826020614938565b835110156129895760405162461bcd60e51b815260206004820152601f60248201527f4c69625574696c733a20746f55696e743235365f6f75744f66426f756e647300604482015260640161041f565b50016020015190565b604054600160a01b900460ff16156129e05760405162461bcd60e51b81526020600482015260116024820152704272696467653a20557067726164696e6760781b604482015260640161041f565b60345460ff1615612a035760405162461bcd60e51b815260040161041f9061490e565b600160356000828254612a169190614938565b909155505060355446821415612a8a5760405162461bcd60e51b815260206004820152603360248201527f4272696467653a2064657374696e6174696f6e20636861696e20696420657175604482015272185b0818dd5c9c995b9d0818da185a5b881a59606a1b606482015260840161041f565b612a9382612f3d565b60008281526048602090815260408083206001600160a01b038b1684529091529020805460ff191660011790556000612ae3612710612add603754886135c290919063ffffffff16565b90613641565b90506000612af18683613683565b90506000612afe8a6136c5565b905086601260ff831614612b2f57612b2c612b1a836012614bea565b612b2590600a614cf1565b89906135c2565b90505b603f54604051638c34bc5560e01b81526001600160a01b038d811660048301526024820184905290911690638c34bc5590604401600060405180830381600087803b158015612b7d57600080fd5b505af1158015612b91573d6000803e3d6000fd5b505050506000612ba08c6122c2565b80519091506001600160a01b031615612ca4576000612bbe8d6137a9565b90506000612bcc8683613881565b9050612bd887826138c3565b9650612be48682613683565b60405163fe9d930360e01b81529096506001600160a01b038f169063fe9d930390612c159089908e90600401614d00565b600060405180830381600087803b158015612c2f57600080fd5b505af1158015612c43573d6000803e3d6000fd5b505050505050868a6001600160a01b031682600001516001600160a01b03167fb2320a1ad388e1e16b142f7d2e822f31d8a2bbdd7d4f29260e7c203c5f45e8498e46898e604051612c979493929190614d19565b60405180910390a4612cf7565b868a6001600160a01b03168d6001600160a01b03167fb2320a1ad388e1e16b142f7d2e822f31d8a2bbdd7d4f29260e7c203c5f45e8498e46898e604051612cee9493929190614d19565b60405180910390a45b8415612d2357603454612d239061010090046001600160a01b03166001600160a01b038e169087613922565b50505050506035548114612d495760405162461bcd60e51b815260040161041f90614950565b50505050505050565b6000600160356000828254612d679190614938565b909155505060355460608601356000908152604360205260409020546001600160a01b031680612dd25760405162461bcd60e51b8152602060048201526016602482015275109c9a5919d94e88151e081b9bdd0818dc9bdcdcd95960521b604482015260640161041f565b6000612e0e612de460208a018a614448565b60208a013560408b013560608c0135612e0360a08e0160808f01614ad8565b8d60a0013546612159565b60608901356000908152604260205260409020549091508114612e7d5760405162461bcd60e51b815260206004820152602160248201527f4272696467653a2057726f6e67207472616e73616374696f6e446174614861736044820152600d60fb1b606482015260840161041f565b612e878882611b69565b15612ece5760405162461bcd60e51b8152602060048201526017602482015276109c9a5919d94e88105b1c9958591e4818db185a5b5959604a1b604482015260640161041f565b6000818152603e60209081526040909120805460ff19166001179055612f029060a08a01359084908a908c01358a8a613952565b9350612f1188838989896139a3565b50506035548114612f345760405162461bcd60e51b815260040161041f90614950565b50949350505050565b60008111611dc95760405162461bcd60e51b815260206004820152601460248201527304272696467653a20436861696e496420697320360641b604482015260640161041f565b468114611dc95760405162461bcd60e51b815260206004820152601960248201527f4272696467653a204e6f7420626c6f636b2e636861696e696400000000000000604482015260640161041f565b6040805160208101859052908101839052606086811b6bffffffffffffffffffffffff1916908201526074810185905260e082901b6001600160e01b031916609482015260009060980160405160208183030381529060405280519060200120905095945050505050565b6001600160a01b0387166130895760405162461bcd60e51b8152602060048201526012602482015271213934b233b29d10273ab636103a37b5b2b760711b604482015260640161041f565b61309281612f3d565b600061309e82896124ef565b90506001600160a01b038116156130f05760405162461bcd60e51b81526020600482015260166024820152754272696467653a20416c72656164792065786973747360501b604482015260640161041f565b60006130fb88613a7e565b6040805490516326d9e96360e01b81529192506001600160a01b0316906326d9e9639061313490889088908c908c908890600401614d6f565b602060405180830381600087803b15801561314e57600080fd5b505af1158015613162573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613186919061488f565b9150613193838a84611af9565b60408051808201909152602081018490526001600160a01b038a1681526131ba8382611a88565b603f546040516378bf2b5360e01b81526001600160a01b038581166004830152602482018e9052909116906378bf2b5390604401600060405180830381600087803b15801561320857600080fd5b505af115801561321c573d6000803e3d6000fd5b50505050896001600160a01b0316836001600160a01b03167f88dcf8b72e53287db29df3fee9a0f2cb07d1f986cee153aa7d7554405d5db0178a8a86896040516132699493929190614da9565b60405180910390a35050505050505050505050565b60006001600160a01b0382166132e15760405162461bcd60e51b815260206004820152602260248201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604482015261737360f01b606482015260840161041f565b506001600160a01b03166000908152602091909152604090205460ff1690565b61330c603382613aea565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b61334e603382613b62565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6039548451602080870151606088015160a08901516001600160a01b0385166000908152604590945260408420805494966134809690957faf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c959194919391928c918c918b6133f283614a75565b909155506040805160208101999099526001600160a01b03978816908901526060880195909552608087019390935260a086019190915290921660c084015260e08301919091526101008201526101208101859052610140016040516020818303038152906040528051906020012060405161190160f01b8152600281019290925260228201526042902090565b95945050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526134f49085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613bde565b50505050565b6001600160a01b03811661355b5760405162461bcd60e51b815260206004820152602260248201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604482015261737360f01b606482015260840161041f565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6000826135d15750600061115b565b60006135dd8385614dd0565b9050826135ea8583614bd6565b146122bb5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b606482015260840161041f565b60006122bb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613d5e565b60006122bb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613d8c565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b0386169161370b9190614def565b600060405180830381855afa9150503d8060008114613746576040519150601f19603f3d011682016040523d82523d6000602084013e61374b565b606091505b5091509150816137955760405162461bcd60e51b81526020600482015260156024820152744c69625574696c733a204e6f20646563696d616c7360581b604482015260640161041f565b80806020019051810190611bce9190614e01565b60408051600481526024810182526020810180516001600160e01b031663556f0dc760e01b1790529051600091829182916001600160a01b038616916137ef9190614def565b600060405180830381855afa9150503d806000811461382a576040519150601f19603f3d011682016040523d82523d6000602084013e61382f565b606091505b5091509150816137955760405162461bcd60e51b815260206004820152601860248201527f4c69625574696c733a204e6f206772616e756c61726974790000000000000000604482015260640161041f565b60006122bb83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250613dbd565b6000806138d08385614938565b9050838110156122bb5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015260640161041f565b6040516001600160a01b0383166024820152604481018290526118dd90849063a9059cbb60e01b906064016134bd565b600061395d87612f3d565b6139678787612542565b15613980576139798686868686613de9565b9050613999565b61399661398d88886124ef565b86868686613f99565b90505b9695505050505050565b6139b06020860186614448565b6060860135600081815260446020908152604091829020546001600160a01b039485169489811694937fa7a84dcc6757cdf9b9122d3bbc42d58358c28dc4b09cc24349599a63c56c62fd9392909116918b0135908b0135613a1760a08d0160808e01614ad8565b604080516001600160a01b039586168152602081019490945283019190915263ffffffff166060820152818916608082015290871660a08281019190915260c082018790528a013560e0820152466101008201526101200160405180910390a45050505050565b600060128260ff161115613ad45760405162461bcd60e51b815260206004820152601c60248201527f4c69625574696c733a20446563696d616c73206e6f74203c3d20313800000000604482015260640161041f565b613adf826012614bea565b61115b90600a614cf1565b613af4828261327e565b613b405760405162461bcd60e51b815260206004820181905260248201527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c65604482015260640161041f565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b613b6c828261327e565b15613bb95760405162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015260640161041f565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6001600160a01b0382163b613c355760405162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015260640161041f565b600080836001600160a01b031683604051613c509190614def565b6000604051808303816000865af19150503d8060008114613c8d576040519150601f19603f3d011682016040523d82523d6000602084013e613c92565b606091505b509150915081613ce45760405162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015260640161041f565b8051156134f45780806020019051810190613cff9190614e1a565b6134f45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161041f565b60008183613d7f5760405162461bcd60e51b815260040161041f91906145ff565b5060006134808486614bd6565b60008184841115613db05760405162461bcd60e51b815260040161041f91906145ff565b50600061348084866148c2565b60008183613dde5760405162461bcd60e51b815260040161041f91906145ff565b50611bce8385614e37565b600080613df5876136c5565b60ff1690506000613e1c613e0a8360126148c2565b613e1590600a614e4b565b8790613641565b905080841115613e655760405162461bcd60e51b8152602060048201526014602482015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b604482015260640161041f565b613e6f8185613683565b6041549093506001600160a01b0389811691161415613f6057604154604051632e1a7d4d60e01b8152600481018390526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b158015613ece57600080fd5b505af1158015613ee2573d6000803e3d6000fd5b50506040516001600160a01b038a16925085156108fc02915085906000818181858888f19350505050158015613f1c573d6000803e3d6000fd5b508315613f5b576040516001600160a01b0386169085156108fc029086906000818181858888f19350505050158015613f59573d6000803e3d6000fd5b505b613f8e565b613f746001600160a01b0389168885613922565b8315613f8e57613f8e6001600160a01b0389168686613922565b505095945050505050565b60006001600160a01b038616613ff15760405162461bcd60e51b815260206004820152601a60248201527f4272696467653a207369646520746f6b656e206973206e756c6c000000000000604482015260640161041f565b6000866001600160a01b031663556f0dc76040518163ffffffff1660e01b815260040160206040518083038186803b15801561402c57600080fd5b505afa158015614040573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140649190614e01565b9050600061407286836135c2565b9050808411156140bb5760405162461bcd60e51b8152602060048201526014602482015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b604482015260640161041f565b6140c58185613683565b604051630dcdc7dd60e41b81526001600160a01b038981166004830152602482018390526080604483015260006084830181905260a0606484015260a48301529194509089169063dcdc7dd09060c401600060405180830381600087803b15801561412f57600080fd5b505af1158015614143573d6000803e3d6000fd5b505050506000841115613f8e57604051630dcdc7dd60e41b81526001600160a01b03868116600483015260248201869052608060448301526000608483015260a06064830152600b60a48301526a72656c617965722066656560a81b60c483015289169063dcdc7dd09060e401600060405180830381600087803b1580156141ca57600080fd5b505af11580156141de573d6000803e3d6000fd5b50505050505095945050505050565b6001600160a01b0381168114611dc957600080fd5b60008083601f84011261421457600080fd5b50813567ffffffffffffffff81111561422c57600080fd5b60208301915083602082850101111561424457600080fd5b9250929050565b60008060008060008060008060c0898b03121561426757600080fd5b8835614272816141ed565b97506020890135614282816141ed565b96506040890135614292816141ed565b955060608901359450608089013567ffffffffffffffff808211156142b657600080fd5b6142c28c838d01614202565b909650945060a08b01359150808211156142db57600080fd5b506142e88b828c01614202565b999c989b5096995094979396929594505050565b60006020828403121561430e57600080fd5b5035919050565b8015158114611dc957600080fd5b60006020828403121561433557600080fd5b81356122bb81614315565b600060c0828403121561435257600080fd5b50919050565b600060c0828403121561436a57600080fd5b6122bb8383614340565b803563ffffffff8116811461438857600080fd5b919050565b60008060008060008060008060006101208a8c0312156143ac57600080fd5b89356143b7816141ed565b985060208a01356143c7816141ed565b975060408a01356143d7816141ed565b965060608a0135955060808a0135945060a08a013593506143fa60c08b01614374565b925060e08a013591506101008a013590509295985092959850929598565b6000806040838503121561442b57600080fd5b82359150602083013561443d816141ed565b809150509250929050565b60006020828403121561445a57600080fd5b81356122bb816141ed565b6000806020838503121561447857600080fd5b823567ffffffffffffffff8082111561449057600080fd5b818501915085601f8301126144a457600080fd5b8135818111156144b357600080fd5b8660208260051b85010111156144c857600080fd5b60209290920196919550909350505050565b60008082840360608112156144ee57600080fd5b83356144f9816141ed565b92506040601f198201121561450d57600080fd5b506040516040810181811067ffffffffffffffff8211171561453f57634e487b7160e01b600052604160045260246000fd5b6040526020840135614550816141ed565b81526040939093013560208401525092909150565b60008060006060848603121561457a57600080fd5b83359250602084013561458c816141ed565b9150604084013561459c816141ed565b809150509250925092565b60005b838110156145c25781810151838201526020016145aa565b838111156134f45750506000910152565b600081518084526145eb8160208601602086016145a7565b601f01601f19169290920160200192915050565b6020815260006122bb60208301846145d3565b60008060e0838503121561462557600080fd5b61462f8484614340565b9460c0939093013593505050565b803560ff8116811461438857600080fd5b6000806000806000806000610180888a03121561466a57600080fd5b6146748989614340565b965060c0880135614684816141ed565b955060e0880135945061010088013593506146a2610120890161463d565b92506101408801359150610160880135905092959891949750929550565b600080600080600080600060e0888a0312156146db57600080fd5b87356146e6816141ed565b965060208801359550604088013594506060880135935061470960808901614374565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561473857600080fd5b50508035926020909101359150565b60008060008060008060008060c0898b03121561476357600080fd5b883597506020890135614775816141ed565b965061478360408a0161463d565b9550606089013567ffffffffffffffff808211156147a057600080fd5b6147ac8c838d01614202565b909750955060808b01359150808211156147c557600080fd5b506147d28b828c01614202565b999c989b50969995989497949560a00135949350505050565b6000806000806080858703121561480157600080fd5b843593506020850135614813816141ed565b92506040850135614823816141ed565b9396929550929360600135925050565b6000806000806080858703121561484957600080fd5b8435614854816141ed565b93506020850135614864816141ed565b92506040850135614874816141ed565b91506060850135614884816141ed565b939692955090935050565b6000602082840312156148a157600080fd5b81516122bb816141ed565b634e487b7160e01b600052601160045260246000fd5b6000828210156148d4576148d46148ac565b500390565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6000821982111561494b5761494b6148ac565b500190565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b6000823560be19833603018112614a0957600080fd5b9190910192915050565b600060208284031215614a2557600080fd5b6122bb8261463d565b6000808335601e19843603018112614a4557600080fd5b83018035915067ffffffffffffffff821115614a6057600080fd5b60200191503681900382131561424457600080fd5b6000600019821415614a8957614a896148ac565b5060010190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b600060208284031215614aea57600080fd5b6122bb82614374565b600060c08284031215614b0557600080fd5b60405160c0810181811067ffffffffffffffff82111715614b3657634e487b7160e01b600052604160045260246000fd5b6040528235614b44816141ed565b80825250602083013560208201526040830135604082015260608301356060820152614b7260808401614374565b608082015260a083013560a08201528091505092915050565b600181811c90821680614b9f57607f821691505b6020821081141561435257634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b600082614be557614be5614bc0565b500490565b600060ff821660ff841680821015614c0457614c046148ac565b90039392505050565b600181815b80851115614c48578160001904821115614c2e57614c2e6148ac565b80851615614c3b57918102915b93841c9390800290614c12565b509250929050565b600082614c5f5750600161115b565b81614c6c5750600061115b565b8160018114614c825760028114614c8c57614ca8565b600191505061115b565b60ff841115614c9d57614c9d6148ac565b50506001821b61115b565b5060208310610133831016604e8410600b8410161715614ccb575081810a61115b565b614cd58383614c0d565b8060001904821115614ce957614ce96148ac565b029392505050565b60006122bb60ff841683614c50565b828152604060208201526000611bce60408301846145d3565b60018060a01b038516815283602082015282604082015260806060820152600061399960808301846145d3565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b606081526000614d83606083018789614d46565b8281036020840152614d96818688614d46565b9150508260408301529695505050505050565b606081526000614dbd606083018688614d46565b6020830194909452506040015292915050565b6000816000190483118215151615614dea57614dea6148ac565b500290565b60008251614a098184602087016145a7565b600060208284031215614e1357600080fd5b5051919050565b600060208284031215614e2c57600080fd5b81516122bb81614315565b600082614e4657614e46614bc0565b500690565b60006122bb8383614c5056fea264697066735822122056e9c6d68b936a7b2c66545886a13f33f54fec9bc3a8a09c82fde6ed9811029364736f6c63430008090033",
+ "deployedBytecode": "0x6080604052600436106103bb5760003560e01c806382a0b8cb116101f2578063c4d66de81161010d578063e4e5bbcb116100a0578063f2fde38b1161006f578063f2fde38b14610ce0578063f698da2514610d00578063f8c8765e14610d16578063fa0caa1614610d3657600080fd5b8063e4e5bbcb14610c6c578063e6fc774414610c8c578063ea21709114610ca2578063eb16136f14610cc057600080fd5b8063d12e825d116100dc578063d12e825d14610be8578063d3401a2214610bfd578063da67703714610c1d578063e07801d014610c4c57600080fd5b8063c4d66de814610b42578063ca07140c14610b62578063cbc7328014610b98578063cc3c0f0614610bb857600080fd5b8063a53d6e6e11610185578063b0e1268e11610154578063b0e1268e14610a9d578063b794726214610abd578063b86f60d214610ade578063b984a40414610afe57600080fd5b8063a53d6e6e14610a1d578063a89f298a14610a3d578063ae06c1b714610a5d578063b048c4fb14610a7d57600080fd5b80638ca01082116101c15780638ca010821461099f5780638da5cb5b146109b45780638f32d59b146109d7578063916dc59d146109fd57600080fd5b806382a0b8cb1461091a57806382dc1ec41461094a5780638456cb591461096a57806388710e2e1461097f57600080fd5b80633f4ba83a116102e25780636b0509b1116102755780637a0ab28f116102445780637a0ab28f146108435780637a98187b146108795780637ecebe00146108d85780638129fc1c1461090557600080fd5b80636b0509b1146107d25780636ef8d66d1461080657806370aff70f1461081b578063715018a61461082e57600080fd5b80634c739509116102b15780634c7395091461074657806354fd4d50146107665780635c975abb1461079a578063615bfd6e146107b257600080fd5b80633f4ba83a146106d157806342cdb2c6146106e657806346fbf68e1461070657806347f8bbd41461072657600080fd5b806322f89ba41161035a5780633a1cbbcb116103295780633a1cbbcb146105ec5780633c3f63f41461063a5780633c7e0cb71461067b5780633cf3058b1461069b57600080fd5b806322f89ba4146105245780632f3cca4e1461056f5780633500c1dc1461058f57806337e76109146105af57600080fd5b80630ed928af116103965780630ed928af146104af5780630ef1335c146104cf57806311efbf61146104ef578063122aa5d41461050457600080fd5b806223de291461042f578063026976191461044f57806307c8f7b01461048f57600080fd5b3661042a576041546001600160a01b0316336001600160a01b0316146104285760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a206e6f74207772617070656443757272656e6379000000000060448201526064015b60405180910390fd5b005b600080fd5b34801561043b57600080fd5b5061042861044a36600461424b565b610d56565b34801561045b57600080fd5b5061047c61046a3660046142fc565b60426020526000908152604090205481565b6040519081526020015b60405180910390f35b34801561049b57600080fd5b506104286104aa366004614323565b6110b1565b3480156104bb57600080fd5b5061047c6104ca366004614358565b611140565b3480156104db57600080fd5b5061047c6104ea366004614358565b611161565b3480156104fb57600080fd5b5060375461047c565b34801561051057600080fd5b5061042861051f36600461438d565b6111d8565b34801561053057600080fd5b5061055f61053f366004614418565b604860209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610486565b34801561057b57600080fd5b5061042861058a366004614448565b611616565b34801561059b57600080fd5b506104286105aa366004614448565b611696565b3480156105bb57600080fd5b5061055f6105ca3660046142fc565b6000908152604260209081526040808320548352603e90915290205460ff1690565b3480156105f857600080fd5b50610622610607366004614448565b603b602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610486565b34801561064657600080fd5b50610622610655366004614418565b60466020908152600092835260408084209091529082529020546001600160a01b031681565b34801561068757600080fd5b50610428610696366004614465565b611768565b3480156106a757600080fd5b506106226106b63660046142fc565b6044602052600090815260409020546001600160a01b031681565b3480156106dd57600080fd5b506104286118e2565b3480156106f257600080fd5b50610428610701366004614448565b61199a565b34801561071257600080fd5b5061055f610721366004614448565b611a7b565b34801561073257600080fd5b506104286107413660046144da565b611a88565b34801561075257600080fd5b50610428610761366004614565565b611af9565b34801561077257600080fd5b506040805180820190915260028152611d8d60f21b60208201525b60405161048691906145ff565b3480156107a657600080fd5b5060345460ff1661055f565b3480156107be57600080fd5b5061055f6107cd366004614612565b611b69565b3480156107de57600080fd5b5061047c7faf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c81565b34801561081257600080fd5b50610428611bd6565b610428610829366004614418565b611be1565b34801561083a57600080fd5b50610428611cd6565b34801561084f57600080fd5b5061062261085e366004614448565b603c602052600090815260409020546001600160a01b031681565b34801561088557600080fd5b506108b9610894366004614448565b604760205260009081526040902080546001909101546001600160a01b039091169082565b604080516001600160a01b039093168352602083019190915201610486565b3480156108e457600080fd5b5061047c6108f3366004614448565b60456020526000908152604090205481565b34801561091157600080fd5b50610428611d5b565b34801561092657600080fd5b5061055f610935366004614448565b603d6020526000908152604090205460ff1681565b34801561095657600080fd5b50610428610965366004614448565b611dcc565b34801561097657600080fd5b50610428611dfa565b34801561098b57600080fd5b5061047c61099a36600461464e565b611e77565b3480156109ab57600080fd5b5061078d611ff2565b3480156109c057600080fd5b5060345461010090046001600160a01b0316610622565b3480156109e357600080fd5b5061055f60345461010090046001600160a01b0316331490565b348015610a0957600080fd5b50610428610a18366004614448565b612080565b348015610a2957600080fd5b50603f54610622906001600160a01b031681565b348015610a4957600080fd5b5061047c610a583660046146c0565b612159565b348015610a6957600080fd5b50610428610a783660046142fc565b6121cb565b348015610a8957600080fd5b5061055f610a98366004614725565b612290565b348015610aa957600080fd5b50604154610622906001600160a01b031681565b348015610ac957600080fd5b5060405461055f90600160a01b900460ff1681565b348015610aea57600080fd5b50604054610622906001600160a01b031681565b348015610b0a57600080fd5b50610b1e610b19366004614448565b6122c2565b6040805182516001600160a01b031681526020928301519281019290925201610486565b348015610b4e57600080fd5b50610428610b5d366004614448565b612341565b348015610b6e57600080fd5b50610622610b7d3660046142fc565b6043602052600090815260409020546001600160a01b031681565b348015610ba457600080fd5b50610428610bb3366004614747565b612403565b348015610bc457600080fd5b5061055f610bd33660046142fc565b603e6020526000908152604090205460ff1681565b348015610bf457600080fd5b50610428612448565b348015610c0957600080fd5b50610622610c18366004614418565b6124ef565b348015610c2957600080fd5b5061055f610c383660046142fc565b600090815260426020526040902054151590565b348015610c5857600080fd5b5061055f610c67366004614418565b612542565b348015610c7857600080fd5b50610428610c873660046147eb565b612597565b348015610c9857600080fd5b5061047c61271081565b348015610cae57600080fd5b506036546001600160a01b0316610622565b348015610ccc57600080fd5b50610428610cdb366004614448565b6125d1565b348015610cec57600080fd5b50610428610cfb366004614448565b612653565b348015610d0c57600080fd5b5061047c60395481565b348015610d2257600080fd5b50610428610d31366004614833565b612691565b348015610d4257600080fd5b50610428610d51366004614448565b6127e6565b6001600160a01b038816301415610d6c576110a7565b6001600160a01b0386163014610dc45760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a204e6f7420746f207468697320616464726573730000000000604482015260640161041f565b60003360405163555ddc6560e11b81526001600160a01b03821660048201527fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce21770546024820152909150600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca9060440160206040518083038186803b158015610e4657600080fd5b505afa158015610e5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7e919061488f565b6001600160a01b03161415610ed55760405162461bcd60e51b815260206004820152601860248201527f4272696467653a204e6f742045524337373720746f6b656e0000000000000000604482015260640161041f565b6020841015610f455760405162461bcd60e51b815260206004820152603660248201527f4272696467653a207573657220646174612077697468206174206c65617374206044820152751d1a194819195cdd1a5b985d1a5bdb90da185a5b925960521b606482015260840161041f565b6040841480610f5c57506001600160a01b0388163b155b610fb95760405162461bcd60e51b815260206004820152602860248201527f4272696467653a2053706563696679207265636569766572206164647265737360448201526720696e206461746160c01b606482015260840161041f565b60006020851461100a5761100586868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600c92506128bf915050565b61100c565b885b9050600061105c87878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506110579250602091508a90506148c2565b61292c565b90506110a3838b848b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250899250612992915050565b5050505b5050505050505050565b6110ca60345461010090046001600160a01b0316331490565b6110e65760405162461bcd60e51b815260040161041f906148d9565b6040805460ff60a01b1916600160a01b831515810291909117808355915160ff9190920416151581527f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad9906020015b60405180910390a150565b600061115b826111536020820182614448565b600080612d52565b92915050565b60608101356000908152604460205260408120546001600160a01b0316336001600160a01b0316146111ce5760405162461bcd60e51b8152602060048201526016602482015275213934b233b29d1034b73b30b634b21039b2b73232b960511b604482015260640161041f565b61115b8233611153565b60345460ff16156111fb5760405162461bcd60e51b815260040161041f9061490e565b60016035600082825461120e9190614938565b90915550506035546036546001600160a01b0316336001600160a01b0316146112725760405162461bcd60e51b8152602060048201526016602482015275213934b233b29d102737ba102332b232b930ba34b7b760511b604482015260640161041f565b61127b83612f3d565b61128482612f84565b61128e838b612542565b806112ac575060006112a0848c6124ef565b6001600160a01b031614155b6112f05760405162461bcd60e51b8152602060048201526015602482015274213934b233b29d102ab735b737bbb7103a37b5b2b760591b604482015260640161041f565b6001600160a01b0388166113385760405162461bcd60e51b815260206004820152600f60248201526e4272696467653a204e756c6c20546f60881b604482015260640161041f565b6000871161137b5760405162461bcd60e51b815260206004820152601060248201526f04272696467653a20416d6f756e7420360841b604482015260640161041f565b856113c15760405162461bcd60e51b8152602060048201526016602482015275084e4d2c8ceca74409cead8d84084d8dec6d690c2e6d60531b604482015260640161041f565b846114045760405162461bcd60e51b8152602060048201526013602482015272084e4d2c8ceca74409cead8d840a8f090c2e6d606b1b604482015260640161041f565b600085815260426020526040902054156114605760405162461bcd60e51b815260206004820152601860248201527f4272696467653a20416c72656164792061636365707465640000000000000000604482015260640161041f565b600061146f8989898989612fd3565b905060006114828a8a8a8a8a8a8a612159565b905061148e8282612290565b156114d55760405162461bcd60e51b8152602060048201526017602482015276109c9a5919d94e88105b1c9958591e4818db185a5b5959604a1b604482015260640161041f565b8060426000898152602001908152602001600020819055508b6043600089815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508a6044600089815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550896001600160a01b03168c6001600160a01b0316887fddae5e892ad96ac0e35e9018a1a3e32ecd7f3dfe55ea34d9ab1e8faecd6ccb5a8e8d8d8c8c8c6040516115df969594939291906001600160a01b039690961686526020860194909452604085019290925263ffffffff166060840152608083015260a082015260c00190565b60405180910390a45050603554811461160a5760405162461bcd60e51b815260040161041f90614950565b50505050505050505050565b600054610100900460ff168061162f575060005460ff16155b61164b5760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff1615801561166d576000805461ffff19166101011790555b611676826125d1565b6034805460ff191690558015611692576000805461ff00191690555b5050565b6116af60345461010090046001600160a01b0316331490565b6116cb5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b03811661171a5760405162461bcd60e51b81526020600482015260166024820152754272696467653a20777261707020697320656d70747960501b604482015260640161041f565b604180546001600160a01b0319166001600160a01b0383169081179091556040519081527f0966c958966f6fac9ff807af074f8117eb2e9ce2b76390db7a158e9bdeb2485c90602001611135565b61178160345461010090046001600160a01b0316331490565b61179d5760405162461bcd60e51b815260040161041f906148d9565b60005b818110156118dd576118cb8383838181106117bd576117bd6149dd565b90506020028101906117cf91906149f3565b358484848181106117e2576117e26149dd565b90506020028101906117f491906149f3565b611805906040810190602001614448565b858585818110611817576118176149dd565b905060200281019061182991906149f3565b61183a906060810190604001614a13565b86868681811061184c5761184c6149dd565b905060200281019061185e91906149f3565b61186c906060810190614a2e565b88888881811061187e5761187e6149dd565b905060200281019061189091906149f3565b61189e906080810190614a2e565b8a8a8a8181106118b0576118b06149dd565b90506020028101906118c291906149f3565b60a0013561303e565b806118d581614a75565b9150506117a0565b505050565b6118eb33611a7b565b6119075760405162461bcd60e51b815260040161041f90614a90565b60345460ff166119505760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161041f565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6119b360345461010090046001600160a01b0316331490565b6119cf5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b038116611a2f5760405162461bcd60e51b815260206004820152602160248201527f4272696467653a2053696465546f6b656e466163746f727920697320656d70746044820152607960f81b606482015260840161041f565b604080546001600160a01b0319166001600160a01b038316908117825590519081527f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e318369252162590602001611135565b600061115b60338361327e565b611aa160345461010090046001600160a01b0316331490565b611abd5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b039182166000908152604760209081526040909120825181546001600160a01b03191694169390931783550151600190910155565b611b1260345461010090046001600160a01b0316331490565b611b2e5760405162461bcd60e51b815260040161041f906148d9565b60009283526046602090815260408085206001600160a01b0394851686529091529092208054919092166001600160a01b0319909116179055565b600080611ba0611b7c6020860186614448565b602086013560408701356060880135611b9b60a08a0160808b01614ad8565b612fd3565b6000818152603e602052604090205490915060ff1680611bce57506000838152603e602052604090205460ff165b949350505050565b611bdf33613301565b565b60415433906001600160a01b0316611c3b5760405162461bcd60e51b815260206004820152601d60248201527f4272696467653a207772617070656443757272656e637920656d707479000000604482015260640161041f565b604160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611c8b57600080fd5b505af1158015611c9f573d6000803e3d6000fd5b50505050506118dd604160009054906101000a90046001600160a01b03168284346040518060200160405280600081525088612992565b611cef60345461010090046001600160a01b0316331490565b611d0b5760405162461bcd60e51b815260040161041f906148d9565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b600054610100900460ff1680611d74575060005460ff16155b611d905760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff16158015611db2576000805461ffff19166101011790555b60016035558015611dc9576000805461ff00191690555b50565b611dd533611a7b565b611df15760405162461bcd60e51b815260040161041f90614a90565b611dc981613343565b611e0333611a7b565b611e1f5760405162461bcd60e51b815260040161041f90614a90565b60345460ff1615611e425760405162461bcd60e51b815260040161041f9061490e565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861197d3390565b600042851015611ebb5760405162461bcd60e51b815260206004820152600f60248201526e109c9a5919d94e8811561412549151608a1b604482015260640161041f565b6000611ed7611ecf368b90038b018b614af3565b898989613385565b6040805160008082526020820180845284905260ff89169282019290925260608101879052608081018690529192509060019060a0016020604051602081039080840390855afa158015611f2f573d6000803e3d6000fd5b5050604051601f190151915060009050611f4c60208c018c614448565b6001600160a01b031614158015611f805750611f6b60208b018b614448565b6001600160a01b0316816001600160a01b0316145b611fcc5760405162461bcd60e51b815260206004820152601960248201527f4272696467653a20494e56414c49445f5349474e415455524500000000000000604482015260640161041f565b611fe48a611fdd6020820182614448565b8b8b612d52565b9a9950505050505050505050565b60388054611fff90614b8b565b80601f016020809104026020016040519081016040528092919081815260200182805461202b90614b8b565b80156120785780601f1061204d57610100808354040283529160200191612078565b820191906000526020600020905b81548152906001019060200180831161205b57829003601f168201915b505050505081565b61209960345461010090046001600160a01b0316331490565b6120b55760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b03811661210b5760405162461bcd60e51b815260206004820152601c60248201527f4272696467653a20416c6c6f77546f6b656e7320697320656d70747900000000604482015260640161041f565b603f80546001600160a01b0319166001600160a01b0383169081179091556040519081527f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e390602001611135565b6040805160208082019790975280820195909552606097881b6bffffffffffffffffffffffff191697850197909752607484019590955260e09190911b6001600160e01b0319166094830152609882015260b8808201939093528351808203909301835260d801909252805191012090565b6121e460345461010090046001600160a01b0316331490565b6122005760405162461bcd60e51b815260040161041f906148d9565b61220d600a612710614bd6565b811061225b5760405162461bcd60e51b815260206004820152601760248201527f4272696467653a20626967676572207468616e20313025000000000000000000604482015260640161041f565b60378190556040518181527f97e97c577f03bda90e2c9739011ec065ed5fbfb36ae217d20bb0d9be95e160cd90602001611135565b6000828152603e602052604081205460ff16806122bb57506000828152603e602052604090205460ff165b9392505050565b604080518082018252600080825260209182018190526001600160a01b038481168252604783529083902083518085019094528054909116808452600190910154918301919091521561231457919050565b60016020808301919091526001600160a01b039283166000908152603c9091526040902054909116815290565b600054610100900460ff168061235a575060005460ff16155b6123765760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff16158015612398576000805461ffff19166101011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015611692576000805461ff00191690555050565b61241c60345461010090046001600160a01b0316331490565b6124385760405162461bcd60e51b815260040161041f906148d9565b6110a7888888888888888861303e565b604080518082018252601081526f52534b20546f6b656e2042726964676560801b60208083019182528351808501855260018152603160f81b908201529151902082517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8152918201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc69181019190915246606082015230608082015260a09020603955565b60008281526046602090815260408083206001600160a01b038086168552925282205416801561252057905061115b565b50506001600160a01b039081166000908152603b602052604090205416919050565b60008281526048602090815260408083206001600160a01b038516845290915281205460ff16801561257557905061115b565b50506001600160a01b03166000908152603d602052604090205460ff16919050565b336125ad6001600160a01b038516823085613489565b6125ca84828585604051806020016040528060008152508a612992565b5050505050565b600054610100900460ff16806125ea575060005460ff16155b6126065760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff16158015612628576000805461ffff19166101011790555b61263182611a7b565b61263e5761263e82613343565b8015611692576000805461ff00191690555050565b61266c60345461010090046001600160a01b0316331490565b6126885760405162461bcd60e51b815260040161041f906148d9565b611dc9816134fa565b600054610100900460ff16806126aa575060005460ff16155b6126c65760405162461bcd60e51b815260040161041f90614995565b600054610100900460ff161580156126e8576000805461ffff19166101011790555b6126f185612341565b6126fa85611616565b603f80546001600160a01b038581166001600160a01b031992831617909255604080548584169083161781556036805493881693909216929092179055516329965a1d60e01b815230600482018190527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b60248301526044820152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90606401600060405180830381600087803b1580156127ae57600080fd5b505af11580156127c2573d6000803e3d6000fd5b505050506127ce612448565b80156125ca576000805461ff00191690555050505050565b6127ff60345461010090046001600160a01b0316331490565b61281b5760405162461bcd60e51b815260040161041f906148d9565b6001600160a01b0381166128715760405162461bcd60e51b815260206004820152601b60248201527f4272696467653a2046656465726174696f6e20697320656d7074790000000000604482015260640161041f565b603680546001600160a01b0319166001600160a01b0383169081179091556040519081527f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb90602001611135565b60006128cc826014614938565b8351101561291c5760405162461bcd60e51b815260206004820152601f60248201527f4c69625574696c733a20746f416464726573735f6f75744f66426f756e647300604482015260640161041f565b500160200151600160601b900490565b6000612939826020614938565b835110156129895760405162461bcd60e51b815260206004820152601f60248201527f4c69625574696c733a20746f55696e743235365f6f75744f66426f756e647300604482015260640161041f565b50016020015190565b604054600160a01b900460ff16156129e05760405162461bcd60e51b81526020600482015260116024820152704272696467653a20557067726164696e6760781b604482015260640161041f565b60345460ff1615612a035760405162461bcd60e51b815260040161041f9061490e565b600160356000828254612a169190614938565b909155505060355446821415612a8a5760405162461bcd60e51b815260206004820152603360248201527f4272696467653a2064657374696e6174696f6e20636861696e20696420657175604482015272185b0818dd5c9c995b9d0818da185a5b881a59606a1b606482015260840161041f565b612a9382612f3d565b60008281526048602090815260408083206001600160a01b038b1684529091529020805460ff191660011790556000612ae3612710612add603754886135c290919063ffffffff16565b90613641565b90506000612af18683613683565b90506000612afe8a6136c5565b905086601260ff831614612b2f57612b2c612b1a836012614bea565b612b2590600a614cf1565b89906135c2565b90505b603f54604051638c34bc5560e01b81526001600160a01b038d811660048301526024820184905290911690638c34bc5590604401600060405180830381600087803b158015612b7d57600080fd5b505af1158015612b91573d6000803e3d6000fd5b505050506000612ba08c6122c2565b80519091506001600160a01b031615612ca4576000612bbe8d6137a9565b90506000612bcc8683613881565b9050612bd887826138c3565b9650612be48682613683565b60405163fe9d930360e01b81529096506001600160a01b038f169063fe9d930390612c159089908e90600401614d00565b600060405180830381600087803b158015612c2f57600080fd5b505af1158015612c43573d6000803e3d6000fd5b505050505050868a6001600160a01b031682600001516001600160a01b03167fb2320a1ad388e1e16b142f7d2e822f31d8a2bbdd7d4f29260e7c203c5f45e8498e46898e604051612c979493929190614d19565b60405180910390a4612cf7565b868a6001600160a01b03168d6001600160a01b03167fb2320a1ad388e1e16b142f7d2e822f31d8a2bbdd7d4f29260e7c203c5f45e8498e46898e604051612cee9493929190614d19565b60405180910390a45b8415612d2357603454612d239061010090046001600160a01b03166001600160a01b038e169087613922565b50505050506035548114612d495760405162461bcd60e51b815260040161041f90614950565b50505050505050565b6000600160356000828254612d679190614938565b909155505060355460608601356000908152604360205260409020546001600160a01b031680612dd25760405162461bcd60e51b8152602060048201526016602482015275109c9a5919d94e88151e081b9bdd0818dc9bdcdcd95960521b604482015260640161041f565b6000612e0e612de460208a018a614448565b60208a013560408b013560608c0135612e0360a08e0160808f01614ad8565b8d60a0013546612159565b60608901356000908152604260205260409020549091508114612e7d5760405162461bcd60e51b815260206004820152602160248201527f4272696467653a2057726f6e67207472616e73616374696f6e446174614861736044820152600d60fb1b606482015260840161041f565b612e878882611b69565b15612ece5760405162461bcd60e51b8152602060048201526017602482015276109c9a5919d94e88105b1c9958591e4818db185a5b5959604a1b604482015260640161041f565b6000818152603e60209081526040909120805460ff19166001179055612f029060a08a01359084908a908c01358a8a613952565b9350612f1188838989896139a3565b50506035548114612f345760405162461bcd60e51b815260040161041f90614950565b50949350505050565b60008111611dc95760405162461bcd60e51b815260206004820152601460248201527304272696467653a20436861696e496420697320360641b604482015260640161041f565b468114611dc95760405162461bcd60e51b815260206004820152601960248201527f4272696467653a204e6f7420626c6f636b2e636861696e696400000000000000604482015260640161041f565b6040805160208101859052908101839052606086811b6bffffffffffffffffffffffff1916908201526074810185905260e082901b6001600160e01b031916609482015260009060980160405160208183030381529060405280519060200120905095945050505050565b6001600160a01b0387166130895760405162461bcd60e51b8152602060048201526012602482015271213934b233b29d10273ab636103a37b5b2b760711b604482015260640161041f565b61309281612f3d565b600061309e82896124ef565b90506001600160a01b038116156130f05760405162461bcd60e51b81526020600482015260166024820152754272696467653a20416c72656164792065786973747360501b604482015260640161041f565b60006130fb88613a7e565b6040805490516326d9e96360e01b81529192506001600160a01b0316906326d9e9639061313490889088908c908c908890600401614d6f565b602060405180830381600087803b15801561314e57600080fd5b505af1158015613162573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613186919061488f565b9150613193838a84611af9565b60408051808201909152602081018490526001600160a01b038a1681526131ba8382611a88565b603f546040516378bf2b5360e01b81526001600160a01b038581166004830152602482018e9052909116906378bf2b5390604401600060405180830381600087803b15801561320857600080fd5b505af115801561321c573d6000803e3d6000fd5b50505050896001600160a01b0316836001600160a01b03167f88dcf8b72e53287db29df3fee9a0f2cb07d1f986cee153aa7d7554405d5db0178a8a86896040516132699493929190614da9565b60405180910390a35050505050505050505050565b60006001600160a01b0382166132e15760405162461bcd60e51b815260206004820152602260248201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604482015261737360f01b606482015260840161041f565b506001600160a01b03166000908152602091909152604090205460ff1690565b61330c603382613aea565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b61334e603382613b62565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6039548451602080870151606088015160a08901516001600160a01b0385166000908152604590945260408420805494966134809690957faf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c959194919391928c918c918b6133f283614a75565b909155506040805160208101999099526001600160a01b03978816908901526060880195909552608087019390935260a086019190915290921660c084015260e08301919091526101008201526101208101859052610140016040516020818303038152906040528051906020012060405161190160f01b8152600281019290925260228201526042902090565b95945050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526134f49085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613bde565b50505050565b6001600160a01b03811661355b5760405162461bcd60e51b815260206004820152602260248201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604482015261737360f01b606482015260840161041f565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6000826135d15750600061115b565b60006135dd8385614dd0565b9050826135ea8583614bd6565b146122bb5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b606482015260840161041f565b60006122bb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613d5e565b60006122bb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613d8c565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b0386169161370b9190614def565b600060405180830381855afa9150503d8060008114613746576040519150601f19603f3d011682016040523d82523d6000602084013e61374b565b606091505b5091509150816137955760405162461bcd60e51b81526020600482015260156024820152744c69625574696c733a204e6f20646563696d616c7360581b604482015260640161041f565b80806020019051810190611bce9190614e01565b60408051600481526024810182526020810180516001600160e01b031663556f0dc760e01b1790529051600091829182916001600160a01b038616916137ef9190614def565b600060405180830381855afa9150503d806000811461382a576040519150601f19603f3d011682016040523d82523d6000602084013e61382f565b606091505b5091509150816137955760405162461bcd60e51b815260206004820152601860248201527f4c69625574696c733a204e6f206772616e756c61726974790000000000000000604482015260640161041f565b60006122bb83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250613dbd565b6000806138d08385614938565b9050838110156122bb5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015260640161041f565b6040516001600160a01b0383166024820152604481018290526118dd90849063a9059cbb60e01b906064016134bd565b600061395d87612f3d565b6139678787612542565b15613980576139798686868686613de9565b9050613999565b61399661398d88886124ef565b86868686613f99565b90505b9695505050505050565b6139b06020860186614448565b6060860135600081815260446020908152604091829020546001600160a01b039485169489811694937fa7a84dcc6757cdf9b9122d3bbc42d58358c28dc4b09cc24349599a63c56c62fd9392909116918b0135908b0135613a1760a08d0160808e01614ad8565b604080516001600160a01b039586168152602081019490945283019190915263ffffffff166060820152818916608082015290871660a08281019190915260c082018790528a013560e0820152466101008201526101200160405180910390a45050505050565b600060128260ff161115613ad45760405162461bcd60e51b815260206004820152601c60248201527f4c69625574696c733a20446563696d616c73206e6f74203c3d20313800000000604482015260640161041f565b613adf826012614bea565b61115b90600a614cf1565b613af4828261327e565b613b405760405162461bcd60e51b815260206004820181905260248201527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c65604482015260640161041f565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b613b6c828261327e565b15613bb95760405162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015260640161041f565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6001600160a01b0382163b613c355760405162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015260640161041f565b600080836001600160a01b031683604051613c509190614def565b6000604051808303816000865af19150503d8060008114613c8d576040519150601f19603f3d011682016040523d82523d6000602084013e613c92565b606091505b509150915081613ce45760405162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015260640161041f565b8051156134f45780806020019051810190613cff9190614e1a565b6134f45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161041f565b60008183613d7f5760405162461bcd60e51b815260040161041f91906145ff565b5060006134808486614bd6565b60008184841115613db05760405162461bcd60e51b815260040161041f91906145ff565b50600061348084866148c2565b60008183613dde5760405162461bcd60e51b815260040161041f91906145ff565b50611bce8385614e37565b600080613df5876136c5565b60ff1690506000613e1c613e0a8360126148c2565b613e1590600a614e4b565b8790613641565b905080841115613e655760405162461bcd60e51b8152602060048201526014602482015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b604482015260640161041f565b613e6f8185613683565b6041549093506001600160a01b0389811691161415613f6057604154604051632e1a7d4d60e01b8152600481018390526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b158015613ece57600080fd5b505af1158015613ee2573d6000803e3d6000fd5b50506040516001600160a01b038a16925085156108fc02915085906000818181858888f19350505050158015613f1c573d6000803e3d6000fd5b508315613f5b576040516001600160a01b0386169085156108fc029086906000818181858888f19350505050158015613f59573d6000803e3d6000fd5b505b613f8e565b613f746001600160a01b0389168885613922565b8315613f8e57613f8e6001600160a01b0389168686613922565b505095945050505050565b60006001600160a01b038616613ff15760405162461bcd60e51b815260206004820152601a60248201527f4272696467653a207369646520746f6b656e206973206e756c6c000000000000604482015260640161041f565b6000866001600160a01b031663556f0dc76040518163ffffffff1660e01b815260040160206040518083038186803b15801561402c57600080fd5b505afa158015614040573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140649190614e01565b9050600061407286836135c2565b9050808411156140bb5760405162461bcd60e51b8152602060048201526014602482015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b604482015260640161041f565b6140c58185613683565b604051630dcdc7dd60e41b81526001600160a01b038981166004830152602482018390526080604483015260006084830181905260a0606484015260a48301529194509089169063dcdc7dd09060c401600060405180830381600087803b15801561412f57600080fd5b505af1158015614143573d6000803e3d6000fd5b505050506000841115613f8e57604051630dcdc7dd60e41b81526001600160a01b03868116600483015260248201869052608060448301526000608483015260a06064830152600b60a48301526a72656c617965722066656560a81b60c483015289169063dcdc7dd09060e401600060405180830381600087803b1580156141ca57600080fd5b505af11580156141de573d6000803e3d6000fd5b50505050505095945050505050565b6001600160a01b0381168114611dc957600080fd5b60008083601f84011261421457600080fd5b50813567ffffffffffffffff81111561422c57600080fd5b60208301915083602082850101111561424457600080fd5b9250929050565b60008060008060008060008060c0898b03121561426757600080fd5b8835614272816141ed565b97506020890135614282816141ed565b96506040890135614292816141ed565b955060608901359450608089013567ffffffffffffffff808211156142b657600080fd5b6142c28c838d01614202565b909650945060a08b01359150808211156142db57600080fd5b506142e88b828c01614202565b999c989b5096995094979396929594505050565b60006020828403121561430e57600080fd5b5035919050565b8015158114611dc957600080fd5b60006020828403121561433557600080fd5b81356122bb81614315565b600060c0828403121561435257600080fd5b50919050565b600060c0828403121561436a57600080fd5b6122bb8383614340565b803563ffffffff8116811461438857600080fd5b919050565b60008060008060008060008060006101208a8c0312156143ac57600080fd5b89356143b7816141ed565b985060208a01356143c7816141ed565b975060408a01356143d7816141ed565b965060608a0135955060808a0135945060a08a013593506143fa60c08b01614374565b925060e08a013591506101008a013590509295985092959850929598565b6000806040838503121561442b57600080fd5b82359150602083013561443d816141ed565b809150509250929050565b60006020828403121561445a57600080fd5b81356122bb816141ed565b6000806020838503121561447857600080fd5b823567ffffffffffffffff8082111561449057600080fd5b818501915085601f8301126144a457600080fd5b8135818111156144b357600080fd5b8660208260051b85010111156144c857600080fd5b60209290920196919550909350505050565b60008082840360608112156144ee57600080fd5b83356144f9816141ed565b92506040601f198201121561450d57600080fd5b506040516040810181811067ffffffffffffffff8211171561453f57634e487b7160e01b600052604160045260246000fd5b6040526020840135614550816141ed565b81526040939093013560208401525092909150565b60008060006060848603121561457a57600080fd5b83359250602084013561458c816141ed565b9150604084013561459c816141ed565b809150509250925092565b60005b838110156145c25781810151838201526020016145aa565b838111156134f45750506000910152565b600081518084526145eb8160208601602086016145a7565b601f01601f19169290920160200192915050565b6020815260006122bb60208301846145d3565b60008060e0838503121561462557600080fd5b61462f8484614340565b9460c0939093013593505050565b803560ff8116811461438857600080fd5b6000806000806000806000610180888a03121561466a57600080fd5b6146748989614340565b965060c0880135614684816141ed565b955060e0880135945061010088013593506146a2610120890161463d565b92506101408801359150610160880135905092959891949750929550565b600080600080600080600060e0888a0312156146db57600080fd5b87356146e6816141ed565b965060208801359550604088013594506060880135935061470960808901614374565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561473857600080fd5b50508035926020909101359150565b60008060008060008060008060c0898b03121561476357600080fd5b883597506020890135614775816141ed565b965061478360408a0161463d565b9550606089013567ffffffffffffffff808211156147a057600080fd5b6147ac8c838d01614202565b909750955060808b01359150808211156147c557600080fd5b506147d28b828c01614202565b999c989b50969995989497949560a00135949350505050565b6000806000806080858703121561480157600080fd5b843593506020850135614813816141ed565b92506040850135614823816141ed565b9396929550929360600135925050565b6000806000806080858703121561484957600080fd5b8435614854816141ed565b93506020850135614864816141ed565b92506040850135614874816141ed565b91506060850135614884816141ed565b939692955090935050565b6000602082840312156148a157600080fd5b81516122bb816141ed565b634e487b7160e01b600052601160045260246000fd5b6000828210156148d4576148d46148ac565b500390565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6000821982111561494b5761494b6148ac565b500190565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b6000823560be19833603018112614a0957600080fd5b9190910192915050565b600060208284031215614a2557600080fd5b6122bb8261463d565b6000808335601e19843603018112614a4557600080fd5b83018035915067ffffffffffffffff821115614a6057600080fd5b60200191503681900382131561424457600080fd5b6000600019821415614a8957614a896148ac565b5060010190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b600060208284031215614aea57600080fd5b6122bb82614374565b600060c08284031215614b0557600080fd5b60405160c0810181811067ffffffffffffffff82111715614b3657634e487b7160e01b600052604160045260246000fd5b6040528235614b44816141ed565b80825250602083013560208201526040830135604082015260608301356060820152614b7260808401614374565b608082015260a083013560a08201528091505092915050565b600181811c90821680614b9f57607f821691505b6020821081141561435257634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b600082614be557614be5614bc0565b500490565b600060ff821660ff841680821015614c0457614c046148ac565b90039392505050565b600181815b80851115614c48578160001904821115614c2e57614c2e6148ac565b80851615614c3b57918102915b93841c9390800290614c12565b509250929050565b600082614c5f5750600161115b565b81614c6c5750600061115b565b8160018114614c825760028114614c8c57614ca8565b600191505061115b565b60ff841115614c9d57614c9d6148ac565b50506001821b61115b565b5060208310610133831016604e8410600b8410161715614ccb575081810a61115b565b614cd58383614c0d565b8060001904821115614ce957614ce96148ac565b029392505050565b60006122bb60ff841683614c50565b828152604060208201526000611bce60408301846145d3565b60018060a01b038516815283602082015282604082015260806060820152600061399960808301846145d3565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b606081526000614d83606083018789614d46565b8281036020840152614d96818688614d46565b9150508260408301529695505050505050565b606081526000614dbd606083018688614d46565b6020830194909452506040015292915050565b6000816000190483118215151615614dea57614dea6148ac565b500290565b60008251614a098184602087016145a7565b600060208284031215614e1357600080fd5b5051919050565b600060208284031215614e2c57600080fd5b81516122bb81614315565b600082614e4657614e46614bc0565b500690565b60006122bb8383614c5056fea264697066735822122056e9c6d68b936a7b2c66545886a13f33f54fec9bc3a8a09c82fde6ed9811029364736f6c63430008090033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "__Pausable_init(address)": {
+ "details": "Initializes the contract in unpaused state. Assigns the Pauser role to the deployer."
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "pause()": {
+ "details": "Called by a pauser to pause, triggers stopped state."
+ },
+ "paused()": {
+ "details": "Returns true if the contract is paused, and false otherwise."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "tokensReceived(address,address,address,uint256,bytes,bytes)": {
+ "params": {
+ "userData": "it can be 2 options in the first one you can send the receiver and the chain id of the destination const userData = web3.eth.abi.encodeParameters( [\"address\", \"uint256\"], [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID] ); or you also can send only the destination chain id, and the receiver would be the same as the from parameter const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);"
+ }
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "unpause()": {
+ "details": "Called by a pauser to unpause, returns to normal state."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "acceptTransfer(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)": {
+ "notice": "Accepts the transaction from the other chain that was voted and sent by the Federation contract"
+ },
+ "claim((address,uint256,bytes32,bytes32,uint32,uint256))": {
+ "notice": "Claims the crossed transaction using the hash, this sends the funds to the address indicated in"
+ },
+ "depositTo(uint256,address)": {
+ "notice": "Use network currency and cross it."
+ },
+ "receiveTokensTo(uint256,address,address,uint256)": {
+ "notice": "ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom"
+ },
+ "tokensReceived(address,address,address,uint256,bytes,bytes)": {
+ "notice": "ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction See https://eips.ethereum.org/EIPS/eip-777#motivation for details"
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 16294,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16297,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16337,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16363,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_pausers",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_struct(Role)10620_storage"
+ },
+ {
+ "astId": 16485,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_paused",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16583,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_owner",
+ "offset": 1,
+ "slot": "52",
+ "type": "t_address"
+ },
+ {
+ "astId": 17302,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_guardCounter",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1344,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "federation",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_address"
+ },
+ {
+ "astId": 1346,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "feePercentage",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1348,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "deprecatedSymbolPrefix",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 1350,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "domainSeparator",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_bytes32"
+ },
+ {
+ "astId": 1352,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_deprecatedSpentToday",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1356,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "deprecatedMappedTokens",
+ "offset": 0,
+ "slot": "59",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 1360,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "deprecatedOriginalTokens",
+ "offset": 0,
+ "slot": "60",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 1364,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "deprecatedKnownTokens",
+ "offset": 0,
+ "slot": "61",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 1368,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "claimed",
+ "offset": 0,
+ "slot": "62",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ },
+ {
+ "astId": 1371,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "allowTokens",
+ "offset": 0,
+ "slot": "63",
+ "type": "t_contract(IAllowTokens)7262"
+ },
+ {
+ "astId": 1374,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "sideTokenFactory",
+ "offset": 0,
+ "slot": "64",
+ "type": "t_contract(ISideTokenFactory)7749"
+ },
+ {
+ "astId": 1376,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "isUpgrading",
+ "offset": 20,
+ "slot": "64",
+ "type": "t_bool"
+ },
+ {
+ "astId": 1387,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "wrappedCurrency",
+ "offset": 0,
+ "slot": "65",
+ "type": "t_contract(IWrapped)7802"
+ },
+ {
+ "astId": 1391,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "transactionsDataHashes",
+ "offset": 0,
+ "slot": "66",
+ "type": "t_mapping(t_bytes32,t_bytes32)"
+ },
+ {
+ "astId": 1395,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originalTokenAddresses",
+ "offset": 0,
+ "slot": "67",
+ "type": "t_mapping(t_bytes32,t_address)"
+ },
+ {
+ "astId": 1399,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "senderAddresses",
+ "offset": 0,
+ "slot": "68",
+ "type": "t_mapping(t_bytes32,t_address)"
+ },
+ {
+ "astId": 1406,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "nonces",
+ "offset": 0,
+ "slot": "69",
+ "type": "t_mapping(t_address,t_uint256)"
+ },
+ {
+ "astId": 1412,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "sideTokenByOriginalTokenByChain",
+ "offset": 0,
+ "slot": "70",
+ "type": "t_mapping(t_uint256,t_mapping(t_address,t_address))"
+ },
+ {
+ "astId": 1417,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originalTokenBySideToken",
+ "offset": 0,
+ "slot": "71",
+ "type": "t_mapping(t_address,t_struct(OriginalToken)7283_storage)"
+ },
+ {
+ "astId": 1423,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "knownTokenByChain",
+ "offset": 0,
+ "slot": "72",
+ "type": "t_mapping(t_uint256,t_mapping(t_address,t_bool))"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IAllowTokens)7262": {
+ "encoding": "inplace",
+ "label": "contract IAllowTokens",
+ "numberOfBytes": "20"
+ },
+ "t_contract(ISideTokenFactory)7749": {
+ "encoding": "inplace",
+ "label": "contract ISideTokenFactory",
+ "numberOfBytes": "20"
+ },
+ "t_contract(IWrapped)7802": {
+ "encoding": "inplace",
+ "label": "contract IWrapped",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_address)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_address,t_struct(OriginalToken)7283_storage)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => struct IBridge.OriginalToken)",
+ "numberOfBytes": "32",
+ "value": "t_struct(OriginalToken)7283_storage"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_mapping(t_bytes32,t_address)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bytes32)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bytes32)",
+ "numberOfBytes": "32",
+ "value": "t_bytes32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_address,t_address))": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => mapping(address => address))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_address)"
+ },
+ "t_mapping(t_uint256,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(OriginalToken)7283_storage": {
+ "encoding": "inplace",
+ "label": "struct IBridge.OriginalToken",
+ "members": [
+ {
+ "astId": 7280,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "tokenAddress",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ },
+ {
+ "astId": 7282,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originChainId",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Role)10620_storage": {
+ "encoding": "inplace",
+ "label": "struct Roles.Role",
+ "members": [
+ {
+ "astId": 10619,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "bearer",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_address,t_bool)"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/BridgeProxy.json b/bridge/deployments/rsktestnet/BridgeProxy.json
new file mode 100644
index 000000000..29cb40289
--- /dev/null
+++ b/bridge/deployments/rsktestnet/BridgeProxy.json
@@ -0,0 +1,234 @@
+{
+ "address": "0x684a8a976635fb7ad74a0134ace990a6a0fcce84",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_admin",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x4ec10A50801f89266F0F1FA7fd3fa320106bBF63",
+ "transactionIndex": 0,
+ "gasUsed": "947465",
+ "logsBloom": "0x00000000020000000000000000008000000000000000004000800000000000001000000000000000000000000020002000000000000000000000000000000000000000000080000000000000000000000081000000000000000000000000000000000000020008000000000000040800000010004020000000000000000000400000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000240801000000000000000000000000000000000000000100000000000000000000000000000020000000000000000000000000000000000000000000000000008000000000000000",
+ "blockHash": "0x36083a7b34699ea6db1b1a64eeba40a5a29fa7d8c9c873e7e1361e02bb124f42",
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152250,
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "address": "0x4ec10A50801f89266F0F1FA7fd3fa320106bBF63",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x00000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x36083a7b34699ea6db1b1a64eeba40a5a29fa7d8c9c873e7e1361e02bb124f42"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152250,
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "address": "0x4ec10A50801f89266F0F1FA7fd3fa320106bBF63",
+ "topics": [
+ "0x6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f8",
+ "0x00000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a"
+ ],
+ "data": "0x",
+ "logIndex": 1,
+ "blockHash": "0x36083a7b34699ea6db1b1a64eeba40a5a29fa7d8c9c873e7e1361e02bb124f42"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152250,
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "address": "0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24",
+ "topics": [
+ "0x93baa6efbd2244243bfee6ce4cfdd1d04fc4c0e9a786abd3a41313bd352db153",
+ "0x0000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf63",
+ "0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b",
+ "0x0000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf63"
+ ],
+ "data": "0x",
+ "logIndex": 2,
+ "blockHash": "0x36083a7b34699ea6db1b1a64eeba40a5a29fa7d8c9c873e7e1361e02bb124f42"
+ }
+ ],
+ "blockNumber": 2152250,
+ "cumulativeGasUsed": "947465",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0xCEA4F7E9a2080D206be1fa7E4245BDecff7102dF",
+ "0x8c35e166d2dea7a8a28aaea11ad7933cdae4b0ab",
+ "0x2fb3b36100000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8000000000000000000000000bb74098e1f6f95198209ba30ba92725a6ccd5eab00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000016200000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Proxies.sol\":\"BridgeProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Proxies.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\\\";\\n\\ncontract BridgeProxy is TransparentUpgradeableProxy {\\n // solhint-disable-next-line no-empty-blocks\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\n}\\n\\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\\n // solhint-disable-next-line no-empty-blocks\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\n}\\n\\ncontract FederationProxy is TransparentUpgradeableProxy {\\n // solhint-disable-next-line no-empty-blocks\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\n}\",\"keccak256\":\"0x58e34ea4864c39b1d234084bc49b12bd7835c0a23f2604e450526eaa7581a554\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0x590a4d952d39a99972cbcb691b472c5d58af9ae8fd142355ad26200affdd2a51\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x0d5202a38732881d576fe3831605fe2633e1bc9f981ebea9c3a368af027e0b71\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x53b00bc48bd4eac1e100195c494267c0ca082bd91ac3018e2ee6155fbcbbb14f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000ca538038062000ca5833981016040819052620000269162000234565b8282828281620000368262000077565b8051156200005757620000558282620000d960201b620002ca1760201c565b505b50620000609050565b6200006b8262000108565b50505050505062000423565b6200008d816200012c60201b620002f61760201c565b620000b55760405162461bcd60e51b8152600401620000ac906200034d565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606062000101838360405180606001604052806027815260200162000c7e6027913962000136565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b606062000143846200012c565b620001625760405162461bcd60e51b8152600401620000ac90620003aa565b600080856001600160a01b0316856040516200017f9190620002fa565b600060405180830381855af49150503d8060008114620001bc576040519150601f19603f3d011682016040523d82523d6000602084013e620001c1565b606091505b509092509050620001d4828286620001de565b9695505050505050565b60608315620001ef57508162000101565b825115620002005782518084602001fd5b8160405162461bcd60e51b8152600401620000ac919062000318565b80516001600160a01b03811681146200013157600080fd5b60008060006060848603121562000249578283fd5b62000254846200021c565b925062000264602085016200021c565b60408501519092506001600160401b038082111562000281578283fd5b818601915086601f83011262000295578283fd5b815181811115620002a257fe5b604051601f8201601f191681016020018381118282101715620002c157fe5b604052818152838201602001891015620002d9578485fd5b620002ec826020830160208701620003f0565b809450505050509250925092565b600082516200030e818460208701620003f0565b9190910192915050565b600060208252825180602084015262000339816040850160208701620003f0565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b838110156200040d578181015183820152602001620003f3565b838111156200041d576000848401525b50505050565b61084b80620004336000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e3ec70ca139aef33041f9d7a058cc6501b5f73e931f4077b7f513ef7e0b3bf5c64736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e3ec70ca139aef33041f9d7a058cc6501b5f73e931f4077b7f513ef7e0b3bf5c64736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/Federation.json b/bridge/deployments/rsktestnet/Federation.json
new file mode 100644
index 000000000..492ec774d
--- /dev/null
+++ b/bridge/deployments/rsktestnet/Federation.json
@@ -0,0 +1,1117 @@
+{
+ "address": "0x21A6e27394AB07c2aEDe03D4BdDb9A239ee0548d",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridge",
+ "type": "address"
+ }
+ ],
+ "name": "BridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Executed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "currentChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "currentBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "fedVersion",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256[]",
+ "name": "fedChainsIds",
+ "type": "uint256[]"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256[]",
+ "name": "fedChainsBlocks",
+ "type": "uint256[]"
+ },
+ {
+ "indexed": false,
+ "internalType": "string[]",
+ "name": "fedChainsInfo",
+ "type": "string[]"
+ }
+ ],
+ "name": "HeartBeat",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Voted",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_MEMBER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_newMember",
+ "type": "address"
+ }
+ ],
+ "name": "addMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridge",
+ "outputs": [
+ {
+ "internalType": "contract IBridge",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "fedVersion",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "fedChainsIds",
+ "type": "uint256[]"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "fedChainsBlocks",
+ "type": "uint256[]"
+ },
+ {
+ "internalType": "string[]",
+ "name": "fedChainsInfo",
+ "type": "string[]"
+ }
+ ],
+ "name": "emitHeartbeat",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getMembers",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getTransactionId",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_members",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isMember",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionIdMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionIdMultichain",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "members",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "processed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_oldMember",
+ "type": "address"
+ }
+ ],
+ "name": "removeMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ }
+ ],
+ "name": "setBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionWasProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "originChainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "destinationChainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "voteTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "votes",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x6c4dbbfc3688ccb4ee9ced04418f6b952698b6e4e8977f30ecfde6dd251acc34",
+ "receipt": {
+ "to": null,
+ "from": "0x63C46fBf3183B0a230833a7076128bdf3D5Bc03F",
+ "contractAddress": "0x21A6e27394AB07c2aEDe03D4BdDb9A239ee0548d",
+ "transactionIndex": 0,
+ "gasUsed": "2187909",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x47336da69d35adb54dda9f3269552d7d81e3e3385e15f946ea149be097419cc0",
+ "transactionHash": "0x6c4dbbfc3688ccb4ee9ced04418f6b952698b6e4e8977f30ecfde6dd251acc34",
+ "logs": [],
+ "blockNumber": 2807030,
+ "cumulativeGasUsed": "2187909",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "numDeployments": 2,
+ "solcInputHash": "257bf35cfef475bad06cad6d9dd245f2",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"bridge\",\"type\":\"address\"}],\"name\":\"BridgeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"}],\"name\":\"Executed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"currentChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"currentBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"fedVersion\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"fedChainsIds\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"fedChainsBlocks\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"fedChainsInfo\",\"type\":\"string[]\"}],\"name\":\"HeartBeat\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"}],\"name\":\"Voted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MEMBER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newMember\",\"type\":\"address\"}],\"name\":\"addMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contract IBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"fedVersion\",\"type\":\"string\"},{\"internalType\":\"uint256[]\",\"name\":\"fedChainsIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"fedChainsBlocks\",\"type\":\"uint256[]\"},{\"internalType\":\"string[]\",\"name\":\"fedChainsInfo\",\"type\":\"string[]\"}],\"name\":\"emitHeartbeat\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMembers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"}],\"name\":\"getTransactionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"hasVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_members\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMember\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionIdMultichain\",\"type\":\"bytes32\"}],\"name\":\"isProcessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionIdMultichain\",\"type\":\"bytes32\"}],\"name\":\"isVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"members\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"processed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_oldMember\",\"type\":\"address\"}],\"name\":\"removeMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"name\":\"setBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"transactionWasProcessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"originChainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"destinationChainId\",\"type\":\"uint256\"}],\"name\":\"voteTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"votes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addMember(address)\":{\"params\":{\"_newMember\":\"address of the new member\"}},\"changeRequirement(uint256)\":{\"details\":\"Emits the RequirementChange event\",\"params\":{\"_required\":\"the number of minimum members to approve an transaction, it has to be bigger than 1\"}},\"emitHeartbeat(string,uint256[],uint256[],string[])\":{\"details\":\"Emits HeartBeat event\"},\"getMembers()\":{\"returns\":{\"_0\":\"Current members\"}},\"getTransactionCount(bytes32)\":{\"params\":{\"transactionId\":\"The transaction hashed from getTransactionId function\"}},\"getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)\":{\"details\":\"It encodes and applies keccak256 to the parameters received in the same order\",\"params\":{\"amount\":\"Could be the amount or the tokenId\",\"blockHash\":\"The block hash in which the transaction with the cross event occurred\",\"destinationChainId\":\"Is chainId of the destination chain\",\"logIndex\":\"Index of the event in the logs\",\"originChainId\":\"Is chainId of the original chain\",\"originalTokenAddress\":\"The address of the token in the origin (main) chain\",\"receiver\":\"Who is going to receive the token in the opposite chain\",\"sender\":\"The address who solicited the cross token\",\"transactionHash\":\"The transaction in which the cross event occurred\"},\"returns\":{\"_0\":\"The hash generated by the parameters.\"}},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"removeMember(address)\":{\"params\":{\"_oldMember\":\"address of the member to be removed from federation\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setBridge(address)\":{\"details\":\"Emits BridgeChanged event\",\"params\":{\"_bridge\":\"the new bridge contract address that should implement the IBridge interface\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"version()\":{\"returns\":{\"_0\":\"version in v{Number}\"}},\"voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)\":{\"params\":{\"blockHash\":\"The block hash in which the transaction with the cross event occurred\",\"destinationChainId\":\"Is chainId of the destination chain\",\"logIndex\":\"Index of the event in the logs\",\"originChainId\":\"Is chainId of the original chain\",\"originalTokenAddress\":\"The address of the token in the origin (main) chain\",\"receiver\":\"Who is going to receive the token in the opposite chain\",\"sender\":\"The address who solicited the cross token\",\"transactionHash\":\"The transaction in which the cross event occurred\",\"value\":\"Amount\"}}},\"stateVariables\":{\"isMember\":{\"details\":\"The address should be a member to vote in transactions\"},\"required\":{\"details\":\"It should have at least the required amount of members\"},\"votes\":{\"details\":\"the members should approve the transaction by 50% + 1\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addMember(address)\":{\"notice\":\"Add a new member to the federation\"},\"changeRequirement(uint256)\":{\"notice\":\"Changes the number of required members to vote and approve an transaction\"},\"emitHeartbeat(string,uint256[],uint256[],string[])\":{\"notice\":\"It emits an HeartBeat like an health check\"},\"getMembers()\":{\"notice\":\"Return all the current members of the federation\"},\"getTransactionCount(bytes32)\":{\"notice\":\"Get the amount of approved votes for that transactionId\"},\"getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)\":{\"notice\":\"Gets the hash of transaction from the following parameters encoded and keccaked\"},\"isMember(address)\":{\"notice\":\"All the addresses that are members of the federation\"},\"processed(bytes32)\":{\"notice\":\"(bytes32) transactionId => (bool) votedCheck if that transaction was already processed\"},\"removeMember(address)\":{\"notice\":\"Remove a member of the federation\"},\"required()\":{\"notice\":\"The minimum amount of votes to approve a transaction\"},\"setBridge(address)\":{\"notice\":\"Sets a new bridge contract\"},\"version()\":{\"notice\":\"Current version of the contract\"},\"voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)\":{\"notice\":\"Vote in a transaction, if it has enough votes it accepts the transfer\"},\"votes(bytes32,address)\":{\"notice\":\"(bytes32) transactionId = keccak256( abi.encodePacked( originalTokenAddress, sender, receiver, amount, blockHash, transactionHash, logIndex ) ) => ( (address) members => (bool) voted )Votes by members by the transaction ID\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Federation/Federation.sol\":\"Federation\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Federation/Federation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n// Upgradables\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\n\\nimport \\\"../interface/IBridge.sol\\\";\\nimport \\\"../interface/IFederation.sol\\\";\\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\\n\\tuint constant public MAX_MEMBER_COUNT = 50;\\n\\taddress constant private NULL_ADDRESS = address(0);\\n\\n\\tIBridge public bridge;\\n\\taddress[] public members;\\n\\n\\t/**\\n\\t\\t@notice The minimum amount of votes to approve a transaction\\n\\t\\t@dev It should have at least the required amount of members\\n\\t\\t*/\\n\\tuint public required;\\n\\n\\t/**\\n\\t\\t@notice All the addresses that are members of the federation\\n\\t\\t@dev The address should be a member to vote in transactions\\n\\t\\t*/\\n\\tmapping (address => bool) public isMember;\\n\\n\\t/**\\n\\t\\t(bytes32) transactionId = keccak256(\\n\\t\\t\\tabi.encodePacked(\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tamount,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\tlogIndex\\n\\t\\t\\t)\\n\\t\\t) => (\\n\\t\\t\\t(address) members => (bool) voted\\n\\t\\t)\\n\\t\\t@notice Votes by members by the transaction ID\\n\\t\\t@dev the members should approve the transaction by 50% + 1\\n\\t\\t*/\\n\\tmapping (bytes32 => mapping (address => bool)) public votes;\\n\\n\\t/**\\n\\t\\t(bytes32) transactionId => (bool) voted\\n\\t\\t@notice Check if that transaction was already processed\\n\\t*/\\n\\tmapping(bytes32 => bool) public processed;\\n\\n\\tmodifier onlyMember() {\\n\\t\\trequire(isMember[_msgSender()], \\\"Federation: Not Federator\\\");\\n\\t\\t_;\\n\\t}\\n\\n\\tmodifier validRequirement(uint membersCount, uint _required) {\\n\\t\\trequire(_required <= membersCount && _required != 0 && membersCount != 0, \\\"Federation: Invalid requirements\\\");\\n\\t\\t_;\\n\\t}\\n\\n\\tfunction initialize(\\n\\t\\taddress[] calldata _members,\\n\\t\\tuint _required,\\n\\t\\taddress _bridge,\\n\\t\\taddress owner\\n\\t) public validRequirement(_members.length, _required) initializer {\\n\\t\\tUpgradableOwnable.initialize(owner);\\n\\t\\trequire(_members.length <= MAX_MEMBER_COUNT, \\\"Federation: Too many members\\\");\\n\\t\\tmembers = _members;\\n\\t\\tfor (uint i = 0; i < _members.length; i++) {\\n\\t\\t\\trequire(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \\\"Federation: Invalid members\\\");\\n\\t\\t\\tisMember[_members[i]] = true;\\n\\t\\t\\temit MemberAddition(_members[i]);\\n\\t\\t}\\n\\t\\trequired = _required;\\n\\t\\temit RequirementChange(required);\\n\\t\\t_setBridge(_bridge);\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Current version of the contract\\n\\t\\t@return version in v{Number}\\n\\t\\t*/\\n\\tfunction version() external pure override returns (string memory) {\\n\\t\\treturn \\\"v3\\\";\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Sets a new bridge contract\\n\\t\\t@dev Emits BridgeChanged event\\n\\t\\t@param _bridge the new bridge contract address that should implement the IBridge interface\\n\\t\\t*/\\n\\tfunction setBridge(address _bridge) external onlyOwner override {\\n\\t\\t_setBridge(_bridge);\\n\\t}\\n\\n\\tfunction _setBridge(address _bridge) internal {\\n\\t\\trequire(_bridge != NULL_ADDRESS, \\\"Federation: Empty bridge\\\");\\n\\t\\tbridge = IBridge(_bridge);\\n\\t\\temit BridgeChanged(_bridge);\\n\\t}\\n\\n\\tfunction validateTransaction(bytes32 transactionId, bytes32 transactionIdMultichain) internal view returns(bool) {\\n\\t\\tuint256 minimumVotes = getMinimalNumberOfVotes();\\n\\t\\tuint256 amountVotes = 0;\\n\\n for (uint256 i = 0; i < members.length; i++) {\\n if (votes[transactionIdMultichain][members[i]]) {\\n amountVotes += 1;\\n\\t\\t\\t} else if (votes[transactionId][members[i]]) {\\n amountVotes += 1;\\n\\t\\t\\t}\\n\\n\\t\\t\\tif (amountVotes >= minimumVotes && amountVotes >= required) {\\n\\t\\t\\t\\treturn true;\\n\\t\\t\\t}\\n }\\n\\n\\t\\treturn false;\\n\\t}\\n\\n\\tfunction getMinimalNumberOfVotes() internal view returns(uint256) {\\n\\t\\treturn members.length / 2 + 1;\\n\\t}\\n\\n\\tfunction isProcessed(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\\n\\t\\treturn processed[transactionIdMultichain] || processed[transactionId];\\n\\t}\\n\\n\\tfunction isVoted(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\\n\\t\\treturn votes[transactionIdMultichain][_msgSender()] || votes[transactionId][_msgSender()];\\n\\t}\\n\\n\\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\\n\\t\\trequire(chainId == block.chainid, \\\"Federation: Not block.chainid\\\");\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Vote in a transaction, if it has enough votes it accepts the transfer\\n\\t\\t@param originalTokenAddress The address of the token in the origin (main) chain\\n\\t\\t@param sender The address who solicited the cross token\\n\\t\\t@param receiver Who is going to receive the token in the opposite chain\\n\\t\\t@param value Amount\\n\\t\\t@param blockHash The block hash in which the transaction with the cross event occurred\\n\\t\\t@param transactionHash The transaction in which the cross event occurred\\n\\t\\t@param logIndex Index of the event in the logs\\n\\t\\t@param originChainId Is chainId of the original chain\\n\\t\\t@param destinationChainId Is chainId of the destination chain\\n\\t\\t*/\\n\\tfunction voteTransaction(\\n\\t\\taddress originalTokenAddress,\\n\\t\\taddress payable sender,\\n\\t\\taddress payable receiver,\\n\\t\\tuint256 value,\\n\\t\\tbytes32 blockHash,\\n\\t\\tbytes32 transactionHash,\\n\\t\\tuint32 logIndex,\\n\\t\\tuint256 originChainId,\\n\\t\\tuint256\\tdestinationChainId\\n\\t) external onlyMember override {\\n\\t\\tshouldBeCurrentChainId(destinationChainId);\\n\\t\\tbytes32 transactionId = keccak256(\\n\\t\\t\\tabi.encodePacked(\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tvalue,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\tlogIndex\\n\\t\\t\\t)\\n\\t\\t);\\n\\n\\t\\tbytes32 transactionIdMultichain = getTransactionId(\\n\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\tsender,\\n\\t\\t\\treceiver,\\n\\t\\t\\tvalue,\\n\\t\\t\\tblockHash,\\n\\t\\t\\ttransactionHash,\\n\\t\\t\\tlogIndex,\\n\\t\\t\\toriginChainId,\\n\\t\\t\\tdestinationChainId\\n\\t\\t);\\n\\n\\t\\tif (isProcessed(transactionId, transactionIdMultichain))\\n\\t\\t\\treturn;\\n\\n\\t\\tif (isVoted(transactionId, transactionIdMultichain))\\n\\t\\t\\treturn;\\n\\n\\t\\tvotes[transactionIdMultichain][_msgSender()] = true;\\n\\t\\temit Voted(\\n\\t\\t\\t_msgSender(),\\n\\t\\t\\ttransactionHash,\\n\\t\\t\\ttransactionIdMultichain,\\n\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\tsender,\\n\\t\\t\\treceiver,\\n\\t\\t\\tvalue,\\n\\t\\t\\tblockHash,\\n\\t\\t\\tlogIndex,\\n\\t\\t\\toriginChainId,\\n\\t\\t\\tdestinationChainId\\n\\t\\t);\\n\\n\\t\\tif (validateTransaction(transactionId, transactionIdMultichain)) {\\n\\t\\t\\tprocessed[transactionIdMultichain] = true;\\n\\n\\t\\t\\tacceptTransfer(\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tvalue,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\tlogIndex,\\n\\t\\t\\t\\t\\n\\t\\t\\t\\toriginChainId,\\n\\t\\t\\t\\tdestinationChainId\\n\\t\\t\\t);\\n\\n\\t\\t\\temit Executed(\\n\\t\\t\\t\\t_msgSender(),\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\ttransactionIdMultichain,\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tvalue,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\tlogIndex,\\n\\t\\t\\t\\toriginChainId,\\n\\t\\t\\t\\tdestinationChainId\\n\\t\\t\\t);\\n\\t\\t}\\n\\t}\\n\\n function acceptTransfer(\\n address originalTokenAddress,\\n address payable sender,\\n address payable receiver,\\n uint256 value,\\n bytes32 blockHash,\\n bytes32 transactionHash,\\n uint32 logIndex,\\n\\tuint256 originChainId,\\n\\tuint256\\tdestinationChainId\\n ) internal {\\n\\t bridge.acceptTransfer(\\n\\t\\toriginalTokenAddress,\\n\\t\\tsender,\\n\\t\\treceiver,\\n\\t\\tvalue,\\n\\t\\tblockHash,\\n\\t\\ttransactionHash,\\n\\t\\tlogIndex,\\n\\t\\toriginChainId,\\n\\t\\tdestinationChainId\\n\\t );\\n }\\n\\n /**\\n @notice Get the amount of approved votes for that transactionId\\n @param transactionId The transaction hashed from getTransactionId function\\n */\\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\\n uint count = 0;\\n for (uint i = 0; i < members.length; i++) {\\n if (votes[transactionId][members[i]])\\n count += 1;\\n }\\n return count;\\n }\\n\\n\\tfunction hasVoted(bytes32 transactionId) external view returns(bool) {\\n\\t\\treturn votes[transactionId][_msgSender()];\\n\\t}\\n\\n\\tfunction transactionWasProcessed(bytes32 transactionId) external view returns(bool) {\\n\\t\\treturn processed[transactionId];\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Gets the hash of transaction from the following parameters encoded and keccaked\\n\\t\\t@dev It encodes and applies keccak256 to the parameters received in the same order\\n\\t\\t@param originalTokenAddress The address of the token in the origin (main) chain\\n\\t\\t@param sender The address who solicited the cross token\\n\\t\\t@param receiver Who is going to receive the token in the opposite chain\\n\\t\\t@param amount Could be the amount or the tokenId\\n\\t\\t@param blockHash The block hash in which the transaction with the cross event occurred\\n\\t\\t@param transactionHash The transaction in which the cross event occurred\\n\\t\\t@param logIndex Index of the event in the logs\\n\\t\\t@param originChainId Is chainId of the original chain\\n\\t\\t@param destinationChainId Is chainId of the destination chain\\n\\t\\t@return The hash generated by the parameters.\\n\\t*/\\n\\tfunction getTransactionId(\\n\\t\\taddress originalTokenAddress,\\n\\t\\taddress sender,\\n\\t\\taddress receiver,\\n\\t\\tuint256 amount,\\n\\t\\tbytes32 blockHash,\\n\\t\\tbytes32 transactionHash,\\n\\t\\tuint32 logIndex,\\n\\t\\tuint256 originChainId,\\n\\t\\tuint256\\tdestinationChainId\\n\\t) public pure returns(bytes32) {\\n\\t\\treturn keccak256(\\n\\t\\t\\tabi.encodePacked(\\n\\t\\t\\t\\toriginalTokenAddress,\\n\\t\\t\\t\\tsender,\\n\\t\\t\\t\\treceiver,\\n\\t\\t\\t\\tamount,\\n\\t\\t\\t\\tblockHash,\\n\\t\\t\\t\\ttransactionHash,\\n\\t\\t\\t\\tlogIndex,\\n\\t\\t\\t\\toriginChainId,\\n\\t\\t\\t\\tdestinationChainId\\n\\t\\t\\t)\\n\\t\\t);\\n\\t}\\n\\n\\tfunction addMember(address _newMember) external onlyOwner override {\\n\\t\\trequire(_newMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\n\\t\\trequire(!isMember[_newMember], \\\"Federation: Member already exists\\\");\\n\\t\\trequire(members.length < MAX_MEMBER_COUNT, \\\"Federation: Max members reached\\\");\\n\\n\\t\\tisMember[_newMember] = true;\\n\\t\\tmembers.push(_newMember);\\n\\t\\temit MemberAddition(_newMember);\\n\\t}\\n\\n\\tfunction removeMember(address _oldMember) external onlyOwner override {\\n\\t\\trequire(_oldMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\n\\t\\trequire(isMember[_oldMember], \\\"Federation: Member doesn't exists\\\");\\n\\t\\trequire(members.length > 1, \\\"Federation: Can't remove all the members\\\");\\n\\t\\trequire(members.length - 1 >= required, \\\"Federation: Can't have less than required members\\\");\\n\\n\\t\\tisMember[_oldMember] = false;\\n\\t\\tfor (uint i = 0; i < members.length - 1; i++) {\\n\\t\\t\\tif (members[i] == _oldMember) {\\n\\t\\t\\t\\tmembers[i] = members[members.length - 1];\\n\\t\\t\\t\\tbreak;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\tmembers.pop(); // remove an element from the end of the array.\\n\\t\\temit MemberRemoval(_oldMember);\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Return all the current members of the federation\\n\\t\\t@return Current members\\n\\t\\t*/\\n\\tfunction getMembers() external view override returns (address[] memory) {\\n\\t\\treturn members;\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice Changes the number of required members to vote and approve an transaction\\n\\t\\t@dev Emits the RequirementChange event\\n\\t\\t@param _required the number of minimum members to approve an transaction, it has to be bigger than 1\\n\\t\\t*/\\n\\tfunction changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\\n\\t\\trequire(_required >= 2, \\\"Federation: Requires at least 2\\\");\\n\\t\\trequired = _required;\\n\\t\\temit RequirementChange(_required);\\n\\t}\\n\\n\\t/**\\n\\t\\t@notice It emits an HeartBeat like an health check\\n\\t\\t@dev Emits HeartBeat event\\n\\t\\t*/\\n\\tfunction emitHeartbeat(\\n\\t\\tstring calldata fedVersion,\\n\\t\\tuint256[] calldata fedChainsIds,\\n\\t\\tuint256[] calldata fedChainsBlocks,\\n\\t\\tstring[] calldata fedChainsInfo\\n\\t) external onlyMember override {\\n\\t\\trequire(fedChainsIds.length == fedChainsBlocks.length &&\\n\\t\\t\\tfedChainsIds.length == fedChainsInfo.length, \\\"Federation: Length missmatch\\\");\\n\\t\\temit HeartBeat(\\n\\t\\t\\t_msgSender(),\\n\\t\\t\\tblock.chainid,\\n\\t\\t\\tblock.number,\\n\\t\\t\\tfedVersion,\\n\\t\\t\\tfedChainsIds,\\n\\t\\t\\tfedChainsBlocks,\\n\\t\\t\\tfedChainsInfo\\n\\t\\t);\\n\\t}\\n}\\n\",\"keccak256\":\"0x2a10301f1d5d923b68ccb895b7d6e1ec4c41afa204f8466f20b2702665ef8769\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\ninterface IBridge {\\n\\n\\tstruct ClaimData {\\n\\t\\taddress payable to;\\n\\t\\tuint256 amount;\\n\\t\\tbytes32 blockHash;\\n\\t\\tbytes32 transactionHash;\\n\\t\\tuint32 logIndex;\\n\\t\\tuint256 originChainId;\\n\\t}\\n\\n\\tstruct OriginalToken {\\n\\t\\taddress tokenAddress;\\n\\t\\tuint256 originChainId;\\n\\t}\\n\\t\\n\\tstruct CreateSideTokenStruct {\\n\\t\\tuint256 _typeId;\\n\\t\\taddress _originalTokenAddress;\\n\\t\\tuint8 _originalTokenDecimals;\\n\\t\\tstring _originalTokenSymbol;\\n\\t\\tstring _originalTokenName;\\n\\t\\tuint256 _originChainId;\\n\\t}\\n\\n\\tfunction version() external pure returns (string memory);\\n\\n\\tfunction getFeePercentage() external view returns(uint);\\n\\n\\t/**\\n\\t\\t* ERC-20 tokens approve and transferFrom pattern\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\n\\t\\t*/\\n\\tfunction receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;\\n\\n\\t/**\\n\\t\\t* Use network currency and cross it.\\n\\t\\t*/\\n\\tfunction depositTo(uint256 chainId, address to) external payable;\\n\\n\\t/**\\n\\t\\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\n\\t\\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\n\\t\\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\\n\\t\\t* const userData = web3.eth.abi.encodeParameters(\\n * [\\\"address\\\", \\\"uint256\\\"],\\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\\n * );\\n\\t\\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\\n\\t\\t* const userData = web3.eth.abi.encodeParameters([\\\"uint256\\\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\\n\\t\\t*/\\n\\tfunction tokensReceived (\\n\\t\\taddress operator,\\n\\t\\taddress from,\\n\\t\\taddress to,\\n\\t\\tuint amount,\\n\\t\\tbytes calldata userData,\\n\\t\\tbytes calldata operatorData\\n\\t) external;\\n\\n\\t/**\\n\\t\\t* Accepts the transaction from the other chain that was voted and sent by the Federation contract\\n\\t\\t*/\\n\\tfunction acceptTransfer(\\n\\t\\taddress _originalTokenAddress,\\n\\t\\taddress payable _from,\\n\\t\\taddress payable _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t) external;\\n\\n\\t/**\\n\\t\\t* Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\n\\t\\t*/\\n\\tfunction claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n\\tfunction claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n\\tfunction claimGasless(\\n\\t\\tClaimData calldata _claimData,\\n\\t\\taddress payable _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _deadline,\\n\\t\\tuint8 _v,\\n\\t\\tbytes32 _r,\\n\\t\\tbytes32 _s\\n\\t) external returns (uint256 receivedAmount);\\n\\n\\tfunction createSideToken(\\n\\t\\tuint256 _typeId,\\n\\t\\taddress _originalTokenAddress,\\n\\t\\tuint8 _originalTokenDecimals,\\n\\t\\tstring calldata _originalTokenSymbol,\\n\\t\\tstring calldata _originalTokenName,\\n\\t\\tuint256 _chainId\\n\\t) external;\\n\\n\\tfunction createMultipleSideTokens(\\n\\t\\tCreateSideTokenStruct[] calldata createSideTokenStruct\\n\\t) external;\\n\\n\\tfunction getTransactionDataHash(\\n\\t\\taddress _to,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tbytes32 _transactionHash,\\n\\t\\tuint32 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256 _destinationChainId\\n\\t) external returns(bytes32);\\n\\n\\tevent Cross(\\n\\t\\taddress indexed _tokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\tuint256 indexed _destinationChainId,\\n\\t\\taddress _from,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes _userData\\n\\t);\\n\\n\\tevent NewSideToken(\\n\\t\\taddress indexed _newSideTokenAddress,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\tstring _newSymbol,\\n\\t\\tuint256 _granularity,\\n\\t\\tuint256 _chainId\\n\\t);\\n\\tevent AcceptedCrossTransfer(\\n\\t\\tbytes32 indexed _transactionHash,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\taddress _from,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tuint256 _logIndex,\\n\\t\\tuint256 _originChainId,\\n\\t\\tuint256\\t_destinationChainId\\n\\t);\\n\\tevent FeePercentageChanged(uint256 _amount);\\n\\tevent Claimed(\\n\\t\\tbytes32 indexed _transactionHash,\\n\\t\\taddress indexed _originalTokenAddress,\\n\\t\\taddress indexed _to,\\n\\t\\taddress _sender,\\n\\t\\tuint256 _amount,\\n\\t\\tbytes32 _blockHash,\\n\\t\\tuint256 _logIndex,\\n\\t\\taddress _reciever,\\n\\t\\taddress _relayer,\\n\\t\\tuint256 _fee,\\n\\t\\tuint256 _destinationChainId,\\n\\t\\tuint256 _originChainId\\n\\t);\\n}\",\"keccak256\":\"0x1c5d6422edd509f1abc62bc29b41b1c6f80df08235ca289da81c661b8aa33044\",\"license\":\"MIT\"},\"contracts/interface/IFederation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\ninterface IFederation {\\n\\n /**\\n @notice Current version of the contract\\n @return version in v{Number}\\n */\\n function version() external pure returns (string memory);\\n\\n /**\\n @notice Sets a new bridge contract\\n @param _bridge the new bridge contract address that should implement the IBridge interface\\n */\\n function setBridge(address _bridge) external;\\n\\n /**\\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\\n @param originalTokenAddress The address of the token in the origin (main) chain\\n @param sender The address who solicited the cross token\\n @param receiver Who is going to receive the token in the opposite chain\\n @param value Amount\\n @param blockHash The block hash in which the transaction with the cross event occurred\\n @param transactionHash The transaction in which the cross event occurred\\n @param logIndex Index of the event in the logs\\n\\t\\t@param originChainId Is chainId of the original chain\\n\\t\\t@param destinationChainId Is chainId of the destination chain\\n */\\n function voteTransaction(\\n address originalTokenAddress,\\n address payable sender,\\n address payable receiver,\\n uint256 value,\\n bytes32 blockHash,\\n bytes32 transactionHash,\\n uint32 logIndex,\\n\\t uint256 originChainId,\\n\\t uint256\\tdestinationChainId\\n ) external;\\n\\n /**\\n @notice Add a new member to the federation\\n @param _newMember address of the new member\\n */\\n function addMember(address _newMember) external;\\n\\n /**\\n @notice Remove a member of the federation\\n @param _oldMember address of the member to be removed from federation\\n */\\n function removeMember(address _oldMember) external;\\n\\n /**\\n @notice Return all the current members of the federation\\n @return Current members\\n */\\n function getMembers() external view returns (address[] memory);\\n\\n /**\\n @notice Changes the number of required members to vote and approve an transaction\\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\\n */\\n function changeRequirement(uint _required) external;\\n\\n /**\\n @notice It emmits an HeartBeat like an healthy check\\n */\\n function emitHeartbeat(\\n string calldata federatorVersion,\\n\\t\\tuint256[] calldata fedChainsIds,\\n\\t\\tuint256[] calldata fedChainsBlocks,\\n\\t\\tstring[] calldata fedChainsInfo\\n ) external;\\n\\n event Executed(\\n address indexed federator,\\n bytes32 indexed transactionHash,\\n bytes32 indexed transactionId,\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n uint32 logIndex,\\n\\t\\tuint256 originChainId,\\n\\t\\tuint256\\tdestinationChainId\\n );\\n event MemberAddition(address indexed member);\\n event MemberRemoval(address indexed member);\\n event RequirementChange(uint required);\\n event BridgeChanged(address bridge);\\n event Voted(\\n address indexed federator,\\n bytes32 indexed transactionHash,\\n bytes32 indexed transactionId,\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n uint32 logIndex,\\n uint256 originChainId,\\n\\t\\tuint256\\tdestinationChainId\\n );\\n event HeartBeat(\\n address indexed sender,\\n uint256 currentChainId,\\n uint256 currentBlock,\\n string fedVersion,\\n uint256[] fedChainsIds,\\n\\t\\tuint256[] fedChainsBlocks,\\n\\t\\tstring[] fedChainsInfo\\n );\\n\\n}\\n\",\"keccak256\":\"0x22ef32d3798dc52fcf55286858f0a12e0f99fb9c1f0d35c6cfbc3e99b70b0744\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return payable(msg.sender);\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x6f3f274a2270bfe073339370edfa2485e2d515a2656039937f6b972fae96d297\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\",\"keccak256\":\"0x14063a689bff5eecf0f36cb519feb575f60349ecf0d425ead5b931b77dd599d4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract UpgradableOwnable is Initializable, Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function initialize(address sender) public initializer {\\n _owner = sender;\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * > Note: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n\\n}\\n\",\"keccak256\":\"0xdf439a167ae82e7e3dd241ea0c831a1bb0329432ceb4fa889778d1f2d196ce00\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50611f3f806100206000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c80639386775a116100f9578063c1b4a1e311610097578063ca6d56dc11610071578063ca6d56dc14610401578063dc8452cd14610414578063e78cea921461041d578063f2fde38b1461043057600080fd5b8063c1b4a1e3146103b8578063c1f0808a146103cb578063c4d66de8146103ee57600080fd5b8063a1fb4acb116100d3578063a1fb4acb1461034c578063a230c5241461035f578063a93585f014610382578063ba51a6df146103a557600080fd5b80639386775a146102f65780639dc8f9c8146103245780639eab52531461033757600080fd5b8063681fc921116101665780637b6d343a116101405780637b6d343a146102ac5780638da5cb5b146102bf5780638dd14802146102d05780638f32d59b146102e357600080fd5b8063681fc9211461027b578063715018a61461029157806379d9ee721461029957600080fd5b806309c69cfa146101ae5780630b1ca49a146101d65780631b4613cb146101eb5780633f78f0691461021957806354fd4d501461022c5780635daf08ca14610250575b600080fd5b6101c16101bc3660046118ac565b610443565b60405190151581526020015b60405180910390f35b6101e96101e43660046118e3565b61048d565b005b6101c16101f9366004611907565b600090815260386020908152604080832033845290915290205460ff1690565b6101e9610227366004611939565b6107cb565b6040805180820182526002815261763360f01b602082015290516101cd91906119c4565b61026361025e366004611907565b610a0b565b6040516001600160a01b0390911681526020016101cd565b610283603281565b6040519081526020016101cd565b6101e9610a35565b6101e96102a7366004611a65565b610aa9565b6101c16102ba3660046118ac565b610bbb565b6033546001600160a01b0316610263565b6101e96102de3660046118e3565b610bea565b6033546001600160a01b031633146101c1565b6101c1610304366004611b54565b603860209081526000928352604080842090915290825290205460ff1681565b610283610332366004611939565b610c20565b61033f610cad565b6040516101cd9190611b84565b61028361035a366004611907565b610d0f565b6101c161036d3660046118e3565b60376020526000908152604090205460ff1681565b6101c1610390366004611907565b60009081526039602052604090205460ff1690565b6101e96103b3366004611907565b610d97565b6101e96103c6366004611bd1565b610eb9565b6101c16103d9366004611907565b60396020526000908152604090205460ff1681565b6101e96103fc3660046118e3565b6111dc565b6101e961040f3660046118e3565b611292565b61028360365481565b603454610263906001600160a01b031681565b6101e961043e3660046118e3565b61145e565b600081815260386020908152604080832033845290915281205460ff16806104845750600083815260386020908152604080832033845290915290205460ff165b90505b92915050565b6033546001600160a01b031633146104c05760405162461bcd60e51b81526004016104b790611c45565b60405180910390fd5b6001600160a01b0381166105115760405162461bcd60e51b81526020600482015260186024820152772332b232b930ba34b7b71d1022b6b83a3c9036b2b6b132b960411b60448201526064016104b7565b6001600160a01b03811660009081526037602052604090205460ff166105835760405162461bcd60e51b815260206004820152602160248201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746044820152607360f81b60648201526084016104b7565b6035546001106105e65760405162461bcd60e51b815260206004820152602860248201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604482015267206d656d6265727360c01b60648201526084016104b7565b6036546035546105f890600190611c90565b10156106605760405162461bcd60e51b815260206004820152603160248201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604482015270207265717569726564206d656d6265727360781b60648201526084016104b7565b6001600160a01b0381166000908152603760205260408120805460ff191690555b60355461069090600190611c90565b81101561076057816001600160a01b0316603582815481106106b4576106b4611ca7565b6000918252602090912001546001600160a01b0316141561074e57603580546106df90600190611c90565b815481106106ef576106ef611ca7565b600091825260209091200154603580546001600160a01b03909216918390811061071b5761071b611ca7565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610760565b8061075881611cbd565b915050610681565b50603580548061077257610772611cd8565b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b3360009081526037602052604090205460ff166108265760405162461bcd60e51b81526020600482015260196024820152782332b232b930ba34b7b71d102737ba102332b232b930ba37b960391b60448201526064016104b7565b61082f81611491565b6040516bffffffffffffffffffffffff1960608b811b821660208401528a811b8216603484015289901b166048820152605c8101879052607c8101869052609c81018590526001600160e01b031960e085901b1660bc82015260009060c00160405160208183030381529060405280519060200120905060006108b98b8b8b8b8b8b8b8b8b610c20565b90506108c58282610bbb565b156108d1575050610a00565b6108db8282610443565b156108e7575050610a00565b6000818152603860205260408120600191336001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558086336001600160a01b03167fa7be469662a3e5b2343dce0cefce9d3e114875d7334d8d724d3838cf629c5b108e8e8e8e8e8d8d8d60405161096a989796959493929190611cee565b60405180910390a461097c82826114e0565b156109fd576000818152603960205260409020805460ff191660011790556109ab8b8b8b8b8b8b8b8b8b611600565b8086336001600160a01b03167f0fe3e5a751f4df1a701ea5d318482623b6a6b59ece98cb64169279b44219355e8e8e8e8e8e8d8d8d6040516109f4989796959493929190611cee565b60405180910390a45b50505b505050505050505050565b60358181548110610a1b57600080fd5b6000918252602090912001546001600160a01b0316905081565b6033546001600160a01b03163314610a5f5760405162461bcd60e51b81526004016104b790611c45565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b3360009081526037602052604090205460ff16610b045760405162461bcd60e51b81526020600482015260196024820152782332b232b930ba34b7b71d102737ba102332b232b930ba37b960391b60448201526064016104b7565b8483148015610b1257508481145b610b5e5760405162461bcd60e51b815260206004820152601c60248201527f46656465726174696f6e3a204c656e677468206d6973736d617463680000000060448201526064016104b7565b336001600160a01b03167f909659508bf1f4c0ad9b406809f943832e107af28b0b436d9b7d56d3993c77f146438b8b8b8b8b8b8b8b604051610ba99a99989796959493929190611d9a565b60405180910390a25050505050505050565b60008181526039602052604081205460ff16806104845750505060009081526039602052604090205460ff1690565b6033546001600160a01b03163314610c145760405162461bcd60e51b81526004016104b790611c45565b610c1d816116ab565b50565b604080516bffffffffffffffffffffffff1960609b8c1b81166020808401919091529a8c1b8116603483015298909a1b90971660488a0152605c890195909552607c880193909352609c8701919091526001600160e01b031960e091821b1660bc87015260c086019190915280850191909152815180850390910181526101009093019052815191012090565b60606035805480602002602001604051908101604052809291908181526020018280548015610d0557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ce7575b5050505050905090565b600080805b603554811015610d905760008481526038602052604081206035805491929184908110610d4357610d43611ca7565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610d7e57610d7b600183611e87565b91505b80610d8881611cbd565b915050610d14565b5092915050565b6033546001600160a01b03163314610dc15760405162461bcd60e51b81526004016104b790611c45565b60355481818111801590610dd457508015155b8015610ddf57508115155b610e2b5760405162461bcd60e51b815260206004820181905260248201527f46656465726174696f6e3a20496e76616c696420726571756972656d656e747360448201526064016104b7565b6002831015610e7c5760405162461bcd60e51b815260206004820152601f60248201527f46656465726174696f6e3a205265717569726573206174206c6561737420320060448201526064016104b7565b60368390556040518381527fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9060200160405180910390a1505050565b8383818111801590610eca57508015155b8015610ed557508115155b610f215760405162461bcd60e51b815260206004820181905260248201527f46656465726174696f6e3a20496e76616c696420726571756972656d656e747360448201526064016104b7565b600054610100900460ff1680610f3a575060005460ff16155b610f565760405162461bcd60e51b81526004016104b790611e9f565b600054610100900460ff16158015610f78576000805461ffff19166101011790555b610f81846111dc565b6032871115610fd25760405162461bcd60e51b815260206004820152601c60248201527f46656465726174696f6e3a20546f6f206d616e79206d656d626572730000000060448201526064016104b7565b610fde60358989611834565b5060005b8781101561117e57603760008a8a8481811061100057611000611ca7565b905060200201602081019061101591906118e3565b6001600160a01b0316815260208101919091526040016000205460ff1615801561106f5750600089898381811061104e5761104e611ca7565b905060200201602081019061106391906118e3565b6001600160a01b031614155b6110bb5760405162461bcd60e51b815260206004820152601b60248201527f46656465726174696f6e3a20496e76616c6964206d656d62657273000000000060448201526064016104b7565b6001603760008b8b858181106110d3576110d3611ca7565b90506020020160208101906110e891906118e3565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905588888281811061112257611122611ca7565b905060200201602081019061113791906118e3565b6001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a28061117681611cbd565b915050610fe2565b5060368690556040518681527fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9060200160405180910390a16111c0856116ab565b80156111d2576000805461ff00191690555b5050505050505050565b600054610100900460ff16806111f5575060005460ff16155b6112115760405162461bcd60e51b81526004016104b790611e9f565b600054610100900460ff16158015611233576000805461ffff19166101011790555b603380546001600160a01b0319166001600160a01b0384169081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3801561128e576000805461ff00191690555b5050565b6033546001600160a01b031633146112bc5760405162461bcd60e51b81526004016104b790611c45565b6001600160a01b03811661130d5760405162461bcd60e51b81526020600482015260186024820152772332b232b930ba34b7b71d1022b6b83a3c9036b2b6b132b960411b60448201526064016104b7565b6001600160a01b03811660009081526037602052604090205460ff16156113805760405162461bcd60e51b815260206004820152602160248201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746044820152607360f81b60648201526084016104b7565b6035546032116113d25760405162461bcd60e51b815260206004820152601f60248201527f46656465726174696f6e3a204d6178206d656d6265727320726561636865640060448201526064016104b7565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b6033546001600160a01b031633146114885760405162461bcd60e51b81526004016104b790611c45565b610c1d81611755565b468114610c1d5760405162461bcd60e51b815260206004820152601d60248201527f46656465726174696f6e3a204e6f7420626c6f636b2e636861696e696400000060448201526064016104b7565b6000806114eb611812565b90506000805b6035548110156115f4576000858152603860205260408120603580549192918490811061152057611520611ca7565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff161561155f57611558600183611e87565b91506115bf565b6000868152603860205260408120603580549192918490811061158457611584611ca7565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156115bf576115bc600183611e87565b91505b8282101580156115d157506036548210155b156115e25760019350505050610487565b806115ec81611cbd565b9150506114f1565b50600095945050505050565b60345460405163048aa97560e21b81526001600160a01b038b811660048301528a811660248301528981166044830152606482018990526084820188905260a4820187905263ffffffff861660c483015260e4820185905261010482018490529091169063122aa5d49061012401600060405180830381600087803b15801561168857600080fd5b505af115801561169c573d6000803e3d6000fd5b50505050505050505050505050565b6001600160a01b0381166117015760405162461bcd60e51b815260206004820152601860248201527f46656465726174696f6e3a20456d70747920627269646765000000000000000060448201526064016104b7565b603480546001600160a01b0319166001600160a01b0383169081179091556040519081527f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b925517827944979060200160405180910390a150565b6001600160a01b0381166117b65760405162461bcd60e51b815260206004820152602260248201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604482015261737360f01b60648201526084016104b7565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b60355460009061182490600290611ee7565b61182f906001611e87565b905090565b828054828255906000526020600020908101928215611887579160200282015b828111156118875781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190611854565b50611893929150611897565b5090565b5b808211156118935760008155600101611898565b600080604083850312156118bf57600080fd5b50508035926020909101359150565b6001600160a01b0381168114610c1d57600080fd5b6000602082840312156118f557600080fd5b8135611900816118ce565b9392505050565b60006020828403121561191957600080fd5b5035919050565b803563ffffffff8116811461193457600080fd5b919050565b60008060008060008060008060006101208a8c03121561195857600080fd5b8935611963816118ce565b985060208a0135611973816118ce565b975060408a0135611983816118ce565b965060608a0135955060808a0135945060a08a013593506119a660c08b01611920565b925060e08a013591506101008a013590509295985092959850929598565b600060208083528351808285015260005b818110156119f1578581018301518582016040015282016119d5565b81811115611a03576000604083870101525b50601f01601f1916929092016040019392505050565b60008083601f840112611a2b57600080fd5b50813567ffffffffffffffff811115611a4357600080fd5b6020830191508360208260051b8501011115611a5e57600080fd5b9250929050565b6000806000806000806000806080898b031215611a8157600080fd5b883567ffffffffffffffff80821115611a9957600080fd5b818b0191508b601f830112611aad57600080fd5b813581811115611abc57600080fd5b8c6020828501011115611ace57600080fd5b60209283019a509850908a01359080821115611ae957600080fd5b611af58c838d01611a19565b909850965060408b0135915080821115611b0e57600080fd5b611b1a8c838d01611a19565b909650945060608b0135915080821115611b3357600080fd5b50611b408b828c01611a19565b999c989b5096995094979396929594505050565b60008060408385031215611b6757600080fd5b823591506020830135611b79816118ce565b809150509250929050565b6020808252825182820181905260009190848201906040850190845b81811015611bc55783516001600160a01b031683529284019291840191600101611ba0565b50909695505050505050565b600080600080600060808688031215611be957600080fd5b853567ffffffffffffffff811115611c0057600080fd5b611c0c88828901611a19565b909650945050602086013592506040860135611c27816118ce565b91506060860135611c37816118ce565b809150509295509295909350565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082821015611ca257611ca2611c7a565b500390565b634e487b7160e01b600052603260045260246000fd5b6000600019821415611cd157611cd1611c7a565b5060010190565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b03988916815296881660208801529490961660408601526060850192909252608084015263ffffffff1660a083015260c082019290925260e08101919091526101000190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b81835260006001600160fb1b03831115611d7d57600080fd5b8260051b8083602087013760009401602001938452509192915050565b8a8152600060208b8184015260c06040840152611dbb60c084018b8d611d3b565b8381036060850152611dce818a8c611d64565b90508381036080850152611de381888a611d64565b84810360a08601528581529050818101600586901b820183018760005b88811015611e6f57848303601f190184528135368b9003601e19018112611e2657600080fd5b8a01803567ffffffffffffffff811115611e3f57600080fd5b8036038c1315611e4e57600080fd5b611e5b85828a8501611d3b565b958801959450505090850190600101611e00565b5050809450505050509b9a5050505050505050505050565b60008219821115611e9a57611e9a611c7a565b500190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b600082611f0457634e487b7160e01b600052601260045260246000fd5b50049056fea264697066735822122080da2d173e8a3678490d1bba1778aecda04e4b4a98d863e10c49639aad6d265d64736f6c63430008090033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a95760003560e01c80639386775a116100f9578063c1b4a1e311610097578063ca6d56dc11610071578063ca6d56dc14610401578063dc8452cd14610414578063e78cea921461041d578063f2fde38b1461043057600080fd5b8063c1b4a1e3146103b8578063c1f0808a146103cb578063c4d66de8146103ee57600080fd5b8063a1fb4acb116100d3578063a1fb4acb1461034c578063a230c5241461035f578063a93585f014610382578063ba51a6df146103a557600080fd5b80639386775a146102f65780639dc8f9c8146103245780639eab52531461033757600080fd5b8063681fc921116101665780637b6d343a116101405780637b6d343a146102ac5780638da5cb5b146102bf5780638dd14802146102d05780638f32d59b146102e357600080fd5b8063681fc9211461027b578063715018a61461029157806379d9ee721461029957600080fd5b806309c69cfa146101ae5780630b1ca49a146101d65780631b4613cb146101eb5780633f78f0691461021957806354fd4d501461022c5780635daf08ca14610250575b600080fd5b6101c16101bc3660046118ac565b610443565b60405190151581526020015b60405180910390f35b6101e96101e43660046118e3565b61048d565b005b6101c16101f9366004611907565b600090815260386020908152604080832033845290915290205460ff1690565b6101e9610227366004611939565b6107cb565b6040805180820182526002815261763360f01b602082015290516101cd91906119c4565b61026361025e366004611907565b610a0b565b6040516001600160a01b0390911681526020016101cd565b610283603281565b6040519081526020016101cd565b6101e9610a35565b6101e96102a7366004611a65565b610aa9565b6101c16102ba3660046118ac565b610bbb565b6033546001600160a01b0316610263565b6101e96102de3660046118e3565b610bea565b6033546001600160a01b031633146101c1565b6101c1610304366004611b54565b603860209081526000928352604080842090915290825290205460ff1681565b610283610332366004611939565b610c20565b61033f610cad565b6040516101cd9190611b84565b61028361035a366004611907565b610d0f565b6101c161036d3660046118e3565b60376020526000908152604090205460ff1681565b6101c1610390366004611907565b60009081526039602052604090205460ff1690565b6101e96103b3366004611907565b610d97565b6101e96103c6366004611bd1565b610eb9565b6101c16103d9366004611907565b60396020526000908152604090205460ff1681565b6101e96103fc3660046118e3565b6111dc565b6101e961040f3660046118e3565b611292565b61028360365481565b603454610263906001600160a01b031681565b6101e961043e3660046118e3565b61145e565b600081815260386020908152604080832033845290915281205460ff16806104845750600083815260386020908152604080832033845290915290205460ff165b90505b92915050565b6033546001600160a01b031633146104c05760405162461bcd60e51b81526004016104b790611c45565b60405180910390fd5b6001600160a01b0381166105115760405162461bcd60e51b81526020600482015260186024820152772332b232b930ba34b7b71d1022b6b83a3c9036b2b6b132b960411b60448201526064016104b7565b6001600160a01b03811660009081526037602052604090205460ff166105835760405162461bcd60e51b815260206004820152602160248201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746044820152607360f81b60648201526084016104b7565b6035546001106105e65760405162461bcd60e51b815260206004820152602860248201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604482015267206d656d6265727360c01b60648201526084016104b7565b6036546035546105f890600190611c90565b10156106605760405162461bcd60e51b815260206004820152603160248201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604482015270207265717569726564206d656d6265727360781b60648201526084016104b7565b6001600160a01b0381166000908152603760205260408120805460ff191690555b60355461069090600190611c90565b81101561076057816001600160a01b0316603582815481106106b4576106b4611ca7565b6000918252602090912001546001600160a01b0316141561074e57603580546106df90600190611c90565b815481106106ef576106ef611ca7565b600091825260209091200154603580546001600160a01b03909216918390811061071b5761071b611ca7565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610760565b8061075881611cbd565b915050610681565b50603580548061077257610772611cd8565b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b3360009081526037602052604090205460ff166108265760405162461bcd60e51b81526020600482015260196024820152782332b232b930ba34b7b71d102737ba102332b232b930ba37b960391b60448201526064016104b7565b61082f81611491565b6040516bffffffffffffffffffffffff1960608b811b821660208401528a811b8216603484015289901b166048820152605c8101879052607c8101869052609c81018590526001600160e01b031960e085901b1660bc82015260009060c00160405160208183030381529060405280519060200120905060006108b98b8b8b8b8b8b8b8b8b610c20565b90506108c58282610bbb565b156108d1575050610a00565b6108db8282610443565b156108e7575050610a00565b6000818152603860205260408120600191336001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558086336001600160a01b03167fa7be469662a3e5b2343dce0cefce9d3e114875d7334d8d724d3838cf629c5b108e8e8e8e8e8d8d8d60405161096a989796959493929190611cee565b60405180910390a461097c82826114e0565b156109fd576000818152603960205260409020805460ff191660011790556109ab8b8b8b8b8b8b8b8b8b611600565b8086336001600160a01b03167f0fe3e5a751f4df1a701ea5d318482623b6a6b59ece98cb64169279b44219355e8e8e8e8e8e8d8d8d6040516109f4989796959493929190611cee565b60405180910390a45b50505b505050505050505050565b60358181548110610a1b57600080fd5b6000918252602090912001546001600160a01b0316905081565b6033546001600160a01b03163314610a5f5760405162461bcd60e51b81526004016104b790611c45565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b3360009081526037602052604090205460ff16610b045760405162461bcd60e51b81526020600482015260196024820152782332b232b930ba34b7b71d102737ba102332b232b930ba37b960391b60448201526064016104b7565b8483148015610b1257508481145b610b5e5760405162461bcd60e51b815260206004820152601c60248201527f46656465726174696f6e3a204c656e677468206d6973736d617463680000000060448201526064016104b7565b336001600160a01b03167f909659508bf1f4c0ad9b406809f943832e107af28b0b436d9b7d56d3993c77f146438b8b8b8b8b8b8b8b604051610ba99a99989796959493929190611d9a565b60405180910390a25050505050505050565b60008181526039602052604081205460ff16806104845750505060009081526039602052604090205460ff1690565b6033546001600160a01b03163314610c145760405162461bcd60e51b81526004016104b790611c45565b610c1d816116ab565b50565b604080516bffffffffffffffffffffffff1960609b8c1b81166020808401919091529a8c1b8116603483015298909a1b90971660488a0152605c890195909552607c880193909352609c8701919091526001600160e01b031960e091821b1660bc87015260c086019190915280850191909152815180850390910181526101009093019052815191012090565b60606035805480602002602001604051908101604052809291908181526020018280548015610d0557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ce7575b5050505050905090565b600080805b603554811015610d905760008481526038602052604081206035805491929184908110610d4357610d43611ca7565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610d7e57610d7b600183611e87565b91505b80610d8881611cbd565b915050610d14565b5092915050565b6033546001600160a01b03163314610dc15760405162461bcd60e51b81526004016104b790611c45565b60355481818111801590610dd457508015155b8015610ddf57508115155b610e2b5760405162461bcd60e51b815260206004820181905260248201527f46656465726174696f6e3a20496e76616c696420726571756972656d656e747360448201526064016104b7565b6002831015610e7c5760405162461bcd60e51b815260206004820152601f60248201527f46656465726174696f6e3a205265717569726573206174206c6561737420320060448201526064016104b7565b60368390556040518381527fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9060200160405180910390a1505050565b8383818111801590610eca57508015155b8015610ed557508115155b610f215760405162461bcd60e51b815260206004820181905260248201527f46656465726174696f6e3a20496e76616c696420726571756972656d656e747360448201526064016104b7565b600054610100900460ff1680610f3a575060005460ff16155b610f565760405162461bcd60e51b81526004016104b790611e9f565b600054610100900460ff16158015610f78576000805461ffff19166101011790555b610f81846111dc565b6032871115610fd25760405162461bcd60e51b815260206004820152601c60248201527f46656465726174696f6e3a20546f6f206d616e79206d656d626572730000000060448201526064016104b7565b610fde60358989611834565b5060005b8781101561117e57603760008a8a8481811061100057611000611ca7565b905060200201602081019061101591906118e3565b6001600160a01b0316815260208101919091526040016000205460ff1615801561106f5750600089898381811061104e5761104e611ca7565b905060200201602081019061106391906118e3565b6001600160a01b031614155b6110bb5760405162461bcd60e51b815260206004820152601b60248201527f46656465726174696f6e3a20496e76616c6964206d656d62657273000000000060448201526064016104b7565b6001603760008b8b858181106110d3576110d3611ca7565b90506020020160208101906110e891906118e3565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905588888281811061112257611122611ca7565b905060200201602081019061113791906118e3565b6001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a28061117681611cbd565b915050610fe2565b5060368690556040518681527fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9060200160405180910390a16111c0856116ab565b80156111d2576000805461ff00191690555b5050505050505050565b600054610100900460ff16806111f5575060005460ff16155b6112115760405162461bcd60e51b81526004016104b790611e9f565b600054610100900460ff16158015611233576000805461ffff19166101011790555b603380546001600160a01b0319166001600160a01b0384169081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3801561128e576000805461ff00191690555b5050565b6033546001600160a01b031633146112bc5760405162461bcd60e51b81526004016104b790611c45565b6001600160a01b03811661130d5760405162461bcd60e51b81526020600482015260186024820152772332b232b930ba34b7b71d1022b6b83a3c9036b2b6b132b960411b60448201526064016104b7565b6001600160a01b03811660009081526037602052604090205460ff16156113805760405162461bcd60e51b815260206004820152602160248201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746044820152607360f81b60648201526084016104b7565b6035546032116113d25760405162461bcd60e51b815260206004820152601f60248201527f46656465726174696f6e3a204d6178206d656d6265727320726561636865640060448201526064016104b7565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b6033546001600160a01b031633146114885760405162461bcd60e51b81526004016104b790611c45565b610c1d81611755565b468114610c1d5760405162461bcd60e51b815260206004820152601d60248201527f46656465726174696f6e3a204e6f7420626c6f636b2e636861696e696400000060448201526064016104b7565b6000806114eb611812565b90506000805b6035548110156115f4576000858152603860205260408120603580549192918490811061152057611520611ca7565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff161561155f57611558600183611e87565b91506115bf565b6000868152603860205260408120603580549192918490811061158457611584611ca7565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156115bf576115bc600183611e87565b91505b8282101580156115d157506036548210155b156115e25760019350505050610487565b806115ec81611cbd565b9150506114f1565b50600095945050505050565b60345460405163048aa97560e21b81526001600160a01b038b811660048301528a811660248301528981166044830152606482018990526084820188905260a4820187905263ffffffff861660c483015260e4820185905261010482018490529091169063122aa5d49061012401600060405180830381600087803b15801561168857600080fd5b505af115801561169c573d6000803e3d6000fd5b50505050505050505050505050565b6001600160a01b0381166117015760405162461bcd60e51b815260206004820152601860248201527f46656465726174696f6e3a20456d70747920627269646765000000000000000060448201526064016104b7565b603480546001600160a01b0319166001600160a01b0383169081179091556040519081527f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b925517827944979060200160405180910390a150565b6001600160a01b0381166117b65760405162461bcd60e51b815260206004820152602260248201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604482015261737360f01b60648201526084016104b7565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b60355460009061182490600290611ee7565b61182f906001611e87565b905090565b828054828255906000526020600020908101928215611887579160200282015b828111156118875781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190611854565b50611893929150611897565b5090565b5b808211156118935760008155600101611898565b600080604083850312156118bf57600080fd5b50508035926020909101359150565b6001600160a01b0381168114610c1d57600080fd5b6000602082840312156118f557600080fd5b8135611900816118ce565b9392505050565b60006020828403121561191957600080fd5b5035919050565b803563ffffffff8116811461193457600080fd5b919050565b60008060008060008060008060006101208a8c03121561195857600080fd5b8935611963816118ce565b985060208a0135611973816118ce565b975060408a0135611983816118ce565b965060608a0135955060808a0135945060a08a013593506119a660c08b01611920565b925060e08a013591506101008a013590509295985092959850929598565b600060208083528351808285015260005b818110156119f1578581018301518582016040015282016119d5565b81811115611a03576000604083870101525b50601f01601f1916929092016040019392505050565b60008083601f840112611a2b57600080fd5b50813567ffffffffffffffff811115611a4357600080fd5b6020830191508360208260051b8501011115611a5e57600080fd5b9250929050565b6000806000806000806000806080898b031215611a8157600080fd5b883567ffffffffffffffff80821115611a9957600080fd5b818b0191508b601f830112611aad57600080fd5b813581811115611abc57600080fd5b8c6020828501011115611ace57600080fd5b60209283019a509850908a01359080821115611ae957600080fd5b611af58c838d01611a19565b909850965060408b0135915080821115611b0e57600080fd5b611b1a8c838d01611a19565b909650945060608b0135915080821115611b3357600080fd5b50611b408b828c01611a19565b999c989b5096995094979396929594505050565b60008060408385031215611b6757600080fd5b823591506020830135611b79816118ce565b809150509250929050565b6020808252825182820181905260009190848201906040850190845b81811015611bc55783516001600160a01b031683529284019291840191600101611ba0565b50909695505050505050565b600080600080600060808688031215611be957600080fd5b853567ffffffffffffffff811115611c0057600080fd5b611c0c88828901611a19565b909650945050602086013592506040860135611c27816118ce565b91506060860135611c37816118ce565b809150509295509295909350565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082821015611ca257611ca2611c7a565b500390565b634e487b7160e01b600052603260045260246000fd5b6000600019821415611cd157611cd1611c7a565b5060010190565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b03988916815296881660208801529490961660408601526060850192909252608084015263ffffffff1660a083015260c082019290925260e08101919091526101000190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b81835260006001600160fb1b03831115611d7d57600080fd5b8260051b8083602087013760009401602001938452509192915050565b8a8152600060208b8184015260c06040840152611dbb60c084018b8d611d3b565b8381036060850152611dce818a8c611d64565b90508381036080850152611de381888a611d64565b84810360a08601528581529050818101600586901b820183018760005b88811015611e6f57848303601f190184528135368b9003601e19018112611e2657600080fd5b8a01803567ffffffffffffffff811115611e3f57600080fd5b8036038c1315611e4e57600080fd5b611e5b85828a8501611d3b565b958801959450505090850190600101611e00565b5050809450505050509b9a5050505050505050505050565b60008219821115611e9a57611e9a611c7a565b500190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b600082611f0457634e487b7160e01b600052601260045260246000fd5b50049056fea264697066735822122080da2d173e8a3678490d1bba1778aecda04e4b4a98d863e10c49639aad6d265d64736f6c63430008090033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "addMember(address)": {
+ "params": {
+ "_newMember": "address of the new member"
+ }
+ },
+ "changeRequirement(uint256)": {
+ "details": "Emits the RequirementChange event",
+ "params": {
+ "_required": "the number of minimum members to approve an transaction, it has to be bigger than 1"
+ }
+ },
+ "emitHeartbeat(string,uint256[],uint256[],string[])": {
+ "details": "Emits HeartBeat event"
+ },
+ "getMembers()": {
+ "returns": {
+ "_0": "Current members"
+ }
+ },
+ "getTransactionCount(bytes32)": {
+ "params": {
+ "transactionId": "The transaction hashed from getTransactionId function"
+ }
+ },
+ "getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)": {
+ "details": "It encodes and applies keccak256 to the parameters received in the same order",
+ "params": {
+ "amount": "Could be the amount or the tokenId",
+ "blockHash": "The block hash in which the transaction with the cross event occurred",
+ "destinationChainId": "Is chainId of the destination chain",
+ "logIndex": "Index of the event in the logs",
+ "originChainId": "Is chainId of the original chain",
+ "originalTokenAddress": "The address of the token in the origin (main) chain",
+ "receiver": "Who is going to receive the token in the opposite chain",
+ "sender": "The address who solicited the cross token",
+ "transactionHash": "The transaction in which the cross event occurred"
+ },
+ "returns": {
+ "_0": "The hash generated by the parameters."
+ }
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "removeMember(address)": {
+ "params": {
+ "_oldMember": "address of the member to be removed from federation"
+ }
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "setBridge(address)": {
+ "details": "Emits BridgeChanged event",
+ "params": {
+ "_bridge": "the new bridge contract address that should implement the IBridge interface"
+ }
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "version()": {
+ "returns": {
+ "_0": "version in v{Number}"
+ }
+ },
+ "voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)": {
+ "params": {
+ "blockHash": "The block hash in which the transaction with the cross event occurred",
+ "destinationChainId": "Is chainId of the destination chain",
+ "logIndex": "Index of the event in the logs",
+ "originChainId": "Is chainId of the original chain",
+ "originalTokenAddress": "The address of the token in the origin (main) chain",
+ "receiver": "Who is going to receive the token in the opposite chain",
+ "sender": "The address who solicited the cross token",
+ "transactionHash": "The transaction in which the cross event occurred",
+ "value": "Amount"
+ }
+ }
+ },
+ "stateVariables": {
+ "isMember": {
+ "details": "The address should be a member to vote in transactions"
+ },
+ "required": {
+ "details": "It should have at least the required amount of members"
+ },
+ "votes": {
+ "details": "the members should approve the transaction by 50% + 1"
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "addMember(address)": {
+ "notice": "Add a new member to the federation"
+ },
+ "changeRequirement(uint256)": {
+ "notice": "Changes the number of required members to vote and approve an transaction"
+ },
+ "emitHeartbeat(string,uint256[],uint256[],string[])": {
+ "notice": "It emits an HeartBeat like an health check"
+ },
+ "getMembers()": {
+ "notice": "Return all the current members of the federation"
+ },
+ "getTransactionCount(bytes32)": {
+ "notice": "Get the amount of approved votes for that transactionId"
+ },
+ "getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)": {
+ "notice": "Gets the hash of transaction from the following parameters encoded and keccaked"
+ },
+ "isMember(address)": {
+ "notice": "All the addresses that are members of the federation"
+ },
+ "processed(bytes32)": {
+ "notice": "(bytes32) transactionId => (bool) votedCheck if that transaction was already processed"
+ },
+ "removeMember(address)": {
+ "notice": "Remove a member of the federation"
+ },
+ "required()": {
+ "notice": "The minimum amount of votes to approve a transaction"
+ },
+ "setBridge(address)": {
+ "notice": "Sets a new bridge contract"
+ },
+ "version()": {
+ "notice": "Current version of the contract"
+ },
+ "voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint256,uint256)": {
+ "notice": "Vote in a transaction, if it has enough votes it accepts the transfer"
+ },
+ "votes(bytes32,address)": {
+ "notice": "(bytes32) transactionId = keccak256( abi.encodePacked( originalTokenAddress, sender, receiver, amount, blockHash, transactionHash, logIndex ) ) => ( (address) members => (bool) voted )Votes by members by the transaction ID"
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 14589,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 14592,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 14632,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 14878,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 5025,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "bridge",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_contract(IBridge)7435"
+ },
+ {
+ "astId": 5028,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "members",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 5031,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "required",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 5036,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "isMember",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 5043,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "votes",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_mapping(t_bytes32,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 5048,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "processed",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IBridge)7435": {
+ "encoding": "inplace",
+ "label": "contract IBridge",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/FederationProxy.json b/bridge/deployments/rsktestnet/FederationProxy.json
new file mode 100644
index 000000000..4dcb406c6
--- /dev/null
+++ b/bridge/deployments/rsktestnet/FederationProxy.json
@@ -0,0 +1,257 @@
+{
+ "address": "0x5d663981d930e8ec108280b9d80885658148ab0f",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "transactionIndex": 0,
+ "gasUsed": "895606",
+ "logsBloom": "0x00000000000000000001000000008000000100000000000000800000000000000000000000000000000000000000000000000000000000000080000000000000000000800000000000000000000000100001000000000000000000000000000000000000020000000000000000040800000000000000000000000000000000400000000000000000000020008000000000000000000000000000000000000000000000000000000000000000000000000000008000008000000010800000000000000040000000000000000000000100000000000000000000000000000020000010000000000000000000000000000100000000000000000800000000000000",
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4",
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152252,
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "address": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x00000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152252,
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "address": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "topics": [
+ "0x72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c7",
+ "0x0000000000000000000000008f397ff074ff190fc650e5cab4da039a8163e12a"
+ ],
+ "data": "0x",
+ "logIndex": 1,
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152252,
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "address": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "topics": [
+ "0xa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "logIndex": 2,
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152252,
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "address": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "topics": [
+ "0x9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b92551782794497"
+ ],
+ "data": "0x0000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf63",
+ "logIndex": 3,
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4"
+ }
+ ],
+ "blockNumber": 2152252,
+ "cumulativeGasUsed": "895606",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0x9c36A1E78D68417396FE6c715A5515d659973cF6",
+ "0x8c35e166d2dea7a8a28aaea11ad7933cdae4b0ab",
+ "0xc1b4a1e3000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf6300000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000008f397ff074ff190fc650e5cab4da039a8163e12a"
+ ],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"stateVariables\":{\"_ADMIN_SLOT\":{\"details\":\"Storage slot with the admin of the contract. This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0x590a4d952d39a99972cbcb691b472c5d58af9ae8fd142355ad26200affdd2a51\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x0d5202a38732881d576fe3831605fe2633e1bc9f981ebea9c3a368af027e0b71\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x53b00bc48bd4eac1e100195c494267c0ca082bd91ac3018e2ee6155fbcbbb14f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000c9f38038062000c9f83398101604081905262000026916200022e565b8281620000338262000071565b8051156200005457620000528282620000d360201b620002ca1760201c565b505b506200005d9050565b620000688262000102565b5050506200041d565b62000087816200012660201b620002f61760201c565b620000af5760405162461bcd60e51b8152600401620000a69062000347565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6060620000fb838360405180606001604052806027815260200162000c786027913962000130565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b60606200013d8462000126565b6200015c5760405162461bcd60e51b8152600401620000a690620003a4565b600080856001600160a01b031685604051620001799190620002f4565b600060405180830381855af49150503d8060008114620001b6576040519150601f19603f3d011682016040523d82523d6000602084013e620001bb565b606091505b509092509050620001ce828286620001d8565b9695505050505050565b60608315620001e9575081620000fb565b825115620001fa5782518084602001fd5b8160405162461bcd60e51b8152600401620000a6919062000312565b80516001600160a01b03811681146200012b57600080fd5b60008060006060848603121562000243578283fd5b6200024e8462000216565b92506200025e6020850162000216565b60408501519092506001600160401b03808211156200027b578283fd5b818601915086601f8301126200028f578283fd5b8151818111156200029c57fe5b604051601f8201601f191681016020018381118282101715620002bb57fe5b604052818152838201602001891015620002d3578485fd5b620002e6826020830160208701620003ea565b809450505050509250925092565b6000825162000308818460208701620003ea565b9190910192915050565b600060208252825180602084015262000333816040850160208701620003ea565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b8381101562000407578181015183820152602001620003ed565b8381111562000417576000848401525b50505050565b61084b806200042d6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fabbc30a04f636413f38ca4eda3e460473659576ddb6aaf9066d31235c793fc064736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fabbc30a04f636413f38ca4eda3e460473659576ddb6aaf9066d31235c793fc064736f6c63430007060033",
+ "devdoc": {
+ "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.",
+ "events": {
+ "AdminChanged(address,address)": {
+ "details": "Emitted when the admin account has changed."
+ }
+ },
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "constructor": {
+ "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "stateVariables": {
+ "_ADMIN_SLOT": {
+ "details": "Storage slot with the admin of the contract. This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/FederationV2.json b/bridge/deployments/rsktestnet/FederationV2.json
new file mode 100644
index 000000000..494691d2e
--- /dev/null
+++ b/bridge/deployments/rsktestnet/FederationV2.json
@@ -0,0 +1,905 @@
+{
+ "address": "0x28d2f02381915275b2a42798739b0522fcb39339",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridge",
+ "type": "address"
+ }
+ ],
+ "name": "BridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Executed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "HeartBeat",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Voted",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_MEMBER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_newMember",
+ "type": "address"
+ }
+ ],
+ "name": "addMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridge",
+ "outputs": [
+ {
+ "internalType": "contract IBridge",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "emitHeartbeat",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getMembers",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "getTransactionId",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_members",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isMember",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "members",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "processed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_oldMember",
+ "type": "address"
+ }
+ ],
+ "name": "removeMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ }
+ ],
+ "name": "setBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionWasProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "voteTransaction",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "votes",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x19d064fe48152b878f3d9335a6bce717230a681f843f53eb17cbea04811f51cd",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x9c36A1E78D68417396FE6c715A5515d659973cF6",
+ "transactionIndex": 0,
+ "gasUsed": "1897118",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x8342e7f56adeebb21f7cf5af57f5fc1054b18f7c52c89d995cab2c19280d17e0",
+ "transactionHash": "0x19d064fe48152b878f3d9335a6bce717230a681f843f53eb17cbea04811f51cd",
+ "logs": [],
+ "blockNumber": 2152180,
+ "cumulativeGasUsed": "1897118",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"bridge\",\"type\":\"address\"}],\"name\":\"BridgeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"Executed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fedRskBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fedEthBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"federatorVersion\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"nodeRskInfo\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"nodeEthInfo\",\"type\":\"string\"}],\"name\":\"HeartBeat\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"Voted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MEMBER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newMember\",\"type\":\"address\"}],\"name\":\"addMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contract IBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fedRskBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fedEthBlock\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"federatorVersion\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nodeRskInfo\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nodeEthInfo\",\"type\":\"string\"}],\"name\":\"emitHeartbeat\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMembers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"getTransactionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"hasVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_members\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMember\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"members\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"processed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_oldMember\",\"type\":\"address\"}],\"name\":\"removeMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"name\":\"setBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"transactionWasProcessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"voteTransaction\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"votes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Federation/FederationV2.sol\":\"FederationV2\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Federation/FederationV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n// Upgradables\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\n\\nimport \\\"../interface/IBridge.sol\\\";\\n\\ncontract FederationV2 is Initializable, UpgradableOwnable {\\n uint constant public MAX_MEMBER_COUNT = 50;\\n address constant private NULL_ADDRESS = address(0);\\n\\n IBridge public bridge;\\n address[] public members;\\n uint public required;\\n\\n mapping (address => bool) public isMember;\\n mapping (bytes32 => mapping (address => bool)) public votes;\\n mapping(bytes32 => bool) public processed;\\n\\n event Executed(\\n address indexed federator,\\n bytes32 indexed transactionHash,\\n bytes32 indexed transactionId,\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n uint32 logIndex\\n );\\n event MemberAddition(address indexed member);\\n event MemberRemoval(address indexed member);\\n event RequirementChange(uint required);\\n event BridgeChanged(address bridge);\\n event Voted(\\n address indexed federator,\\n bytes32 indexed transactionHash,\\n bytes32 indexed transactionId,\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n uint32 logIndex\\n );\\n event HeartBeat(\\n address indexed sender,\\n uint256 fedRskBlock,\\n uint256 fedEthBlock,\\n string federatorVersion,\\n string nodeRskInfo,\\n string nodeEthInfo\\n );\\n\\n modifier onlyMember() {\\n require(isMember[_msgSender()], \\\"Federation: Not Federator\\\");\\n _;\\n }\\n\\n modifier validRequirement(uint membersCount, uint _required) {\\n // solium-disable-next-line max-len\\n require(_required <= membersCount && _required != 0 && membersCount != 0, \\\"Federation: Invalid requirements\\\");\\n _;\\n }\\n\\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\\n public validRequirement(_members.length, _required) initializer {\\n UpgradableOwnable.initialize(owner);\\n require(_members.length <= MAX_MEMBER_COUNT, \\\"Federation: Too many members\\\");\\n members = _members;\\n for (uint i = 0; i < _members.length; i++) {\\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \\\"Federation: Invalid members\\\");\\n isMember[_members[i]] = true;\\n emit MemberAddition(_members[i]);\\n }\\n required = _required;\\n emit RequirementChange(required);\\n _setBridge(_bridge);\\n }\\n\\n function version() external pure returns (string memory) {\\n return \\\"v2\\\";\\n }\\n\\n function setBridge(address _bridge) external onlyOwner {\\n _setBridge(_bridge);\\n }\\n\\n function _setBridge(address _bridge) internal {\\n require(_bridge != NULL_ADDRESS, \\\"Federation: Empty bridge\\\");\\n bridge = IBridge(_bridge);\\n emit BridgeChanged(_bridge);\\n }\\n\\n function voteTransaction(\\n address originalTokenAddress,\\n address payable sender,\\n address payable receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n bytes32 transactionHash,\\n uint32 logIndex\\n )\\n public onlyMember returns(bool)\\n {\\n bytes32 transactionId = getTransactionId(\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n transactionHash,\\n logIndex\\n );\\n if (processed[transactionId])\\n return true;\\n\\n if (votes[transactionId][_msgSender()])\\n return true;\\n\\n votes[transactionId][_msgSender()] = true;\\n emit Voted(\\n _msgSender(),\\n transactionHash,\\n transactionId,\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n logIndex\\n );\\n\\n uint transactionCount = getTransactionCount(transactionId);\\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\\n processed[transactionId] = true;\\n bridge.acceptTransfer(\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n transactionHash,\\n logIndex\\n );\\n emit Executed(\\n _msgSender(),\\n transactionHash,\\n transactionId,\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n logIndex\\n );\\n return true;\\n }\\n\\n return true;\\n }\\n\\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\\n uint count = 0;\\n for (uint i = 0; i < members.length; i++) {\\n if (votes[transactionId][members[i]])\\n count += 1;\\n }\\n return count;\\n }\\n\\n function hasVoted(bytes32 transactionId) external view returns(bool)\\n {\\n return votes[transactionId][_msgSender()];\\n }\\n\\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\\n {\\n return processed[transactionId];\\n }\\n\\n function getTransactionId(\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n bytes32 transactionHash,\\n uint32 logIndex\\n ) public pure returns(bytes32)\\n {\\n return keccak256(\\n abi.encodePacked(\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n transactionHash,\\n logIndex\\n )\\n );\\n }\\n\\n function addMember(address _newMember) external onlyOwner\\n {\\n require(_newMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\n require(!isMember[_newMember], \\\"Federation: Member already exists\\\");\\n require(members.length < MAX_MEMBER_COUNT, \\\"Federation: Max members reached\\\");\\n\\n isMember[_newMember] = true;\\n members.push(_newMember);\\n emit MemberAddition(_newMember);\\n }\\n\\n function removeMember(address _oldMember) external onlyOwner\\n {\\n require(_oldMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\n require(isMember[_oldMember], \\\"Federation: Member doesn't exists\\\");\\n require(members.length > 1, \\\"Federation: Can't remove all the members\\\");\\n require(members.length - 1 >= required, \\\"Federation: Can't have less than required members\\\");\\n\\n isMember[_oldMember] = false;\\n for (uint i = 0; i < members.length - 1; i++) {\\n if (members[i] == _oldMember) {\\n members[i] = members[members.length - 1];\\n break;\\n }\\n }\\n members.pop(); // remove an element from the end of the array.\\n emit MemberRemoval(_oldMember);\\n }\\n\\n function getMembers() external view returns (address[] memory)\\n {\\n return members;\\n }\\n\\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\\n {\\n require(_required >= 2, \\\"Federation: Requires at least 2\\\");\\n required = _required;\\n emit RequirementChange(_required);\\n }\\n\\n function emitHeartbeat(\\n uint256 fedRskBlock,\\n uint256 fedEthBlock,\\n string calldata federatorVersion,\\n string calldata nodeRskInfo,\\n string calldata nodeEthInfo\\n ) external onlyMember {\\n emit HeartBeat(\\n _msgSender(),\\n fedRskBlock,\\n fedEthBlock,\\n federatorVersion,\\n nodeRskInfo,\\n nodeEthInfo\\n );\\n }\\n}\",\"keccak256\":\"0x6f9f6a650c694e2a400fa8ea64871fb3aa19eb5610d6a3ea726318c3491c866b\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\ninterface IBridge {\\n\\n struct ClaimData {\\n address payable to;\\n uint256 amount;\\n bytes32 blockHash;\\n bytes32 transactionHash;\\n uint32 logIndex;\\n }\\n\\n function version() external pure returns (string memory);\\n\\n function getFeePercentage() external view returns(uint);\\n\\n /**\\n * ERC-20 tokens approve and transferFrom pattern\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\n */\\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\\n\\n /**\\n * Use network currency and cross it.\\n */\\n function depositTo(address to) external payable;\\n\\n /**\\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\n */\\n function tokensReceived (\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n\\n /**\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\n */\\n function acceptTransfer(\\n address _originalTokenAddress,\\n address payable _from,\\n address payable _to,\\n uint256 _amount,\\n bytes32 _blockHash,\\n bytes32 _transactionHash,\\n uint32 _logIndex\\n ) external;\\n\\n /**\\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\n */\\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n function claimGasless(\\n ClaimData calldata _claimData,\\n address payable _relayer,\\n uint256 _fee,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external returns (uint256 receivedAmount);\\n\\n function getTransactionDataHash(\\n address _to,\\n uint256 _amount,\\n bytes32 _blockHash,\\n bytes32 _transactionHash,\\n uint32 _logIndex\\n ) external returns(bytes32);\\n\\n event Cross(\\n address indexed _tokenAddress,\\n address indexed _from,\\n address indexed _to,\\n uint256 _amount,\\n bytes _userData\\n );\\n event NewSideToken(\\n address indexed _newSideTokenAddress,\\n address indexed _originalTokenAddress,\\n string _newSymbol,\\n uint256 _granularity\\n );\\n event AcceptedCrossTransfer(\\n bytes32 indexed _transactionHash,\\n address indexed _originalTokenAddress,\\n address indexed _to,\\n address _from,\\n uint256 _amount,\\n bytes32 _blockHash,\\n uint256 _logIndex\\n );\\n event FeePercentageChanged(uint256 _amount);\\n event Claimed(\\n bytes32 indexed _transactionHash,\\n address indexed _originalTokenAddress,\\n address indexed _to,\\n address _sender,\\n uint256 _amount,\\n bytes32 _blockHash,\\n uint256 _logIndex,\\n address _reciever,\\n address _relayer,\\n uint256 _fee\\n );\\n}\",\"keccak256\":\"0x188bdd14d3e1d1eaddd5d86a4d957a8c6a7e6c4571058b6db13a974db3ab5f39\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\",\"keccak256\":\"0x3eeeb5ea6bf7d3458bb36acebd4268b406e6a1525e009d4d8a90626c277a37d1\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract UpgradableOwnable is Initializable, Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function initialize(address sender) public initializer {\\n _owner = sender;\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * > Note: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n\\n}\\n\",\"keccak256\":\"0x2e0e58f4a3991801550e6a52512a3c1bbcaa5cb824120c177cb6ec1b4fa0ce97\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50611afa806100206000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063a1fb4acb116100de578063c1f0808a11610097578063dc8452cd11610071578063dc8452cd14610311578063e78cea9214610319578063f2fde38b14610321578063fa6297ba1461033457610173565b8063c1f0808a146102d8578063c4d66de8146102eb578063ca6d56dc146102fe57610173565b8063a1fb4acb14610266578063a230c52414610279578063a93585f01461028c578063b9a3b9dc1461029f578063ba51a6df146102b2578063c1b4a1e3146102c557610173565b8063715018a611610130578063715018a6146102135780638da5cb5b1461021b5780638dd14802146102235780638f32d59b146102365780639386775a1461023e5780639eab52531461025157610173565b80630b1ca49a146101785780631b4613cb1461018d57806335d4aa9e146101b657806354fd4d50146101c95780635daf08ca146101de578063681fc921146101fe575b600080fd5b61018b61018636600461128b565b610347565b005b6101a061019b366004611404565b610555565b6040516101ad9190611661565b60405180910390f35b6101a06101c43660046112ae565b610591565b6101d161080b565b6040516101ad9190611675565b6101f16101ec366004611404565b610827565b6040516101ad919061157c565b610206610851565b6040516101ad919061166c565b61018b610856565b6101f16108c4565b61018b61023136600461128b565b6108d3565b6101a0610903565b6101a061024c36600461141c565b610929565b610259610949565b6040516101ad9190611614565b610206610274366004611404565b6109ab565b6101a061028736600461128b565b610a1c565b6101a061029a366004611404565b610a31565b61018b6102ad36600461144b565b610a46565b61018b6102c0366004611404565b610aeb565b61018b6102d3366004611324565b610bac565b6101a06102e6366004611404565b610e1a565b61018b6102f936600461128b565b610e2f565b61018b61030c36600461128b565b610ef4565b610206611025565b6101f161102b565b61018b61032f36600461128b565b61103a565b6102066103423660046112ae565b611067565b61034f610903565b6103745760405162461bcd60e51b815260040161036b906118f4565b60405180910390fd5b6001600160a01b03811661039a5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff166103d25760405162461bcd60e51b815260040161036b9061176b565b6035546001106103f45760405162461bcd60e51b815260040161036b90611997565b60365460355460001901101561041c5760405162461bcd60e51b815260040161036b906118a3565b6001600160a01b0381166000908152603760205260408120805460ff191690555b603554600019018110156104f057816001600160a01b03166035828154811061046257fe5b6000918252602090912001546001600160a01b031614156104e85760358054600019810190811061048f57fe5b600091825260209091200154603580546001600160a01b0390921691839081106104b557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506104f0565b60010161043d565b5060358054806104fc57fe5b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b60008181526038602052604081208161056c6110a9565b6001600160a01b0316815260208101919091526040016000205460ff1690505b919050565b60006037600061059f6110a9565b6001600160a01b0316815260208101919091526040016000205460ff166105d85760405162461bcd60e51b815260040161036b90611a21565b60006105e989898989898989611067565b60008181526039602052604090205490915060ff161561060d576001915050610800565b6000818152603860205260408120906106246110a9565b6001600160a01b0316815260208101919091526040016000205460ff1615610650576001915050610800565b60008181526038602052604081206001916106696110a9565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055808461069b6110a9565b6001600160a01b03167fd22894491aaa5bb67855bcff4b9730bdf7768be1e25f66ced9a7d7ad623bf2918c8c8c8c8c8b6040516106dd969594939291906115d6565b60405180910390a460006106f0826109ab565b9050603654811015801561070d5750603554600290046001018110155b156107f95760008281526039602052604090819020805460ff191660011790556034549051636a86319160e01b81526001600160a01b0390911690636a86319190610768908d908d908d908d908d908d908d90600401611590565b600060405180830381600087803b15801561078257600080fd5b505af1158015610796573d6000803e3d6000fd5b5050505081856107a46110a9565b6001600160a01b03167fe21e4d3d66ef78424137270e65cfafe938736bb770702ab4fd630383e7820b738d8d8d8d8d8c6040516107e6969594939291906115d6565b60405180910390a4600192505050610800565b6001925050505b979650505050505050565b6040805180820190915260028152613b1960f11b602082015290565b6035818154811061083757600080fd5b6000918252602090912001546001600160a01b0316905081565b603281565b61085e610903565b61087a5760405162461bcd60e51b815260040161036b906118f4565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6108db610903565b6108f75760405162461bcd60e51b815260040161036b906118f4565b610900816110ad565b50565b6033546000906001600160a01b031661091a6110a9565b6001600160a01b031614905090565b603860209081526000928352604080842090915290825290205460ff1681565b606060358054806020026020016040519081016040528092919081815260200182805480156109a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610983575b5050505050905090565b600080805b603554811015610a1557600084815260386020526040812060358054919291849081106109d957fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0d576001820191505b6001016109b0565b5092915050565b60376020526000908152604090205460ff1681565b60009081526039602052604090205460ff1690565b60376000610a526110a9565b6001600160a01b0316815260208101919091526040016000205460ff16610a8b5760405162461bcd60e51b815260040161036b90611a21565b610a936110a9565b6001600160a01b03167fbb00e6cbdccbb5b7549e189335249187223d88583604555326aa1d7ccbcad4428989898989898989604051610ad9989796959493929190611a58565b60405180910390a25050505050505050565b610af3610903565b610b0f5760405162461bcd60e51b815260040161036b906118f4565b60355481818111801590610b2257508015155b8015610b2d57508115155b610b495760405162461bcd60e51b815260040161036b906116c8565b6002831015610b6a5760405162461bcd60e51b815260040161036b90611929565b60368390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610b9f90859061166c565b60405180910390a1505050565b835183818111158015610bbe57508015155b8015610bc957508115155b610be55760405162461bcd60e51b815260040161036b906116c8565b600054610100900460ff1680610bfe575060005460ff16155b610c1a5760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610c45576000805460ff1961ff0019909116610100171660011790555b610c4e84610e2f565b603287511115610c705760405162461bcd60e51b815260040161036b90611734565b8651610c839060359060208a01906111ab565b5060005b8751811015610db85760376000898381518110610ca057fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015610cfa575060006001600160a01b0316888281518110610ce657fe5b60200260200101516001600160a01b031614155b610d165760405162461bcd60e51b815260040161036b906117f4565b6001603760008a8481518110610d2857fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550878181518110610d7357fe5b60200260200101516001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a2600101610c87565b5060368690556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610dee90889061166c565b60405180910390a1610dff856110ad565b8015610e11576000805461ff00191690555b50505050505050565b60396020526000908152604090205460ff1681565b600054610100900460ff1680610e48575060005460ff16155b610e645760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610e8f576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610ef0576000805461ff00191690555b5050565b610efc610903565b610f185760405162461bcd60e51b815260040161036b906118f4565b6001600160a01b038116610f3e5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff1615610f775760405162461bcd60e51b815260040161036b9061182b565b603554603211610f995760405162461bcd60e51b815260040161036b906116fd565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b60365481565b6034546001600160a01b031681565b611042610903565b61105e5760405162461bcd60e51b815260040161036b906118f4565b61090081611129565b600087878787878787604051602001611086979695949392919061151e565b604051602081830303815290604052805190602001209050979650505050505050565b3390565b6001600160a01b0381166110d35760405162461bcd60e51b815260040161036b9061186c565b603480546001600160a01b0319166001600160a01b0383161790556040517f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b925517827944979061111e90839061157c565b60405180910390a150565b6001600160a01b03811661114f5760405162461bcd60e51b815260040161036b906119df565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b828054828255906000526020600020908101928215611200579160200282015b8281111561120057825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906111cb565b5061120c929150611210565b5090565b5b8082111561120c5760008155600101611211565b803561058c81611aaf565b60008083601f840112611241578182fd5b50813567ffffffffffffffff811115611258578182fd5b60208301915083602082850101111561127057600080fd5b9250929050565b803563ffffffff8116811461058c57600080fd5b60006020828403121561129c578081fd5b81356112a781611aaf565b9392505050565b600080600080600080600060e0888a0312156112c8578283fd5b87356112d381611aaf565b965060208801356112e381611aaf565b955060408801356112f381611aaf565b9450606088013593506080880135925060a0880135915061131660c08901611277565b905092959891949750929550565b60008060008060808587031215611339578384fd5b843567ffffffffffffffff80821115611350578586fd5b818701915087601f830112611363578586fd5b813560208282111561137157fe5b8082026040518282820101818110868211171561138a57fe5b604052838152828101945085830182870184018d10156113a8578a8bfd5b8a96505b848710156113d1576113bd81611225565b8652600196909601959483019483016113ac565b5098505088013595506113eb925050604087019050611225565b91506113f960608601611225565b905092959194509250565b600060208284031215611415578081fd5b5035919050565b6000806040838503121561142e578182fd5b82359150602083013561144081611aaf565b809150509250929050565b60008060008060008060008060a0898b031215611466578081fd5b8835975060208901359650604089013567ffffffffffffffff8082111561148b578283fd5b6114978c838d01611230565b909850965060608b01359150808211156114af578283fd5b6114bb8c838d01611230565b909650945060808b01359150808211156114d3578283fd5b506114e08b828c01611230565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b606097881b6bffffffffffffffffffffffff19908116825296881b871660148201529490961b9094166028840152603c830191909152605c820152607c81019190915260e09190911b6001600160e01b031916609c82015260a00190565b6001600160a01b0391909116815260200190565b6001600160a01b03978816815295871660208701529390951660408501526060840191909152608083015260a082019290925263ffffffff90911660c082015260e00190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925263ffffffff90911660a082015260c00190565b6020808252825182820181905260009190848201906040850190845b818110156116555783516001600160a01b031683529284019291840191600101611630565b50909695505050505050565b901515815260200190565b90815260200190565b6000602080835283518082850152825b818110156116a157858101830151858201604001528201611685565b818111156116b25783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f46656465726174696f6e3a20496e76616c696420726571756972656d656e7473604082015260600190565b6020808252601f908201527f46656465726174696f6e3a204d6178206d656d62657273207265616368656400604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20546f6f206d616e79206d656d6265727300000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746040820152607360f81b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252601b908201527f46656465726174696f6e3a20496e76616c6964206d656d626572730000000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746040820152607360f81b606082015260800190565b60208082526018908201527f46656465726174696f6e3a20456d707479206272696467650000000000000000604082015260600190565b60208082526031908201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604082015270207265717569726564206d656d6265727360781b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f46656465726174696f6e3a205265717569726573206174206c65617374203200604082015260600190565b60208082526018908201527f46656465726174696f6e3a20456d707479206d656d6265720000000000000000604082015260600190565b60208082526028908201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604082015267206d656d6265727360c01b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526019908201527f46656465726174696f6e3a204e6f7420466564657261746f7200000000000000604082015260600190565b600089825288602083015260a06040830152611a7860a08301888a6114f4565b8281036060840152611a8b8187896114f4565b90508281036080840152611aa08185876114f4565b9b9a5050505050505050505050565b6001600160a01b038116811461090057600080fdfea2646970667358221220128a4b4f51a83044e466d0c301c3119ae839536443710de99b33113388de820464736f6c63430007060033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101735760003560e01c8063a1fb4acb116100de578063c1f0808a11610097578063dc8452cd11610071578063dc8452cd14610311578063e78cea9214610319578063f2fde38b14610321578063fa6297ba1461033457610173565b8063c1f0808a146102d8578063c4d66de8146102eb578063ca6d56dc146102fe57610173565b8063a1fb4acb14610266578063a230c52414610279578063a93585f01461028c578063b9a3b9dc1461029f578063ba51a6df146102b2578063c1b4a1e3146102c557610173565b8063715018a611610130578063715018a6146102135780638da5cb5b1461021b5780638dd14802146102235780638f32d59b146102365780639386775a1461023e5780639eab52531461025157610173565b80630b1ca49a146101785780631b4613cb1461018d57806335d4aa9e146101b657806354fd4d50146101c95780635daf08ca146101de578063681fc921146101fe575b600080fd5b61018b61018636600461128b565b610347565b005b6101a061019b366004611404565b610555565b6040516101ad9190611661565b60405180910390f35b6101a06101c43660046112ae565b610591565b6101d161080b565b6040516101ad9190611675565b6101f16101ec366004611404565b610827565b6040516101ad919061157c565b610206610851565b6040516101ad919061166c565b61018b610856565b6101f16108c4565b61018b61023136600461128b565b6108d3565b6101a0610903565b6101a061024c36600461141c565b610929565b610259610949565b6040516101ad9190611614565b610206610274366004611404565b6109ab565b6101a061028736600461128b565b610a1c565b6101a061029a366004611404565b610a31565b61018b6102ad36600461144b565b610a46565b61018b6102c0366004611404565b610aeb565b61018b6102d3366004611324565b610bac565b6101a06102e6366004611404565b610e1a565b61018b6102f936600461128b565b610e2f565b61018b61030c36600461128b565b610ef4565b610206611025565b6101f161102b565b61018b61032f36600461128b565b61103a565b6102066103423660046112ae565b611067565b61034f610903565b6103745760405162461bcd60e51b815260040161036b906118f4565b60405180910390fd5b6001600160a01b03811661039a5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff166103d25760405162461bcd60e51b815260040161036b9061176b565b6035546001106103f45760405162461bcd60e51b815260040161036b90611997565b60365460355460001901101561041c5760405162461bcd60e51b815260040161036b906118a3565b6001600160a01b0381166000908152603760205260408120805460ff191690555b603554600019018110156104f057816001600160a01b03166035828154811061046257fe5b6000918252602090912001546001600160a01b031614156104e85760358054600019810190811061048f57fe5b600091825260209091200154603580546001600160a01b0390921691839081106104b557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506104f0565b60010161043d565b5060358054806104fc57fe5b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b60008181526038602052604081208161056c6110a9565b6001600160a01b0316815260208101919091526040016000205460ff1690505b919050565b60006037600061059f6110a9565b6001600160a01b0316815260208101919091526040016000205460ff166105d85760405162461bcd60e51b815260040161036b90611a21565b60006105e989898989898989611067565b60008181526039602052604090205490915060ff161561060d576001915050610800565b6000818152603860205260408120906106246110a9565b6001600160a01b0316815260208101919091526040016000205460ff1615610650576001915050610800565b60008181526038602052604081206001916106696110a9565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055808461069b6110a9565b6001600160a01b03167fd22894491aaa5bb67855bcff4b9730bdf7768be1e25f66ced9a7d7ad623bf2918c8c8c8c8c8b6040516106dd969594939291906115d6565b60405180910390a460006106f0826109ab565b9050603654811015801561070d5750603554600290046001018110155b156107f95760008281526039602052604090819020805460ff191660011790556034549051636a86319160e01b81526001600160a01b0390911690636a86319190610768908d908d908d908d908d908d908d90600401611590565b600060405180830381600087803b15801561078257600080fd5b505af1158015610796573d6000803e3d6000fd5b5050505081856107a46110a9565b6001600160a01b03167fe21e4d3d66ef78424137270e65cfafe938736bb770702ab4fd630383e7820b738d8d8d8d8d8c6040516107e6969594939291906115d6565b60405180910390a4600192505050610800565b6001925050505b979650505050505050565b6040805180820190915260028152613b1960f11b602082015290565b6035818154811061083757600080fd5b6000918252602090912001546001600160a01b0316905081565b603281565b61085e610903565b61087a5760405162461bcd60e51b815260040161036b906118f4565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6108db610903565b6108f75760405162461bcd60e51b815260040161036b906118f4565b610900816110ad565b50565b6033546000906001600160a01b031661091a6110a9565b6001600160a01b031614905090565b603860209081526000928352604080842090915290825290205460ff1681565b606060358054806020026020016040519081016040528092919081815260200182805480156109a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610983575b5050505050905090565b600080805b603554811015610a1557600084815260386020526040812060358054919291849081106109d957fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0d576001820191505b6001016109b0565b5092915050565b60376020526000908152604090205460ff1681565b60009081526039602052604090205460ff1690565b60376000610a526110a9565b6001600160a01b0316815260208101919091526040016000205460ff16610a8b5760405162461bcd60e51b815260040161036b90611a21565b610a936110a9565b6001600160a01b03167fbb00e6cbdccbb5b7549e189335249187223d88583604555326aa1d7ccbcad4428989898989898989604051610ad9989796959493929190611a58565b60405180910390a25050505050505050565b610af3610903565b610b0f5760405162461bcd60e51b815260040161036b906118f4565b60355481818111801590610b2257508015155b8015610b2d57508115155b610b495760405162461bcd60e51b815260040161036b906116c8565b6002831015610b6a5760405162461bcd60e51b815260040161036b90611929565b60368390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610b9f90859061166c565b60405180910390a1505050565b835183818111158015610bbe57508015155b8015610bc957508115155b610be55760405162461bcd60e51b815260040161036b906116c8565b600054610100900460ff1680610bfe575060005460ff16155b610c1a5760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610c45576000805460ff1961ff0019909116610100171660011790555b610c4e84610e2f565b603287511115610c705760405162461bcd60e51b815260040161036b90611734565b8651610c839060359060208a01906111ab565b5060005b8751811015610db85760376000898381518110610ca057fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015610cfa575060006001600160a01b0316888281518110610ce657fe5b60200260200101516001600160a01b031614155b610d165760405162461bcd60e51b815260040161036b906117f4565b6001603760008a8481518110610d2857fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550878181518110610d7357fe5b60200260200101516001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a2600101610c87565b5060368690556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610dee90889061166c565b60405180910390a1610dff856110ad565b8015610e11576000805461ff00191690555b50505050505050565b60396020526000908152604090205460ff1681565b600054610100900460ff1680610e48575060005460ff16155b610e645760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610e8f576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610ef0576000805461ff00191690555b5050565b610efc610903565b610f185760405162461bcd60e51b815260040161036b906118f4565b6001600160a01b038116610f3e5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff1615610f775760405162461bcd60e51b815260040161036b9061182b565b603554603211610f995760405162461bcd60e51b815260040161036b906116fd565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b60365481565b6034546001600160a01b031681565b611042610903565b61105e5760405162461bcd60e51b815260040161036b906118f4565b61090081611129565b600087878787878787604051602001611086979695949392919061151e565b604051602081830303815290604052805190602001209050979650505050505050565b3390565b6001600160a01b0381166110d35760405162461bcd60e51b815260040161036b9061186c565b603480546001600160a01b0319166001600160a01b0383161790556040517f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b925517827944979061111e90839061157c565b60405180910390a150565b6001600160a01b03811661114f5760405162461bcd60e51b815260040161036b906119df565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b828054828255906000526020600020908101928215611200579160200282015b8281111561120057825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906111cb565b5061120c929150611210565b5090565b5b8082111561120c5760008155600101611211565b803561058c81611aaf565b60008083601f840112611241578182fd5b50813567ffffffffffffffff811115611258578182fd5b60208301915083602082850101111561127057600080fd5b9250929050565b803563ffffffff8116811461058c57600080fd5b60006020828403121561129c578081fd5b81356112a781611aaf565b9392505050565b600080600080600080600060e0888a0312156112c8578283fd5b87356112d381611aaf565b965060208801356112e381611aaf565b955060408801356112f381611aaf565b9450606088013593506080880135925060a0880135915061131660c08901611277565b905092959891949750929550565b60008060008060808587031215611339578384fd5b843567ffffffffffffffff80821115611350578586fd5b818701915087601f830112611363578586fd5b813560208282111561137157fe5b8082026040518282820101818110868211171561138a57fe5b604052838152828101945085830182870184018d10156113a8578a8bfd5b8a96505b848710156113d1576113bd81611225565b8652600196909601959483019483016113ac565b5098505088013595506113eb925050604087019050611225565b91506113f960608601611225565b905092959194509250565b600060208284031215611415578081fd5b5035919050565b6000806040838503121561142e578182fd5b82359150602083013561144081611aaf565b809150509250929050565b60008060008060008060008060a0898b031215611466578081fd5b8835975060208901359650604089013567ffffffffffffffff8082111561148b578283fd5b6114978c838d01611230565b909850965060608b01359150808211156114af578283fd5b6114bb8c838d01611230565b909650945060808b01359150808211156114d3578283fd5b506114e08b828c01611230565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b606097881b6bffffffffffffffffffffffff19908116825296881b871660148201529490961b9094166028840152603c830191909152605c820152607c81019190915260e09190911b6001600160e01b031916609c82015260a00190565b6001600160a01b0391909116815260200190565b6001600160a01b03978816815295871660208701529390951660408501526060840191909152608083015260a082019290925263ffffffff90911660c082015260e00190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925263ffffffff90911660a082015260c00190565b6020808252825182820181905260009190848201906040850190845b818110156116555783516001600160a01b031683529284019291840191600101611630565b50909695505050505050565b901515815260200190565b90815260200190565b6000602080835283518082850152825b818110156116a157858101830151858201604001528201611685565b818111156116b25783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f46656465726174696f6e3a20496e76616c696420726571756972656d656e7473604082015260600190565b6020808252601f908201527f46656465726174696f6e3a204d6178206d656d62657273207265616368656400604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20546f6f206d616e79206d656d6265727300000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746040820152607360f81b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252601b908201527f46656465726174696f6e3a20496e76616c6964206d656d626572730000000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746040820152607360f81b606082015260800190565b60208082526018908201527f46656465726174696f6e3a20456d707479206272696467650000000000000000604082015260600190565b60208082526031908201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604082015270207265717569726564206d656d6265727360781b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f46656465726174696f6e3a205265717569726573206174206c65617374203200604082015260600190565b60208082526018908201527f46656465726174696f6e3a20456d707479206d656d6265720000000000000000604082015260600190565b60208082526028908201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604082015267206d656d6265727360c01b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526019908201527f46656465726174696f6e3a204e6f7420466564657261746f7200000000000000604082015260600190565b600089825288602083015260a06040830152611a7860a08301888a6114f4565b8281036060840152611a8b8187896114f4565b90508281036080840152611aa08185876114f4565b9b9a5050505050505050505050565b6001600160a01b038116811461090057600080fdfea2646970667358221220128a4b4f51a83044e466d0c301c3119ae839536443710de99b33113388de820464736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15785,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15788,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15828,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16072,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 5414,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "bridge",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_contract(IBridge)7398"
+ },
+ {
+ "astId": 5417,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "members",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 5419,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "required",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 5423,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "isMember",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 5429,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "votes",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_mapping(t_bytes32,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 5433,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "processed",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IBridge)7398": {
+ "encoding": "inplace",
+ "label": "contract IBridge",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/MultiSigWallet.json b/bridge/deployments/rsktestnet/MultiSigWallet.json
new file mode 100644
index 000000000..0cba5232a
--- /dev/null
+++ b/bridge/deployments/rsktestnet/MultiSigWallet.json
@@ -0,0 +1,843 @@
+{
+ "address": "0x88f6b2bc66f4c31a3669b9b1359524abf79cfc4a",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_owners",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Confirmation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposit",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Execution",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "ExecutionFailure",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnerAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnerRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Revocation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Submission",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_OWNER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "addOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "confirmTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "confirmations",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "executeTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getConfirmationCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "count",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getConfirmations",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "_confirmations",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getOwners",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "pending",
+ "type": "bool"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "count",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "from",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "to",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "pending",
+ "type": "bool"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "name": "getTransactionIds",
+ "outputs": [
+ {
+ "internalType": "uint256[]",
+ "name": "_transactionIds",
+ "type": "uint256[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "isConfirmed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "owners",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "removeOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "replaceOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "revokeConfirmation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "destination",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "submitTransaction",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "transactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "transactions",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "destination",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x3220b2ff54a523efde76537b235936e6dd8382bf5482db2c8433f6bdd558e172",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x6fd64b716Ef38Cbcdc966bfF1517F5B34CaA43F1",
+ "transactionIndex": 0,
+ "gasUsed": "2019878",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x879ccf214b2f36d116c885abe787bd0b2590a85bb773539465443a9750bf9284",
+ "transactionHash": "0x3220b2ff54a523efde76537b235936e6dd8382bf5482db2c8433f6bdd558e172",
+ "logs": [],
+ "blockNumber": 2152170,
+ "cumulativeGasUsed": "2019878",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ [
+ "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8"
+ ],
+ 1
+ ],
+ "solcInputHash": "3b83f9cb61a99eec06a616e65f41d75c",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_owners\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Confirmation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Execution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"ExecutionFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnerAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnerRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Revocation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Submission\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_OWNER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"addOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"confirmTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"confirmations\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"executeTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"getConfirmationCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"getConfirmations\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_confirmations\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pending\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"from\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"to\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"pending\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"name\":\"getTransactionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_transactionIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"isConfirmed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"owners\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"removeOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"replaceOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"revokeConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"submitTransaction\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"transactions\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"author\":\"Stefan George - \",\"kind\":\"dev\",\"methods\":{\"addOwner(address)\":{\"details\":\"Allows to add a new owner. Transaction has to be sent by wallet.\",\"params\":{\"owner\":\"Address of new owner.\"}},\"changeRequirement(uint256)\":{\"details\":\"Allows to change the number of required confirmations. Transaction has to be sent by wallet.\",\"params\":{\"_required\":\"Number of required confirmations.\"}},\"confirmTransaction(uint256)\":{\"details\":\"Allows an owner to confirm a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"constructor\":{\"details\":\"Contract constructor sets initial owners and required number of confirmations.\",\"params\":{\"_owners\":\"List of initial owners.\",\"_required\":\"Number of required confirmations.\"}},\"executeTransaction(uint256)\":{\"details\":\"Allows anyone to execute a confirmed transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"getConfirmationCount(uint256)\":{\"details\":\"Returns number of confirmations of a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"count\":\"Number of confirmations.\"}},\"getConfirmations(uint256)\":{\"details\":\"Returns array with owner addresses, which confirmed transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"_confirmations\":\"Returns array of owner addresses.\"}},\"getOwners()\":{\"details\":\"Returns list of owners.\",\"returns\":{\"_0\":\"List of owner addresses.\"}},\"getTransactionCount(bool,bool)\":{\"details\":\"Returns total number of transactions after filers are applied.\",\"params\":{\"executed\":\"Include executed transactions.\",\"pending\":\"Include pending transactions.\"},\"returns\":{\"count\":\"Total number of transactions after filters are applied.\"}},\"getTransactionIds(uint256,uint256,bool,bool)\":{\"details\":\"Returns list of transaction IDs in defined range.\",\"params\":{\"executed\":\"Include executed transactions.\",\"from\":\"Index start position of transaction array.\",\"pending\":\"Include pending transactions.\",\"to\":\"Index end position of transaction array.\"},\"returns\":{\"_transactionIds\":\"Returns array of transaction IDs.\"}},\"isConfirmed(uint256)\":{\"details\":\"Returns the confirmation status of a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"_0\":\"Confirmation status.\"}},\"removeOwner(address)\":{\"details\":\"Allows to remove an owner. Transaction has to be sent by wallet.\",\"params\":{\"owner\":\"Address of owner.\"}},\"replaceOwner(address,address)\":{\"details\":\"Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\",\"params\":{\"newOwner\":\"Address of new owner.\",\"owner\":\"Address of owner to be replaced.\"}},\"revokeConfirmation(uint256)\":{\"details\":\"Allows an owner to revoke a confirmation for a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"submitTransaction(address,uint256,bytes)\":{\"details\":\"Allows an owner to submit and confirm a transaction.\",\"params\":{\"data\":\"Transaction data payload.\",\"destination\":\"Transaction target address.\",\"value\":\"Transaction ether value.\"},\"returns\":{\"transactionId\":\"Returns transaction ID.\"}}},\"title\":\"Multisignature wallet - Allows multiple parties to agree on transactions before execution.\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/MultiSigWallet.sol\":\"MultiSigWallet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/MultiSigWallet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.\\n/// @author Stefan George - \\ncontract MultiSigWallet {\\n\\n /*\\n * Events\\n */\\n event Confirmation(address indexed sender, uint indexed transactionId);\\n event Revocation(address indexed sender, uint indexed transactionId);\\n event Submission(uint indexed transactionId);\\n event Execution(uint indexed transactionId);\\n event ExecutionFailure(uint indexed transactionId);\\n event Deposit(address indexed sender, uint value);\\n event OwnerAddition(address indexed owner);\\n event OwnerRemoval(address indexed owner);\\n event RequirementChange(uint required);\\n\\n /*\\n * views\\n */\\n uint constant public MAX_OWNER_COUNT = 50;\\n\\n /*\\n * Storage\\n */\\n mapping (uint => Transaction) public transactions;\\n mapping (uint => mapping (address => bool)) public confirmations;\\n mapping (address => bool) public isOwner;\\n address[] public owners;\\n uint public required;\\n uint public transactionCount;\\n\\n struct Transaction {\\n address destination;\\n uint value;\\n bytes data;\\n bool executed;\\n }\\n\\n /*\\n * Modifiers\\n */\\n modifier onlyWallet() {\\n require(msg.sender == address(this), \\\"Only wallet allowed\\\");\\n _;\\n }\\n\\n modifier ownerDoesNotExist(address owner) {\\n require(!isOwner[owner], \\\"The owner already exists\\\");\\n _;\\n }\\n\\n modifier ownerExists(address owner) {\\n require(isOwner[owner], \\\"The owner does not exist\\\");\\n _;\\n }\\n\\n modifier transactionExists(uint transactionId) {\\n require(transactions[transactionId].destination != address(0), \\\"Transaction does not exist\\\");\\n _;\\n }\\n\\n modifier confirmed(uint transactionId, address owner) {\\n require(confirmations[transactionId][owner], \\\"Transaction is not confirmed by owner\\\");\\n _;\\n }\\n\\n modifier notConfirmed(uint transactionId, address owner) {\\n require(!confirmations[transactionId][owner], \\\"Transaction is already confirmed by owner\\\");\\n _;\\n }\\n\\n modifier notExecuted(uint transactionId) {\\n require(!transactions[transactionId].executed, \\\"Transaction was already executed\\\");\\n _;\\n }\\n\\n modifier notNull(address _address) {\\n require(_address != address(0), \\\"Address cannot be empty\\\");\\n _;\\n }\\n\\n modifier validRequirement(uint ownerCount, uint _required) {\\n // solium-disable-next-line max-len\\n require(ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && _required != 0 && ownerCount != 0, \\\"Required value is invalid for the current owners count\\\");\\n _;\\n }\\n\\n /// @dev Fallback function allows to deposit ether.\\n receive ()\\n external\\n payable\\n {\\n if (msg.value > 0)\\n emit Deposit(msg.sender, msg.value);\\n }\\n\\n /*\\n * Public functions\\n */\\n /// @dev Contract constructor sets initial owners and required number of confirmations.\\n /// @param _owners List of initial owners.\\n /// @param _required Number of required confirmations.\\n constructor(address[] memory _owners, uint _required)\\n validRequirement(_owners.length, _required)\\n {\\n for (uint i = 0; i < _owners.length; i++) {\\n require(!isOwner[_owners[i]] && _owners[i] != address(0), \\\"Owners addresses are invalid\\\");\\n isOwner[_owners[i]] = true;\\n }\\n owners = _owners;\\n required = _required;\\n }\\n\\n /// @dev Allows to add a new owner. Transaction has to be sent by wallet.\\n /// @param owner Address of new owner.\\n function addOwner(address owner)\\n public\\n onlyWallet\\n ownerDoesNotExist(owner)\\n notNull(owner)\\n validRequirement(owners.length + 1, required)\\n {\\n isOwner[owner] = true;\\n owners.push(owner);\\n emit OwnerAddition(owner);\\n }\\n\\n /// @dev Allows to remove an owner. Transaction has to be sent by wallet.\\n /// @param owner Address of owner.\\n function removeOwner(address owner)\\n public\\n onlyWallet\\n ownerExists(owner)\\n {\\n isOwner[owner] = false;\\n for (uint i = 0; i < owners.length - 1; i++)\\n if (owners[i] == owner) {\\n owners[i] = owners[owners.length - 1];\\n break;\\n }\\n owners.pop(); // remove an element from the end of the array.\\n if (required > owners.length)\\n changeRequirement(owners.length);\\n emit OwnerRemoval(owner);\\n }\\n\\n /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\\n /// @param owner Address of owner to be replaced.\\n /// @param newOwner Address of new owner.\\n function replaceOwner(address owner, address newOwner)\\n public\\n onlyWallet\\n ownerExists(owner)\\n ownerDoesNotExist(newOwner)\\n {\\n for (uint i = 0; i < owners.length; i++)\\n if (owners[i] == owner) {\\n owners[i] = newOwner;\\n break;\\n }\\n isOwner[owner] = false;\\n isOwner[newOwner] = true;\\n emit OwnerRemoval(owner);\\n emit OwnerAddition(newOwner);\\n }\\n\\n /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.\\n /// @param _required Number of required confirmations.\\n function changeRequirement(uint _required)\\n public\\n onlyWallet\\n validRequirement(owners.length, _required)\\n {\\n required = _required;\\n emit RequirementChange(_required);\\n }\\n\\n /// @dev Allows an owner to submit and confirm a transaction.\\n /// @param destination Transaction target address.\\n /// @param value Transaction ether value.\\n /// @param data Transaction data payload.\\n /// @return transactionId Returns transaction ID.\\n function submitTransaction(address destination, uint value, bytes memory data)\\n public\\n returns (uint transactionId)\\n {\\n transactionId = addTransaction(destination, value, data);\\n confirmTransaction(transactionId);\\n }\\n\\n /// @dev Allows an owner to confirm a transaction.\\n /// @param transactionId Transaction ID.\\n function confirmTransaction(uint transactionId)\\n public\\n ownerExists(msg.sender)\\n transactionExists(transactionId)\\n notConfirmed(transactionId, msg.sender)\\n {\\n confirmations[transactionId][msg.sender] = true;\\n emit Confirmation(msg.sender, transactionId);\\n executeTransaction(transactionId);\\n }\\n\\n /// @dev Allows an owner to revoke a confirmation for a transaction.\\n /// @param transactionId Transaction ID.\\n function revokeConfirmation(uint transactionId)\\n public\\n ownerExists(msg.sender)\\n confirmed(transactionId, msg.sender)\\n notExecuted(transactionId)\\n {\\n confirmations[transactionId][msg.sender] = false;\\n emit Revocation(msg.sender, transactionId);\\n }\\n\\n /// @dev Allows anyone to execute a confirmed transaction.\\n /// @param transactionId Transaction ID.\\n function executeTransaction(uint transactionId)\\n public\\n ownerExists(msg.sender)\\n confirmed(transactionId, msg.sender)\\n notExecuted(transactionId)\\n {\\n if (isConfirmed(transactionId)) {\\n Transaction storage txn = transactions[transactionId];\\n txn.executed = true;\\n if (external_call(txn.destination, txn.value, txn.data.length, txn.data))\\n emit Execution(transactionId);\\n else {\\n emit ExecutionFailure(transactionId);\\n txn.executed = false;\\n }\\n }\\n }\\n\\n // call has been separated into its own function in order to take advantage\\n // of the Solidity's code generator to produce a loop that copies tx.data into memory.\\n function external_call(address destination, uint value, uint dataLength, bytes memory data) internal returns (bool) {\\n bool result;\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n let x := mload(0x40) // \\\"Allocate\\\" memory for output (0x40 is where \\\"free memory\\\" pointer is stored by convention)\\n let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that\\n result := call(\\n sub(gas(), 34710), // 34710 is the value that solidity is currently emitting\\n // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +\\n // callNewAccountGas (25000, in case the destination address does not exist and needs creating)\\n destination,\\n value,\\n d,\\n dataLength, // Size of the input (in bytes) - this is what fixes the padding problem\\n x,\\n 0 // Output is ignored, therefore the output size is zero\\n )\\n }\\n return result;\\n }\\n\\n /// @dev Returns the confirmation status of a transaction.\\n /// @param transactionId Transaction ID.\\n /// @return Confirmation status.\\n function isConfirmed(uint transactionId)\\n public\\n view\\n returns (bool)\\n {\\n uint count = 0;\\n for (uint i = 0; i < owners.length; i++) {\\n if (confirmations[transactionId][owners[i]])\\n count += 1;\\n if (count == required)\\n return true;\\n }\\n return false;\\n }\\n\\n /*\\n * Internal functions\\n */\\n /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.\\n /// @param destination Transaction target address.\\n /// @param value Transaction ether value.\\n /// @param data Transaction data payload.\\n /// @return transactionId Returns transaction ID.\\n function addTransaction(address destination, uint value, bytes memory data)\\n internal\\n notNull(destination)\\n returns (uint transactionId)\\n {\\n transactionId = transactionCount;\\n transactions[transactionId] = Transaction({\\n destination: destination,\\n value: value,\\n data: data,\\n executed: false\\n });\\n transactionCount += 1;\\n emit Submission(transactionId);\\n }\\n\\n /*\\n * Web3 call functions\\n */\\n /// @dev Returns number of confirmations of a transaction.\\n /// @param transactionId Transaction ID.\\n /// @return count Number of confirmations.\\n function getConfirmationCount(uint transactionId)\\n public\\n view\\n returns (uint count)\\n {\\n for (uint i = 0; i < owners.length; i++) {\\n if (confirmations[transactionId][owners[i]]) {\\n count += 1;\\n }\\n }\\n }\\n\\n /// @dev Returns total number of transactions after filers are applied.\\n /// @param pending Include pending transactions.\\n /// @param executed Include executed transactions.\\n /// @return count Total number of transactions after filters are applied.\\n function getTransactionCount(bool pending, bool executed)\\n public\\n view\\n returns (uint count)\\n {\\n for (uint i = 0; i < transactionCount; i++) {\\n if ( pending && !transactions[i].executed || executed && transactions[i].executed) {\\n count += 1;\\n }\\n }\\n }\\n\\n /// @dev Returns list of owners.\\n /// @return List of owner addresses.\\n function getOwners()\\n public\\n view\\n returns (address[] memory)\\n {\\n return owners;\\n }\\n\\n /// @dev Returns array with owner addresses, which confirmed transaction.\\n /// @param transactionId Transaction ID.\\n /// @return _confirmations Returns array of owner addresses.\\n function getConfirmations(uint transactionId)\\n public\\n view\\n returns (address[] memory _confirmations)\\n {\\n address[] memory confirmationsTemp = new address[](owners.length);\\n uint count = 0;\\n uint i;\\n for (i = 0; i < owners.length; i++)\\n if (confirmations[transactionId][owners[i]]) {\\n confirmationsTemp[count] = owners[i];\\n count += 1;\\n }\\n _confirmations = new address[](count);\\n for (i = 0; i < count; i++)\\n _confirmations[i] = confirmationsTemp[i];\\n }\\n\\n /// @dev Returns list of transaction IDs in defined range.\\n /// @param from Index start position of transaction array.\\n /// @param to Index end position of transaction array.\\n /// @param pending Include pending transactions.\\n /// @param executed Include executed transactions.\\n /// @return _transactionIds Returns array of transaction IDs.\\n function getTransactionIds(uint from, uint to, bool pending, bool executed)\\n public\\n view\\n returns (uint[] memory _transactionIds)\\n {\\n uint[] memory transactionIdsTemp = new uint[](transactionCount);\\n uint count = 0;\\n uint i;\\n for (i = 0; i < transactionCount; i++)\\n if ( pending && !transactions[i].executed || executed && transactions[i].executed)\\n {\\n transactionIdsTemp[count] = i;\\n count += 1;\\n }\\n _transactionIds = new uint[](to - from);\\n for (i = from; i < to; i++)\\n _transactionIds[i - from] = transactionIdsTemp[i];\\n }\\n}\",\"keccak256\":\"0x48128d95302f2405b2ca70996b8f12f7d9c52224aadf3b381139246bf2baa31b\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x60806040523480156200001157600080fd5b5060405162001e5838038062001e58833981016040819052620000349162000231565b81518160328211158015620000495750818111155b80156200005557508015155b80156200006157508115155b620000895760405162461bcd60e51b81526004016200008090620002f7565b60405180910390fd5b60005b8451811015620001705760026000868381518110620000a757fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1615801562000103575060006001600160a01b0316858281518110620000ef57fe5b60200260200101516001600160a01b031614155b620001225760405162461bcd60e51b8152600401620000809062000354565b6001600260008784815181106200013557fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff19169115159190911790556001016200008c565b5083516200018690600390602087019062000193565b505050600455506200038b565b828054828255906000526020600020908101928215620001eb579160200282015b82811115620001eb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620001b4565b50620001f9929150620001fd565b5090565b5b80821115620001f95760008155600101620001fe565b80516001600160a01b03811681146200022c57600080fd5b919050565b6000806040838503121562000244578182fd5b82516001600160401b03808211156200025b578384fd5b818501915085601f8301126200026f578384fd5b81516020828211156200027e57fe5b808202604051828282010181811086821117156200029857fe5b604052838152828101945085830182870184018b1015620002b7578889fd5b8896505b84871015620002e457620002cf8162000214565b865260019690960195948301948301620002bb565b5097909101519698969750505050505050565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f7220746860408201527f652063757272656e74206f776e65727320636f756e7400000000000000000000606082015260800190565b6020808252601c908201527f4f776e657273206164647265737365732061726520696e76616c696400000000604082015260600190565b611abd806200039b6000396000f3fe60806040526004361061012e5760003560e01c8063a0e67e2b116100ab578063c01a8c841161006f578063c01a8c84146103a6578063c6427474146103c6578063d74f8edd146103e6578063dc8452cd146103fb578063e20056e614610410578063ee22610b146104305761017d565b8063a0e67e2b14610302578063a8abe69a14610324578063b5dc40c314610351578063b77bf60014610371578063ba51a6df146103865761017d565b806354741525116100f257806354741525146102455780637065cb4814610272578063784547a7146102925780638b51d13f146102b25780639ace38c2146102d25761017d565b8063025e7c2714610182578063173825d9146101b857806320ea8d86146101d85780632f54bf6e146101f85780633411c81c146102255761017d565b3661017d57341561017b57336001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040516101729190611a7e565b60405180910390a25b005b600080fd5b34801561018e57600080fd5b506101a261019d3660046116ba565b610450565b6040516101af919061173f565b60405180910390f35b3480156101c457600080fd5b5061017b6101d3366004611594565b61047a565b3480156101e457600080fd5b5061017b6101f33660046116ba565b61062e565b34801561020457600080fd5b50610218610213366004611594565b61071d565b6040516101af9190611851565b34801561023157600080fd5b506102186102403660046116d2565b610732565b34801561025157600080fd5b50610265610260366004611691565b610752565b6040516101af9190611a7e565b34801561027e57600080fd5b5061017b61028d366004611594565b6107be565b34801561029e57600080fd5b506102186102ad3660046116ba565b61091e565b3480156102be57600080fd5b506102656102cd3660046116ba565b6109a9565b3480156102de57600080fd5b506102f26102ed3660046116ba565b610a18565b6040516101af9493929190611753565b34801561030e57600080fd5b50610317610ad6565b6040516101af91906117cc565b34801561033057600080fd5b5061034461033f3660046116f4565b610b38565b6040516101af9190611819565b34801561035d57600080fd5b5061031761036c3660046116ba565b610c92565b34801561037d57600080fd5b50610265610e37565b34801561039257600080fd5b5061017b6103a13660046116ba565b610e3d565b3480156103b257600080fd5b5061017b6103c13660046116ba565b610ee5565b3480156103d257600080fd5b506102656103e13660046115e0565b610fe5565b3480156103f257600080fd5b50610265611004565b34801561040757600080fd5b50610265611009565b34801561041c57600080fd5b5061017b61042b3660046115ae565b61100f565b34801561043c57600080fd5b5061017b61044b3660046116ba565b6111c5565b6003818154811061046057600080fd5b6000918252602090912001546001600160a01b0316905081565b3330146104a25760405162461bcd60e51b815260040161049990611977565b60405180910390fd5b6001600160a01b038116600090815260026020526040902054819060ff166104dc5760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b0382166000908152600260205260408120805460ff191690555b600354600019018110156105b057826001600160a01b03166003828154811061052257fe5b6000918252602090912001546001600160a01b031614156105a85760038054600019810190811061054f57fe5b600091825260209091200154600380546001600160a01b03909216918390811061057557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506105b0565b6001016104fd565b5060038054806105bc57fe5b600082815260209020810160001990810180546001600160a01b031916905501905560035460045411156105f6576003546105f690610e3d565b6040516001600160a01b038316907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a25050565b3360008181526002602052604090205460ff1661065d5760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff1661069a5760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156106ce5760405162461bcd60e51b815260040161049990611a49565b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b6005548110156107b75783801561077f575060008181526020819052604090206003015460ff16155b806107a357508280156107a3575060008181526020819052604090206003015460ff165b156107af576001820191505b600101610756565b5092915050565b3330146107dd5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038116600090815260026020526040902054819060ff16156108185760405162461bcd60e51b815260040161049990611a12565b816001600160a01b03811661083f5760405162461bcd60e51b815260040161049990611940565b6003805490506001016004546032821115801561085c5750818111155b801561086757508015155b801561087257508115155b61088e5760405162461bcd60e51b8152600401610499906118a5565b6001600160a01b038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b60035481101561099d576000848152600160205260408120600380549192918490811061094c57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610980576001820191505b600454821415610995576001925050506109a4565b600101610923565b5060009150505b919050565b6000805b600354811015610a1257600083815260016020526040812060038054919291849081106109d657fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0a576001820191505b6001016109ad565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f81018890048802840188019096528583526001600160a01b0390931695909491929190830182828015610ac35780601f10610a9857610100808354040283529160200191610ac3565b820191906000526020600020905b815481529060010190602001808311610aa657829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610b2e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b10575b5050505050905090565b6060600060055467ffffffffffffffff81118015610b5557600080fd5b50604051908082528060200260200182016040528015610b7f578160200160208202803683370190505b5090506000805b600554811015610c0057858015610baf575060008181526020819052604090206003015460ff16155b80610bd35750848015610bd3575060008181526020819052604090206003015460ff165b15610bf85780838381518110610be557fe5b6020026020010181815250506001820191505b600101610b86565b87870367ffffffffffffffff81118015610c1957600080fd5b50604051908082528060200260200182016040528015610c43578160200160208202803683370190505b5093508790505b86811015610c8757828181518110610c5e57fe5b60200260200101518489830381518110610c7457fe5b6020908102919091010152600101610c4a565b505050949350505050565b60035460609060009067ffffffffffffffff81118015610cb157600080fd5b50604051908082528060200260200182016040528015610cdb578160200160208202803683370190505b5090506000805b600354811015610d9e5760008581526001602052604081206003805491929184908110610d0b57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610d965760038181548110610d4557fe5b9060005260206000200160009054906101000a90046001600160a01b0316838381518110610d6f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001820191505b600101610ce2565b8167ffffffffffffffff81118015610db557600080fd5b50604051908082528060200260200182016040528015610ddf578160200160208202803683370190505b509350600090505b81811015610e2f57828181518110610dfb57fe5b6020026020010151848281518110610e0f57fe5b6001600160a01b0390921660209283029190910190910152600101610de7565b505050919050565b60055481565b333014610e5c5760405162461bcd60e51b815260040161049990611977565b6003548160328211801590610e715750818111155b8015610e7c57508015155b8015610e8757508115155b610ea35760405162461bcd60e51b8152600401610499906118a5565b60048390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610ed8908590611a7e565b60405180910390a1505050565b3360008181526002602052604090205460ff16610f145760405162461bcd60e51b8152600401610499906119a4565b60008281526020819052604090205482906001600160a01b0316610f4a5760405162461bcd60e51b8152600401610499906119db565b60008381526001602090815260408083203380855292529091205484919060ff1615610f885760405162461bcd60e51b81526004016104999061185c565b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3610fde856111c5565b5050505050565b6000610ff28484846113b5565b9050610ffd81610ee5565b9392505050565b603281565b60045481565b33301461102e5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038216600090815260026020526040902054829060ff166110685760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b038216600090815260026020526040902054829060ff16156110a35760405162461bcd60e51b815260040161049990611a12565b60005b60035481101561112b57846001600160a01b0316600382815481106110c757fe5b6000918252602090912001546001600160a01b031614156111235783600382815481106110f057fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061112b565b6001016110a6565b506001600160a01b03808516600081815260026020526040808220805460ff1990811690915593871682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a26040516001600160a01b038416907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a250505050565b3360008181526002602052604090205460ff166111f45760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff166112315760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156112655760405162461bcd60e51b815260040161049990611a49565b61126e8561091e565b15610fde576000858152602081815260409182902060038101805460ff19166001908117909155815481830154600280850180548851601f600019978316156101000297909701909116929092049485018790048702820187019097528381529395611340956001600160a01b039093169491939283908301828280156113365780601f1061130b57610100808354040283529160200191611336565b820191906000526020600020905b81548152906001019060200180831161131957829003601f168201915b50505050506114a9565b156113755760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26113ad565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038101805460ff191690555b505050505050565b6000836001600160a01b0381166113de5760405162461bcd60e51b815260040161049990611940565b600554604080516080810182526001600160a01b038881168252602080830189815283850189815260006060860181905287815280845295909520845181546001600160a01b031916941693909317835551600183015592518051949650919390926114519260028501929101906114cc565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b6000806040516020840160008287838a8c6187965a03f198975050505050505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826115025760008555611548565b82601f1061151b57805160ff1916838001178555611548565b82800160010185558215611548579182015b8281111561154857825182559160200191906001019061152d565b50611554929150611558565b5090565b5b808211156115545760008155600101611559565b80356001600160a01b03811681146109a457600080fd5b803580151581146109a457600080fd5b6000602082840312156115a5578081fd5b610ffd8261156d565b600080604083850312156115c0578081fd5b6115c98361156d565b91506115d76020840161156d565b90509250929050565b6000806000606084860312156115f4578081fd5b6115fd8461156d565b92506020808501359250604085013567ffffffffffffffff80821115611621578384fd5b818701915087601f830112611634578384fd5b81358181111561164057fe5b604051601f8201601f191681018501838111828210171561165d57fe5b60405281815283820185018a1015611673578586fd5b81858501868301378585838301015280955050505050509250925092565b600080604083850312156116a3578182fd5b6116ac83611584565b91506115d760208401611584565b6000602082840312156116cb578081fd5b5035919050565b600080604083850312156116e4578182fd5b823591506115d76020840161156d565b60008060008060808587031215611709578081fd5b843593506020850135925061172060408601611584565b915061172e60608601611584565b905092959194509250565b15159052565b6001600160a01b0391909116815260200190565b600060018060a01b038616825260208581840152608060408401528451806080850152825b818110156117945786810183015185820160a001528201611778565b818111156117a5578360a083870101525b50601f01601f1916830160a00191506117c390506060830184611739565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d5783516001600160a01b0316835292840192918401916001016117e8565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d57835183529284019291840191600101611835565b901515815260200190565b60208082526029908201527f5472616e73616374696f6e20697320616c726561647920636f6e6669726d656460408201526810313c9037bbb732b960b91b606082015260800190565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f72207468604082015275194818dd5c9c995b9d081bdddb995c9cc818dbdd5b9d60521b606082015260800190565b60208082526025908201527f5472616e73616374696f6e206973206e6f7420636f6e6669726d65642062792060408201526437bbb732b960d91b606082015260800190565b60208082526017908201527f416464726573732063616e6e6f7420626520656d707479000000000000000000604082015260600190565b60208082526013908201527213db9b1e481dd85b1b195d08185b1b1bddd959606a1b604082015260600190565b60208082526018908201527f546865206f776e657220646f6573206e6f742065786973740000000000000000604082015260600190565b6020808252601a908201527f5472616e73616374696f6e20646f6573206e6f74206578697374000000000000604082015260600190565b60208082526018908201527f546865206f776e657220616c7265616479206578697374730000000000000000604082015260600190565b6020808252818101527f5472616e73616374696f6e2077617320616c7265616479206578656375746564604082015260600190565b9081526020019056fea264697066735822122062c2739111652d12775c1bfdbf576765e75e1ef9880050cc336a31164f199d6c64736f6c63430007060033",
+ "deployedBytecode": "0x60806040526004361061012e5760003560e01c8063a0e67e2b116100ab578063c01a8c841161006f578063c01a8c84146103a6578063c6427474146103c6578063d74f8edd146103e6578063dc8452cd146103fb578063e20056e614610410578063ee22610b146104305761017d565b8063a0e67e2b14610302578063a8abe69a14610324578063b5dc40c314610351578063b77bf60014610371578063ba51a6df146103865761017d565b806354741525116100f257806354741525146102455780637065cb4814610272578063784547a7146102925780638b51d13f146102b25780639ace38c2146102d25761017d565b8063025e7c2714610182578063173825d9146101b857806320ea8d86146101d85780632f54bf6e146101f85780633411c81c146102255761017d565b3661017d57341561017b57336001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040516101729190611a7e565b60405180910390a25b005b600080fd5b34801561018e57600080fd5b506101a261019d3660046116ba565b610450565b6040516101af919061173f565b60405180910390f35b3480156101c457600080fd5b5061017b6101d3366004611594565b61047a565b3480156101e457600080fd5b5061017b6101f33660046116ba565b61062e565b34801561020457600080fd5b50610218610213366004611594565b61071d565b6040516101af9190611851565b34801561023157600080fd5b506102186102403660046116d2565b610732565b34801561025157600080fd5b50610265610260366004611691565b610752565b6040516101af9190611a7e565b34801561027e57600080fd5b5061017b61028d366004611594565b6107be565b34801561029e57600080fd5b506102186102ad3660046116ba565b61091e565b3480156102be57600080fd5b506102656102cd3660046116ba565b6109a9565b3480156102de57600080fd5b506102f26102ed3660046116ba565b610a18565b6040516101af9493929190611753565b34801561030e57600080fd5b50610317610ad6565b6040516101af91906117cc565b34801561033057600080fd5b5061034461033f3660046116f4565b610b38565b6040516101af9190611819565b34801561035d57600080fd5b5061031761036c3660046116ba565b610c92565b34801561037d57600080fd5b50610265610e37565b34801561039257600080fd5b5061017b6103a13660046116ba565b610e3d565b3480156103b257600080fd5b5061017b6103c13660046116ba565b610ee5565b3480156103d257600080fd5b506102656103e13660046115e0565b610fe5565b3480156103f257600080fd5b50610265611004565b34801561040757600080fd5b50610265611009565b34801561041c57600080fd5b5061017b61042b3660046115ae565b61100f565b34801561043c57600080fd5b5061017b61044b3660046116ba565b6111c5565b6003818154811061046057600080fd5b6000918252602090912001546001600160a01b0316905081565b3330146104a25760405162461bcd60e51b815260040161049990611977565b60405180910390fd5b6001600160a01b038116600090815260026020526040902054819060ff166104dc5760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b0382166000908152600260205260408120805460ff191690555b600354600019018110156105b057826001600160a01b03166003828154811061052257fe5b6000918252602090912001546001600160a01b031614156105a85760038054600019810190811061054f57fe5b600091825260209091200154600380546001600160a01b03909216918390811061057557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506105b0565b6001016104fd565b5060038054806105bc57fe5b600082815260209020810160001990810180546001600160a01b031916905501905560035460045411156105f6576003546105f690610e3d565b6040516001600160a01b038316907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a25050565b3360008181526002602052604090205460ff1661065d5760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff1661069a5760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156106ce5760405162461bcd60e51b815260040161049990611a49565b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b6005548110156107b75783801561077f575060008181526020819052604090206003015460ff16155b806107a357508280156107a3575060008181526020819052604090206003015460ff165b156107af576001820191505b600101610756565b5092915050565b3330146107dd5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038116600090815260026020526040902054819060ff16156108185760405162461bcd60e51b815260040161049990611a12565b816001600160a01b03811661083f5760405162461bcd60e51b815260040161049990611940565b6003805490506001016004546032821115801561085c5750818111155b801561086757508015155b801561087257508115155b61088e5760405162461bcd60e51b8152600401610499906118a5565b6001600160a01b038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b60035481101561099d576000848152600160205260408120600380549192918490811061094c57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610980576001820191505b600454821415610995576001925050506109a4565b600101610923565b5060009150505b919050565b6000805b600354811015610a1257600083815260016020526040812060038054919291849081106109d657fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0a576001820191505b6001016109ad565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f81018890048802840188019096528583526001600160a01b0390931695909491929190830182828015610ac35780601f10610a9857610100808354040283529160200191610ac3565b820191906000526020600020905b815481529060010190602001808311610aa657829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610b2e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b10575b5050505050905090565b6060600060055467ffffffffffffffff81118015610b5557600080fd5b50604051908082528060200260200182016040528015610b7f578160200160208202803683370190505b5090506000805b600554811015610c0057858015610baf575060008181526020819052604090206003015460ff16155b80610bd35750848015610bd3575060008181526020819052604090206003015460ff165b15610bf85780838381518110610be557fe5b6020026020010181815250506001820191505b600101610b86565b87870367ffffffffffffffff81118015610c1957600080fd5b50604051908082528060200260200182016040528015610c43578160200160208202803683370190505b5093508790505b86811015610c8757828181518110610c5e57fe5b60200260200101518489830381518110610c7457fe5b6020908102919091010152600101610c4a565b505050949350505050565b60035460609060009067ffffffffffffffff81118015610cb157600080fd5b50604051908082528060200260200182016040528015610cdb578160200160208202803683370190505b5090506000805b600354811015610d9e5760008581526001602052604081206003805491929184908110610d0b57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610d965760038181548110610d4557fe5b9060005260206000200160009054906101000a90046001600160a01b0316838381518110610d6f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001820191505b600101610ce2565b8167ffffffffffffffff81118015610db557600080fd5b50604051908082528060200260200182016040528015610ddf578160200160208202803683370190505b509350600090505b81811015610e2f57828181518110610dfb57fe5b6020026020010151848281518110610e0f57fe5b6001600160a01b0390921660209283029190910190910152600101610de7565b505050919050565b60055481565b333014610e5c5760405162461bcd60e51b815260040161049990611977565b6003548160328211801590610e715750818111155b8015610e7c57508015155b8015610e8757508115155b610ea35760405162461bcd60e51b8152600401610499906118a5565b60048390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610ed8908590611a7e565b60405180910390a1505050565b3360008181526002602052604090205460ff16610f145760405162461bcd60e51b8152600401610499906119a4565b60008281526020819052604090205482906001600160a01b0316610f4a5760405162461bcd60e51b8152600401610499906119db565b60008381526001602090815260408083203380855292529091205484919060ff1615610f885760405162461bcd60e51b81526004016104999061185c565b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3610fde856111c5565b5050505050565b6000610ff28484846113b5565b9050610ffd81610ee5565b9392505050565b603281565b60045481565b33301461102e5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038216600090815260026020526040902054829060ff166110685760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b038216600090815260026020526040902054829060ff16156110a35760405162461bcd60e51b815260040161049990611a12565b60005b60035481101561112b57846001600160a01b0316600382815481106110c757fe5b6000918252602090912001546001600160a01b031614156111235783600382815481106110f057fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061112b565b6001016110a6565b506001600160a01b03808516600081815260026020526040808220805460ff1990811690915593871682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a26040516001600160a01b038416907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a250505050565b3360008181526002602052604090205460ff166111f45760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff166112315760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156112655760405162461bcd60e51b815260040161049990611a49565b61126e8561091e565b15610fde576000858152602081815260409182902060038101805460ff19166001908117909155815481830154600280850180548851601f600019978316156101000297909701909116929092049485018790048702820187019097528381529395611340956001600160a01b039093169491939283908301828280156113365780601f1061130b57610100808354040283529160200191611336565b820191906000526020600020905b81548152906001019060200180831161131957829003601f168201915b50505050506114a9565b156113755760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26113ad565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038101805460ff191690555b505050505050565b6000836001600160a01b0381166113de5760405162461bcd60e51b815260040161049990611940565b600554604080516080810182526001600160a01b038881168252602080830189815283850189815260006060860181905287815280845295909520845181546001600160a01b031916941693909317835551600183015592518051949650919390926114519260028501929101906114cc565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b6000806040516020840160008287838a8c6187965a03f198975050505050505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826115025760008555611548565b82601f1061151b57805160ff1916838001178555611548565b82800160010185558215611548579182015b8281111561154857825182559160200191906001019061152d565b50611554929150611558565b5090565b5b808211156115545760008155600101611559565b80356001600160a01b03811681146109a457600080fd5b803580151581146109a457600080fd5b6000602082840312156115a5578081fd5b610ffd8261156d565b600080604083850312156115c0578081fd5b6115c98361156d565b91506115d76020840161156d565b90509250929050565b6000806000606084860312156115f4578081fd5b6115fd8461156d565b92506020808501359250604085013567ffffffffffffffff80821115611621578384fd5b818701915087601f830112611634578384fd5b81358181111561164057fe5b604051601f8201601f191681018501838111828210171561165d57fe5b60405281815283820185018a1015611673578586fd5b81858501868301378585838301015280955050505050509250925092565b600080604083850312156116a3578182fd5b6116ac83611584565b91506115d760208401611584565b6000602082840312156116cb578081fd5b5035919050565b600080604083850312156116e4578182fd5b823591506115d76020840161156d565b60008060008060808587031215611709578081fd5b843593506020850135925061172060408601611584565b915061172e60608601611584565b905092959194509250565b15159052565b6001600160a01b0391909116815260200190565b600060018060a01b038616825260208581840152608060408401528451806080850152825b818110156117945786810183015185820160a001528201611778565b818111156117a5578360a083870101525b50601f01601f1916830160a00191506117c390506060830184611739565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d5783516001600160a01b0316835292840192918401916001016117e8565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d57835183529284019291840191600101611835565b901515815260200190565b60208082526029908201527f5472616e73616374696f6e20697320616c726561647920636f6e6669726d656460408201526810313c9037bbb732b960b91b606082015260800190565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f72207468604082015275194818dd5c9c995b9d081bdddb995c9cc818dbdd5b9d60521b606082015260800190565b60208082526025908201527f5472616e73616374696f6e206973206e6f7420636f6e6669726d65642062792060408201526437bbb732b960d91b606082015260800190565b60208082526017908201527f416464726573732063616e6e6f7420626520656d707479000000000000000000604082015260600190565b60208082526013908201527213db9b1e481dd85b1b195d08185b1b1bddd959606a1b604082015260600190565b60208082526018908201527f546865206f776e657220646f6573206e6f742065786973740000000000000000604082015260600190565b6020808252601a908201527f5472616e73616374696f6e20646f6573206e6f74206578697374000000000000604082015260600190565b60208082526018908201527f546865206f776e657220616c7265616479206578697374730000000000000000604082015260600190565b6020808252818101527f5472616e73616374696f6e2077617320616c7265616479206578656375746564604082015260600190565b9081526020019056fea264697066735822122062c2739111652d12775c1bfdbf576765e75e1ef9880050cc336a31164f199d6c64736f6c63430007060033",
+ "devdoc": {
+ "author": "Stefan George - ",
+ "kind": "dev",
+ "methods": {
+ "addOwner(address)": {
+ "details": "Allows to add a new owner. Transaction has to be sent by wallet.",
+ "params": {
+ "owner": "Address of new owner."
+ }
+ },
+ "changeRequirement(uint256)": {
+ "details": "Allows to change the number of required confirmations. Transaction has to be sent by wallet.",
+ "params": {
+ "_required": "Number of required confirmations."
+ }
+ },
+ "confirmTransaction(uint256)": {
+ "details": "Allows an owner to confirm a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "constructor": {
+ "details": "Contract constructor sets initial owners and required number of confirmations.",
+ "params": {
+ "_owners": "List of initial owners.",
+ "_required": "Number of required confirmations."
+ }
+ },
+ "executeTransaction(uint256)": {
+ "details": "Allows anyone to execute a confirmed transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "getConfirmationCount(uint256)": {
+ "details": "Returns number of confirmations of a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "count": "Number of confirmations."
+ }
+ },
+ "getConfirmations(uint256)": {
+ "details": "Returns array with owner addresses, which confirmed transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "_confirmations": "Returns array of owner addresses."
+ }
+ },
+ "getOwners()": {
+ "details": "Returns list of owners.",
+ "returns": {
+ "_0": "List of owner addresses."
+ }
+ },
+ "getTransactionCount(bool,bool)": {
+ "details": "Returns total number of transactions after filers are applied.",
+ "params": {
+ "executed": "Include executed transactions.",
+ "pending": "Include pending transactions."
+ },
+ "returns": {
+ "count": "Total number of transactions after filters are applied."
+ }
+ },
+ "getTransactionIds(uint256,uint256,bool,bool)": {
+ "details": "Returns list of transaction IDs in defined range.",
+ "params": {
+ "executed": "Include executed transactions.",
+ "from": "Index start position of transaction array.",
+ "pending": "Include pending transactions.",
+ "to": "Index end position of transaction array."
+ },
+ "returns": {
+ "_transactionIds": "Returns array of transaction IDs."
+ }
+ },
+ "isConfirmed(uint256)": {
+ "details": "Returns the confirmation status of a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "_0": "Confirmation status."
+ }
+ },
+ "removeOwner(address)": {
+ "details": "Allows to remove an owner. Transaction has to be sent by wallet.",
+ "params": {
+ "owner": "Address of owner."
+ }
+ },
+ "replaceOwner(address,address)": {
+ "details": "Allows to replace an owner with a new owner. Transaction has to be sent by wallet.",
+ "params": {
+ "newOwner": "Address of new owner.",
+ "owner": "Address of owner to be replaced."
+ }
+ },
+ "revokeConfirmation(uint256)": {
+ "details": "Allows an owner to revoke a confirmation for a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "submitTransaction(address,uint256,bytes)": {
+ "details": "Allows an owner to submit and confirm a transaction.",
+ "params": {
+ "data": "Transaction data payload.",
+ "destination": "Transaction target address.",
+ "value": "Transaction ether value."
+ },
+ "returns": {
+ "transactionId": "Returns transaction ID."
+ }
+ }
+ },
+ "title": "Multisignature wallet - Allows multiple parties to agree on transactions before execution.",
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 52,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "transactions",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_uint256,t_struct(Transaction)78_storage)"
+ },
+ {
+ "astId": 58,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "confirmations",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_mapping(t_uint256,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 62,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "isOwner",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 65,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "owners",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 67,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "required",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 69,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "transactionCount",
+ "offset": 0,
+ "slot": "5",
+ "type": "t_uint256"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes_storage": {
+ "encoding": "bytes",
+ "label": "bytes",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_uint256,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_mapping(t_uint256,t_struct(Transaction)78_storage)": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => struct MultiSigWallet.Transaction)",
+ "numberOfBytes": "32",
+ "value": "t_struct(Transaction)78_storage"
+ },
+ "t_struct(Transaction)78_storage": {
+ "encoding": "inplace",
+ "label": "struct MultiSigWallet.Transaction",
+ "members": [
+ {
+ "astId": 71,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "destination",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ },
+ {
+ "astId": 73,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "value",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 75,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "data",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_bytes_storage"
+ },
+ {
+ "astId": 77,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "executed",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_bool"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/ProxyAdmin.json b/bridge/deployments/rsktestnet/ProxyAdmin.json
new file mode 100644
index 000000000..fe5dd077d
--- /dev/null
+++ b/bridge/deployments/rsktestnet/ProxyAdmin.json
@@ -0,0 +1,261 @@
+{
+ "address": "0x8c35e166d2dea7a8a28aaea11ad7933cdae4b0ab",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeProxyAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ }
+ ],
+ "name": "getProxyAdmin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ }
+ ],
+ "name": "getProxyImplementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgrade",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xccb5efec2a755bdacf9df4f51f512e23701a31e89a59c11fc6bb0f6134c34a2d",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x826e131ADF0fFc77308540966d757B466fa72FFd",
+ "transactionIndex": 0,
+ "gasUsed": "601344",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000100000000000000020000020000000000000800000000000000000000000000000000400000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000020000000000000200000000000000000000000000000000000040000000000000000",
+ "blockHash": "0x23d2689ca13007d1c676dd0836055c3198c867cd10fc217c7808e956e6004304",
+ "transactionHash": "0xccb5efec2a755bdacf9df4f51f512e23701a31e89a59c11fc6bb0f6134c34a2d",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152171,
+ "transactionHash": "0xccb5efec2a755bdacf9df4f51f512e23701a31e89a59c11fc6bb0f6134c34a2d",
+ "address": "0x826e131ADF0fFc77308540966d757B466fa72FFd",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x23d2689ca13007d1c676dd0836055c3198c867cd10fc217c7808e956e6004304"
+ }
+ ],
+ "blockNumber": 2152171,
+ "cumulativeGasUsed": "601344",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\",\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"details\":\"Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`.\"},\"getProxyAdmin(address)\":{\"details\":\"Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"getProxyImplementation(address)\":{\"details\":\"Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"details\":\"Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`.\"},\"upgradeAndCall(address,address,bytes)\":{\"details\":\"Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol\":\"ProxyAdmin\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../GSN/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () {\\n _owner = _msgSender();\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x82fe89d36187df48c5e24e6ca1cf0566f4b0c0a3bd8da835ab64100e28d21b62\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0x590a4d952d39a99972cbcb691b472c5d58af9ae8fd142355ad26200affdd2a51\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../../ownership/Ownable.sol\\\";\\nimport \\\"./TransparentUpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\\n */\\ncontract ProxyAdmin is Ownable {\\n\\n /**\\n * @dev Returns the current implementation of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"implementation()\\\")) == 0x5c60da1b\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"5c60da1b\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Returns the current admin of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"admin()\\\")) == 0xf851a440\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"f851a440\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Changes the admin of `proxy` to `newAdmin`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the current admin of `proxy`.\\n */\\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\\n proxy.changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\\n proxy.upgradeTo(implementation);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\\n }\\n}\\n\",\"keccak256\":\"0x808ad1c30093ccfc011509c642615a9bad84d0e1eced5327fe50d3ec145a9899\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x0d5202a38732881d576fe3831605fe2633e1bc9f981ebea9c3a368af027e0b71\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x53b00bc48bd4eac1e100195c494267c0ca082bd91ac3018e2ee6155fbcbbb14f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50610019610066565b600080546001600160a01b0319166001600160a01b03928316178082556040519216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a361006a565b3390565b61079e806100796000396000f3fe6080604052600436106100865760003560e01c80638f32d59b116100595780638f32d59b1461010d5780639623609d1461012f57806399a88ec414610142578063f2fde38b14610162578063f3b7dead1461018257610086565b8063204e1c7a1461008b578063715018a6146100c15780637eff275e146100d85780638da5cb5b146100f8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610503565b6101a2565b6040516100b89190610656565b60405180910390f35b3480156100cd57600080fd5b506100d6610228565b005b3480156100e457600080fd5b506100d66100f3366004610542565b61029f565b34801561010457600080fd5b506100ab610325565b34801561011957600080fd5b50610122610334565b6040516100b891906106cd565b6100d661013d36600461057a565b610358565b34801561014e57600080fd5b506100d661015d366004610542565b6103e3565b34801561016e57600080fd5b506100d661017d366004610503565b610433565b34801561018e57600080fd5b506100ab61019d366004610503565b610463565b6000806000836001600160a01b03166040516101bd90610636565b600060405180830381855afa9150503d80600081146101f8576040519150601f19603f3d011682016040523d82523d6000602084013e6101fd565b606091505b50915091508161020c57600080fd5b808060200190518101906102209190610526565b949350505050565b610230610334565b6102555760405162461bcd60e51b815260040161024c9061071e565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6102a7610334565b6102c35760405162461bcd60e51b815260040161024c9061071e565b6040516308f2839760e41b81526001600160a01b03831690638f283970906102ef908490600401610656565b600060405180830381600087803b15801561030957600080fd5b505af115801561031d573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031690565b600080546001600160a01b031661034961047e565b6001600160a01b031614905090565b610360610334565b61037c5760405162461bcd60e51b815260040161024c9061071e565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906103ac908690869060040161066a565b6000604051808303818588803b1580156103c557600080fd5b505af11580156103d9573d6000803e3d6000fd5b5050505050505050565b6103eb610334565b6104075760405162461bcd60e51b815260040161024c9061071e565b604051631b2ce7f360e11b81526001600160a01b03831690633659cfe6906102ef908490600401610656565b61043b610334565b6104575760405162461bcd60e51b815260040161024c9061071e565b61046081610482565b50565b6000806000836001600160a01b03166040516101bd90610646565b3390565b6001600160a01b0381166104a85760405162461bcd60e51b815260040161024c906106d8565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600060208284031215610514578081fd5b813561051f81610753565b9392505050565b600060208284031215610537578081fd5b815161051f81610753565b60008060408385031215610554578081fd5b823561055f81610753565b9150602083013561056f81610753565b809150509250929050565b60008060006060848603121561058e578081fd5b833561059981610753565b92506020848101356105aa81610753565b9250604085013567ffffffffffffffff808211156105c6578384fd5b818701915087601f8301126105d9578384fd5b8135818111156105e557fe5b604051601f8201601f191681018501838111828210171561060257fe5b60405281815283820185018a1015610618578586fd5b81858501868301378585838301015280955050505050509250925092565b635c60da1b60e01b815260040190565b6303e1469160e61b815260040190565b6001600160a01b0391909116815260200190565b600060018060a01b038416825260206040818401528351806040850152825b818110156106a557858101830151858201606001528201610689565b818111156106b65783606083870101525b50601f01601f191692909201606001949350505050565b901515815260200190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6001600160a01b038116811461046057600080fdfea2646970667358221220142b10fc4fdd881bdff70408546e1b1005f22944adc6b0a0da6becaf7c2b47a164736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106100865760003560e01c80638f32d59b116100595780638f32d59b1461010d5780639623609d1461012f57806399a88ec414610142578063f2fde38b14610162578063f3b7dead1461018257610086565b8063204e1c7a1461008b578063715018a6146100c15780637eff275e146100d85780638da5cb5b146100f8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610503565b6101a2565b6040516100b89190610656565b60405180910390f35b3480156100cd57600080fd5b506100d6610228565b005b3480156100e457600080fd5b506100d66100f3366004610542565b61029f565b34801561010457600080fd5b506100ab610325565b34801561011957600080fd5b50610122610334565b6040516100b891906106cd565b6100d661013d36600461057a565b610358565b34801561014e57600080fd5b506100d661015d366004610542565b6103e3565b34801561016e57600080fd5b506100d661017d366004610503565b610433565b34801561018e57600080fd5b506100ab61019d366004610503565b610463565b6000806000836001600160a01b03166040516101bd90610636565b600060405180830381855afa9150503d80600081146101f8576040519150601f19603f3d011682016040523d82523d6000602084013e6101fd565b606091505b50915091508161020c57600080fd5b808060200190518101906102209190610526565b949350505050565b610230610334565b6102555760405162461bcd60e51b815260040161024c9061071e565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6102a7610334565b6102c35760405162461bcd60e51b815260040161024c9061071e565b6040516308f2839760e41b81526001600160a01b03831690638f283970906102ef908490600401610656565b600060405180830381600087803b15801561030957600080fd5b505af115801561031d573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031690565b600080546001600160a01b031661034961047e565b6001600160a01b031614905090565b610360610334565b61037c5760405162461bcd60e51b815260040161024c9061071e565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906103ac908690869060040161066a565b6000604051808303818588803b1580156103c557600080fd5b505af11580156103d9573d6000803e3d6000fd5b5050505050505050565b6103eb610334565b6104075760405162461bcd60e51b815260040161024c9061071e565b604051631b2ce7f360e11b81526001600160a01b03831690633659cfe6906102ef908490600401610656565b61043b610334565b6104575760405162461bcd60e51b815260040161024c9061071e565b61046081610482565b50565b6000806000836001600160a01b03166040516101bd90610646565b3390565b6001600160a01b0381166104a85760405162461bcd60e51b815260040161024c906106d8565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600060208284031215610514578081fd5b813561051f81610753565b9392505050565b600060208284031215610537578081fd5b815161051f81610753565b60008060408385031215610554578081fd5b823561055f81610753565b9150602083013561056f81610753565b809150509250929050565b60008060006060848603121561058e578081fd5b833561059981610753565b92506020848101356105aa81610753565b9250604085013567ffffffffffffffff808211156105c6578384fd5b818701915087601f8301126105d9578384fd5b8135818111156105e557fe5b604051601f8201601f191681018501838111828210171561060257fe5b60405281815283820185018a1015610618578586fd5b81858501868301378585838301015280955050505050509250925092565b635c60da1b60e01b815260040190565b6303e1469160e61b815260040190565b6001600160a01b0391909116815260200190565b600060018060a01b038416825260206040818401528351806040850152825b818110156106a557858101830151858201606001528201610689565b818111156106b65783606083870101525b50601f01601f191692909201606001949350505050565b901515815260200190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6001600160a01b038116811461046057600080fdfea2646970667358221220142b10fc4fdd881bdff70408546e1b1005f22944adc6b0a0da6becaf7c2b47a164736f6c63430007060033",
+ "devdoc": {
+ "details": "This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.",
+ "kind": "dev",
+ "methods": {
+ "changeProxyAdmin(address,address)": {
+ "details": "Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`."
+ },
+ "getProxyAdmin(address)": {
+ "details": "Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "getProxyImplementation(address)": {
+ "details": "Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "upgrade(address,address)": {
+ "details": "Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "upgradeAndCall(address,address,bytes)": {
+ "details": "Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 10887,
+ "contract": "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol:ProxyAdmin",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/SideTokenFactory.json b/bridge/deployments/rsktestnet/SideTokenFactory.json
new file mode 100644
index 000000000..d0b47bae2
--- /dev/null
+++ b/bridge/deployments/rsktestnet/SideTokenFactory.json
@@ -0,0 +1,173 @@
+{
+ "address": "0x08C191A7B5Edaa59853705F7eaE95E3E4238D73e",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "SideTokenCreated",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xf071cbcee4df45bf0ae491286231caef0506950be07a1abcbc958b9fd4f2a393",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0xbB74098e1F6F95198209bA30BA92725a6CCd5eab",
+ "transactionIndex": 0,
+ "gasUsed": "3175216",
+ "logsBloom": "0x08000400000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000100000",
+ "blockHash": "0x79b80ecb04e871e6dfecafd5fe3a5df3b027a87a2268ac97a843fcdea8e78280",
+ "transactionHash": "0xf071cbcee4df45bf0ae491286231caef0506950be07a1abcbc958b9fd4f2a393",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152177,
+ "transactionHash": "0xf071cbcee4df45bf0ae491286231caef0506950be07a1abcbc958b9fd4f2a393",
+ "address": "0xbB74098e1F6F95198209bA30BA92725a6CCd5eab",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ],
+ "data": "0x000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8",
+ "logIndex": 0,
+ "blockHash": "0x79b80ecb04e871e6dfecafd5fe3a5df3b027a87a2268ac97a843fcdea8e78280"
+ }
+ ],
+ "blockNumber": 2152177,
+ "cumulativeGasUsed": "3175216",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"granularity\",\"type\":\"uint256\"}],\"name\":\"SideTokenCreated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"granularity\",\"type\":\"uint256\"}],\"name\":\"createSideToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/SideTokenFactory/SideTokenFactory.sol\":\"SideTokenFactory\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/SideToken/SideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../zeppelin/token/ERC777/ERC777.sol\\\";\\nimport \\\"../interface/IERC677Receiver.sol\\\";\\nimport \\\"../interface/ISideToken.sol\\\";\\nimport \\\"../lib/LibEIP712.sol\\\";\\n\\ncontract SideToken is ISideToken, ERC777 {\\n using Address for address;\\n using SafeMath for uint256;\\n\\n address public minter;\\n uint256 private _granularity;\\n\\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\\n bytes32 public domainSeparator;\\n // keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\\n mapping(address => uint) public nonces;\\n\\n // ERC677 Transfer Event\\n event Transfer(address,address,uint256,bytes);\\n\\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\\n require(_minterAddr != address(0), \\\"SideToken: Empty Minter\\\");\\n require(_newGranularity >= 1, \\\"SideToken: Granularity < 1\\\");\\n minter = _minterAddr;\\n _granularity = _newGranularity;\\n\\n uint chainId;\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n chainId := chainid()\\n }\\n domainSeparator = LibEIP712.hashEIP712Domain(\\n name(),\\n \\\"1\\\",\\n chainId,\\n address(this)\\n );\\n }\\n\\n modifier onlyMinter() {\\n require(_msgSender() == minter, \\\"SideToken: Caller is not the minter\\\");\\n _;\\n }\\n\\n function mint(\\n address account,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n )\\n external onlyMinter override\\n {\\n _mint(_msgSender(), account, amount, userData, operatorData);\\n }\\n\\n /**\\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\\n * @param recipient The address to transfer to.\\n * @param amount The amount to be transferred.\\n * @param data The extra data to be passed to the receiving contract.\\n */\\n function transferAndCall(address recipient, uint amount, bytes calldata data)\\n external returns (bool success)\\n {\\n address from = _msgSender();\\n\\n _send(from, from, recipient, amount, data, \\\"\\\", false);\\n emit Transfer(from, recipient, amount, data);\\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\\n return true;\\n }\\n\\n function granularity() public view override returns (uint256) {\\n return _granularity;\\n }\\n\\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\\n require(deadline >= block.timestamp, \\\"SideToken: EXPIRED\\\"); // solhint-disable-line not-rely-on-time\\n bytes32 digest = LibEIP712.hashEIP712Message(\\n domainSeparator,\\n keccak256(\\n abi.encode(\\n PERMIT_TYPEHASH,\\n owner,\\n spender,\\n value,\\n nonces[owner]++,\\n deadline\\n )\\n )\\n );\\n address recoveredAddress = ecrecover(digest, v, r, s);\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"SideToken: INVALID_SIGNATURE\\\");\\n _approve(owner, spender, value);\\n }\\n\\n}\",\"keccak256\":\"0x4f6915fef50725cfde92986c2e2c83c80758b7de6d863d125974c1e1b5c47c82\",\"license\":\"MIT\"},\"contracts/SideTokenFactory/SideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../zeppelin/ownership/Secondary.sol\\\";\\nimport \\\"../interface/ISideTokenFactory.sol\\\";\\nimport \\\"../SideToken/SideToken.sol\\\";\\n\\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\\n\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\\n external onlyPrimary override returns(address) {\\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\\n emit SideTokenCreated(sideToken, symbol, granularity);\\n return sideToken;\\n }\\n}\",\"keccak256\":\"0xd777e928d953e0bc0f31cbcaa50b9e10eb501fd580fe7b32da279833824def44\",\"license\":\"MIT\"},\"contracts/interface/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\\n}\",\"keccak256\":\"0xea0204863235cba5119f6c54b594ea1eefa84e4741ee607ed7ee05f62cb2d9e0\",\"license\":\"MIT\"},\"contracts/interface/ISideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\ninterface ISideToken {\\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\\n}\",\"keccak256\":\"0xf01477bc820f57970d7d8384417ac0aead22bd336077e371c48da917270013b4\",\"license\":\"MIT\"},\"contracts/interface/ISideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\ninterface ISideTokenFactory {\\n\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\\n\\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\\n}\",\"keccak256\":\"0x550c1af5fa52739ac28f58c36f04ba634213c5307ae95b412e41f3ee1d2e7217\",\"license\":\"MIT\"},\"contracts/lib/LibEIP712.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\\nlibrary LibEIP712 {\\n\\n // Hash of the EIP712 Domain Separator Schema\\n // keccak256(abi.encodePacked(\\n // \\\"EIP712Domain(\\\",\\n // \\\"string name,\\\",\\n // \\\"string version,\\\",\\n // \\\"uint256 chainId,\\\",\\n // \\\"address verifyingContract\\\",\\n // \\\")\\\"\\n // ))\\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\\n\\n /// @dev Calculates a EIP712 domain separator.\\n /// @param name The EIP712 domain name.\\n /// @param version The EIP712 domain version.\\n /// @param verifyingContract The EIP712 verifying contract.\\n /// @return result EIP712 domain separator.\\n function hashEIP712Domain(\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract\\n )\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\\n\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\\n // keccak256(bytes(name)),\\n // keccak256(bytes(version)),\\n // chainId,\\n // uint256(verifyingContract)\\n // ))\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Calculate hashes of dynamic data\\n let nameHash := keccak256(add(name, 32), mload(name))\\n let versionHash := keccak256(add(version, 32), mload(version))\\n\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n // Store params in memory\\n mstore(memPtr, schemaHash)\\n mstore(add(memPtr, 32), nameHash)\\n mstore(add(memPtr, 64), versionHash)\\n mstore(add(memPtr, 96), chainId)\\n mstore(add(memPtr, 128), verifyingContract)\\n\\n // Compute hash\\n result := keccak256(memPtr, 160)\\n }\\n return result;\\n }\\n\\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\\n /// with getDomainHash().\\n /// @param hashStruct The EIP712 hash struct.\\n /// @return result EIP712 hash applied to the given EIP712 Domain.\\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // EIP191_HEADER,\\n // EIP712_DOMAIN_HASH,\\n // hashStruct\\n // ));\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\\n\\n // Compute hash\\n result := keccak256(memPtr, 66)\\n }\\n return result;\\n }\\n}\",\"keccak256\":\"0x6116e22c413fc65e87bf7db958d5c1f301b493494813f76dce512f8254c3b012\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC1820Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\n * implementers for interfaces in this registry, as well as query support.\\n *\\n * Implementers may be shared by multiple accounts, and can also implement more\\n * than a single interface for each account. Contracts can implement interfaces\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\n * contract.\\n *\\n * {IERC165} interfaces can also be queried via the registry.\\n *\\n * For an in-depth explanation and source code analysis, see the EIP text.\\n */\\ninterface IERC1820Registry {\\n /**\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\n * account is able to set interface implementers for it.\\n *\\n * By default, each account is its own manager. Passing a value of `0x0` in\\n * `newManager` will reset the manager to this initial state.\\n *\\n * Emits a {ManagerChanged} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `account`.\\n */\\n function setManager(address account, address newManager) external;\\n\\n /**\\n * @dev Returns the manager for `account`.\\n *\\n * See {setManager}.\\n */\\n function getManager(address account) external view returns (address);\\n\\n /**\\n * @dev Sets the `implementer` contract as `account`'s implementer for\\n * `interfaceHash`.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n * The zero address can also be used in `implementer` to remove an old one.\\n *\\n * See {interfaceHash} to learn how these are created.\\n *\\n * Emits an {InterfaceImplementerSet} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `_account`.\\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\n * end in 28 zeroes).\\n * - `_implementer` must implement {IERC1820Implementer} and return true when\\n * queried for support, unless `implementer` is the caller. See\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\n */\\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\\n\\n /**\\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\\n * implementer is registered, returns the zero address.\\n *\\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\n * zeroes), `_account` will be queried for support of it.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n */\\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\\n\\n /**\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\n * corresponding\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\n */\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\n\\n /**\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\n * @param account Address of the contract for which to update the cache.\\n * @param interfaceId ERC165 interface for which to update the cache.\\n */\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\n * If the result is not cached a direct lookup on the contract address is performed.\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\n * {updateERC165Cache} with the contract address.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\n\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\n\\n event ManagerChanged(address indexed account, address indexed newManager);\\n}\\n\",\"keccak256\":\"0x1b44f619ae588fd201e93b126b80576e1244ef468e8b4e54e62fbad6a805cc87\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x09ca2716452528a6e69ac9f83f874292a1e547630473f3133038314a2f16029e\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Secondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../GSN/Context.sol\\\";\\n/**\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\n */\\nabstract contract Secondary is Context {\\n address private _primary;\\n\\n /**\\n * @dev Emitted when the primary contract changes.\\n */\\n event PrimaryTransferred(\\n address recipient\\n );\\n\\n /**\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\n */\\n constructor () {\\n _primary = _msgSender();\\n emit PrimaryTransferred(_primary);\\n }\\n\\n /**\\n * @dev Reverts if called from any account other than the primary.\\n */\\n modifier onlyPrimary() {\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\n _;\\n }\\n\\n /**\\n * @return the address of the primary.\\n */\\n function primary() public view returns (address) {\\n return _primary;\\n }\\n\\n /**\\n * @dev Transfers contract to a new primary.\\n * @param recipient The address of new primary.\\n */\\n function transferPrimary(address recipient) public onlyPrimary {\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\n _primary = recipient;\\n emit PrimaryTransferred(_primary);\\n }\\n}\\n\",\"keccak256\":\"0x79b3afb98ca1e12e33c63da57ca460fc217f2110a4fa1c18c67a7d84e048d285\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {ERC20Detailed}.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x1bc9527655c4be58541c2fb90c0a05952938961c289f505c70160f87e08aef33\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/ERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"./IERC777.sol\\\";\\nimport \\\"./IERC777Recipient.sol\\\";\\nimport \\\"./IERC777Sender.sol\\\";\\nimport \\\"../../token/ERC20/IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../introspection/IERC1820Registry.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC777} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n *\\n * Support for ERC20 is included in this contract, as specified by the EIP: both\\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\\n * movements.\\n *\\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\\n * are no special restrictions in the amount of tokens that created, moved, or\\n * destroyed. This makes integration with ERC20 applications seamless.\\n */\\ncontract ERC777 is Context, IERC777, IERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\n\\n mapping(address => uint256) private _balances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\\n // See https://github.com/ethereum/solidity/issues/4024.\\n\\n // keccak256(\\\"ERC777TokensSender\\\")\\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\\n\\n // keccak256(\\\"ERC777TokensRecipient\\\")\\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\\n\\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\\n address[] private _defaultOperatorsArray;\\n\\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\\n mapping(address => bool) private _defaultOperators;\\n\\n // For each account, a mapping of its operators and revoked default operators.\\n mapping(address => mapping(address => bool)) private _operators;\\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\\n\\n // ERC20-allowances\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n /**\\n * @dev `defaultOperators` may be an empty array.\\n */\\n constructor(\\n string memory aName,\\n string memory aSymbol,\\n address[] memory theDefaultOperators\\n ) {\\n _name = aName;\\n _symbol = aSymbol;\\n\\n _defaultOperatorsArray = theDefaultOperators;\\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\\n _defaultOperators[_defaultOperatorsArray[i]] = true;\\n }\\n\\n // register interfaces\\n _erc1820.setInterfaceImplementer(address(this), keccak256(\\\"ERC777Token\\\"), address(this));\\n _erc1820.setInterfaceImplementer(address(this), keccak256(\\\"ERC20Token\\\"), address(this));\\n }\\n\\n /**\\n * @dev See {IERC777-name}.\\n */\\n function name() public view override(IERC777) returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC777-symbol}.\\n */\\n function symbol() public view override(IERC777) returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {ERC20Detailed-decimals}.\\n *\\n * Always returns 18, as per the\\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\\n */\\n function decimals() public pure override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC777-granularity}.\\n *\\n * This implementation always returns `1`.\\n */\\n function granularity() public view virtual override(IERC777) returns (uint256) {\\n return 1;\\n }\\n\\n /**\\n * @dev See {IERC777-totalSupply}.\\n */\\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\\n */\\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\\n return _balances[tokenHolder];\\n }\\n\\n /**\\n * @dev See {IERC777-send}.\\n *\\n * Also emits a {Transfer} event for ERC20 compatibility.\\n */\\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\\n _send(_msgSender(), _msgSender(), recipient, amount, data, \\\"\\\", true);\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\\n * interface if it is a contract.\\n *\\n * Also emits a {Sent} event.\\n */\\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\\n require(recipient != address(0), \\\"ERC777: transfer to zero address\\\");\\n\\n address from = _msgSender();\\n\\n _callTokensToSend(from, from, recipient, amount, \\\"\\\", \\\"\\\");\\n\\n _move(from, from, recipient, amount, \\\"\\\", \\\"\\\");\\n\\n _callTokensReceived(from, from, recipient, amount, \\\"\\\", \\\"\\\", false);\\n\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC777-burn}.\\n *\\n * Also emits a {Transfer} event for ERC20 compatibility.\\n */\\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\\n _burn(_msgSender(), _msgSender(), amount, data, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC777-isOperatorFor}.\\n */\\n function isOperatorFor(\\n address operator,\\n address tokenHolder\\n ) public view override(IERC777) returns (bool) {\\n return operator == tokenHolder ||\\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\\n _operators[tokenHolder][operator];\\n }\\n\\n /**\\n * @dev See {IERC777-authorizeOperator}.\\n */\\n function authorizeOperator(address operator) external override(IERC777) {\\n require(_msgSender() != operator, \\\"ERC777: authorizing self as operator\\\");\\n\\n if (_defaultOperators[operator]) {\\n delete _revokedDefaultOperators[_msgSender()][operator];\\n } else {\\n _operators[_msgSender()][operator] = true;\\n }\\n\\n emit AuthorizedOperator(operator, _msgSender());\\n }\\n\\n /**\\n * @dev See {IERC777-revokeOperator}.\\n */\\n function revokeOperator(address operator) external override(IERC777) {\\n require(operator != _msgSender(), \\\"ERC777: revoking self as operator\\\");\\n\\n if (_defaultOperators[operator]) {\\n _revokedDefaultOperators[_msgSender()][operator] = true;\\n } else {\\n delete _operators[_msgSender()][operator];\\n }\\n\\n emit RevokedOperator(operator, _msgSender());\\n }\\n\\n /**\\n * @dev See {IERC777-defaultOperators}.\\n */\\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\\n return _defaultOperatorsArray;\\n }\\n\\n /**\\n * @dev See {IERC777-operatorSend}.\\n *\\n * Emits {Sent} and {Transfer} events.\\n */\\n function operatorSend(\\n address sender,\\n address recipient,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n )\\n external override(IERC777)\\n {\\n require(isOperatorFor(_msgSender(), sender), \\\"ERC777: caller is not an operator\\\");\\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\\n }\\n\\n /**\\n * @dev See {IERC777-operatorBurn}.\\n *\\n * Emits {Burned} and {Transfer} events.\\n */\\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\\n external override(IERC777) {\\n require(isOperatorFor(_msgSender(), account), \\\"ERC777: caller is not an operator\\\");\\n _burn(_msgSender(), account, amount, data, operatorData);\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n *\\n * Note that operator and allowance concepts are orthogonal: operators may\\n * not have allowance, and accounts with allowance may not be operators\\n * themselves.\\n */\\n function allowance(address holder, address spender)\\n public view override(IERC20) returns (uint256) {\\n return _allowances[holder][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Note that accounts cannot have allowance issued by their operators.\\n */\\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\\n address holder = _msgSender();\\n _approve(holder, spender, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Note that operator and allowance concepts are orthogonal: operators cannot\\n * call `transferFrom` (unless they have allowance), and accounts with\\n * allowance cannot call `operatorSend` (unless they are operators).\\n *\\n * Emits {Sent}, {Transfer} and {Approval} events.\\n */\\n function transferFrom(address holder, address recipient, uint256 amount)\\n external override(IERC20) returns (bool) {\\n require(recipient != address(0), \\\"ERC777: transfer to zero address\\\");\\n require(holder != address(0), \\\"ERC777: transfer from zero address\\\");\\n\\n address spender = _msgSender();\\n\\n _callTokensToSend(spender, holder, recipient, amount, \\\"\\\", \\\"\\\");\\n\\n _move(spender, holder, recipient, amount, \\\"\\\", \\\"\\\");\\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \\\"ERC777: transfer amount exceeds allowance\\\"));\\n\\n _callTokensReceived(spender, holder, recipient, amount, \\\"\\\", \\\"\\\", false);\\n\\n return true;\\n }\\n\\n /**\\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * If a send hook is registered for `account`, the corresponding function\\n * will be called with `operator`, `data` and `operatorData`.\\n *\\n * See {IERC777Sender} and {IERC777Recipient}.\\n *\\n * Emits {Minted} and {Transfer} events.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - if `account` is a contract, it must implement the {IERC777Recipient}\\n * interface.\\n */\\n function _mint(\\n address operator,\\n address account,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData\\n )\\n internal\\n {\\n require(account != address(0), \\\"ERC777: mint to zero address\\\");\\n\\n // Update state variables\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n\\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\\n\\n emit Minted(operator, account, amount, userData, operatorData);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Send tokens\\n * @param operator address operator requesting the transfer\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\\n */\\n function _send(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData,\\n bool requireReceptionAck\\n )\\n internal\\n {\\n require(from != address(0), \\\"ERC777: send from zero address\\\");\\n require(to != address(0), \\\"ERC777: send to zero address\\\");\\n\\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\\n\\n _move(operator, from, to, amount, userData, operatorData);\\n\\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\\n }\\n\\n /**\\n * @dev Burn tokens\\n * @param operator address operator requesting the operation\\n * @param from address token holder address\\n * @param amount uint256 amount of tokens to burn\\n * @param data bytes extra information provided by the token holder\\n * @param operatorData bytes extra information provided by the operator (if any)\\n */\\n function _burn(\\n address operator,\\n address from,\\n uint256 amount,\\n bytes memory data,\\n bytes memory operatorData\\n )\\n internal\\n {\\n require(from != address(0), \\\"ERC777: burn from zero address\\\");\\n\\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\\n\\n // Update state variables\\n _balances[from] = _balances[from].sub(amount, \\\"ERC777: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n\\n emit Burned(operator, from, amount, data, operatorData);\\n emit Transfer(from, address(0), amount);\\n }\\n\\n function _move(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData\\n )\\n internal\\n {\\n _balances[from] = _balances[from].sub(amount, \\\"ERC777: transfer amount exceeds balance\\\");\\n _balances[to] = _balances[to].add(amount);\\n\\n emit Sent(operator, from, to, amount, userData, operatorData);\\n emit Transfer(from, to, amount);\\n }\\n\\n function _approve(address holder, address spender, uint256 value) internal {\\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\\n // currently unnecessary.\\n //require(holder != address(0), \\\"ERC777: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC777: approve to zero address\\\");\\n\\n _allowances[holder][spender] = value;\\n emit Approval(holder, spender, value);\\n }\\n\\n /**\\n * @dev Call from.tokensToSend() if the interface is registered\\n * @param operator address operator requesting the transfer\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n */\\n function _callTokensToSend(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData\\n )\\n internal\\n {\\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\\n if (implementer != address(0)) {\\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\\n }\\n }\\n\\n /**\\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\\n * tokensReceived() was not registered for the recipient\\n * @param operator address operator requesting the transfer\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\\n */\\n function _callTokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData,\\n bool requireReceptionAck\\n )\\n private\\n {\\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\\n if (implementer != address(0)) {\\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\\n } else if (requireReceptionAck) {\\n require(!to.isContract(), \\\"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xcde4544ee18969a20b184e0acccecfa116a5abbfd9c2a1ebd4dcafc7b65cfc86\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777Token standard as defined in the EIP.\\n *\\n * This contract uses the\\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\\n * token holders and recipients react to token movements by using setting implementers\\n * for the associated interfaces in said registry. See `IERC1820Registry` and\\n * `ERC1820Implementer`.\\n */\\ninterface IERC777 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the smallest part of the token that is not divisible. This\\n * means all token operations (creation, movement and destruction) must have\\n * amounts that are a multiple of this number.\\n *\\n * For most token contracts, this value will equal 1.\\n */\\n function granularity() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by an account (`owner`).\\n */\\n function balanceOf(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * If send or receive hooks are registered for the caller and `recipient`,\\n * the corresponding functions will be called with `data` and empty\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function send(address recipient, uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Destroys `amount` tokens from the caller's account, reducing the\\n * total supply.\\n *\\n * If a send hook is registered for the caller, the corresponding function\\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n */\\n function burn(uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Returns true if an account is an operator of `tokenHolder`.\\n * Operators can send and burn tokens on behalf of their owners. All\\n * accounts are their own operator.\\n *\\n * See `operatorSend` and `operatorBurn`.\\n */\\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor`.\\n *\\n * Emits an `AuthorizedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function authorizeOperator(address operator) external;\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor` and `defaultOperators`.\\n *\\n * Emits a `RevokedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function revokeOperator(address operator) external;\\n\\n /**\\n * @dev Returns the list of default operators. These accounts are operators\\n * for all token holders, even if `authorizeOperator` was never called on\\n * them.\\n *\\n * This list is immutable, but individual holders may revoke these via\\n * `revokeOperator`, in which case `isOperatorFor` will return false.\\n */\\n function defaultOperators() external view returns (address[] memory);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\\n * be an operator of `sender`.\\n *\\n * If send or receive hooks are registered for `sender` and `recipient`,\\n * the corresponding functions will be called with `data` and\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - `sender` cannot be the zero address.\\n * - `sender` must have at least `amount` tokens.\\n * - the caller must be an operator for `sender`.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function operatorSend(\\n address sender,\\n address recipient,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n /**\\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\\n * The caller must be an operator of `account`.\\n *\\n * If a send hook is registered for `account`, the corresponding function\\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n * - the caller must be an operator for `account`.\\n */\\n function operatorBurn(\\n address account,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n event Sent(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256 amount,\\n bytes data,\\n bytes operatorData\\n );\\n\\n function decimals() external returns (uint8);\\n\\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\\n\\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\\n\\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\\n\\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\\n}\\n\",\"keccak256\":\"0x9ace3cf83443ae90a995a8e33652238fa2b5afb258897757f85467d5fb437c1a\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\n *\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an `IERC777` token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0xc8dae3544a459d13f23ba0c7737f6e279e06d83ef86b8f7a0318d83bcf4147e3\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Sender.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\\n *\\n * `IERC777` Token holders can be notified of operations performed on their\\n * tokens by having a contract implement this interface (contract holders can be\\n * their own implementer) and registering it on the\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\n *\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\n */\\ninterface IERC777Sender {\\n /**\\n * @dev Called by an `IERC777` token contract whenever a registered holder's\\n * (`from`) tokens are about to be moved or destroyed. The type of operation\\n * is conveyed by `to` being the zero address or not.\\n *\\n * This call occurs _before_ the token contract's state is updated, so\\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensToSend(\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x222036566a212defc97ef08e8f41f08dbc4880c69839f0e8d76f4d4d2406c862\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50610019610074565b600080546001600160a01b0319166001600160a01b0392831617908190556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610067921690610078565b60405180910390a161008c565b3390565b6001600160a01b0391909116815260200190565b612d628061009b6000396000f3fe60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b57806326d9e9631462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002b8565b6200009d565b005b6200007b62000075366004620002e8565b6200016c565b6040516200008a91906200038a565b60405180910390f35b6200007b6200024d565b6000546001600160a01b0316620000b36200025c565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000458565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc906200040e565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992620001619216906200038a565b60405180910390a150565b600080546001600160a01b0316620001836200025c565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000458565b600086868686620001bc6200024d565b87604051620001cb9062000260565b620001dc969594939291906200039e565b604051809103906000f080158015620001f9573d6000803e3d6000fd5b509050806001600160a01b03167ff57d2ded8330a4affd2fa52378069be534fe22288536537d1a1cfc06151845078686866040516200023b93929190620003e8565b60405180910390a29695505050505050565b6000546001600160a01b031690565b3390565b61288880620004a583390190565b60008083601f84011262000280578182fd5b50813567ffffffffffffffff81111562000298578182fd5b602083019150836020828501011115620002b157600080fd5b9250929050565b600060208284031215620002ca578081fd5b81356001600160a01b0381168114620002e1578182fd5b9392505050565b60008060008060006060868803121562000300578081fd5b853567ffffffffffffffff8082111562000318578283fd5b6200032689838a016200026e565b909750955060208801359150808211156200033f578283fd5b506200034e888289016200026e565b96999598509660400135949350505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060808252620003b460808301888a62000360565b8281036020840152620003c981878962000360565b6001600160a01b03959095166040840152505060600152949350505050565b600060408252620003fe60408301858762000360565b9050826020830152949350505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b506040516200288838038062002888833981016040819052620000349162000561565b60408051600081526020808201909252855186928692916200005d9160029190860190620003c2565b50815162000073906003906020850190620003c2565b5080516200008990600490602084019062000457565b5060005b600454811015620000e95760016005600060048481548110620000ac57fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff19169115159190911790556001016200008d565b506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90620001479030907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054908290600401620005f0565b600060405180830381600087803b1580156200016257600080fd5b505af115801562000177573d6000803e3d6000fd5b50506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad2492506329965a1d9150620001d89030907faea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a908290600401620005f0565b600060405180830381600087803b158015620001f357600080fd5b505af115801562000208573d6000803e3d6000fd5b50505050506001600160a01b038416151591506200024590505760405162461bcd60e51b81526004016200023c9062000613565b60405180910390fd5b6001811015620002695760405162461bcd60e51b81526004016200023c906200064a565b600980546001600160a01b0319166001600160a01b038416179055600a81905546620002c562000298620002d4565b604051806040016040528060018152602001603160f81b81525083306200036b60201b62000fa41760201c565b600b5550620006819350505050565b60028054604080516020601f6000196101006001871615020190941685900493840181900481028201810190925282815260609390929091830182828015620003615780601f10620003355761010080835404028352916020019162000361565b820191906000526020600020905b8154815290600101906020018083116200034357829003601f168201915b5050505050905090565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620003fa576000855562000445565b82601f106200041557805160ff191683800117855562000445565b8280016001018555821562000445579182015b828111156200044557825182559160200191906001019062000428565b5062000453929150620004af565b5090565b82805482825590600052602060002090810192821562000445579160200282015b828111156200044557825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000478565b5b80821115620004535760008155600101620004b0565b600082601f830112620004d7578081fd5b81516001600160401b0380821115620004ec57fe5b6040516020601f8401601f19168201810183811183821017156200050c57fe5b604052838252858401810187101562000523578485fd5b8492505b8383101562000546578583018101518284018201529182019162000527565b838311156200055757848185840101525b5095945050505050565b6000806000806080858703121562000577578384fd5b84516001600160401b03808211156200058e578586fd5b6200059c88838901620004c6565b95506020870151915080821115620005b2578485fd5b50620005c187828801620004c6565b604087015190945090506001600160a01b0381168114620005e0578283fd5b6060959095015193969295505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b6020808252601a908201527f53696465546f6b656e3a204772616e756c6172697479203c2031000000000000604082015260600190565b6121f780620006916000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80637ecebe00116100de578063d95b637111610097578063f698da2511610071578063f698da2514610308578063fad8b32a14610310578063fc673c4f14610323578063fe9d93031461033657610173565b8063d95b6371146102cf578063dcdc7dd0146102e2578063dd62ed3e146102f557610173565b80637ecebe0014610268578063959b8c3f1461027b57806395d89b411461028e5780639bd9bbc614610296578063a9059cbb146102a9578063d505accf146102bc57610173565b806330adf81f1161013057806330adf81f14610208578063313ce567146102105780634000aea014610225578063556f0dc71461023857806362ad1b831461024057806370a082311461025557610173565b806306e485381461017857806306fdde031461019657806307546172146101ab578063095ea7b3146101c057806318160ddd146101e057806323b872dd146101f5575b600080fd5b610180610349565b60405161018d9190611c97565b60405180910390f35b61019e6103ab565b60405161018d9190611d4a565b6101b3610435565b60405161018d9190611b9f565b6101d36101ce3660046119d2565b610444565b60405161018d9190611ce4565b6101e8610466565b60405161018d9190611cef565b6101d3610203366004611881565b61046c565b6101e86105b4565b6102186105d8565b60405161018d9190612128565b6101d36102333660046119fd565b6105dd565b6101e86106eb565b61025361024e3660046118c1565b6106f1565b005b6101e8610263366004611811565b6107a8565b6101e8610276366004611811565b6107c3565b610253610289366004611811565b6107d5565b61019e610902565b6102536102a43660046119fd565b610963565b6101d36102b73660046119d2565b6109cb565b6102536102ca36600461195d565b610a85565b6101d36102dd366004611849565b610bd8565b6102536102f0366004611a57565b610c7a565b6101e8610303366004611849565b610d39565b6101e8610d64565b61025361031e366004611811565b610d6a565b610253610331366004611a57565b610e97565b610253610344366004611ae0565b610f41565b606060048054806020026020016040519081016040528092919081815260200182805480156103a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610383575b5050505050905090565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b820191906000526020600020905b81548152906001019060200180831161041757509395945050505050565b6009546001600160a01b031681565b60008061044f610ffb565b905061045c818585610fff565b5060019392505050565b60015490565b60006001600160a01b03831661049d5760405162461bcd60e51b815260040161049490611e50565b60405180910390fd5b6001600160a01b0384166104c35760405162461bcd60e51b815260040161049490612043565b60006104cd610ffb565b90506104fb81868686604051806020016040528060008152506040518060200160405280600081525061108d565b6105278186868660405180602001604052806000815250604051806020016040528060008152506111bb565b61057b858261057686604051806060016040528060298152602001612176602991396001600160a01b03808c166000908152600860209081526040808320938b168352929052205491906112db565b610fff565b6105a98186868660405180602001604052806000815250604051806020016040528060008152506000611307565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601290565b6000806105e8610ffb565b905061063c8182888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060408051602081019091528181529350915061146e9050565b7fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c168187878787604051610673959493929190611c0d565b60405180910390a1604051635260769b60e11b81526001600160a01b0387169063a4c0ed36906106ad908490899089908990600401611c65565b600060405180830381600087803b1580156106c757600080fd5b505af11580156106db573d6000803e3d6000fd5b5060019998505050505050505050565b600a5490565b6107026106fc610ffb565b88610bd8565b61071e5760405162461bcd60e51b815260040161049490612085565b61079f610729610ffb565b88888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a91508990819084018382808284376000920191909152506001925061146e915050565b50505050505050565b6001600160a01b031660009081526020819052604090205490565b600c6020526000908152604090205481565b806001600160a01b03166107e7610ffb565b6001600160a01b0316141561080e5760405162461bcd60e51b815260040161049490611dcb565b6001600160a01b03811660009081526005602052604090205460ff1615610871576007600061083b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690556108b8565b60016006600061087f610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b6108c0610ffb565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b6109c561096e610ffb565b610976610ffb565b868686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604080516020810190915290815292506001915061146e9050565b50505050565b60006001600160a01b0383166109f35760405162461bcd60e51b815260040161049490611e50565b60006109fd610ffb565b9050610a2b81828686604051806020016040528060008152506040518060200160405280600081525061108d565b610a578182868660405180602001604052806000815250604051806020016040528060008152506111bb565b61045c8182868660405180602001604052806000815250604051806020016040528060008152506000611307565b42841015610aa55760405162461bcd60e51b815260040161049490611fa9565b600b546001600160a01b0388166000908152600c6020908152604080832080546001810190915590519293610b27939092610b0c927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928e928e928e9290918e9101611cf8565b604051602081830303815290604052805190602001206114e5565b9050600060018286868660405160008152602001604052604051610b4e9493929190611d2c565b6020604051602081039080840390855afa158015610b70573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610ba65750886001600160a01b0316816001600160a01b0316145b610bc25760405162461bcd60e51b815260040161049490611f2f565b610bcd898989610fff565b505050505050505050565b6000816001600160a01b0316836001600160a01b03161480610c4357506001600160a01b03831660009081526005602052604090205460ff168015610c4357506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b80610c7357506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b6009546001600160a01b0316610c8e610ffb565b6001600160a01b031614610cb45760405162461bcd60e51b815260040161049490611f66565b610d31610cbf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061150492505050565b505050505050565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b600b5481565b610d72610ffb565b6001600160a01b0316816001600160a01b03161415610da35760405162461bcd60e51b815260040161049490611e0f565b6001600160a01b03811660009081526005602052604090205460ff1615610e0f57600160076000610dd2610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055610e4d565b60066000610e1b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b610e55610ffb565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b610ea8610ea2610ffb565b87610bd8565b610ec45760405162461bcd60e51b815260040161049490612085565b610d31610ecf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061162c92505050565b610f9f610f4c610ffb565b610f54610ffb565b8585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805160208101909152908152925061162c915050565b505050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b3390565b6001600160a01b0382166110255760405162461bcd60e51b8152600401610494906120c6565b6001600160a01b0380841660008181526008602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611080908590611cef565b60405180910390a3505050565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906110e99089907f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89590600401611c4c565b60206040518083038186803b15801561110157600080fd5b505afa158015611115573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611139919061182d565b90506001600160a01b0381161561079f57604051633ad5cbc160e11b81526001600160a01b038216906375ab978290611180908a908a908a908a908a908a90600401611bb3565b600060405180830381600087803b15801561119a57600080fd5b505af11580156111ae573d6000803e3d6000fd5b5050505050505050505050565b6111f88360405180606001604052806027815260200161214f602791396001600160a01b03881660009081526020819052604090205491906112db565b6001600160a01b038087166000908152602081905260408082209390935590861681522054611227908461175d565b6001600160a01b0380861660008181526020819052604090819020939093559151878216918916907f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc8261467798790611280908890889088906120fd565b60405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516112cb9190611cef565b60405180910390a3505050505050565b600081848411156112ff5760405162461bcd60e51b81526004016104949190611d4a565b505050900390565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906113639089907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b90600401611c4c565b60206040518083038186803b15801561137b57600080fd5b505afa15801561138f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b3919061182d565b90506001600160a01b0381161561142f576040516223de2960e01b81526001600160a01b038216906223de29906113f8908b908b908b908b908b908b90600401611bb3565b600060405180830381600087803b15801561141257600080fd5b505af1158015611426573d6000803e3d6000fd5b50505050611464565b811561146457611447866001600160a01b0316611782565b156114645760405162461bcd60e51b815260040161049490611ebc565b5050505050505050565b6001600160a01b0386166114945760405162461bcd60e51b815260040161049490611fd5565b6001600160a01b0385166114ba5760405162461bcd60e51b81526004016104949061200c565b6114c887878787878761108d565b6114d68787878787876111bb565b61079f87878787878787611307565b60405161190160f01b8152600281019290925260228201526042902090565b6001600160a01b03841661152a5760405162461bcd60e51b815260040161049490611e85565b600154611537908461175d565b6001556001600160a01b03841660009081526020819052604090205461155d908461175d565b6001600160a01b03851660009081526020819052604081209190915561158a908690868686866001611307565b836001600160a01b0316856001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d8585856040516115d1939291906120fd565b60405180910390a3836001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b60405180910390a35050505050565b6001600160a01b0384166116525760405162461bcd60e51b815260040161049490611d94565b6116618585600086868661108d565b61169e8360405180606001604052806023815260200161219f602391396001600160a01b03871660009081526020819052604090205491906112db565b6001600160a01b0385166000908152602081905260409020556001546116c49084611788565b600181905550836001600160a01b0316856001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098858585604051611711939291906120fd565b60405180910390a360006001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b600082820183811015610c735760405162461bcd60e51b815260040161049490611d5d565b3b151590565b6000610c7383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506112db565b60008083601f8401126117db578182fd5b50813567ffffffffffffffff8111156117f2578182fd5b60208301915083602082850101111561180a57600080fd5b9250929050565b600060208284031215611822578081fd5b8135610c7381612136565b60006020828403121561183e578081fd5b8151610c7381612136565b6000806040838503121561185b578081fd5b823561186681612136565b9150602083013561187681612136565b809150509250929050565b600080600060608486031215611895578081fd5b83356118a081612136565b925060208401356118b081612136565b929592945050506040919091013590565b600080600080600080600060a0888a0312156118db578283fd5b87356118e681612136565b965060208801356118f681612136565b955060408801359450606088013567ffffffffffffffff80821115611919578485fd5b6119258b838c016117ca565b909650945060808a013591508082111561193d578384fd5b5061194a8a828b016117ca565b989b979a50959850939692959293505050565b600080600080600080600060e0888a031215611977578283fd5b873561198281612136565b9650602088013561199281612136565b95506040880135945060608801359350608088013560ff811681146119b5578384fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156119e4578182fd5b82356119ef81612136565b946020939093013593505050565b60008060008060608587031215611a12578384fd5b8435611a1d81612136565b935060208501359250604085013567ffffffffffffffff811115611a3f578283fd5b611a4b878288016117ca565b95989497509550505050565b60008060008060008060808789031215611a6f578182fd5b8635611a7a81612136565b955060208701359450604087013567ffffffffffffffff80821115611a9d578384fd5b611aa98a838b016117ca565b90965094506060890135915080821115611ac1578384fd5b50611ace89828a016117ca565b979a9699509497509295939492505050565b600080600060408486031215611af4578283fd5b83359250602084013567ffffffffffffffff811115611b11578283fd5b611b1d868287016117ca565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b81811015611b7957602081850181015186830182015201611b5d565b81811115611b8a5782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0387811682528681166020830152851660408201526060810184905260c060808201819052600090611bee90830185611b54565b82810360a0840152611c008185611b54565b9998505050505050505050565b6001600160a01b0386811682528516602082015260408101849052608060608201819052600090611c419083018486611b2a565b979650505050505050565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038616825284602083015260606040830152611c8d606083018486611b2a565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611cd85783516001600160a01b031683529284019291840191600101611cb3565b50909695505050505050565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610c736020830184611b54565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f4552433737373a206275726e2066726f6d207a65726f20616464726573730000604082015260600190565b60208082526024908201527f4552433737373a20617574686f72697a696e672073656c66206173206f70657260408201526330ba37b960e11b606082015260800190565b60208082526021908201527f4552433737373a207265766f6b696e672073656c66206173206f70657261746f6040820152603960f91b606082015260800190565b6020808252818101527f4552433737373a207472616e7366657220746f207a65726f2061646472657373604082015260600190565b6020808252601c908201527f4552433737373a206d696e7420746f207a65726f206164647265737300000000604082015260600190565b6020808252604d908201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460408201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60608201526c1ad95b9cd49958da5c1a595b9d609a1b608082015260a00190565b6020808252601c908201527f53696465546f6b656e3a20494e56414c49445f5349474e415455524500000000604082015260600190565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b60208082526012908201527114da5919551bdad95b8e881156141254915160721b604082015260600190565b6020808252601e908201527f4552433737373a2073656e642066726f6d207a65726f20616464726573730000604082015260600190565b6020808252601c908201527f4552433737373a2073656e6420746f207a65726f206164647265737300000000604082015260600190565b60208082526022908201527f4552433737373a207472616e736665722066726f6d207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526021908201527f4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f6040820152603960f91b606082015260800190565b6020808252601f908201527f4552433737373a20617070726f766520746f207a65726f206164647265737300604082015260600190565b6000848252606060208301526121166060830185611b54565b8281036040840152611c8d8185611b54565b60ff91909116815260200190565b6001600160a01b038116811461214b57600080fd5b5056fe4552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a206275726e20616d6f756e7420657863656564732062616c616e6365a2646970667358221220e96305596548c1ccf5a73d7bede36fbfaeee3f672cbf14157179325f27c57bf764736f6c63430007060033a26469706673582212204cc330cf5079dbaee9f34fb1607540a3d5891d5eeb955ff8beaa47811a8c189964736f6c63430007060033",
+ "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b57806326d9e9631462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002b8565b6200009d565b005b6200007b62000075366004620002e8565b6200016c565b6040516200008a91906200038a565b60405180910390f35b6200007b6200024d565b6000546001600160a01b0316620000b36200025c565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000458565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc906200040e565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992620001619216906200038a565b60405180910390a150565b600080546001600160a01b0316620001836200025c565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000458565b600086868686620001bc6200024d565b87604051620001cb9062000260565b620001dc969594939291906200039e565b604051809103906000f080158015620001f9573d6000803e3d6000fd5b509050806001600160a01b03167ff57d2ded8330a4affd2fa52378069be534fe22288536537d1a1cfc06151845078686866040516200023b93929190620003e8565b60405180910390a29695505050505050565b6000546001600160a01b031690565b3390565b61288880620004a583390190565b60008083601f84011262000280578182fd5b50813567ffffffffffffffff81111562000298578182fd5b602083019150836020828501011115620002b157600080fd5b9250929050565b600060208284031215620002ca578081fd5b81356001600160a01b0381168114620002e1578182fd5b9392505050565b60008060008060006060868803121562000300578081fd5b853567ffffffffffffffff8082111562000318578283fd5b6200032689838a016200026e565b909750955060208801359150808211156200033f578283fd5b506200034e888289016200026e565b96999598509660400135949350505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060808252620003b460808301888a62000360565b8281036020840152620003c981878962000360565b6001600160a01b03959095166040840152505060600152949350505050565b600060408252620003fe60408301858762000360565b9050826020830152949350505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b506040516200288838038062002888833981016040819052620000349162000561565b60408051600081526020808201909252855186928692916200005d9160029190860190620003c2565b50815162000073906003906020850190620003c2565b5080516200008990600490602084019062000457565b5060005b600454811015620000e95760016005600060048481548110620000ac57fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff19169115159190911790556001016200008d565b506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90620001479030907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054908290600401620005f0565b600060405180830381600087803b1580156200016257600080fd5b505af115801562000177573d6000803e3d6000fd5b50506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad2492506329965a1d9150620001d89030907faea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a908290600401620005f0565b600060405180830381600087803b158015620001f357600080fd5b505af115801562000208573d6000803e3d6000fd5b50505050506001600160a01b038416151591506200024590505760405162461bcd60e51b81526004016200023c9062000613565b60405180910390fd5b6001811015620002695760405162461bcd60e51b81526004016200023c906200064a565b600980546001600160a01b0319166001600160a01b038416179055600a81905546620002c562000298620002d4565b604051806040016040528060018152602001603160f81b81525083306200036b60201b62000fa41760201c565b600b5550620006819350505050565b60028054604080516020601f6000196101006001871615020190941685900493840181900481028201810190925282815260609390929091830182828015620003615780601f10620003355761010080835404028352916020019162000361565b820191906000526020600020905b8154815290600101906020018083116200034357829003601f168201915b5050505050905090565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620003fa576000855562000445565b82601f106200041557805160ff191683800117855562000445565b8280016001018555821562000445579182015b828111156200044557825182559160200191906001019062000428565b5062000453929150620004af565b5090565b82805482825590600052602060002090810192821562000445579160200282015b828111156200044557825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000478565b5b80821115620004535760008155600101620004b0565b600082601f830112620004d7578081fd5b81516001600160401b0380821115620004ec57fe5b6040516020601f8401601f19168201810183811183821017156200050c57fe5b604052838252858401810187101562000523578485fd5b8492505b8383101562000546578583018101518284018201529182019162000527565b838311156200055757848185840101525b5095945050505050565b6000806000806080858703121562000577578384fd5b84516001600160401b03808211156200058e578586fd5b6200059c88838901620004c6565b95506020870151915080821115620005b2578485fd5b50620005c187828801620004c6565b604087015190945090506001600160a01b0381168114620005e0578283fd5b6060959095015193969295505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b6020808252601a908201527f53696465546f6b656e3a204772616e756c6172697479203c2031000000000000604082015260600190565b6121f780620006916000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80637ecebe00116100de578063d95b637111610097578063f698da2511610071578063f698da2514610308578063fad8b32a14610310578063fc673c4f14610323578063fe9d93031461033657610173565b8063d95b6371146102cf578063dcdc7dd0146102e2578063dd62ed3e146102f557610173565b80637ecebe0014610268578063959b8c3f1461027b57806395d89b411461028e5780639bd9bbc614610296578063a9059cbb146102a9578063d505accf146102bc57610173565b806330adf81f1161013057806330adf81f14610208578063313ce567146102105780634000aea014610225578063556f0dc71461023857806362ad1b831461024057806370a082311461025557610173565b806306e485381461017857806306fdde031461019657806307546172146101ab578063095ea7b3146101c057806318160ddd146101e057806323b872dd146101f5575b600080fd5b610180610349565b60405161018d9190611c97565b60405180910390f35b61019e6103ab565b60405161018d9190611d4a565b6101b3610435565b60405161018d9190611b9f565b6101d36101ce3660046119d2565b610444565b60405161018d9190611ce4565b6101e8610466565b60405161018d9190611cef565b6101d3610203366004611881565b61046c565b6101e86105b4565b6102186105d8565b60405161018d9190612128565b6101d36102333660046119fd565b6105dd565b6101e86106eb565b61025361024e3660046118c1565b6106f1565b005b6101e8610263366004611811565b6107a8565b6101e8610276366004611811565b6107c3565b610253610289366004611811565b6107d5565b61019e610902565b6102536102a43660046119fd565b610963565b6101d36102b73660046119d2565b6109cb565b6102536102ca36600461195d565b610a85565b6101d36102dd366004611849565b610bd8565b6102536102f0366004611a57565b610c7a565b6101e8610303366004611849565b610d39565b6101e8610d64565b61025361031e366004611811565b610d6a565b610253610331366004611a57565b610e97565b610253610344366004611ae0565b610f41565b606060048054806020026020016040519081016040528092919081815260200182805480156103a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610383575b5050505050905090565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b820191906000526020600020905b81548152906001019060200180831161041757509395945050505050565b6009546001600160a01b031681565b60008061044f610ffb565b905061045c818585610fff565b5060019392505050565b60015490565b60006001600160a01b03831661049d5760405162461bcd60e51b815260040161049490611e50565b60405180910390fd5b6001600160a01b0384166104c35760405162461bcd60e51b815260040161049490612043565b60006104cd610ffb565b90506104fb81868686604051806020016040528060008152506040518060200160405280600081525061108d565b6105278186868660405180602001604052806000815250604051806020016040528060008152506111bb565b61057b858261057686604051806060016040528060298152602001612176602991396001600160a01b03808c166000908152600860209081526040808320938b168352929052205491906112db565b610fff565b6105a98186868660405180602001604052806000815250604051806020016040528060008152506000611307565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601290565b6000806105e8610ffb565b905061063c8182888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060408051602081019091528181529350915061146e9050565b7fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c168187878787604051610673959493929190611c0d565b60405180910390a1604051635260769b60e11b81526001600160a01b0387169063a4c0ed36906106ad908490899089908990600401611c65565b600060405180830381600087803b1580156106c757600080fd5b505af11580156106db573d6000803e3d6000fd5b5060019998505050505050505050565b600a5490565b6107026106fc610ffb565b88610bd8565b61071e5760405162461bcd60e51b815260040161049490612085565b61079f610729610ffb565b88888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a91508990819084018382808284376000920191909152506001925061146e915050565b50505050505050565b6001600160a01b031660009081526020819052604090205490565b600c6020526000908152604090205481565b806001600160a01b03166107e7610ffb565b6001600160a01b0316141561080e5760405162461bcd60e51b815260040161049490611dcb565b6001600160a01b03811660009081526005602052604090205460ff1615610871576007600061083b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690556108b8565b60016006600061087f610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b6108c0610ffb565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b6109c561096e610ffb565b610976610ffb565b868686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604080516020810190915290815292506001915061146e9050565b50505050565b60006001600160a01b0383166109f35760405162461bcd60e51b815260040161049490611e50565b60006109fd610ffb565b9050610a2b81828686604051806020016040528060008152506040518060200160405280600081525061108d565b610a578182868660405180602001604052806000815250604051806020016040528060008152506111bb565b61045c8182868660405180602001604052806000815250604051806020016040528060008152506000611307565b42841015610aa55760405162461bcd60e51b815260040161049490611fa9565b600b546001600160a01b0388166000908152600c6020908152604080832080546001810190915590519293610b27939092610b0c927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928e928e928e9290918e9101611cf8565b604051602081830303815290604052805190602001206114e5565b9050600060018286868660405160008152602001604052604051610b4e9493929190611d2c565b6020604051602081039080840390855afa158015610b70573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610ba65750886001600160a01b0316816001600160a01b0316145b610bc25760405162461bcd60e51b815260040161049490611f2f565b610bcd898989610fff565b505050505050505050565b6000816001600160a01b0316836001600160a01b03161480610c4357506001600160a01b03831660009081526005602052604090205460ff168015610c4357506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b80610c7357506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b6009546001600160a01b0316610c8e610ffb565b6001600160a01b031614610cb45760405162461bcd60e51b815260040161049490611f66565b610d31610cbf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061150492505050565b505050505050565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b600b5481565b610d72610ffb565b6001600160a01b0316816001600160a01b03161415610da35760405162461bcd60e51b815260040161049490611e0f565b6001600160a01b03811660009081526005602052604090205460ff1615610e0f57600160076000610dd2610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055610e4d565b60066000610e1b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b610e55610ffb565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b610ea8610ea2610ffb565b87610bd8565b610ec45760405162461bcd60e51b815260040161049490612085565b610d31610ecf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061162c92505050565b610f9f610f4c610ffb565b610f54610ffb565b8585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805160208101909152908152925061162c915050565b505050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b3390565b6001600160a01b0382166110255760405162461bcd60e51b8152600401610494906120c6565b6001600160a01b0380841660008181526008602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611080908590611cef565b60405180910390a3505050565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906110e99089907f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89590600401611c4c565b60206040518083038186803b15801561110157600080fd5b505afa158015611115573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611139919061182d565b90506001600160a01b0381161561079f57604051633ad5cbc160e11b81526001600160a01b038216906375ab978290611180908a908a908a908a908a908a90600401611bb3565b600060405180830381600087803b15801561119a57600080fd5b505af11580156111ae573d6000803e3d6000fd5b5050505050505050505050565b6111f88360405180606001604052806027815260200161214f602791396001600160a01b03881660009081526020819052604090205491906112db565b6001600160a01b038087166000908152602081905260408082209390935590861681522054611227908461175d565b6001600160a01b0380861660008181526020819052604090819020939093559151878216918916907f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc8261467798790611280908890889088906120fd565b60405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516112cb9190611cef565b60405180910390a3505050505050565b600081848411156112ff5760405162461bcd60e51b81526004016104949190611d4a565b505050900390565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906113639089907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b90600401611c4c565b60206040518083038186803b15801561137b57600080fd5b505afa15801561138f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b3919061182d565b90506001600160a01b0381161561142f576040516223de2960e01b81526001600160a01b038216906223de29906113f8908b908b908b908b908b908b90600401611bb3565b600060405180830381600087803b15801561141257600080fd5b505af1158015611426573d6000803e3d6000fd5b50505050611464565b811561146457611447866001600160a01b0316611782565b156114645760405162461bcd60e51b815260040161049490611ebc565b5050505050505050565b6001600160a01b0386166114945760405162461bcd60e51b815260040161049490611fd5565b6001600160a01b0385166114ba5760405162461bcd60e51b81526004016104949061200c565b6114c887878787878761108d565b6114d68787878787876111bb565b61079f87878787878787611307565b60405161190160f01b8152600281019290925260228201526042902090565b6001600160a01b03841661152a5760405162461bcd60e51b815260040161049490611e85565b600154611537908461175d565b6001556001600160a01b03841660009081526020819052604090205461155d908461175d565b6001600160a01b03851660009081526020819052604081209190915561158a908690868686866001611307565b836001600160a01b0316856001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d8585856040516115d1939291906120fd565b60405180910390a3836001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b60405180910390a35050505050565b6001600160a01b0384166116525760405162461bcd60e51b815260040161049490611d94565b6116618585600086868661108d565b61169e8360405180606001604052806023815260200161219f602391396001600160a01b03871660009081526020819052604090205491906112db565b6001600160a01b0385166000908152602081905260409020556001546116c49084611788565b600181905550836001600160a01b0316856001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098858585604051611711939291906120fd565b60405180910390a360006001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b600082820183811015610c735760405162461bcd60e51b815260040161049490611d5d565b3b151590565b6000610c7383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506112db565b60008083601f8401126117db578182fd5b50813567ffffffffffffffff8111156117f2578182fd5b60208301915083602082850101111561180a57600080fd5b9250929050565b600060208284031215611822578081fd5b8135610c7381612136565b60006020828403121561183e578081fd5b8151610c7381612136565b6000806040838503121561185b578081fd5b823561186681612136565b9150602083013561187681612136565b809150509250929050565b600080600060608486031215611895578081fd5b83356118a081612136565b925060208401356118b081612136565b929592945050506040919091013590565b600080600080600080600060a0888a0312156118db578283fd5b87356118e681612136565b965060208801356118f681612136565b955060408801359450606088013567ffffffffffffffff80821115611919578485fd5b6119258b838c016117ca565b909650945060808a013591508082111561193d578384fd5b5061194a8a828b016117ca565b989b979a50959850939692959293505050565b600080600080600080600060e0888a031215611977578283fd5b873561198281612136565b9650602088013561199281612136565b95506040880135945060608801359350608088013560ff811681146119b5578384fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156119e4578182fd5b82356119ef81612136565b946020939093013593505050565b60008060008060608587031215611a12578384fd5b8435611a1d81612136565b935060208501359250604085013567ffffffffffffffff811115611a3f578283fd5b611a4b878288016117ca565b95989497509550505050565b60008060008060008060808789031215611a6f578182fd5b8635611a7a81612136565b955060208701359450604087013567ffffffffffffffff80821115611a9d578384fd5b611aa98a838b016117ca565b90965094506060890135915080821115611ac1578384fd5b50611ace89828a016117ca565b979a9699509497509295939492505050565b600080600060408486031215611af4578283fd5b83359250602084013567ffffffffffffffff811115611b11578283fd5b611b1d868287016117ca565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b81811015611b7957602081850181015186830182015201611b5d565b81811115611b8a5782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0387811682528681166020830152851660408201526060810184905260c060808201819052600090611bee90830185611b54565b82810360a0840152611c008185611b54565b9998505050505050505050565b6001600160a01b0386811682528516602082015260408101849052608060608201819052600090611c419083018486611b2a565b979650505050505050565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038616825284602083015260606040830152611c8d606083018486611b2a565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611cd85783516001600160a01b031683529284019291840191600101611cb3565b50909695505050505050565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610c736020830184611b54565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f4552433737373a206275726e2066726f6d207a65726f20616464726573730000604082015260600190565b60208082526024908201527f4552433737373a20617574686f72697a696e672073656c66206173206f70657260408201526330ba37b960e11b606082015260800190565b60208082526021908201527f4552433737373a207265766f6b696e672073656c66206173206f70657261746f6040820152603960f91b606082015260800190565b6020808252818101527f4552433737373a207472616e7366657220746f207a65726f2061646472657373604082015260600190565b6020808252601c908201527f4552433737373a206d696e7420746f207a65726f206164647265737300000000604082015260600190565b6020808252604d908201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460408201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60608201526c1ad95b9cd49958da5c1a595b9d609a1b608082015260a00190565b6020808252601c908201527f53696465546f6b656e3a20494e56414c49445f5349474e415455524500000000604082015260600190565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b60208082526012908201527114da5919551bdad95b8e881156141254915160721b604082015260600190565b6020808252601e908201527f4552433737373a2073656e642066726f6d207a65726f20616464726573730000604082015260600190565b6020808252601c908201527f4552433737373a2073656e6420746f207a65726f206164647265737300000000604082015260600190565b60208082526022908201527f4552433737373a207472616e736665722066726f6d207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526021908201527f4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f6040820152603960f91b606082015260800190565b6020808252601f908201527f4552433737373a20617070726f766520746f207a65726f206164647265737300604082015260600190565b6000848252606060208301526121166060830185611b54565b8281036040840152611c8d8185611b54565b60ff91909116815260200190565b6001600160a01b038116811461214b57600080fd5b5056fe4552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a206275726e20616d6f756e7420657863656564732062616c616e6365a2646970667358221220e96305596548c1ccf5a73d7bede36fbfaeee3f672cbf14157179325f27c57bf764736f6c63430007060033a26469706673582212204cc330cf5079dbaee9f34fb1607540a3d5891d5eeb955ff8beaa47811a8c189964736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 11014,
+ "contract": "contracts/SideTokenFactory/SideTokenFactory.sol:SideTokenFactory",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/WRBTC.json b/bridge/deployments/rsktestnet/WRBTC.json
new file mode 100644
index 000000000..f6d549d6e
--- /dev/null
+++ b/bridge/deployments/rsktestnet/WRBTC.json
@@ -0,0 +1,400 @@
+{
+ "address": "0xd15cDD74DfF1A6A81Ca639B038839B126BC01FF9",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "guy",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposit",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Withdrawal",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "guy",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "deposit",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdraw",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xa55afc0a86fae3e78c22da4d796f54929788ac921ad83ef5ebf35902982c73ca",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0xcAB50DA63928519b4dD58e3766D90B8E860982D9",
+ "transactionIndex": 0,
+ "gasUsed": "665718",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xdb8404801fc937df8ffbc62579c7ec91193ef9ac5d47401cb5a264ab3ce8090c",
+ "transactionHash": "0xa55afc0a86fae3e78c22da4d796f54929788ac921ad83ef5ebf35902982c73ca",
+ "logs": [],
+ "blockNumber": 2152326,
+ "cumulativeGasUsed": "665718",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/test/WRBTC.sol\":\"WRBTC\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interface/IWrapped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\ninterface IWrapped {\\n function balanceOf(address) external returns(uint);\\n\\n function deposit() external payable;\\n\\n function withdraw(uint wad) external;\\n\\n function totalSupply() external view returns (uint);\\n\\n function approve(address guy, uint wad) external returns (bool);\\n\\n function transfer(address dst, uint wad) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint wad)\\n external\\n returns (bool);\\n}\",\"keccak256\":\"0x2d8a99b6a030e37f01dba86db80e3bd29d1d01e592e399c8635df3fb636ec0d1\",\"license\":\"MIT\"},\"contracts/test/WRBTC.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../interface/IWrapped.sol\\\";\\n\\ncontract WRBTC is IWrapped {\\n string public name = \\\"Wrapped RBTC\\\";\\n string public symbol = \\\"WRBTC\\\";\\n uint8 public decimals = 18;\\n\\n event Approval(address indexed src, address indexed guy, uint wad);\\n event Transfer(address indexed src, address indexed dst, uint wad);\\n event Deposit(address indexed dst, uint wad);\\n event Withdrawal(address indexed src, uint wad);\\n\\n mapping (address => uint) override public balanceOf;\\n mapping (address => mapping (address => uint)) public allowance;\\n\\n receive () external payable {\\n deposit();\\n }\\n function deposit() override public payable {\\n balanceOf[msg.sender] += msg.value;\\n emit Deposit(msg.sender, msg.value);\\n }\\n function withdraw(uint wad) override public {\\n require(balanceOf[msg.sender] >= wad, \\\"WRBTC: Balance less than wad\\\");\\n balanceOf[msg.sender] -= wad;\\n msg.sender.transfer(wad);\\n emit Withdrawal(msg.sender, wad);\\n }\\n\\n function totalSupply() override public view returns (uint) {\\n return address(this).balance;\\n }\\n\\n function approve(address guy, uint wad) override public returns (bool) {\\n allowance[msg.sender][guy] = wad;\\n emit Approval(msg.sender, guy, wad);\\n return true;\\n }\\n\\n function transfer(address dst, uint wad) override public returns (bool) {\\n return transferFrom(msg.sender, dst, wad);\\n }\\n\\n function transferFrom(address src, address dst, uint wad)\\n override public\\n returns (bool)\\n {\\n require(balanceOf[src] >= wad, \\\"WRBTC: Balance less than wad\\\");\\n\\n if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\\n require(allowance[src][msg.sender] >= wad, \\\"WRBTC: Allowance less than wad\\\");\\n allowance[src][msg.sender] -= wad;\\n }\\n\\n balanceOf[src] -= wad;\\n balanceOf[dst] += wad;\\n\\n emit Transfer(src, dst, wad);\\n\\n return true;\\n }\\n}\",\"keccak256\":\"0xf664c159f6302a78c9e6393c00de0c2630dc3e830215dc467a03f17a533b6807\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x60c0604052600c60808190526b57726170706564205242544360a01b60a090815261002d916000919061007a565b5060408051808201909152600580825264575242544360d81b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b5061011b565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826100b057600085556100f6565b82601f106100c957805160ff19168380011785556100f6565b828001600101855582156100f6579182015b828111156100f65782518255916020019190600101906100db565b50610102929150610106565b5090565b5b808211156101025760008155600101610107565b6107d28061012a6000396000f3fe6080604052600436106100a05760003560e01c8063313ce56711610064578063313ce5671461021f57806370a082311461024a57806395d89b411461027d578063a9059cbb14610292578063d0e30db0146102cb578063dd62ed3e146102d3576100af565b806306fdde03146100b4578063095ea7b31461013e57806318160ddd1461018b57806323b872dd146101b25780632e1a7d4d146101f5576100af565b366100af576100ad61030e565b005b600080fd5b3480156100c057600080fd5b506100c961035d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101035781810151838201526020016100eb565b50505050905090810190601f1680156101305780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014a57600080fd5b506101776004803603604081101561016157600080fd5b506001600160a01b0381351690602001356103eb565b604080519115158252519081900360200190f35b34801561019757600080fd5b506101a0610451565b60408051918252519081900360200190f35b3480156101be57600080fd5b50610177600480360360608110156101d557600080fd5b506001600160a01b03813581169160208101359091169060400135610455565b34801561020157600080fd5b506100ad6004803603602081101561021857600080fd5b5035610619565b34801561022b57600080fd5b506102346106f6565b6040805160ff9092168252519081900360200190f35b34801561025657600080fd5b506101a06004803603602081101561026d57600080fd5b50356001600160a01b03166106ff565b34801561028957600080fd5b506100c9610711565b34801561029e57600080fd5b50610177600480360360408110156102b557600080fd5b506001600160a01b03813516906020013561076b565b6100ad61030e565b3480156102df57600080fd5b506101a0600480360360408110156102f657600080fd5b506001600160a01b038135811691602001351661077f565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b820191906000526020600020905b8154815290600101906020018083116103c657829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b6001600160a01b0383166000908152600360205260408120548211156104c2576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b6001600160a01b038416331480159061050057506001600160a01b038416600090815260046020908152604080832033845290915290205460001914155b156105a8576001600160a01b038416600090815260046020908152604080832033845290915290205482111561057d576040805162461bcd60e51b815260206004820152601e60248201527f57524254433a20416c6c6f77616e6365206c657373207468616e207761640000604482015290519081900360640190fd5b6001600160a01b03841660009081526004602090815260408083203384529091529020805483900390555b6001600160a01b03808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561067d576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106bc573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b6000610778338484610455565b9392505050565b60046020908152600092835260408084209091529082529020548156fea26469706673582212202d01111733e2aa80d67d08b8b3a53d89aabe0e468d80eba287b4a34d46db4ab564736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106100a05760003560e01c8063313ce56711610064578063313ce5671461021f57806370a082311461024a57806395d89b411461027d578063a9059cbb14610292578063d0e30db0146102cb578063dd62ed3e146102d3576100af565b806306fdde03146100b4578063095ea7b31461013e57806318160ddd1461018b57806323b872dd146101b25780632e1a7d4d146101f5576100af565b366100af576100ad61030e565b005b600080fd5b3480156100c057600080fd5b506100c961035d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101035781810151838201526020016100eb565b50505050905090810190601f1680156101305780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014a57600080fd5b506101776004803603604081101561016157600080fd5b506001600160a01b0381351690602001356103eb565b604080519115158252519081900360200190f35b34801561019757600080fd5b506101a0610451565b60408051918252519081900360200190f35b3480156101be57600080fd5b50610177600480360360608110156101d557600080fd5b506001600160a01b03813581169160208101359091169060400135610455565b34801561020157600080fd5b506100ad6004803603602081101561021857600080fd5b5035610619565b34801561022b57600080fd5b506102346106f6565b6040805160ff9092168252519081900360200190f35b34801561025657600080fd5b506101a06004803603602081101561026d57600080fd5b50356001600160a01b03166106ff565b34801561028957600080fd5b506100c9610711565b34801561029e57600080fd5b50610177600480360360408110156102b557600080fd5b506001600160a01b03813516906020013561076b565b6100ad61030e565b3480156102df57600080fd5b506101a0600480360360408110156102f657600080fd5b506001600160a01b038135811691602001351661077f565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b820191906000526020600020905b8154815290600101906020018083116103c657829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b6001600160a01b0383166000908152600360205260408120548211156104c2576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b6001600160a01b038416331480159061050057506001600160a01b038416600090815260046020908152604080832033845290915290205460001914155b156105a8576001600160a01b038416600090815260046020908152604080832033845290915290205482111561057d576040805162461bcd60e51b815260206004820152601e60248201527f57524254433a20416c6c6f77616e6365206c657373207468616e207761640000604482015290519081900360640190fd5b6001600160a01b03841660009081526004602090815260408083203384529091529020805483900390555b6001600160a01b03808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561067d576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106bc573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b6000610778338484610455565b9392505050565b60046020908152600092835260408084209091529082529020548156fea26469706673582212202d01111733e2aa80d67d08b8b3a53d89aabe0e468d80eba287b4a34d46db4ab564736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {},
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 9308,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "name",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 9311,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "symbol",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 9314,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "decimals",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint8"
+ },
+ {
+ "astId": 9347,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "balanceOf",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_mapping(t_address,t_uint256)"
+ },
+ {
+ "astId": 9353,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "allowance",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_uint256))": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_uint256)"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "encoding": "inplace",
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/solcInputs/257bf35cfef475bad06cad6d9dd245f2.json b/bridge/deployments/rsktestnet/solcInputs/257bf35cfef475bad06cad6d9dd245f2.json
new file mode 100644
index 000000000..fc67aa92f
--- /dev/null
+++ b/bridge/deployments/rsktestnet/solcInputs/257bf35cfef475bad06cad6d9dd245f2.json
@@ -0,0 +1,270 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/math/SafeMath.sol\";\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\n\nimport \"../interface/IAllowTokens.sol\";\n\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\n\tusing SafeMath for uint256;\n\n\taddress constant private NULL_ADDRESS = address(0);\n\tuint256 constant public MAX_TYPES = 250;\n\tmapping (address => TokenInfo) public allowedTokens;\n\tmapping (uint256 => Limits) public typeLimits;\n\tuint256 public smallAmountConfirmations;\n\tuint256 public mediumAmountConfirmations;\n\tuint256 public largeAmountConfirmations;\n\tstring[] public typeDescriptions;\n\n\tevent SetToken(address indexed _tokenAddress, uint256 _typeId);\n\tevent AllowedTokenRemoved(address indexed _tokenAddress);\n\tevent TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\n\tevent TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\n\tevent UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\n\tevent ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\n\n\tmodifier notNull(address _address) {\n\t\trequire(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\n\t\t_;\n\t}\n\n\tfunction initialize(\n\t\taddress _manager,\n\t\taddress _primary,\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations,\n\t\tTypeInfo[] memory typesInfo) public initializer {\n\t\tUpgradableOwnable.initialize(_manager);\n\t\tUpgradableSecondary.__Secondary_init(_primary);\n\t\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t\tfor(uint i = 0; i < typesInfo.length; i = i + 1) {\n\t\t\t_addTokenType(typesInfo[i].description, typesInfo[i].limits);\n\t\t}\n\t}\n\n\tfunction version() override external pure returns (string memory) {\n\t\treturn \"v1\";\n\t}\n\n\tfunction tokenInfo(address tokenAddress) public view returns(TokenInfo memory) {\n\t\treturn allowedTokens[tokenAddress];\n\t}\n\n\tfunction setTokenInfoByTokenAddress(address tokenAddress, TokenInfo memory info) internal {\n\t\trequire(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n\t\tallowedTokens[tokenAddress] = info;\n\t}\n\n\tfunction getInfoAndLimits(\n\t\taddress tokenAddress\n\t) public view override returns (\n\t\tTokenInfo memory info,\n\t\tLimits memory limit\n\t) {\n\t\tinfo = tokenInfo(tokenAddress);\n\t\tlimit = typeLimits[info.typeId];\n\t\treturn (info, limit);\n\t}\n\n\tfunction calcMaxWithdraw(address token) public view override returns (uint256 maxWithdraw) {\n\t\t(TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\n\t\treturn _calcMaxWithdraw(info, limits);\n\t}\n\n\tfunction _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\n\t\t// solium-disable-next-line security/no-block-members\n\t\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n\t\t\tinfo.spentToday = 0;\n\t\t}\n\t\tif (limits.daily <= info.spentToday) {\n\t\t\treturn 0;\n\t\t}\n\t\tmaxWithdraw = limits.daily - info.spentToday;\n\t\tif (maxWithdraw > limits.max) {\n\t\t\tmaxWithdraw = limits.max;\n\t\t}\n\t\treturn maxWithdraw;\n\t}\n\n\tfunction updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\n\t\t(TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\n\t\trequire(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\n\t\trequire(amount >= limit.min, \"AllowTokens: Lower than limit\");\n\n\t\t// solium-disable-next-line security/no-block-members\n\t\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n\t\t\t// solium-disable-next-line security/no-block-members\n\t\t\tinfo.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n\t\t\tinfo.spentToday = 0;\n\t\t}\n\t\tuint maxWithdraw = _calcMaxWithdraw(info, limit);\n\t\trequire(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\n\t\tinfo.spentToday = info.spentToday.add(amount);\n\t\tsetTokenInfoByTokenAddress(token, info);\n\n\t\temit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\n\t}\n\n\tfunction _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\n\t\trequire(bytes(description).length > 0, \"AllowTokens: Empty description\");\n\t\tlen = typeDescriptions.length;\n\t\trequire(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\n\t\ttypeDescriptions.push(description);\n\t\t_setTypeLimits(len, limits);\n\t\temit TokenTypeAdded(len, description);\n\t\treturn len;\n\t}\n\n\tfunction addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\n\t\treturn _addTokenType(description, limits);\n\t}\n\n\tfunction _setTypeLimits(uint256 typeId, Limits memory limits) private {\n\t\trequire(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\n\t\trequire(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\n\t\trequire(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\n\t\trequire(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\n\t\trequire(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\n\t\ttypeLimits[typeId] = limits;\n\t\temit TypeLimitsChanged(typeId, limits);\n\t}\n\n\tfunction setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\n\t\t_setTypeLimits(typeId, limits);\n\t}\n\n\tfunction getTypesLimits() external view override returns(Limits[] memory limits) {\n\t\tlimits = new Limits[](typeDescriptions.length);\n\t\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\n\t\t\tlimits[i] = typeLimits[i];\n\t\t}\n\t\treturn limits;\n\t}\n\n\tfunction getTypeDescriptionsLength() external view override returns(uint256) {\n\t\treturn typeDescriptions.length;\n\t}\n\n\tfunction getTypeDescriptions() external view override returns(string[] memory descriptions) {\n\t\tdescriptions = new string[](typeDescriptions.length);\n\t\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\n\t\t\tdescriptions[i] = typeDescriptions[i];\n\t\t}\n\t\treturn descriptions;\n\t}\n\n\tfunction isTokenAllowed(address token) public view notNull(token) override returns (bool) {\n\t\treturn tokenInfo(token).allowed;\n\t}\n\n\tfunction setToken(address token, uint256 typeId) override public notNull(token) {\n\t\trequire(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n\t\trequire(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\n\t\tTokenInfo memory info = tokenInfo(token);\n\t\tinfo.allowed = true;\n\t\tinfo.typeId = typeId;\n\t\tsetTokenInfoByTokenAddress(token, info);\n\t\temit SetToken(token, typeId);\n\t}\n\n\tfunction setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\n\t\trequire(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\n\t\tfor(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\n\t\t\tsetToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\n\t\t}\n\t}\n\n\tfunction removeAllowedToken(address token) external notNull(token) onlyOwner {\n\t\tTokenInfo memory info = tokenInfo(token);\n\t\trequire(info.allowed, \"AllowTokens: Not Allowed\");\n\t\tinfo.allowed = false;\n\t\tsetTokenInfoByTokenAddress(token, info);\n\t\temit AllowedTokenRemoved(token);\n\t}\n\n\tfunction setConfirmations(\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations) external onlyOwner {\n\t\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t}\n\n\tfunction _setConfirmations(\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations) private {\n\t\trequire(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\n\t\trequire(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\n\t\tsmallAmountConfirmations = _smallAmountConfirmations;\n\t\tmediumAmountConfirmations = _mediumAmountConfirmations;\n\t\tlargeAmountConfirmations = _largeAmountConfirmations;\n\t\temit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t}\n\n\tfunction getConfirmations() external view override\n\t\treturns (\n\t\tuint256 smallAmount,\n\t\tuint256 mediumAmount,\n\t\tuint256 largeAmount\n\t) {\n\t\treturn (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\n\t}\n\n}\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @title Initializable\n *\n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(initializing || !initialized, \"Contract instance is already initialized\");\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\n * the owner.\n */\ncontract UpgradableOwnable is Initializable, Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function initialize(address sender) public initializer {\n _owner = sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * > Note: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\ncontract UpgradableSecondary is Initializable, Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n function __Secondary_init(address sender) public initializer {\n _primary = sender;\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(recipient);\n }\n\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IAllowTokens {\n\n\tstruct Limits {\n\t\tuint256 min;\n\t\tuint256 max;\n\t\tuint256 daily;\n\t\tuint256 mediumAmount;\n\t\tuint256 largeAmount;\n\t}\n\n\tstruct TokenInfo {\n\t\tbool allowed;\n\t\tuint256 typeId;\n\t\tuint256 spentToday;\n\t\tuint256 lastDay;\n\t}\n\n\tstruct TypeInfo {\n\t\tstring description;\n\t\tLimits limits;\n\t}\n\n\tstruct TokensAndType {\n\t\taddress token;\n\t\tuint256 typeId;\n\t}\n\n\tfunction version() external pure returns (string memory);\n\n\tfunction getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\n\n\tfunction calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\n\n\tfunction getTypesLimits() external view returns(Limits[] memory limits);\n\n\tfunction getTypeDescriptionsLength() external view returns(uint256);\n\n\tfunction getTypeDescriptions() external view returns(string[] memory descriptions);\n\n\tfunction setToken(address token, uint256 typeId) external;\n\n\tfunction getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\n\n\tfunction isTokenAllowed(address token) external view returns (bool);\n\n\tfunction updateTokenTransfer(address token, uint256 amount) external;\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n\n function _msgSender() internal view returns (address payable) {\n return payable(msg.sender);\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
+ },
+ "contracts/Bridge/BridgeV3.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// import \"hardhat/console.sol\";\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./IBridgeV3.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n\ncontract BridgeV3 is Initializable, IBridgeV3, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant internal NULL_ADDRESS = address(0);\n bytes32 constant internal NULL_HASH = bytes32(0);\n IERC1820Registry constant internal erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address internal federation;\n uint256 internal feePercentage;\n string public symbolPrefix;\n bytes32 public DOMAIN_SEPARATOR; // replaces uint256 internal _depprecatedLastDay;\n uint256 internal _deprecatedSpentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n uint256 constant public feePercentageDivider = 10000; // Porcentage with up to 2 decimals\n //Bridge_v3 variables\n bytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\");\n IWrapped public wrappedCurrency;\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n // keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\n mapping(address => uint) public nonces;\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool _isUpgrading);\n event WrappedCurrencyChanged(address _wrappedCurrency);\n\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n federation = _federation;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n initDomainSeparator();\n }\n\n receive () external payable {\n // The fallback function is needed to use WRBTC\n require(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n }\n\n function version() override external pure returns (string memory) {\n return \"v3\";\n }\n\n function initDomainSeparator() public {\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n DOMAIN_SEPARATOR = LibEIP712.hashEIP712Domain(\n \"RSK Token Bridge\",\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"Bridge: Not Federation\");\n require(knownTokens[_originalTokenAddress] ||\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\n \"Bridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"Bridge: Null To\");\n require(_amount > 0, \"Bridge: Amount 0\");\n require(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _amount,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed also has the previously processed using the older bridge version\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n require(!claimed[_transactionDataHash], \"Bridge: Already claimed\");\n\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\n senderAddresses[_transactionHash] = _from;\n\n emit AcceptedCrossTransfer(\n _transactionHash,\n _originalTokenAddress,\n _to,\n _from,\n _amount,\n _blockHash,\n _logIndex\n );\n }\n\n\n function createSideToken(\n uint256 _typeId,\n address _originalTokenAddress,\n uint8 _originalTokenDecimals,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n address sideToken = mappedTokens[_originalTokenAddress];\n require(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\n\n mappedTokens[_originalTokenAddress] = sideToken;\n originalTokens[sideToken] = _originalTokenAddress;\n allowTokens.setToken(sideToken, _typeId);\n\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\n }\n\n function claim(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function claimFallback(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n receivedAmount = _claim(\n _claimData,\n _msgSender(),\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function getDigest(\n ClaimData memory _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline\n ) internal returns (bytes32) {\n return LibEIP712.hashEIP712Message(\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n CLAIM_TYPEHASH,\n _claimData.to,\n _claimData.amount,\n _claimData.transactionHash,\n _relayer,\n _fee,\n nonces[_claimData.to]++,\n _deadline\n )\n )\n );\n }\n\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external override returns (uint256 receivedAmount) {\n require(_deadline >= block.timestamp, \"Bridge: EXPIRED\");\n\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claim(\n ClaimData calldata _claimData,\n address payable _reciever,\n address payable _relayer,\n uint256 _fee\n ) internal nonReentrant returns (uint256 receivedAmount) {\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n require(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.amount,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n require(!claimed[transactionDataHash], \"Bridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (knownTokens[originalTokenAddress]) {\n receivedAmount =_claimCrossBackToToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n } else {\n receivedAmount =_claimCrossToSideToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n }\n emit Claimed(\n _claimData.transactionHash,\n originalTokenAddress,\n _claimData.to,\n senderAddresses[_claimData.transactionHash],\n _claimData.amount,\n _claimData.blockHash,\n _claimData.logIndex,\n _reciever,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claimCrossToSideToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n address sideToken = mappedTokens[_originalTokenAddress];\n uint256 granularity = IERC777(sideToken).granularity();\n uint256 formattedAmount = _amount.mul(granularity);\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n ISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n if(_fee > 0) {\n ISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n }\n return receivedAmount;\n }\n\n function _claimCrossBackToToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n //As side tokens are ERC777 they will always have 18 decimals\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n if(address(wrappedCurrency) == _originalTokenAddress) {\n wrappedCurrency.withdraw(formattedAmount);\n _receiver.transfer(receivedAmount);\n if(_fee > 0) {\n _relayer.transfer(_fee);\n }\n } else {\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n if(_fee > 0) {\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n }\n }\n return receivedAmount;\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\n address sender = _msgSender();\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, to, amount, \"\");\n }\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) override external payable {\n address sender = _msgSender();\n require(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n wrappedCurrency.deposit{ value: msg.value }();\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \"\");\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external override(IBridgeV3, IERC777Recipient){\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to this address\");\n address tokenToUse = _msgSender();\n require(erc1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n require(userData.length != 0 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\n crossTokens(tokenToUse, from, receiver, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\n internal whenNotUpgrading whenNotPaused nonReentrant {\n knownTokens[tokenToUse] = true;\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n uint256 amountMinusFees = amount.sub(fee);\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n // We consider the amount before fees converted to 18 decimals to check the limits\n // updateTokenTransfer revert if token not allowed\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n address originalTokenAddress = tokenToUse;\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\n //Side Token Crossing\n originalTokenAddress = originalTokens[tokenToUse];\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\n uint256 modulo = amountMinusFees.mod(granularity);\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n }\n\n emit Cross(\n originalTokenAddress,\n from,\n to,\n amountMinusFees,\n userData\n );\n\n if (fee > 0) {\n //Send the payment to the MultiSig of the Federation\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n }\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n )\n public pure override returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n }\n\n function setFeePercentage(uint amount) external onlyOwner {\n require(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() external view override returns(uint) {\n return feePercentage;\n }\n\n function changeFederation(address newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n require(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n wrappedCurrency = IWrapped(_wrappedCurrency);\n emit WrappedCurrencyChanged(_wrappedCurrency);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionsDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionsDataHashes[transactionHash]];\n }\n\n}"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\n/**\n * @title Helps contracts guard against reentrancy attacks.\n * @author Remco Bloemen , Eenae \n * @dev If you mark a function `nonReentrant`, you should also\n * mark it `external`.\n */\ncontract ReentrancyGuard is Initializable {\n /// @dev counter to allow mutex lock with only one SSTORE operation\n uint256 private _guardCounter;\n\n function initialize() public initializer {\n // The counter starts at one to prevent changing it from zero to a non-zero\n // value, which is a more expensive operation.\n _guardCounter = 1;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _guardCounter += 1;\n uint256 localCounter = _guardCounter;\n _;\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\n }\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\nimport \"../access/roles/UpgradablePauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n function __Pausable_init(address sender) public initializer {\n UpgradablePauserRole.__PauserRol_init(sender);\n\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as `account`'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `_account`.\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `_implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\n\n /**\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `_account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an `IERC777` token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {ERC20Detailed}.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeERC20: low-level call failed\");\n\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See `IERC1820Registry` and\n * `ERC1820Implementer`.\n */\ninterface IERC777 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See `operatorSend` and `operatorBurn`.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor`.\n *\n * Emits an `AuthorizedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor` and `defaultOperators`.\n *\n * Emits a `RevokedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if `authorizeOperator` was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * `revokeOperator`, in which case `isOperatorFor` will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n\n function decimals() external returns (uint8);\n\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n}\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\nlibrary LibEIP712 {\n\n // Hash of the EIP712 Domain Separator Schema\n // keccak256(abi.encodePacked(\n // \"EIP712Domain(\",\n // \"string name,\",\n // \"string version,\",\n // \"uint256 chainId,\",\n // \"address verifyingContract\",\n // \")\"\n // ))\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n /// @dev Calculates a EIP712 domain separator.\n /// @param name The EIP712 domain name.\n /// @param version The EIP712 domain version.\n /// @param verifyingContract The EIP712 verifying contract.\n /// @return result EIP712 domain separator.\n function hashEIP712Domain(\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n // keccak256(bytes(name)),\n // keccak256(bytes(version)),\n // chainId,\n // uint256(verifyingContract)\n // ))\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Calculate hashes of dynamic data\n let nameHash := keccak256(add(name, 32), mload(name))\n let versionHash := keccak256(add(version, 32), mload(version))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n // Store params in memory\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), nameHash)\n mstore(add(memPtr, 64), versionHash)\n mstore(add(memPtr, 96), chainId)\n mstore(add(memPtr, 128), verifyingContract)\n\n // Compute hash\n result := keccak256(memPtr, 160)\n }\n return result;\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\n /// with getDomainHash().\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to the given EIP712 Domain.\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n internal\n pure\n returns (bytes32 result)\n {\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct\n // ));\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nlibrary LibUtils {\n\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\n return uint256(10)**(18-decimals);\n }\n\n function getDecimals(address tokenToUse) internal view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"LibUtils: No decimals\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n return uint8(abi.decode(data, (uint256)));\n }\n\n function getGranularity(address tokenToUse) internal view returns (uint256) {\n //support granularity if ERC777\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\n require(success, \"LibUtils: No granularity\");\n\n return abi.decode(data, (uint256));\n }\n\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n addr := mload(add(bys,20))\n }\n }\n\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\n require(_bytes.length >= _start + 20, \"LibUtils: toAddress_outOfBounds\");\n address tempAddress;\n\n assembly {\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n }\n\n return tempAddress;\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\n require(_bytes.length >= _start + 16, \"LibUtils: toUint128_outOfBounds\");\n uint128 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x10), _start))\n }\n\n return tempUint;\n }\n\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\n\t\trequire(_bytes.length >= _start + 32, \"LibUtils: toUint256_outOfBounds\");\n\t\tuint256 tempUint;\n\n // solium-disable-next-line security/no-inline-assembly\n\t\tassembly {\n\t\t\ttempUint := mload(add(add(_bytes, 0x20), _start))\n\t\t}\n\n\t\treturn tempUint;\n\t}\n}\n"
+ },
+ "contracts/Bridge/IBridgeV3.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IBridgeV3 {\n\n struct ClaimData {\n address payable to;\n uint256 amount;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) external payable;\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n */\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external returns (uint256 receivedAmount);\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns(bytes32);\n\n event Cross(\n address indexed _tokenAddress,\n address indexed _from,\n address indexed _to,\n uint256 _amount,\n bytes _userData\n );\n event NewSideToken(\n address indexed _newSideTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 _granularity\n );\n event AcceptedCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FeePercentageChanged(uint256 _amount);\n event Claimed(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _reciever,\n address _relayer,\n uint256 _fee\n );\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideToken {\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideTokenFactory {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\n\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IWrapped {\n function balanceOf(address) external returns(uint);\n\n function deposit() external payable;\n\n function withdraw(uint wad) external;\n\n function totalSupply() external view returns (uint);\n\n function approve(address guy, uint wad) external returns (bool);\n\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad)\n external\n returns (bool);\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../Initializable.sol\";\n\nimport \"../../../GSN/Context.sol\";\nimport \"../../../access/Roles.sol\";\n\ncontract UpgradablePauserRole is Initializable, Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n function __PauserRol_init(address sender) public initializer {\n if (!isPauser(sender)) {\n _addPauser(sender);\n }\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @title Roles\n * @dev Library for managing addresses assigned to a Role.\n */\nlibrary Roles {\n struct Role {\n mapping (address => bool) bearer;\n }\n\n /**\n * @dev Give an account access to this role.\n */\n function add(Role storage role, address account) internal {\n require(!has(role, account), \"Roles: account already has role\");\n role.bearer[account] = true;\n }\n\n /**\n * @dev Remove an account's access to this role.\n */\n function remove(Role storage role, address account) internal {\n require(has(role, account), \"Roles: account doesn't have role\");\n role.bearer[account] = false;\n }\n\n /**\n * @dev Check if an account has this role.\n * @return bool\n */\n function has(Role storage role, address account) internal view returns (bool) {\n require(account != address(0), \"Roles: account is the zero address\");\n return role.bearer[account];\n }\n}\n"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract WRBTC is IWrapped {\n string public name = \"Wrapped RBTC\";\n string public symbol = \"WRBTC\";\n uint8 public decimals = 18;\n\n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n event Deposit(address indexed dst, uint wad);\n event Withdrawal(address indexed src, uint wad);\n\n mapping (address => uint) override public balanceOf;\n mapping (address => mapping (address => uint)) public allowance;\n\n receive () external payable {\n deposit();\n }\n function deposit() override public payable {\n balanceOf[msg.sender] += msg.value;\n emit Deposit(msg.sender, msg.value);\n }\n function withdraw(uint wad) override public {\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\n balanceOf[msg.sender] -= wad;\n (bool success, ) = msg.sender.call{value:wad, gas:23000}(\"\");\n require(success, \"WRBTC: transfer fail\");\n emit Withdrawal(msg.sender, wad);\n }\n\n function totalSupply() override public view returns (uint) {\n return address(this).balance;\n }\n\n function approve(address guy, uint wad) override public returns (bool) {\n allowance[msg.sender][guy] = wad;\n emit Approval(msg.sender, guy, wad);\n return true;\n }\n\n function transfer(address dst, uint wad) override public returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad)\n override public\n returns (bool)\n {\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\n\n if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\n allowance[src][msg.sender] -= wad;\n }\n\n balanceOf[src] -= wad;\n balanceOf[dst] += wad;\n\n emit Transfer(src, dst, wad);\n\n return true;\n }\n}"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// import \"hardhat/console.sol\";\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n\tusing SafeMath for uint256;\n\tusing SafeERC20 for IERC20;\n\tusing Address for address;\n\n\taddress constant internal NULL_ADDRESS = address(0);\n\tbytes32 constant internal NULL_HASH = bytes32(0);\n\tIERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n\taddress internal federation;\n\tuint256 internal feePercentage;\n\tstring public deprecatedSymbolPrefix;\n\t// domainSeparator replaces uint256 internal _depprecatedLastDay;\n\tbytes32 public domainSeparator;\n\tuint256 internal _deprecatedSpentToday;\n\n\tmapping (address => address) public deprecatedMappedTokens; // OriginalToken => SideToken\n\tmapping (address => address) public deprecatedOriginalTokens; // SideToken => OriginalToken\n\tmapping (address => bool) public deprecatedKnownTokens; // OriginalToken => true\n\n\t// claimed can use the same of bytes32\n\tmapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n\n\tIAllowTokens public allowTokens;\n\tISideTokenFactory public sideTokenFactory;\n\t//Bridge_v1 variables\n\tbool public isUpgrading;\n\t// Percentage with up to 2 decimals\n\tuint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\n\t//Bridge_v2 variables\n\tbytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\n\tIWrapped public wrappedCurrency;\n\tmapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n\tmapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n\tmapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n\t// keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,uint256 originChainId,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n\tbytes32 public constant CLAIM_TYPEHASH = 0xaf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c;\n\tmapping(address => uint) public nonces;\n\n\t//Bridge_v3 variables multichain\n\tmapping (uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain; // chainId => OriginalToken Address => SideToken Address\n\tmapping (address => OriginalToken) public originalTokenBySideToken; // SideTokenAddress => struct {}\n\tmapping (uint256 => mapping(address => bool)) public knownTokenByChain; // chainId => OriginalToken Address => Know\n\n\tevent AllowTokensChanged(address _newAllowTokens);\n\tevent FederationChanged(address _newFederation);\n\tevent SideTokenFactoryChanged(address _newSideTokenFactory);\n\tevent Upgrading(bool _isUpgrading);\n\tevent WrappedCurrencyChanged(address _wrappedCurrency);\n\n\tfunction initialize(\n\t\taddress _manager,\n\t\taddress _federation,\n\t\taddress _allowTokens,\n\t\taddress _sideTokenFactory\n\t) public initializer {\n\t\tUpgradableOwnable.initialize(_manager);\n\t\tUpgradablePausable.__Pausable_init(_manager);\n\t\tallowTokens = IAllowTokens(_allowTokens);\n\t\tsideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n\t\tfederation = _federation;\n\t\t//keccak256(\"ERC777TokensRecipient\")\n\t\tERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n\t\tinitDomainSeparator();\n\t}\n\n\treceive () external payable {\n\t\t// The fallback function is needed to use WRBTC\n\t\trequire(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n\t}\n\n\tfunction version() override external pure returns (string memory) {\n\t\treturn \"v4\";\n\t}\n\n\tfunction initDomainSeparator() public {\n\t\tdomainSeparator = LibEIP712.hashEIP712Domain(\n\t\t\t\"RSK Token Bridge\",\n\t\t\t\"1\",\n\t\t\tblock.chainid,\n\t\t\taddress(this)\n\t\t);\n\t}\n\n\tmodifier whenNotUpgrading() {\n\t\trequire(!isUpgrading, \"Bridge: Upgrading\");\n\t\t_;\n\t}\n\n\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\n\t\trequire(chainId == block.chainid, \"Bridge: Not block.chainid\");\n\t}\n\n\tfunction sideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\n\t\taddress sideTokenAddr = sideTokenByOriginalTokenByChain[chainId][originalToken];\n\n\t\tif (sideTokenAddr != NULL_ADDRESS) {\n\t\t\treturn sideTokenAddr;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\treturn deprecatedMappedTokens[originalToken];\n\t}\n\n\tfunction setSideTokenByOriginalAddressByChain(uint256 chainId, address originalToken, address sideToken) public onlyOwner {\n\t\tsideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\n\t}\n\n\tfunction getOriginalTokenBySideToken(address sideToken) public view returns(OriginalToken memory originalToken) {\n\t\toriginalToken = originalTokenBySideToken[sideToken];\n\t\tif (originalToken.tokenAddress != NULL_ADDRESS) {\n\t\t\treturn originalToken;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\toriginalToken.originChainId = 1; // ethereum main chain id\n\t\toriginalToken.tokenAddress = deprecatedOriginalTokens[sideToken];\n\t\treturn originalToken;\n\t}\n\n\tfunction setOriginalTokenBySideTokenByChain(address sideToken, OriginalToken memory originalToken) public onlyOwner {\n\t\toriginalTokenBySideToken[sideToken] = originalToken;\n\t}\n\n\tfunction knownToken(uint256 chainId, address originalToken) public view returns(bool) {\n\t\tbool knowToken = knownTokenByChain[chainId][originalToken];\n\t\tif (knowToken) {\n\t\t\treturn knowToken;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\treturn deprecatedKnownTokens[originalToken];\n\t}\n\n\tfunction _setKnownTokenByChain(uint256 chainId, address originalToken, bool knownTokenValue) internal {\n\t\tknownTokenByChain[chainId][originalToken] = knownTokenValue;\n\t}\n\n\tfunction acceptTransfer(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _from,\n\t\taddress payable _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) external whenNotPaused nonReentrant override {\n\t\trequire(_msgSender() == federation, \"Bridge: Not Federation\");\n\t\tcheckChainId(_originChainId);\n\t\tshouldBeCurrentChainId(_destinationChainId);\n\t\trequire(knownToken(_originChainId, _originalTokenAddress) ||\n\t\t\tsideTokenByOriginalToken(_originChainId, _originalTokenAddress) != NULL_ADDRESS,\n\t\t\t\"Bridge: Unknown token\"\n\t\t);\n\t\trequire(_to != NULL_ADDRESS, \"Bridge: Null To\");\n\t\trequire(_amount > 0, \"Bridge: Amount 0\");\n\t\trequire(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n\t\trequire(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n\t\trequire(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n\t\tbytes32 _transactionDataHash = getTransactionDataHash(\n\t\t\t_to,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_transactionHash,\n\t\t\t_logIndex\n\t\t);\n\n\t\tbytes32 _transactionDataHashMultichain = getTransactionDataHash(\n\t\t\t_to,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_transactionHash,\n\t\t\t_logIndex,\n\t\t\t_originChainId,\n\t\t\t_destinationChainId\n\t\t);\n\t\t// Do not remove, claimed also has the previously processed using the older bridge version\n\t\t// https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n\t\trequire(!isClaimed(_transactionDataHash, _transactionDataHashMultichain), \"Bridge: Already claimed\");\n\n\t\ttransactionsDataHashes[_transactionHash] = _transactionDataHashMultichain;\n\t\toriginalTokenAddresses[_transactionHash] = _originalTokenAddress;\n\t\tsenderAddresses[_transactionHash] = _from;\n\n\t\temit AcceptedCrossTransfer(\n\t\t\t_transactionHash,\n\t\t\t_originalTokenAddress,\n\t\t\t_to,\n\t\t\t_from,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_logIndex,\n\t\t\t_originChainId,\n\t\t\t_destinationChainId\n\t\t);\n\t}\n\n\tfunction checkChainId(uint256 chainId) internal pure {\n\t\trequire(chainId > 0, \"Bridge: ChainId is 0\");\n\t}\n\n\tfunction _createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _tokenSymbol,\n\t\tstring calldata _tokenName,\n\t\tuint256 _originChainId\n\t) internal {\n\t\trequire(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n\t\tcheckChainId(_originChainId);\n\t\taddress sideToken = sideTokenByOriginalToken(_originChainId, _originalTokenAddress);\n\t\trequire(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n\n\t\tuint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n\n\t\t// Create side token\n\t\tsideToken = sideTokenFactory.createSideToken(_tokenName, _tokenSymbol, granularity);\n\n\t\tsetSideTokenByOriginalAddressByChain(_originChainId, _originalTokenAddress, sideToken);\n\n\t\tOriginalToken memory originalToken;\n\t\toriginalToken.originChainId = _originChainId;\n\t\toriginalToken.tokenAddress = _originalTokenAddress;\n\t\tsetOriginalTokenBySideTokenByChain(sideToken, originalToken);\n\t\tallowTokens.setToken(sideToken, _typeId);\n\n\t\temit NewSideToken(sideToken, _originalTokenAddress, _tokenSymbol, granularity, _originChainId);\n\t}\n\n\tfunction createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _tokenSymbol,\n\t\tstring calldata _tokenName,\n\t\tuint256 _originChainId\n\t) external onlyOwner override {\n\t\t_createSideToken(\n\t\t\t_typeId,\n\t\t\t_originalTokenAddress,\n\t\t\t_originalTokenDecimals,\n\t\t\t_tokenSymbol,\n\t\t\t_tokenName,\n\t\t\t_originChainId\n\t\t);\n\t}\n\n\tfunction createMultipleSideTokens(\n\t\tCreateSideTokenStruct[] calldata createSideTokenStruct\n\t) external onlyOwner {\n\t\tfor(uint256 i = 0; i < createSideTokenStruct.length; i++) {\n\t\t\t_createSideToken(\n\t\t\t\tcreateSideTokenStruct[i]._typeId,\n\t\t\t\tcreateSideTokenStruct[i]._originalTokenAddress,\n\t\t\t\tcreateSideTokenStruct[i]._originalTokenDecimals,\n\t\t\t\tcreateSideTokenStruct[i]._originalTokenSymbol,\n\t\t\t\tcreateSideTokenStruct[i]._originalTokenName,\n\t\t\t\tcreateSideTokenStruct[i]._originChainId\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction claim(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\n\t\treceivedAmount = _claim(\n\t\t\t_claimData,\n\t\t\t_claimData.to,\n\t\t\tpayable(address(0)),\n\t\t\t0\n\t\t);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction claimFallback(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\n\t\trequire(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n\t\treceivedAmount = _claim(\n\t\t\t_claimData,\n\t\t\t_msgSender(),\n\t\t\tpayable(address(0)),\n\t\t\t0\n\t\t);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction getDigest(\n\t\tClaimData memory _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline\n\t) internal returns (bytes32) {\n\t\treturn LibEIP712.hashEIP712Message(\n\t\t\tdomainSeparator,\n\t\t\tkeccak256(\n\t\t\t\tabi.encode(\n\t\t\t\t\tCLAIM_TYPEHASH,\n\t\t\t\t\t_claimData.to,\n\t\t\t\t\t_claimData.amount,\n\t\t\t\t\t_claimData.transactionHash,\n\t\t\t\t\t_claimData.originChainId,\n\t\t\t\t\t_relayer,\n\t\t\t\t\t_fee,\n\t\t\t\t\tnonces[_claimData.to]++,\n\t\t\t\t\t_deadline\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t}\n\n\t// Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n\tfunction claimGasless(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline,\n\t\tuint8 _v,\n\t\tbytes32 _r,\n\t\tbytes32 _s\n\t) external override returns (uint256 receivedAmount) {\n\t\trequire(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\n\n\t\tbytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n\t\taddress recoveredAddress = ecrecover(digest, _v, _r, _s);\n\t\trequire(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n\t\treturn _claim(\n\t\t\t_claimData,\n\t\t\t_claimData.to,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\t}\n\n\tfunction isClaimed(bytes32 transactionDataHash, bytes32 transactionDataHashMultichain) public view returns(bool) {\n\t\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\n\t}\n\n\tfunction isClaimed(ClaimData calldata _claimData, bytes32 transactionDataHashMultichain) public view returns(bool) {\n\t\tbytes32 transactionDataHash = getTransactionDataHash(\n\t\t\t_claimData.to,\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.transactionHash,\n\t\t\t_claimData.logIndex\n\t\t);\n\n\t\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\n\t}\n\n\tfunction _claim(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _reciever,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal nonReentrant returns (uint256 receivedAmount) {\n\t\taddress originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n\t\trequire(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n\t\tbytes32 transactionDataHash = getTransactionDataHash(\n\t\t\t_claimData.to,\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.transactionHash,\n\t\t\t_claimData.logIndex,\n\t\t\t_claimData.originChainId,\n\t\t\tblock.chainid\n\t\t);\n\n\t\trequire(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n\t\trequire(!isClaimed(_claimData, transactionDataHash), \"Bridge: Already claimed\");\n\t\tclaimed[transactionDataHash] = true;\n\n\t\treceivedAmount = _claimCross(\n\t\t\t_claimData.originChainId,\n\t\t\toriginalTokenAddress,\n\t\t\t_reciever,\n\t\t\t_claimData.amount,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\n\t\temitClaimed(_claimData, originalTokenAddress, _reciever, _relayer, _fee);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction emitClaimed(\n\t\tClaimData calldata _claimData,\n\t\taddress _originalTokenAddress,\n\t\taddress payable _reciever,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal {\n\t\temit Claimed(\n\t\t\t_claimData.transactionHash,\n\t\t\t_originalTokenAddress,\n\t\t\t_claimData.to,\n\t\t\tsenderAddresses[_claimData.transactionHash],\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.logIndex,\n\t\t\t_reciever,\n\t\t\t_relayer,\n\t\t\t_fee,\n\t\t\t_claimData.originChainId,\n\t\t\tblock.chainid\n\t\t);\n\t}\n\n\tfunction _claimCross(\n\t\tuint256 _originalChainId,\n\t\taddress _originalTokenAddress,\n\t\taddress payable _reciever,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256) {\n\t\tcheckChainId(_originalChainId);\n\t\tif (knownToken(_originalChainId, _originalTokenAddress)) {\n\t\t\treturn _claimCrossBackToToken(\n\t\t\t\t_originalTokenAddress,\n\t\t\t\t_reciever,\n\t\t\t\t_amount,\n\t\t\t\t_relayer,\n\t\t\t\t_fee\n\t\t\t);\n\t\t}\n\n\t\treturn _claimCrossToSideToken(\n\t\t\tsideTokenByOriginalToken(_originalChainId, _originalTokenAddress),\n\t\t\t_reciever,\n\t\t\t_amount,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\t}\n\n\tfunction _claimCrossToSideToken(\n\t\taddress _sideToken,\n\t\taddress payable _receiver,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256 receivedAmount) {\n\t\trequire(_sideToken != NULL_ADDRESS, \"Bridge: side token is null\");\n\t\tuint256 granularity = IERC777(_sideToken).granularity();\n\t\tuint256 formattedAmount = _amount.mul(granularity);\n\t\trequire(_fee <= formattedAmount, \"Bridge: fee too high\");\n\t\treceivedAmount = formattedAmount.sub(_fee);\n\t\tISideToken(_sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n\t\tif (_fee > 0) {\n\t\t\tISideToken(_sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n\t\t}\n\t\treturn receivedAmount;\n\t}\n\n\tfunction _claimCrossBackToToken(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _receiver,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256 receivedAmount) {\n\t\tuint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n\t\t//As side tokens are ERC777 they will always have 18 decimals\n\t\tuint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n\t\trequire(_fee <= formattedAmount, \"Bridge: fee too high\");\n\t\treceivedAmount = formattedAmount.sub(_fee);\n\t\tif (address(wrappedCurrency) == _originalTokenAddress) {\n\t\t\twrappedCurrency.withdraw(formattedAmount);\n\t\t\t_receiver.transfer(receivedAmount);\n\t\t\tif(_fee > 0) {\n\t\t\t\t_relayer.transfer(_fee);\n\t\t\t}\n\t\t} else {\n\t\t\tIERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n\t\t\tif(_fee > 0) {\n\t\t\t\tIERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n\t\t\t}\n\t\t}\n\t\treturn receivedAmount;\n\t}\n\n\t/**\n\t\t* ERC-20 tokens approve and transferFrom pattern\n\t\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n\t\t*/\n\tfunction receiveTokensTo(uint256 destinationChainId, address tokenToUse, address to, uint256 amount) external override {\n\t\taddress sender = _msgSender();\n\t\t//Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n\t\tIERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n\t\tcrossTokens(tokenToUse, sender, to, amount, \"\", destinationChainId);\n\t}\n\n\t/**\n\t\t* Use network currency and cross it.\n\t\t*/\n\tfunction depositTo(uint256 chainId, address to) external payable override {\n\t\taddress sender = _msgSender();\n\t\trequire(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n\t\twrappedCurrency.deposit{ value: msg.value }();\n\t\tcrossTokens(address(wrappedCurrency), sender, to, msg.value, \"\", chainId);\n\t}\n\n\t/**\n\t\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n\t\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n\t\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\n\t\t* const userData = web3.eth.abi.encodeParameters(\n * [\"address\", \"uint256\"],\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\n * );\n\t\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\n\t\t* const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\n\t\t*/\n\tfunction tokensReceived(\n\t\taddress operator,\n\t\taddress from,\n\t\taddress to,\n\t\tuint amount,\n\t\tbytes calldata userData, // [address,uint256] user addrest receiver, destinationChainId || [uint256] same as from, destinationChainId\n\t\tbytes calldata\n\t) external override(IBridge, IERC777Recipient) {\n\t\t//Hook from ERC777address\n\t\tif(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n\t\trequire(to == address(this), \"Bridge: Not to this address\");\n\t\taddress tokenToUse = _msgSender();\n\t\trequire(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n\t\trequire(userData.length >= 32, \"Bridge: user data with at least the destinationChainId\");\n\t\trequire(userData.length == 64 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n\t\taddress receiver = userData.length == 32 ? from : LibUtils.toAddress(userData, 12);\n\t\tuint256 destinationChainId = LibUtils.toUint256(userData, userData.length - 32);\n\t\tcrossTokens(tokenToUse, from, receiver, amount, userData, destinationChainId);\n\t}\n\n\tfunction crossTokens(\n\t\taddress tokenToUse,\n\t\taddress from,\n\t\taddress to,\n\t\tuint256 amount,\n\t\tbytes memory userData,\n\t\tuint256 destinationChainId\n\t) internal whenNotUpgrading whenNotPaused nonReentrant {\n\t\trequire(block.chainid != destinationChainId, \"Bridge: destination chain id equal current chain id\");\n\t\tcheckChainId(destinationChainId);\n\t\t_setKnownTokenByChain(destinationChainId, tokenToUse, true);\n\t\tuint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n\t\tuint256 amountMinusFees = amount.sub(fee);\n\t\tuint8 decimals = LibUtils.getDecimals(tokenToUse);\n\t\tuint formattedAmount = amount;\n\t\tif (decimals != 18) {\n\t\t\tformattedAmount = amount.mul(uint256(10)**(18-decimals));\n\t\t}\n\t\t// We consider the amount before fees converted to 18 decimals to check the limits\n\t\t// updateTokenTransfer revert if token not allowed\n\t\tallowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n\n\t\tOriginalToken memory sideToken = getOriginalTokenBySideToken(tokenToUse);\n\t\tif (sideToken.tokenAddress != NULL_ADDRESS) {\n\t\t\t// Side Token Crossing back\n\t\t\t{ // Created scope to avoid stack too deep\n\t\t\t\tuint256 granularity = LibUtils.getGranularity(tokenToUse);\n\t\t\t\tuint256 modulo = amountMinusFees.mod(granularity);\n\t\t\t\tfee = fee.add(modulo);\n\t\t\t\tamountMinusFees = amountMinusFees.sub(modulo);\n\t\t\t\tIERC777(tokenToUse).burn(amountMinusFees, userData);\n\t\t\t}\n\t\t\temit Cross(\n\t\t\t\tsideToken.tokenAddress,\n\t\t\t\tto,\n\t\t\t\tdestinationChainId,\n\t\t\t\tfrom,\n\t\t\t\tblock.chainid,\n\t\t\t\tamountMinusFees,\n\t\t\t\tuserData\n\t\t\t);\n\t\t} else {\n\t\t\temit Cross(\n\t\t\t\ttokenToUse,\n\t\t\t\tto,\n\t\t\t\tdestinationChainId,\n\t\t\t\tfrom,\n\t\t\t\tblock.chainid,\n\t\t\t\tamountMinusFees,\n\t\t\t\tuserData\n\t\t\t);\n\t\t}\n\n\t\tif (fee > 0) {\n\t\t\t//Send the payment to the MultiSig of the Federation\n\t\t\tIERC20(tokenToUse).safeTransfer(owner(), fee);\n\t\t}\n\t}\n\n\t// function for retrocompatibility\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex\n\t) internal pure returns(bytes32) {\n\t\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n\t}\n\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) public pure override returns(bytes32) {\n\t\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex, _originChainId, _destinationChainId));\n\t}\n\n\tfunction setFeePercentage(uint amount) external onlyOwner {\n\t\trequire(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n\t\tfeePercentage = amount;\n\t\temit FeePercentageChanged(feePercentage);\n\t}\n\n\tfunction getFeePercentage() external view override returns(uint) {\n\t\treturn feePercentage;\n\t}\n\n\tfunction changeFederation(address newFederation) external onlyOwner {\n\t\trequire(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n\t\tfederation = newFederation;\n\t\temit FederationChanged(federation);\n\t}\n\n\tfunction changeAllowTokens(address newAllowTokens) external onlyOwner {\n\t\trequire(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n\t\tallowTokens = IAllowTokens(newAllowTokens);\n\t\temit AllowTokensChanged(newAllowTokens);\n\t}\n\n\tfunction getFederation() external view returns(address) {\n\t\treturn federation;\n\t}\n\n\tfunction changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n\t\trequire(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n\t\tsideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n\t\temit SideTokenFactoryChanged(newSideTokenFactory);\n\t}\n\n\tfunction setUpgrading(bool _isUpgrading) external onlyOwner {\n\t\tisUpgrading = _isUpgrading;\n\t\temit Upgrading(isUpgrading);\n\t}\n\n\tfunction setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n\t\trequire(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n\t\twrappedCurrency = IWrapped(_wrappedCurrency);\n\t\temit WrappedCurrencyChanged(_wrappedCurrency);\n\t}\n\n\tfunction hasCrossed(bytes32 transactionHash) public view returns (bool) {\n\t\treturn transactionsDataHashes[transactionHash] != bytes32(0);\n\t}\n\n\tfunction hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n\t\treturn claimed[transactionsDataHashes[transactionHash]];\n\t}\n\n}\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IBridge {\n\n\tstruct ClaimData {\n\t\taddress payable to;\n\t\tuint256 amount;\n\t\tbytes32 blockHash;\n\t\tbytes32 transactionHash;\n\t\tuint32 logIndex;\n\t\tuint256 originChainId;\n\t}\n\n\tstruct OriginalToken {\n\t\taddress tokenAddress;\n\t\tuint256 originChainId;\n\t}\n\t\n\tstruct CreateSideTokenStruct {\n\t\tuint256 _typeId;\n\t\taddress _originalTokenAddress;\n\t\tuint8 _originalTokenDecimals;\n\t\tstring _originalTokenSymbol;\n\t\tstring _originalTokenName;\n\t\tuint256 _originChainId;\n\t}\n\n\tfunction version() external pure returns (string memory);\n\n\tfunction getFeePercentage() external view returns(uint);\n\n\t/**\n\t\t* ERC-20 tokens approve and transferFrom pattern\n\t\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n\t\t*/\n\tfunction receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;\n\n\t/**\n\t\t* Use network currency and cross it.\n\t\t*/\n\tfunction depositTo(uint256 chainId, address to) external payable;\n\n\t/**\n\t\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n\t\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n\t\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\n\t\t* const userData = web3.eth.abi.encodeParameters(\n * [\"address\", \"uint256\"],\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\n * );\n\t\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\n\t\t* const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\n\t\t*/\n\tfunction tokensReceived (\n\t\taddress operator,\n\t\taddress from,\n\t\taddress to,\n\t\tuint amount,\n\t\tbytes calldata userData,\n\t\tbytes calldata operatorData\n\t) external;\n\n\t/**\n\t\t* Accepts the transaction from the other chain that was voted and sent by the Federation contract\n\t\t*/\n\tfunction acceptTransfer(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _from,\n\t\taddress payable _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) external;\n\n\t/**\n\t\t* Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n\t\t*/\n\tfunction claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n\tfunction claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n\tfunction claimGasless(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline,\n\t\tuint8 _v,\n\t\tbytes32 _r,\n\t\tbytes32 _s\n\t) external returns (uint256 receivedAmount);\n\n\tfunction createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _originalTokenSymbol,\n\t\tstring calldata _originalTokenName,\n\t\tuint256 _chainId\n\t) external;\n\n\tfunction createMultipleSideTokens(\n\t\tCreateSideTokenStruct[] calldata createSideTokenStruct\n\t) external;\n\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256 _destinationChainId\n\t) external returns(bytes32);\n\n\tevent Cross(\n\t\taddress indexed _tokenAddress,\n\t\taddress indexed _to,\n\t\tuint256 indexed _destinationChainId,\n\t\taddress _from,\n\t\tuint256 _originChainId,\n\t\tuint256 _amount,\n\t\tbytes _userData\n\t);\n\n\tevent NewSideToken(\n\t\taddress indexed _newSideTokenAddress,\n\t\taddress indexed _originalTokenAddress,\n\t\tstring _newSymbol,\n\t\tuint256 _granularity,\n\t\tuint256 _chainId\n\t);\n\tevent AcceptedCrossTransfer(\n\t\tbytes32 indexed _transactionHash,\n\t\taddress indexed _originalTokenAddress,\n\t\taddress indexed _to,\n\t\taddress _from,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tuint256 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t);\n\tevent FeePercentageChanged(uint256 _amount);\n\tevent Claimed(\n\t\tbytes32 indexed _transactionHash,\n\t\taddress indexed _originalTokenAddress,\n\t\taddress indexed _to,\n\t\taddress _sender,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tuint256 _logIndex,\n\t\taddress _reciever,\n\t\taddress _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _destinationChainId,\n\t\tuint256 _originChainId\n\t);\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../SideToken/SideToken.sol\";\n\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\n external onlyPrimary override returns(address) {\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\n emit SideTokenCreated(sideToken, symbol, granularity);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\nabstract contract Secondary is Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n constructor () {\n _primary = _msgSender();\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(_primary);\n }\n}\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\nimport \"../interface/IERC677Receiver.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../lib/LibEIP712.sol\";\n\ncontract SideToken is ISideToken, ERC777 {\n using SafeMath for uint256;\n\n address public minter;\n uint256 private _granularity;\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n bytes32 public domainSeparator;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n // ERC677 Transfer Event\n event Transfer(address,address,uint256,bytes);\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\n minter = _minterAddr;\n _granularity = _newGranularity;\n\n domainSeparator = LibEIP712.hashEIP712Domain(\n name(),\n \"1\",\n block.chainid,\n address(this)\n );\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter override\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n /**\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\n * @param recipient The address to transfer to.\n * @param amount The amount to be transferred.\n * @param data The extra data to be passed to the receiving contract.\n */\n function transferAndCall(address recipient, uint amount, bytes calldata data)\n external returns (bool success)\n {\n address from = _msgSender();\n\n _send(from, from, recipient, amount, data, \"\", false);\n emit Transfer(from, recipient, amount, data);\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\n return true;\n }\n\n function granularity() public view override returns (uint256) {\n return _granularity;\n }\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\n bytes32 digest = LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../../token/ERC20/IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\n // See https://github.com/ethereum/solidity/issues/4024.\n\n // keccak256(\"ERC777TokensSender\")\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\n\n // keccak256(\"ERC777TokensRecipient\")\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping (address => mapping (address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(\n string memory aName,\n string memory aSymbol,\n address[] memory theDefaultOperators\n ) {\n _name = aName;\n _symbol = aSymbol;\n\n _defaultOperatorsArray = theDefaultOperators;\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\n _defaultOperators[_defaultOperatorsArray[i]] = true;\n }\n\n // register interfaces\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view override(IERC777) returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view override(IERC777) returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20Detailed-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override(IERC777) returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n\n address from = _msgSender();\n\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\n\n _move(from, from, recipient, amount, \"\", \"\");\n\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(\n address operator,\n address tokenHolder\n ) public view override(IERC777) returns (bool) {\n return operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) external override(IERC777) {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) external override(IERC777) {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n )\n external override(IERC777)\n {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {Transfer} events.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\n external override(IERC777) {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\n _burn(_msgSender(), account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender)\n public view override(IERC20) returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {Transfer} and {Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount)\n external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n require(holder != address(0), \"ERC777: transfer from zero address\");\n\n address spender = _msgSender();\n\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\n\n _move(spender, holder, recipient, amount, \"\", \"\");\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\n\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address operator,\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n require(account != address(0), \"ERC777: mint to zero address\");\n\n // Update state variables\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n internal\n {\n require(from != address(0), \"ERC777: send from zero address\");\n require(to != address(0), \"ERC777: send to zero address\");\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param operator address operator requesting the operation\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(\n address operator,\n address from,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n )\n internal\n {\n require(from != address(0), \"ERC777: burn from zero address\");\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n // Update state variables\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\n _balances[to] = _balances[to].add(amount);\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n function _approve(address holder, address spender, uint256 value) internal {\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\n // currently unnecessary.\n //require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n private\n {\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n}\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * `IERC777` Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an `IERC777` token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\nimport \"../interface/IERC677Receiver.sol\";\n\ncontract mockERC677Receiver is IERC677Receiver {\n event Success(address _sender, uint _value, bytes _data);\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\n emit Success(_sender, _value, _data);\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Optional functions from the ERC20 standard.\n */\nabstract contract ERC20Detailed is IERC20 {\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\n * these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\n _name = aName;\n _symbol = aSymbol;\n _decimals = theDecimals;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20Mintable}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() override public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) override public view returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) override public returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) override public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) override public returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal {\n require(sender != address(0), \"ERC20: transfer from zero address\");\n require(recipient != address(0), \"ERC20: transfer to zero address\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: mint to zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: burn from zero address\");\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n *\n * This is internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal {\n require(owner != address(0), \"ERC20: approve from zero address\");\n require(spender != address(0), \"ERC20: approve to zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\n * from the caller's allowance.\n *\n * See {_burn} and {_approve}.\n */\n function _burnFrom(address account, uint256 amount) internal {\n _burn(account, amount);\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\n }\n}\n"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract MainToken is ERC20Detailed, ERC20 {\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\n ERC20Detailed(name, symbol, decimals)\n {\n _mint(msg.sender, totalSupply);\n }\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\n bool result = transfer(_to, _value);\n if (!result) return false;\n\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\n receiver.tokenFallback(msg.sender, _value, _data);\n\n // IMPORTANT: the ERC-677 specification does not say\n // anything about the use of the receiver contract's\n // tokenFallback method return value. Given\n // its return type matches with this method's return\n // type, returning it could be a possibility.\n // We here take the more conservative approach and\n // ignore the return value, returning true\n // to signal a succesful transfer despite tokenFallback's\n // return value -- fact being tokens are transferred\n // in any case.\n return true;\n }\n}\n\ninterface ERC677TransferReceiver {\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\n}"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IBridge.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockReceiveTokensCall is IERC777Recipient {\n address public bridge;\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor(address _bridge) {\n bridge = _bridge;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount, uint256 destinationChainId) external {\n IERC20(tokenToUse).approve(bridge, amount);\n IBridge(bridge).receiveTokensTo(destinationChainId, tokenToUse, receiver, amount);\n }\n\n function callDepositTo(address receiver, uint256 destinationChainId) external payable {\n IBridge(bridge).depositTo{ value: msg.value }(destinationChainId, receiver);\n }\n\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\n IERC777(tokenToUse).send(bridge, amount, data);\n }\n\n // Mandatory for IERC777Recipient\n function tokensReceived(\n address,\n address,\n address,\n uint,\n bytes calldata,\n bytes calldata\n ) override external view {\n this;\n }\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockERC777Recipient is IERC777Recipient {\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor() {\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\n }\n\n event Success(\n address operator,\n address from,\n address to,\n uint amount,\n bytes userData,\n bytes operatorData);\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) override external {\n emit Success(operator, from, to, amount, userData, operatorData);\n }\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\n\ncontract SideTokenV1 is ERC777 {\n address public minter;\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\n minter = _minterAddr;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../SideToken/SideTokenV1.sol\";\n\ncontract SideTokenFactoryV1 is Secondary {\n event CreatedSideToken(address sideToken, string symbol);\n\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\n emit CreatedSideToken(address(sideToken), symbol);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./ERC721.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721Burnable is Context, ERC721 {\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n _burn(tokenId);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _tokenOwners.contains(tokenId);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(tokenId);\n\n emit Transfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n */\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC721.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC721 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC721Pausable is ERC721, Pausable {\n /**\n * @dev See {ERC721-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\nimport \"../access/roles/PauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context, PauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n constructor () {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract PauserRole is Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n constructor () {\n _addPauser(_msgSender());\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC1155 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Pausable is ERC1155, Pausable {\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using SafeMath for uint256;\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping (uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /*\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri_) {\n _setURI(uri_);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) external view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: balance query for the zero address\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(amount);\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, address(0), id, amount);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\n /**\n @dev Handles the receipt of a single ERC1155 token type. This function is\n called at the end of a `safeTransferFrom` after the balance has been updated.\n To accept the transfer, this must return\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n (i.e. 0xf23a6e61, or its own function selector).\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n )\n external\n returns(bytes4);\n\n /**\n @dev Handles the receipt of a multiple ERC1155 token types. This function\n is called at the end of a `safeBatchTransferFrom` after the balances have\n been updated. To accept the transfer(s), this must return\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n (i.e. 0xbc197c81, or its own function selector).\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match values array)\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n )\n external\n returns(bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Burnable is ERC1155 {\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./Proxy.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n *\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\n * {TransparentUpgradeableProxy}.\n */\ncontract UpgradeableProxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _setImplementation(_logic);\n if(_data.length > 0) {\n Address.functionDelegateCall(_logic, _data);\n }\n }\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n bytes32 slot = _IMPLEMENTATION_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n impl := sload(slot)\n }\n }\n\n /**\n * @dev Upgrades the proxy to a new implementation.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal virtual {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\n\n bytes32 slot = _IMPLEMENTATION_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newImplementation)\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./UpgradeableProxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _setAdmin(admin_);\n }\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _admin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _admin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\n emit AdminChanged(_admin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external virtual ifAdmin {\n _upgradeTo(newImplementation);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\n _upgradeTo(newImplementation);\n Address.functionDelegateCall(newImplementation, data);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address adm) {\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n adm := sload(slot)\n }\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n bytes32 slot = _ADMIN_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newAdmin)\n }\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../ownership/Ownable.sol\";\nimport \"./TransparentUpgradeableProxy.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () {\n _owner = _msgSender();\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../../zeppelin/ownership/Ownable.sol\";\nimport \"../../zeppelin/math/SafeMath.sol\";\nimport \"../../zeppelin/utils/Strings.sol\";\nimport \"./OpenSeaEIP712Base.sol\";\n\n\n/**\n * @title OpenSea721\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\n */\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\n using SafeMath for uint256;\n\n uint256 private _currentTokenId = 0;\n\n constructor(\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n _initializeEIP712(_name);\n }\n\n function baseTokenURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/api/creature/\";\n }\n\n function contractURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\n }\n\n /**\n * @dev Mints a token to an address with a tokenURI.\n * @param _to address of the future owner of the token\n */\n function mintTo(address _to) public onlyOwner {\n uint256 newTokenId = _getNextTokenId();\n _mint(_to, newTokenId);\n _incrementTokenId();\n }\n\n /**\n * @dev calculates the next token ID based on value of _currentTokenId\n * @return uint256 for the next token ID\n */\n function _getNextTokenId() private view returns (uint256) {\n return _currentTokenId.add(1);\n }\n\n /**\n * @dev increments the value of _currentTokenId\n */\n function _incrementTokenId() private {\n _currentTokenId++;\n }\n\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\n }\n\n}"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../zeppelin/upgradable/Initializable.sol\";\n\ncontract OpenSeaEIP712Base is Initializable {\n struct EIP712Domain {\n string name;\n string version;\n address verifyingContract;\n bytes32 salt;\n }\n\n string constant public ERC712_VERSION = \"1\";\n\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\n bytes(\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\n )\n );\n bytes32 internal domainSeperator;\n\n // supposed to be called once while initializing.\n // one of the contracts that inherits this contract follows proxy pattern\n // so it is not possible to do this in a constructor\n function _initializeEIP712(\n string memory name\n )\n internal\n initializer\n {\n _setDomainSeperator(name);\n }\n\n function _setDomainSeperator(string memory name) internal {\n domainSeperator = keccak256(\n abi.encode(\n EIP712_DOMAIN_TYPEHASH,\n keccak256(bytes(name)),\n keccak256(bytes(ERC712_VERSION)),\n address(this),\n bytes32(block.chainid)\n )\n );\n }\n\n function getDomainSeperator() public view returns (bytes32) {\n return domainSeperator;\n }\n\n /**\n * Accept message hash and returns hash message in EIP712 compatible form\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\n * https://eips.ethereum.org/EIPS/eip-712\n * \"\\\\x19\" makes the encoding deterministic\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\n */\n function toTypedMessageHash(bytes32 messageHash)\n internal\n view\n returns (bytes32)\n {\n return\n keccak256(\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\n );\n }\n}\n"
+ },
+ "contracts/Federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../Bridge/IBridgeV3.sol\";\n\ncontract FederationV2 is Initializable, UpgradableOwnable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridgeV3 public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\n validRequirement(_members.length, _required) public initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n }\n\n function version() external pure returns (string memory) {\n return \"v2\";\n }\n\n function setBridge(address _bridge) external onlyOwner {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridgeV3(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n )\n public onlyMember returns(bool)\n {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32)\n {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}"
+ },
+ "contracts/Federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/IFederation.sol\";\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\n\tuint constant public MAX_MEMBER_COUNT = 50;\n\taddress constant private NULL_ADDRESS = address(0);\n\n\tIBridge public bridge;\n\taddress[] public members;\n\n\t/**\n\t\t@notice The minimum amount of votes to approve a transaction\n\t\t@dev It should have at least the required amount of members\n\t\t*/\n\tuint public required;\n\n\t/**\n\t\t@notice All the addresses that are members of the federation\n\t\t@dev The address should be a member to vote in transactions\n\t\t*/\n\tmapping (address => bool) public isMember;\n\n\t/**\n\t\t(bytes32) transactionId = keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tamount,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex\n\t\t\t)\n\t\t) => (\n\t\t\t(address) members => (bool) voted\n\t\t)\n\t\t@notice Votes by members by the transaction ID\n\t\t@dev the members should approve the transaction by 50% + 1\n\t\t*/\n\tmapping (bytes32 => mapping (address => bool)) public votes;\n\n\t/**\n\t\t(bytes32) transactionId => (bool) voted\n\t\t@notice Check if that transaction was already processed\n\t*/\n\tmapping(bytes32 => bool) public processed;\n\n\tmodifier onlyMember() {\n\t\trequire(isMember[_msgSender()], \"Federation: Not Federator\");\n\t\t_;\n\t}\n\n\tmodifier validRequirement(uint membersCount, uint _required) {\n\t\trequire(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n\t\t_;\n\t}\n\n\tfunction initialize(\n\t\taddress[] calldata _members,\n\t\tuint _required,\n\t\taddress _bridge,\n\t\taddress owner\n\t) public validRequirement(_members.length, _required) initializer {\n\t\tUpgradableOwnable.initialize(owner);\n\t\trequire(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n\t\tmembers = _members;\n\t\tfor (uint i = 0; i < _members.length; i++) {\n\t\t\trequire(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n\t\t\tisMember[_members[i]] = true;\n\t\t\temit MemberAddition(_members[i]);\n\t\t}\n\t\trequired = _required;\n\t\temit RequirementChange(required);\n\t\t_setBridge(_bridge);\n\t}\n\n\t/**\n\t\t@notice Current version of the contract\n\t\t@return version in v{Number}\n\t\t*/\n\tfunction version() external pure override returns (string memory) {\n\t\treturn \"v3\";\n\t}\n\n\t/**\n\t\t@notice Sets a new bridge contract\n\t\t@dev Emits BridgeChanged event\n\t\t@param _bridge the new bridge contract address that should implement the IBridge interface\n\t\t*/\n\tfunction setBridge(address _bridge) external onlyOwner override {\n\t\t_setBridge(_bridge);\n\t}\n\n\tfunction _setBridge(address _bridge) internal {\n\t\trequire(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n\t\tbridge = IBridge(_bridge);\n\t\temit BridgeChanged(_bridge);\n\t}\n\n\tfunction validateTransaction(bytes32 transactionId, bytes32 transactionIdMultichain) internal view returns(bool) {\n\t\tuint256 minimumVotes = getMinimalNumberOfVotes();\n\t\tuint256 amountVotes = 0;\n\n for (uint256 i = 0; i < members.length; i++) {\n if (votes[transactionIdMultichain][members[i]]) {\n amountVotes += 1;\n\t\t\t} else if (votes[transactionId][members[i]]) {\n amountVotes += 1;\n\t\t\t}\n\n\t\t\tif (amountVotes >= minimumVotes && amountVotes >= required) {\n\t\t\t\treturn true;\n\t\t\t}\n }\n\n\t\treturn false;\n\t}\n\n\tfunction getMinimalNumberOfVotes() internal view returns(uint256) {\n\t\treturn members.length / 2 + 1;\n\t}\n\n\tfunction isProcessed(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\n\t\treturn processed[transactionIdMultichain] || processed[transactionId];\n\t}\n\n\tfunction isVoted(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\n\t\treturn votes[transactionIdMultichain][_msgSender()] || votes[transactionId][_msgSender()];\n\t}\n\n\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\n\t\trequire(chainId == block.chainid, \"Federation: Not block.chainid\");\n\t}\n\n\t/**\n\t\t@notice Vote in a transaction, if it has enough votes it accepts the transfer\n\t\t@param originalTokenAddress The address of the token in the origin (main) chain\n\t\t@param sender The address who solicited the cross token\n\t\t@param receiver Who is going to receive the token in the opposite chain\n\t\t@param value Amount\n\t\t@param blockHash The block hash in which the transaction with the cross event occurred\n\t\t@param transactionHash The transaction in which the cross event occurred\n\t\t@param logIndex Index of the event in the logs\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n\t\t*/\n\tfunction voteTransaction(\n\t\taddress originalTokenAddress,\n\t\taddress payable sender,\n\t\taddress payable receiver,\n\t\tuint256 value,\n\t\tbytes32 blockHash,\n\t\tbytes32 transactionHash,\n\t\tuint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n\t) external onlyMember override {\n\t\tshouldBeCurrentChainId(destinationChainId);\n\t\tbytes32 transactionId = keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex\n\t\t\t)\n\t\t);\n\n\t\tbytes32 transactionIdMultichain = getTransactionId(\n\t\t\toriginalTokenAddress,\n\t\t\tsender,\n\t\t\treceiver,\n\t\t\tvalue,\n\t\t\tblockHash,\n\t\t\ttransactionHash,\n\t\t\tlogIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n\t\t);\n\n\t\tif (isProcessed(transactionId, transactionIdMultichain))\n\t\t\treturn;\n\n\t\tif (isVoted(transactionId, transactionIdMultichain))\n\t\t\treturn;\n\n\t\tvotes[transactionIdMultichain][_msgSender()] = true;\n\t\temit Voted(\n\t\t\t_msgSender(),\n\t\t\ttransactionHash,\n\t\t\ttransactionIdMultichain,\n\t\t\toriginalTokenAddress,\n\t\t\tsender,\n\t\t\treceiver,\n\t\t\tvalue,\n\t\t\tblockHash,\n\t\t\tlogIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n\t\t);\n\n\t\tif (validateTransaction(transactionId, transactionIdMultichain)) {\n\t\t\tprocessed[transactionIdMultichain] = true;\n\n\t\t\tacceptTransfer(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex,\n\t\t\t\t\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\n\t\t\temit Executed(\n\t\t\t\t_msgSender(),\n\t\t\t\ttransactionHash,\n\t\t\t\ttransactionIdMultichain,\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\tlogIndex,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\t\t}\n\t}\n\n function acceptTransfer(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n\tuint256 originChainId,\n\tuint256\tdestinationChainId\n ) internal {\n\t bridge.acceptTransfer(\n\t\toriginalTokenAddress,\n\t\tsender,\n\t\treceiver,\n\t\tvalue,\n\t\tblockHash,\n\t\ttransactionHash,\n\t\tlogIndex,\n\t\toriginChainId,\n\t\tdestinationChainId\n\t );\n }\n\n /**\n @notice Get the amount of approved votes for that transactionId\n @param transactionId The transaction hashed from getTransactionId function\n */\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n\tfunction hasVoted(bytes32 transactionId) external view returns(bool) {\n\t\treturn votes[transactionId][_msgSender()];\n\t}\n\n\tfunction transactionWasProcessed(bytes32 transactionId) external view returns(bool) {\n\t\treturn processed[transactionId];\n\t}\n\n\t/**\n\t\t@notice Gets the hash of transaction from the following parameters encoded and keccaked\n\t\t@dev It encodes and applies keccak256 to the parameters received in the same order\n\t\t@param originalTokenAddress The address of the token in the origin (main) chain\n\t\t@param sender The address who solicited the cross token\n\t\t@param receiver Who is going to receive the token in the opposite chain\n\t\t@param amount Could be the amount or the tokenId\n\t\t@param blockHash The block hash in which the transaction with the cross event occurred\n\t\t@param transactionHash The transaction in which the cross event occurred\n\t\t@param logIndex Index of the event in the logs\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n\t\t@return The hash generated by the parameters.\n\t*/\n\tfunction getTransactionId(\n\t\taddress originalTokenAddress,\n\t\taddress sender,\n\t\taddress receiver,\n\t\tuint256 amount,\n\t\tbytes32 blockHash,\n\t\tbytes32 transactionHash,\n\t\tuint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n\t) public pure returns(bytes32) {\n\t\treturn keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tamount,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t)\n\t\t);\n\t}\n\n\tfunction addMember(address _newMember) external onlyOwner override {\n\t\trequire(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n\t\trequire(!isMember[_newMember], \"Federation: Member already exists\");\n\t\trequire(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n\t\tisMember[_newMember] = true;\n\t\tmembers.push(_newMember);\n\t\temit MemberAddition(_newMember);\n\t}\n\n\tfunction removeMember(address _oldMember) external onlyOwner override {\n\t\trequire(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n\t\trequire(isMember[_oldMember], \"Federation: Member doesn't exists\");\n\t\trequire(members.length > 1, \"Federation: Can't remove all the members\");\n\t\trequire(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n\t\tisMember[_oldMember] = false;\n\t\tfor (uint i = 0; i < members.length - 1; i++) {\n\t\t\tif (members[i] == _oldMember) {\n\t\t\t\tmembers[i] = members[members.length - 1];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tmembers.pop(); // remove an element from the end of the array.\n\t\temit MemberRemoval(_oldMember);\n\t}\n\n\t/**\n\t\t@notice Return all the current members of the federation\n\t\t@return Current members\n\t\t*/\n\tfunction getMembers() external view override returns (address[] memory) {\n\t\treturn members;\n\t}\n\n\t/**\n\t\t@notice Changes the number of required members to vote and approve an transaction\n\t\t@dev Emits the RequirementChange event\n\t\t@param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n\t\t*/\n\tfunction changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\n\t\trequire(_required >= 2, \"Federation: Requires at least 2\");\n\t\trequired = _required;\n\t\temit RequirementChange(_required);\n\t}\n\n\t/**\n\t\t@notice It emits an HeartBeat like an health check\n\t\t@dev Emits HeartBeat event\n\t\t*/\n\tfunction emitHeartbeat(\n\t\tstring calldata fedVersion,\n\t\tuint256[] calldata fedChainsIds,\n\t\tuint256[] calldata fedChainsBlocks,\n\t\tstring[] calldata fedChainsInfo\n\t) external onlyMember override {\n\t\trequire(fedChainsIds.length == fedChainsBlocks.length &&\n\t\t\tfedChainsIds.length == fedChainsInfo.length, \"Federation: Length missmatch\");\n\t\temit HeartBeat(\n\t\t\t_msgSender(),\n\t\t\tblock.chainid,\n\t\t\tblock.number,\n\t\t\tfedVersion,\n\t\t\tfedChainsIds,\n\t\t\tfedChainsBlocks,\n\t\t\tfedChainsInfo\n\t\t);\n\t}\n}\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface IFederation {\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure returns (string memory);\n\n /**\n @notice Sets a new bridge contract\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external;\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Amount\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n\t uint256 originChainId,\n\t uint256\tdestinationChainId\n ) external;\n\n /**\n @notice Add a new member to the federation\n @param _newMember address of the new member\n */\n function addMember(address _newMember) external;\n\n /**\n @notice Remove a member of the federation\n @param _oldMember address of the member to be removed from federation\n */\n function removeMember(address _oldMember) external;\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view returns (address[] memory);\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external;\n\n /**\n @notice It emmits an HeartBeat like an healthy check\n */\n function emitHeartbeat(\n string calldata federatorVersion,\n\t\tuint256[] calldata fedChainsIds,\n\t\tuint256[] calldata fedChainsBlocks,\n\t\tstring[] calldata fedChainsInfo\n ) external;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex,\n uint256 originChainId,\n\t\tuint256\tdestinationChainId\n );\n event HeartBeat(\n address indexed sender,\n uint256 currentChainId,\n uint256 currentBlock,\n string fedVersion,\n uint256[] fedChainsIds,\n\t\tuint256[] fedChainsBlocks,\n\t\tstring[] fedChainsInfo\n );\n\n}\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract MinterRole is Context {\n using Roles for Roles.Role;\n\n event MinterAdded(address indexed account);\n event MinterRemoved(address indexed account);\n\n Roles.Role private _minters;\n\n constructor () {\n _addMinter(_msgSender());\n }\n\n modifier onlyMinter() {\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\n _;\n }\n\n function isMinter(address account) public view returns (bool) {\n return _minters.has(account);\n }\n\n function addMinter(address account) public onlyMinter {\n _addMinter(account);\n }\n\n function renounceMinter() public {\n _removeMinter(_msgSender());\n }\n\n function _addMinter(address account) internal {\n _minters.add(account);\n emit MinterAdded(account);\n }\n\n function _removeMinter(address account) internal {\n _minters.remove(account);\n emit MinterRemoved(account);\n }\n}\n"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract AllowTokensV0 is Ownable {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n\n mapping (address => bool) public allowedTokens;\n bool private validateAllowedTokens;\n uint256 private maxTokensAllowed;\n uint256 private minTokensAllowed;\n uint256 public dailyLimit;\n\n event AllowedTokenAdded(address indexed _tokenAddress);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event AllowedTokenValidation(bool _enabled);\n event MaxTokensAllowedChanged(uint256 _maxTokens);\n event MinTokensAllowedChanged(uint256 _minTokens);\n event DailyLimitChanged(uint256 dailyLimit);\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\n _;\n }\n\n constructor(address _manager) {\n transferOwnership(_manager);\n validateAllowedTokens = true;\n maxTokensAllowed = 10000 ether;\n minTokensAllowed = 1 ether;\n dailyLimit = 100000 ether;\n }\n\n function isValidatingAllowedTokens() external view returns(bool) {\n return validateAllowedTokens;\n }\n\n function getMaxTokensAllowed() external view returns(uint256) {\n return maxTokensAllowed;\n }\n\n function getMinTokensAllowed() external view returns(uint256) {\n return minTokensAllowed;\n }\n\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\n return allowedTokens[token];\n }\n\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\n if (validateAllowedTokens) {\n return allowedTokenExist(token);\n }\n return true;\n }\n\n function addAllowedToken(address token) external onlyOwner {\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\n allowedTokens[token] = true;\n emit AllowedTokenAdded(token);\n }\n\n function removeAllowedToken(address token) external onlyOwner {\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\n allowedTokens[token] = false;\n emit AllowedTokenRemoved(token);\n }\n\n function enableAllowedTokensValidation() external onlyOwner {\n validateAllowedTokens = true;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function disableAllowedTokensValidation() external onlyOwner {\n // Before disabling Allowed Tokens Validations some kind of contract validation system\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\n validateAllowedTokens = false;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\n maxTokensAllowed = maxTokens;\n emit MaxTokensAllowedChanged(maxTokensAllowed);\n }\n\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\n minTokensAllowed = minTokens;\n emit MinTokensAllowedChanged(minTokensAllowed);\n }\n\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\n dailyLimit = _dailyLimit;\n emit DailyLimitChanged(_dailyLimit);\n }\n\n // solium-disable-next-line max-len\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\n if(amount > maxTokensAllowed)\n return false;\n if(amount < minTokensAllowed)\n return false;\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\n return false;\n if(!isSideToken && !isTokenAllowed(tokenToUse))\n return false;\n return true;\n }\n\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\n uint maxWithrow = dailyLimit - spentToday;\n if (dailyLimit < spentToday)\n return 0;\n if(maxWithrow > maxTokensAllowed)\n maxWithrow = maxTokensAllowed;\n return maxWithrow;\n }\n\n}\n"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\n\ncontract BridgeProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract FederationProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() {\n _registerInterface(\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\n );\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Receiver.sol\";\n\n /**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers. \n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract AlternativeERC20Detailed is ERC20 {\n string private _name;\n bytes32 private _symbol;\n uint256 private _decimals;\n\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\n {\n _name = aName;\n _symbol = aSymbol;\n _decimals = someDecimals;\n _mint(msg.sender, aTotalSupply);\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (bytes32) {\n return _symbol;\n }\n\n function decimals() public view returns (uint256) {\n return _decimals;\n }\n}"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../lib/LibUtils.sol\";\n\ncontract LibUtilsHarness {\n\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\n return LibUtils.decimalsToGranularity(decimals);\n }\n\n function getDecimals(address tokenToUse) external view returns (uint8) {\n return LibUtils.getDecimals(tokenToUse);\n }\n\n function getGranularity(address tokenToUse) external view returns (uint256) {\n return LibUtils.getGranularity(tokenToUse);\n }\n\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\n return LibUtils.bytesToAddress(bys);\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) external pure returns (uint128) {\n return LibUtils.toUint128(_bytes, _start);\n }\n\n}\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/solcInputs/3b83f9cb61a99eec06a616e65f41d75c.json b/bridge/deployments/rsktestnet/solcInputs/3b83f9cb61a99eec06a616e65f41d75c.json
new file mode 100644
index 000000000..e68d5ccb0
--- /dev/null
+++ b/bridge/deployments/rsktestnet/solcInputs/3b83f9cb61a99eec06a616e65f41d75c.json
@@ -0,0 +1,36 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/MultiSigWallet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.\n/// @author Stefan George - \ncontract MultiSigWallet {\n\n /*\n * Events\n */\n event Confirmation(address indexed sender, uint indexed transactionId);\n event Revocation(address indexed sender, uint indexed transactionId);\n event Submission(uint indexed transactionId);\n event Execution(uint indexed transactionId);\n event ExecutionFailure(uint indexed transactionId);\n event Deposit(address indexed sender, uint value);\n event OwnerAddition(address indexed owner);\n event OwnerRemoval(address indexed owner);\n event RequirementChange(uint required);\n\n /*\n * views\n */\n uint constant public MAX_OWNER_COUNT = 50;\n\n /*\n * Storage\n */\n mapping (uint => Transaction) public transactions;\n mapping (uint => mapping (address => bool)) public confirmations;\n mapping (address => bool) public isOwner;\n address[] public owners;\n uint public required;\n uint public transactionCount;\n\n struct Transaction {\n address destination;\n uint value;\n bytes data;\n bool executed;\n }\n\n /*\n * Modifiers\n */\n modifier onlyWallet() {\n require(msg.sender == address(this), \"Only wallet allowed\");\n _;\n }\n\n modifier ownerDoesNotExist(address owner) {\n require(!isOwner[owner], \"The owner already exists\");\n _;\n }\n\n modifier ownerExists(address owner) {\n require(isOwner[owner], \"The owner does not exist\");\n _;\n }\n\n modifier transactionExists(uint transactionId) {\n require(transactions[transactionId].destination != address(0), \"Transaction does not exist\");\n _;\n }\n\n modifier confirmed(uint transactionId, address owner) {\n require(confirmations[transactionId][owner], \"Transaction is not confirmed by owner\");\n _;\n }\n\n modifier notConfirmed(uint transactionId, address owner) {\n require(!confirmations[transactionId][owner], \"Transaction is already confirmed by owner\");\n _;\n }\n\n modifier notExecuted(uint transactionId) {\n require(!transactions[transactionId].executed, \"Transaction was already executed\");\n _;\n }\n\n modifier notNull(address _address) {\n require(_address != address(0), \"Address cannot be empty\");\n _;\n }\n\n modifier validRequirement(uint ownerCount, uint _required) {\n // solium-disable-next-line max-len\n require(ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && _required != 0 && ownerCount != 0, \"Required value is invalid for the current owners count\");\n _;\n }\n\n /// @dev Fallback function allows to deposit ether.\n receive ()\n external\n payable\n {\n if (msg.value > 0)\n emit Deposit(msg.sender, msg.value);\n }\n\n /*\n * Public functions\n */\n /// @dev Contract constructor sets initial owners and required number of confirmations.\n /// @param _owners List of initial owners.\n /// @param _required Number of required confirmations.\n constructor(address[] memory _owners, uint _required)\n validRequirement(_owners.length, _required)\n {\n for (uint i = 0; i < _owners.length; i++) {\n require(!isOwner[_owners[i]] && _owners[i] != address(0), \"Owners addresses are invalid\");\n isOwner[_owners[i]] = true;\n }\n owners = _owners;\n required = _required;\n }\n\n /// @dev Allows to add a new owner. Transaction has to be sent by wallet.\n /// @param owner Address of new owner.\n function addOwner(address owner)\n public\n onlyWallet\n ownerDoesNotExist(owner)\n notNull(owner)\n validRequirement(owners.length + 1, required)\n {\n isOwner[owner] = true;\n owners.push(owner);\n emit OwnerAddition(owner);\n }\n\n /// @dev Allows to remove an owner. Transaction has to be sent by wallet.\n /// @param owner Address of owner.\n function removeOwner(address owner)\n public\n onlyWallet\n ownerExists(owner)\n {\n isOwner[owner] = false;\n for (uint i = 0; i < owners.length - 1; i++)\n if (owners[i] == owner) {\n owners[i] = owners[owners.length - 1];\n break;\n }\n owners.pop(); // remove an element from the end of the array.\n if (required > owners.length)\n changeRequirement(owners.length);\n emit OwnerRemoval(owner);\n }\n\n /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\n /// @param owner Address of owner to be replaced.\n /// @param newOwner Address of new owner.\n function replaceOwner(address owner, address newOwner)\n public\n onlyWallet\n ownerExists(owner)\n ownerDoesNotExist(newOwner)\n {\n for (uint i = 0; i < owners.length; i++)\n if (owners[i] == owner) {\n owners[i] = newOwner;\n break;\n }\n isOwner[owner] = false;\n isOwner[newOwner] = true;\n emit OwnerRemoval(owner);\n emit OwnerAddition(newOwner);\n }\n\n /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.\n /// @param _required Number of required confirmations.\n function changeRequirement(uint _required)\n public\n onlyWallet\n validRequirement(owners.length, _required)\n {\n required = _required;\n emit RequirementChange(_required);\n }\n\n /// @dev Allows an owner to submit and confirm a transaction.\n /// @param destination Transaction target address.\n /// @param value Transaction ether value.\n /// @param data Transaction data payload.\n /// @return transactionId Returns transaction ID.\n function submitTransaction(address destination, uint value, bytes memory data)\n public\n returns (uint transactionId)\n {\n transactionId = addTransaction(destination, value, data);\n confirmTransaction(transactionId);\n }\n\n /// @dev Allows an owner to confirm a transaction.\n /// @param transactionId Transaction ID.\n function confirmTransaction(uint transactionId)\n public\n ownerExists(msg.sender)\n transactionExists(transactionId)\n notConfirmed(transactionId, msg.sender)\n {\n confirmations[transactionId][msg.sender] = true;\n emit Confirmation(msg.sender, transactionId);\n executeTransaction(transactionId);\n }\n\n /// @dev Allows an owner to revoke a confirmation for a transaction.\n /// @param transactionId Transaction ID.\n function revokeConfirmation(uint transactionId)\n public\n ownerExists(msg.sender)\n confirmed(transactionId, msg.sender)\n notExecuted(transactionId)\n {\n confirmations[transactionId][msg.sender] = false;\n emit Revocation(msg.sender, transactionId);\n }\n\n /// @dev Allows anyone to execute a confirmed transaction.\n /// @param transactionId Transaction ID.\n function executeTransaction(uint transactionId)\n public\n ownerExists(msg.sender)\n confirmed(transactionId, msg.sender)\n notExecuted(transactionId)\n {\n if (isConfirmed(transactionId)) {\n Transaction storage txn = transactions[transactionId];\n txn.executed = true;\n if (external_call(txn.destination, txn.value, txn.data.length, txn.data))\n emit Execution(transactionId);\n else {\n emit ExecutionFailure(transactionId);\n txn.executed = false;\n }\n }\n }\n\n // call has been separated into its own function in order to take advantage\n // of the Solidity's code generator to produce a loop that copies tx.data into memory.\n function external_call(address destination, uint value, uint dataLength, bytes memory data) internal returns (bool) {\n bool result;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let x := mload(0x40) // \"Allocate\" memory for output (0x40 is where \"free memory\" pointer is stored by convention)\n let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that\n result := call(\n sub(gas(), 34710), // 34710 is the value that solidity is currently emitting\n // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +\n // callNewAccountGas (25000, in case the destination address does not exist and needs creating)\n destination,\n value,\n d,\n dataLength, // Size of the input (in bytes) - this is what fixes the padding problem\n x,\n 0 // Output is ignored, therefore the output size is zero\n )\n }\n return result;\n }\n\n /// @dev Returns the confirmation status of a transaction.\n /// @param transactionId Transaction ID.\n /// @return Confirmation status.\n function isConfirmed(uint transactionId)\n public\n view\n returns (bool)\n {\n uint count = 0;\n for (uint i = 0; i < owners.length; i++) {\n if (confirmations[transactionId][owners[i]])\n count += 1;\n if (count == required)\n return true;\n }\n return false;\n }\n\n /*\n * Internal functions\n */\n /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.\n /// @param destination Transaction target address.\n /// @param value Transaction ether value.\n /// @param data Transaction data payload.\n /// @return transactionId Returns transaction ID.\n function addTransaction(address destination, uint value, bytes memory data)\n internal\n notNull(destination)\n returns (uint transactionId)\n {\n transactionId = transactionCount;\n transactions[transactionId] = Transaction({\n destination: destination,\n value: value,\n data: data,\n executed: false\n });\n transactionCount += 1;\n emit Submission(transactionId);\n }\n\n /*\n * Web3 call functions\n */\n /// @dev Returns number of confirmations of a transaction.\n /// @param transactionId Transaction ID.\n /// @return count Number of confirmations.\n function getConfirmationCount(uint transactionId)\n public\n view\n returns (uint count)\n {\n for (uint i = 0; i < owners.length; i++) {\n if (confirmations[transactionId][owners[i]]) {\n count += 1;\n }\n }\n }\n\n /// @dev Returns total number of transactions after filers are applied.\n /// @param pending Include pending transactions.\n /// @param executed Include executed transactions.\n /// @return count Total number of transactions after filters are applied.\n function getTransactionCount(bool pending, bool executed)\n public\n view\n returns (uint count)\n {\n for (uint i = 0; i < transactionCount; i++) {\n if ( pending && !transactions[i].executed || executed && transactions[i].executed) {\n count += 1;\n }\n }\n }\n\n /// @dev Returns list of owners.\n /// @return List of owner addresses.\n function getOwners()\n public\n view\n returns (address[] memory)\n {\n return owners;\n }\n\n /// @dev Returns array with owner addresses, which confirmed transaction.\n /// @param transactionId Transaction ID.\n /// @return _confirmations Returns array of owner addresses.\n function getConfirmations(uint transactionId)\n public\n view\n returns (address[] memory _confirmations)\n {\n address[] memory confirmationsTemp = new address[](owners.length);\n uint count = 0;\n uint i;\n for (i = 0; i < owners.length; i++)\n if (confirmations[transactionId][owners[i]]) {\n confirmationsTemp[count] = owners[i];\n count += 1;\n }\n _confirmations = new address[](count);\n for (i = 0; i < count; i++)\n _confirmations[i] = confirmationsTemp[i];\n }\n\n /// @dev Returns list of transaction IDs in defined range.\n /// @param from Index start position of transaction array.\n /// @param to Index end position of transaction array.\n /// @param pending Include pending transactions.\n /// @param executed Include executed transactions.\n /// @return _transactionIds Returns array of transaction IDs.\n function getTransactionIds(uint from, uint to, bool pending, bool executed)\n public\n view\n returns (uint[] memory _transactionIds)\n {\n uint[] memory transactionIdsTemp = new uint[](transactionCount);\n uint count = 0;\n uint i;\n for (i = 0; i < transactionCount; i++)\n if ( pending && !transactions[i].executed || executed && transactions[i].executed)\n {\n transactionIdsTemp[count] = i;\n count += 1;\n }\n _transactionIds = new uint[](to - from);\n for (i = from; i < to; i++)\n _transactionIds[i - from] = transactionIdsTemp[i];\n }\n}"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/solcInputs/b19a85096471779fd79d66673cd8b3cb.json b/bridge/deployments/rsktestnet/solcInputs/b19a85096471779fd79d66673cd8b3cb.json
new file mode 100644
index 000000000..3451ed0c1
--- /dev/null
+++ b/bridge/deployments/rsktestnet/solcInputs/b19a85096471779fd79d66673cd8b3cb.json
@@ -0,0 +1,294 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/math/SafeMath.sol\";\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\n\nimport \"../interface/IAllowTokens.sol\";\n\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\n\tusing SafeMath for uint256;\n\n\taddress constant private NULL_ADDRESS = address(0);\n\tuint256 constant public MAX_TYPES = 250;\n\tmapping (address => TokenInfo) public allowedTokens;\n\tmapping (uint256 => Limits) public typeLimits;\n\tuint256 public smallAmountConfirmations;\n\tuint256 public mediumAmountConfirmations;\n\tuint256 public largeAmountConfirmations;\n\tstring[] public typeDescriptions;\n\n\tevent SetToken(address indexed _tokenAddress, uint256 _typeId);\n\tevent AllowedTokenRemoved(address indexed _tokenAddress);\n\tevent TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\n\tevent TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\n\tevent UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\n\tevent ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\n\n\tmodifier notNull(address _address) {\n\t\trequire(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\n\t\t_;\n\t}\n\n\tfunction initialize(\n\t\taddress _manager,\n\t\taddress _primary,\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations,\n\t\tTypeInfo[] memory typesInfo) public initializer {\n\t\tUpgradableOwnable.initialize(_manager);\n\t\tUpgradableSecondary.__Secondary_init(_primary);\n\t\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t\tfor(uint i = 0; i < typesInfo.length; i = i + 1) {\n\t\t\t_addTokenType(typesInfo[i].description, typesInfo[i].limits);\n\t\t}\n\t}\n\n\tfunction version() override external pure returns (string memory) {\n\t\treturn \"v1\";\n\t}\n\n\tfunction tokenInfo(address tokenAddress) public view returns(TokenInfo memory) {\n\t\treturn allowedTokens[tokenAddress];\n\t}\n\n\tfunction setTokenInfoByTokenAddress(address tokenAddress, TokenInfo memory info) internal {\n\t\trequire(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n\t\tallowedTokens[tokenAddress] = info;\n\t}\n\n\tfunction getInfoAndLimits(\n\t\taddress tokenAddress\n\t) public view override returns (\n\t\tTokenInfo memory info,\n\t\tLimits memory limit\n\t) {\n\t\tinfo = tokenInfo(tokenAddress);\n\t\tlimit = typeLimits[info.typeId];\n\t\treturn (info, limit);\n\t}\n\n\tfunction calcMaxWithdraw(address token) public view override returns (uint256 maxWithdraw) {\n\t\t(TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\n\t\treturn _calcMaxWithdraw(info, limits);\n\t}\n\n\tfunction _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\n\t\t// solium-disable-next-line security/no-block-members\n\t\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n\t\t\tinfo.spentToday = 0;\n\t\t}\n\t\tif (limits.daily <= info.spentToday) {\n\t\t\treturn 0;\n\t\t}\n\t\tmaxWithdraw = limits.daily - info.spentToday;\n\t\tif (maxWithdraw > limits.max) {\n\t\t\tmaxWithdraw = limits.max;\n\t\t}\n\t\treturn maxWithdraw;\n\t}\n\n\tfunction updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\n\t\t(TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\n\t\trequire(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\n\t\trequire(amount >= limit.min, \"AllowTokens: Lower than limit\");\n\n\t\t// solium-disable-next-line security/no-block-members\n\t\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n\t\t\t// solium-disable-next-line security/no-block-members\n\t\t\tinfo.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n\t\t\tinfo.spentToday = 0;\n\t\t}\n\t\tuint maxWithdraw = _calcMaxWithdraw(info, limit);\n\t\trequire(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\n\t\tinfo.spentToday = info.spentToday.add(amount);\n\t\tsetTokenInfoByTokenAddress(token, info);\n\n\t\temit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\n\t}\n\n\tfunction _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\n\t\trequire(bytes(description).length > 0, \"AllowTokens: Empty description\");\n\t\tlen = typeDescriptions.length;\n\t\trequire(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\n\t\ttypeDescriptions.push(description);\n\t\t_setTypeLimits(len, limits);\n\t\temit TokenTypeAdded(len, description);\n\t\treturn len;\n\t}\n\n\tfunction addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\n\t\treturn _addTokenType(description, limits);\n\t}\n\n\tfunction _setTypeLimits(uint256 typeId, Limits memory limits) private {\n\t\trequire(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\n\t\trequire(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\n\t\trequire(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\n\t\trequire(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\n\t\trequire(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\n\t\ttypeLimits[typeId] = limits;\n\t\temit TypeLimitsChanged(typeId, limits);\n\t}\n\n\tfunction setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\n\t\t_setTypeLimits(typeId, limits);\n\t}\n\n\tfunction getTypesLimits() external view override returns(Limits[] memory limits) {\n\t\tlimits = new Limits[](typeDescriptions.length);\n\t\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\n\t\t\tlimits[i] = typeLimits[i];\n\t\t}\n\t\treturn limits;\n\t}\n\n\tfunction getTypeDescriptionsLength() external view override returns(uint256) {\n\t\treturn typeDescriptions.length;\n\t}\n\n\tfunction getTypeDescriptions() external view override returns(string[] memory descriptions) {\n\t\tdescriptions = new string[](typeDescriptions.length);\n\t\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\n\t\t\tdescriptions[i] = typeDescriptions[i];\n\t\t}\n\t\treturn descriptions;\n\t}\n\n\tfunction isTokenAllowed(address token) public view notNull(token) override returns (bool) {\n\t\treturn tokenInfo(token).allowed;\n\t}\n\n\tfunction setToken(address token, uint256 typeId) override public notNull(token) {\n\t\trequire(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n\t\trequire(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\n\t\tTokenInfo memory info = tokenInfo(token);\n\t\tinfo.allowed = true;\n\t\tinfo.typeId = typeId;\n\t\tsetTokenInfoByTokenAddress(token, info);\n\t\temit SetToken(token, typeId);\n\t}\n\n\tfunction setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\n\t\trequire(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\n\t\tfor(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\n\t\t\tsetToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\n\t\t}\n\t}\n\n\tfunction removeAllowedToken(address token) external notNull(token) onlyOwner {\n\t\tTokenInfo memory info = tokenInfo(token);\n\t\trequire(info.allowed, \"AllowTokens: Not Allowed\");\n\t\tinfo.allowed = false;\n\t\tsetTokenInfoByTokenAddress(token, info);\n\t\temit AllowedTokenRemoved(token);\n\t}\n\n\tfunction setConfirmations(\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations) external onlyOwner {\n\t\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t}\n\n\tfunction _setConfirmations(\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations) private {\n\t\trequire(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\n\t\trequire(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\n\t\tsmallAmountConfirmations = _smallAmountConfirmations;\n\t\tmediumAmountConfirmations = _mediumAmountConfirmations;\n\t\tlargeAmountConfirmations = _largeAmountConfirmations;\n\t\temit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t}\n\n\tfunction getConfirmations() external view override\n\t\treturns (\n\t\tuint256 smallAmount,\n\t\tuint256 mediumAmount,\n\t\tuint256 largeAmount\n\t) {\n\t\treturn (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\n\t}\n\n}\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @title Initializable\n *\n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(initializing || !initialized, \"Contract instance is already initialized\");\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\n * the owner.\n */\ncontract UpgradableOwnable is Initializable, Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function initialize(address sender) public initializer {\n _owner = sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * > Note: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\ncontract UpgradableSecondary is Initializable, Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n function __Secondary_init(address sender) public initializer {\n _primary = sender;\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(recipient);\n }\n\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IAllowTokens {\n\n\tstruct Limits {\n\t\tuint256 min;\n\t\tuint256 max;\n\t\tuint256 daily;\n\t\tuint256 mediumAmount;\n\t\tuint256 largeAmount;\n\t}\n\n\tstruct TokenInfo {\n\t\tbool allowed;\n\t\tuint256 typeId;\n\t\tuint256 spentToday;\n\t\tuint256 lastDay;\n\t}\n\n\tstruct TypeInfo {\n\t\tstring description;\n\t\tLimits limits;\n\t}\n\n\tstruct TokensAndType {\n\t\taddress token;\n\t\tuint256 typeId;\n\t}\n\n\tfunction version() external pure returns (string memory);\n\n\tfunction getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\n\n\tfunction calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\n\n\tfunction getTypesLimits() external view returns(Limits[] memory limits);\n\n\tfunction getTypeDescriptionsLength() external view returns(uint256);\n\n\tfunction getTypeDescriptions() external view returns(string[] memory descriptions);\n\n\tfunction setToken(address token, uint256 typeId) external;\n\n\tfunction getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\n\n\tfunction isTokenAllowed(address token) external view returns (bool);\n\n\tfunction updateTokenTransfer(address token, uint256 amount) external;\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n\n function _msgSender() internal view returns (address payable) {\n return payable(msg.sender);\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
+ },
+ "contracts/nftbridge/NFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC721/IERC721.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Metadata.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Enumerable.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Receiver.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./INFTBridge.sol\";\nimport \"./ISideNFTToken.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract NFTBridge is\n Initializable,\n INFTBridge,\n UpgradablePausable,\n UpgradableOwnable,\n ReentrancyGuard,\n IERC721Receiver {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address internal constant NULL_ADDRESS = address(0);\n bytes32 internal constant NULL_HASH = bytes32(0);\n IERC1820Registry internal constant ERC1820 =\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address payable internal federation;\n uint256 internal fixedFee;\n\n mapping(uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain;\n mapping(address => OriginalNft) public originalTokenBySideToken;\n mapping(uint256 => mapping(address => bool)) public isAddressFromCrossedOriginalTokenByChain; // uint256 => address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n\n IAllowTokens public allowTokens;\n ISideNFTTokenFactory public sideTokenFactory;\n bool public isUpgrading;\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\n event Upgrading(bool _isUpgrading);\n\n function initialize(\n address _manager,\n address payable _federation,\n address _allowTokens,\n address _sideTokenFactory\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\n federation = _federation;\n ERC1820.setInterfaceImplementer(\n address(this),\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\n address(this)\n );\n }\n\n function version() external pure override returns (string memory) {\n return \"v1\";\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _tokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n uint256\t_destinationChainId\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"NFTBridge: Not Federation\");\n checkChainId(_originChainId);\n shouldBeCurrentChainId(_destinationChainId);\n require(\n isAddressFromCrossedOriginalToken(_originChainId, _tokenAddress) ||\n getSideTokenByOriginalToken(_originChainId, _tokenAddress) != NULL_ADDRESS,\n \"NFTBridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"NFTBridge: Null To\");\n require(_from != NULL_ADDRESS, \"NFTBridge: Null From\");\n require(_blockHash != NULL_HASH, \"NFTBridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"NFTBridge: Null TxHash\");\n require(\n transactionDataHashes[_transactionHash] == bytes32(0),\n \"NFTBridge: Already accepted\"\n );\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _blockHash,\n _transactionHash,\n _logIndex,\n _originChainId,\n\t _destinationChainId\n );\n\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\n require(!claimed[_transactionDataHash], \"NFTBridge: Already claimed\");\n transactionDataHashes[_transactionHash] = _transactionDataHash;\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\n// senderAddresses[_transactionHash] = _from;\n\n emit AcceptedNFTCrossTransfer(\n _transactionHash,\n _tokenAddress,\n _to,\n _from,\n _tokenId,\n _blockHash,\n _logIndex,\n _originChainId,\n\t _destinationChainId\n );\n }\n\n function shouldBeCurrentChainId(uint256 chainId) internal view {\n require(chainId == block.chainid, \"NFTBridge: Not block.chainid\");\n }\n\n function getSideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\n return sideTokenByOriginalTokenByChain[chainId][originalToken];\n }\n\n function _setSideTokenByOriginalToken(uint256 chainId, address originalToken, address sideToken) internal {\n sideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\n }\n\n function getOriginalTokenBySideToken(address sideToken) public view returns(OriginalNft memory) {\n return originalTokenBySideToken[sideToken];\n }\n\n function _setOriginalTokenBySideToken(address sideToken, OriginalNft memory originalToken) internal {\n originalTokenBySideToken[sideToken] = originalToken;\n }\n\n function isAddressFromCrossedOriginalToken(uint256 chainId, address originalToken) public view returns(bool addressHasCrossed) {\n return isAddressFromCrossedOriginalTokenByChain[chainId][originalToken];\n }\n\n function _setAddressFromCrossedOriginalToken(uint256 chainId, address originalToken, bool addressHasCrossed) internal {\n isAddressFromCrossedOriginalTokenByChain[chainId][originalToken] = addressHasCrossed;\n }\n\n function createSideNFTToken(\n address _originalTokenAddress,\n string calldata _tokenSymbol,\n string calldata _tokenName,\n string calldata _baseURI,\n string calldata _contractURI,\n uint256 originChainId\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"NFTBridge: Null original token address\");\n\n require(getSideTokenByOriginalToken(originChainId, _originalTokenAddress) == NULL_ADDRESS, \"NFTBridge: Side token already exists\");\n\n // Create side token\n address sideTokenAddress = sideTokenFactory.createSideNFTToken(_tokenName, _tokenSymbol, _baseURI, _contractURI);\n\n _setSideTokenByOriginalToken(originChainId, _originalTokenAddress, sideTokenAddress);\n\n OriginalNft memory originalNft;\n originalNft.originChainId = originChainId;\n originalNft.nftAddress = _originalTokenAddress;\n _setOriginalTokenBySideToken(sideTokenAddress, originalNft);\n\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, _tokenSymbol, originChainId);\n }\n\n function checkChainId(uint256 chainId) internal pure {\n require(chainId > 0, \"NFTBridge: ChainId is 0\");\n }\n\n function claim(NFTClaimData calldata _claimData) external override {\n _claim(_claimData, _claimData.to);\n }\n\n function claimFallback(NFTClaimData calldata _claimData) external override {\n require(_msgSender() == _claimData.from, \"NFTBridge: invalid sender\");\n _claim(_claimData, _msgSender());\n }\n\n function _claim(\n NFTClaimData calldata _claimData,\n address payable _receiver\n ) internal {\n address tokenAddress = _claimData.tokenAddress;\n uint256 tokenId = _claimData.tokenId;\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.from,\n tokenId,\n tokenAddress,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex,\n _claimData.originChainId,\n block.chainid\n );\n\n\n require(\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\n \"NFTBridge: Wrong txDataHash\"\n );\n require(!claimed[transactionDataHash], \"NFTBridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (isAddressFromCrossedOriginalToken(_claimData.originChainId, tokenAddress)) {\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\n } else {\n address sideTokenAddress = getSideTokenByOriginalToken(_claimData.originChainId, tokenAddress);\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\n }\n\n emit ClaimedNFTToken(\n _claimData.transactionHash,\n tokenAddress,\n _claimData.to,\n _claimData.from,\n _claimData.tokenId,\n _claimData.blockHash,\n _claimData.logIndex,\n _receiver,\n _claimData.originChainId,\n block.chainid\n );\n }\n\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\"creator()\"));\n if (success) {\n return abi.decode(data, (address));\n }\n\n return IERC721(tokenAddress).ownerOf(tokenId);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId,\n uint256 destinationChainId\n ) public payable override {\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\n address payable sender = _msgSender();\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\n\n crossTokens(tokenAddress, to, tokenCreator, tokenId, destinationChainId, \"\");\n\n if (fixedFee == 0) {\n return;\n }\n uint256 msgValue = msg.value;\n require(msgValue >= fixedFee, \"NFTBridge: value is smaller than fixed fee\");\n\n // Send the payment to the MultiSig of the Federation\n federation.transfer(fixedFee);\n\n if (msgValue > fixedFee) { // refund of unused value\n sender.transfer(msgValue.sub(fixedFee));\n }\n }\n\n function crossTokens(\n address tokenAddress,\n address to,\n address tokenCreator,\n uint256 tokenId,\n uint256 destinationChainId,\n bytes memory userData\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\n require(block.chainid != destinationChainId, \"NFTBridge: destination chain id equal current chain id\");\n _setAddressFromCrossedOriginalToken(destinationChainId, tokenAddress, true);\n\n string memory tokenURI = IERC721Metadata(tokenAddress).tokenURI(tokenId);\n\n OriginalNft memory originalToken = getOriginalTokenBySideToken(tokenAddress);\n address originalTokenAddress = tokenAddress;\n if (originalToken.nftAddress != NULL_ADDRESS) {\n ERC721Burnable(tokenAddress).burn(tokenId);\n originalTokenAddress = originalToken.nftAddress;\n }\n\n uint256 totalSupply = IERC721Enumerable(tokenAddress).totalSupply();\n emit Cross(\n originalTokenAddress,\n to,\n destinationChainId,\n _msgSender(),\n block.chainid,\n tokenCreator,\n totalSupply,\n tokenId,\n tokenURI,\n userData\n );\n }\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n ) public pure override returns (bytes32) {\n return keccak256(\n abi.encodePacked(\n _blockHash,\n _transactionHash,\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _logIndex,\n _originChainId,\n _destinationChainId\n )\n );\n }\n\n function setFixedFee(uint256 amount) external onlyOwner {\n fixedFee = amount;\n emit FixedFeeNFTChanged(fixedFee);\n }\n\n function getFixedFee() external view override returns (uint256) {\n return fixedFee;\n }\n\n function changeFederation(address payable newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"NFTBridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"NFTBridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns (address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\n require(\n newSideNFTTokenFactory != NULL_ADDRESS,\n \"NFTBridge: empty SideTokenFactory\"\n );\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionDataHashes[transactionHash]];\n }\n\n /**\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\n/**\n * @title Helps contracts guard against reentrancy attacks.\n * @author Remco Bloemen , Eenae \n * @dev If you mark a function `nonReentrant`, you should also\n * mark it `external`.\n */\ncontract ReentrancyGuard is Initializable {\n /// @dev counter to allow mutex lock with only one SSTORE operation\n uint256 private _guardCounter;\n\n function initialize() public initializer {\n // The counter starts at one to prevent changing it from zero to a non-zero\n // value, which is a more expensive operation.\n _guardCounter = 1;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _guardCounter += 1;\n uint256 localCounter = _guardCounter;\n _;\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\n }\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\nimport \"../access/roles/UpgradablePauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n function __Pausable_init(address sender) public initializer {\n UpgradablePauserRole.__PauserRol_init(sender);\n\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as `account`'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `_account`.\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `_implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\n\n /**\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `_account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {ERC20Detailed}.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeERC20: low-level call failed\");\n\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n */\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./ERC721.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721Burnable is Context, ERC721 {\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n _burn(tokenId);\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\nlibrary LibEIP712 {\n\n // Hash of the EIP712 Domain Separator Schema\n // keccak256(abi.encodePacked(\n // \"EIP712Domain(\",\n // \"string name,\",\n // \"string version,\",\n // \"uint256 chainId,\",\n // \"address verifyingContract\",\n // \")\"\n // ))\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n /// @dev Calculates a EIP712 domain separator.\n /// @param name The EIP712 domain name.\n /// @param version The EIP712 domain version.\n /// @param verifyingContract The EIP712 verifying contract.\n /// @return result EIP712 domain separator.\n function hashEIP712Domain(\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n // keccak256(bytes(name)),\n // keccak256(bytes(version)),\n // chainId,\n // uint256(verifyingContract)\n // ))\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Calculate hashes of dynamic data\n let nameHash := keccak256(add(name, 32), mload(name))\n let versionHash := keccak256(add(version, 32), mload(version))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n // Store params in memory\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), nameHash)\n mstore(add(memPtr, 64), versionHash)\n mstore(add(memPtr, 96), chainId)\n mstore(add(memPtr, 128), verifyingContract)\n\n // Compute hash\n result := keccak256(memPtr, 160)\n }\n return result;\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\n /// with getDomainHash().\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to the given EIP712 Domain.\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n internal\n pure\n returns (bytes32 result)\n {\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct\n // ));\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nlibrary LibUtils {\n\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\n return uint256(10)**(18-decimals);\n }\n\n function getDecimals(address tokenToUse) internal view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"LibUtils: No decimals\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n return uint8(abi.decode(data, (uint256)));\n }\n\n function getGranularity(address tokenToUse) internal view returns (uint256) {\n //support granularity if ERC777\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\n require(success, \"LibUtils: No granularity\");\n\n return abi.decode(data, (uint256));\n }\n\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n addr := mload(add(bys,20))\n }\n }\n\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\n require(_bytes.length >= _start + 20, \"LibUtils: toAddress_outOfBounds\");\n address tempAddress;\n\n assembly {\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n }\n\n return tempAddress;\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\n require(_bytes.length >= _start + 16, \"LibUtils: toUint128_outOfBounds\");\n uint128 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x10), _start))\n }\n\n return tempUint;\n }\n\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\n\t\trequire(_bytes.length >= _start + 32, \"LibUtils: toUint256_outOfBounds\");\n\t\tuint256 tempUint;\n\n // solium-disable-next-line security/no-inline-assembly\n\t\tassembly {\n\t\t\ttempUint := mload(add(add(_bytes, 0x20), _start))\n\t\t}\n\n\t\treturn tempUint;\n\t}\n}\n"
+ },
+ "contracts/nftbridge/INFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface INFTBridge {\n\n struct NFTClaimData {\n address payable to;\n address from;\n uint256 tokenId;\n address tokenAddress;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n uint256 originChainId;\n }\n\n\tstruct OriginalNft {\n\t\taddress nftAddress;\n\t\tuint256 originChainId;\n\t}\n\n function version() external pure returns (string memory);\n\n function getFixedFee() external view returns (uint256);\n\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId,\n uint256 destinationChainId\n ) external payable;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\n */\n function claim(NFTClaimData calldata _claimData) external;\n\n function claimFallback(NFTClaimData calldata _claimData) external;\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\t\tuint256\t_destinationChainId\n ) external returns (bytes32);\n\n event Cross(\n address indexed _originalTokenAddress,\n address indexed _to,\n uint256 indexed _destinationChainId,\n address _from,\n uint256 _originChainId,\n address _tokenCreator,\n uint256 _totalSupply,\n uint256 _tokenId,\n string _tokenURI,\n bytes _userData\n );\n\n event NewSideNFTToken(\n address indexed _newSideNFTTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 originChainId\n );\n event AcceptedNFTCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n );\n event FixedFeeNFTChanged(uint256 _amount);\n event ClaimedNFTToken(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _receiver,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n );\n}\n"
+ },
+ "contracts/nftbridge/ISideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideNFTToken {\n function mint(address account, uint256 tokenId) external;\n}"
+ },
+ "contracts/nftbridge/ISideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideNFTTokenFactory {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external returns(address);\n\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IWrapped {\n function balanceOf(address) external returns(uint);\n\n function deposit() external payable;\n\n function withdraw(uint wad) external;\n\n function totalSupply() external view returns (uint);\n\n function approve(address guy, uint wad) external returns (bool);\n\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad)\n external\n returns (bool);\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../Initializable.sol\";\n\nimport \"../../../GSN/Context.sol\";\nimport \"../../../access/Roles.sol\";\n\ncontract UpgradablePauserRole is Initializable, Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n function __PauserRol_init(address sender) public initializer {\n if (!isPauser(sender)) {\n _addPauser(sender);\n }\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @title Roles\n * @dev Library for managing addresses assigned to a Role.\n */\nlibrary Roles {\n struct Role {\n mapping (address => bool) bearer;\n }\n\n /**\n * @dev Give an account access to this role.\n */\n function add(Role storage role, address account) internal {\n require(!has(role, account), \"Roles: account already has role\");\n role.bearer[account] = true;\n }\n\n /**\n * @dev Remove an account's access to this role.\n */\n function remove(Role storage role, address account) internal {\n require(has(role, account), \"Roles: account doesn't have role\");\n role.bearer[account] = false;\n }\n\n /**\n * @dev Check if an account has this role.\n * @return bool\n */\n function has(Role storage role, address account) internal view returns (bool) {\n require(account != address(0), \"Roles: account is the zero address\");\n return role.bearer[account];\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _tokenOwners.contains(tokenId);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(tokenId);\n\n emit Transfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n}\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n}\n"
+ },
+ "contracts/test/nftbridge/NFTInheritedBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport \"../../nftbridge/NFTBridge.sol\";\n\ncontract NFTInheritedBridge is NFTBridge {\n function checkChainIdExposed(uint256 chainId) public pure {\n return checkChainId(chainId);\n } \n\n function shouldBeCurrentChainIdExposed(uint256 chainId) public view {\n return shouldBeCurrentChainId(chainId);\n } \n}"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract WRBTC is IWrapped {\n string public name = \"Wrapped RBTC\";\n string public symbol = \"WRBTC\";\n uint8 public decimals = 18;\n\n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n event Deposit(address indexed dst, uint wad);\n event Withdrawal(address indexed src, uint wad);\n\n mapping (address => uint) override public balanceOf;\n mapping (address => mapping (address => uint)) public allowance;\n\n receive () external payable {\n deposit();\n }\n function deposit() override public payable {\n balanceOf[msg.sender] += msg.value;\n emit Deposit(msg.sender, msg.value);\n }\n function withdraw(uint wad) override public {\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\n balanceOf[msg.sender] -= wad;\n (bool success, ) = msg.sender.call{value:wad, gas:23000}(\"\");\n require(success, \"WRBTC: transfer fail\");\n emit Withdrawal(msg.sender, wad);\n }\n\n function totalSupply() override public view returns (uint) {\n return address(this).balance;\n }\n\n function approve(address guy, uint wad) override public returns (bool) {\n allowance[msg.sender][guy] = wad;\n emit Approval(msg.sender, guy, wad);\n return true;\n }\n\n function transfer(address dst, uint wad) override public returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad)\n override public\n returns (bool)\n {\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\n\n if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\n allowance[src][msg.sender] -= wad;\n }\n\n balanceOf[src] -= wad;\n balanceOf[dst] += wad;\n\n emit Transfer(src, dst, wad);\n\n return true;\n }\n}"
+ },
+ "contracts/Bridge/BridgeV3.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// import \"hardhat/console.sol\";\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./IBridgeV3.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n\ncontract BridgeV3 is Initializable, IBridgeV3, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant internal NULL_ADDRESS = address(0);\n bytes32 constant internal NULL_HASH = bytes32(0);\n IERC1820Registry constant internal erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address internal federation;\n uint256 internal feePercentage;\n string public symbolPrefix;\n bytes32 public DOMAIN_SEPARATOR; // replaces uint256 internal _depprecatedLastDay;\n uint256 internal _deprecatedSpentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n uint256 constant public feePercentageDivider = 10000; // Porcentage with up to 2 decimals\n //Bridge_v3 variables\n bytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\");\n IWrapped public wrappedCurrency;\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n // keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\n mapping(address => uint) public nonces;\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool _isUpgrading);\n event WrappedCurrencyChanged(address _wrappedCurrency);\n\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n federation = _federation;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n initDomainSeparator();\n }\n\n receive () external payable {\n // The fallback function is needed to use WRBTC\n require(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n }\n\n function version() override external pure returns (string memory) {\n return \"v3\";\n }\n\n function initDomainSeparator() public {\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n DOMAIN_SEPARATOR = LibEIP712.hashEIP712Domain(\n \"RSK Token Bridge\",\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"Bridge: Not Federation\");\n require(knownTokens[_originalTokenAddress] ||\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\n \"Bridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"Bridge: Null To\");\n require(_amount > 0, \"Bridge: Amount 0\");\n require(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _amount,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed also has the previously processed using the older bridge version\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n require(!claimed[_transactionDataHash], \"Bridge: Already claimed\");\n\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\n senderAddresses[_transactionHash] = _from;\n\n emit AcceptedCrossTransfer(\n _transactionHash,\n _originalTokenAddress,\n _to,\n _from,\n _amount,\n _blockHash,\n _logIndex\n );\n }\n\n\n function createSideToken(\n uint256 _typeId,\n address _originalTokenAddress,\n uint8 _originalTokenDecimals,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n address sideToken = mappedTokens[_originalTokenAddress];\n require(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\n\n mappedTokens[_originalTokenAddress] = sideToken;\n originalTokens[sideToken] = _originalTokenAddress;\n allowTokens.setToken(sideToken, _typeId);\n\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\n }\n\n function claim(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function claimFallback(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n receivedAmount = _claim(\n _claimData,\n _msgSender(),\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function getDigest(\n ClaimData memory _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline\n ) internal returns (bytes32) {\n return LibEIP712.hashEIP712Message(\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n CLAIM_TYPEHASH,\n _claimData.to,\n _claimData.amount,\n _claimData.transactionHash,\n _relayer,\n _fee,\n nonces[_claimData.to]++,\n _deadline\n )\n )\n );\n }\n\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external override returns (uint256 receivedAmount) {\n require(_deadline >= block.timestamp, \"Bridge: EXPIRED\");\n\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claim(\n ClaimData calldata _claimData,\n address payable _reciever,\n address payable _relayer,\n uint256 _fee\n ) internal nonReentrant returns (uint256 receivedAmount) {\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n require(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.amount,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n require(!claimed[transactionDataHash], \"Bridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (knownTokens[originalTokenAddress]) {\n receivedAmount =_claimCrossBackToToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n } else {\n receivedAmount =_claimCrossToSideToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n }\n emit Claimed(\n _claimData.transactionHash,\n originalTokenAddress,\n _claimData.to,\n senderAddresses[_claimData.transactionHash],\n _claimData.amount,\n _claimData.blockHash,\n _claimData.logIndex,\n _reciever,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claimCrossToSideToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n address sideToken = mappedTokens[_originalTokenAddress];\n uint256 granularity = IERC777(sideToken).granularity();\n uint256 formattedAmount = _amount.mul(granularity);\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n ISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n if(_fee > 0) {\n ISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n }\n return receivedAmount;\n }\n\n function _claimCrossBackToToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n //As side tokens are ERC777 they will always have 18 decimals\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n if(address(wrappedCurrency) == _originalTokenAddress) {\n wrappedCurrency.withdraw(formattedAmount);\n _receiver.transfer(receivedAmount);\n if(_fee > 0) {\n _relayer.transfer(_fee);\n }\n } else {\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n if(_fee > 0) {\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n }\n }\n return receivedAmount;\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\n address sender = _msgSender();\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, to, amount, \"\");\n }\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) override external payable {\n address sender = _msgSender();\n require(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n wrappedCurrency.deposit{ value: msg.value }();\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \"\");\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external override(IBridgeV3, IERC777Recipient){\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to this address\");\n address tokenToUse = _msgSender();\n require(erc1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n require(userData.length != 0 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\n crossTokens(tokenToUse, from, receiver, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\n internal whenNotUpgrading whenNotPaused nonReentrant {\n knownTokens[tokenToUse] = true;\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n uint256 amountMinusFees = amount.sub(fee);\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n // We consider the amount before fees converted to 18 decimals to check the limits\n // updateTokenTransfer revert if token not allowed\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n address originalTokenAddress = tokenToUse;\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\n //Side Token Crossing\n originalTokenAddress = originalTokens[tokenToUse];\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\n uint256 modulo = amountMinusFees.mod(granularity);\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n }\n\n emit Cross(\n originalTokenAddress,\n from,\n to,\n amountMinusFees,\n userData\n );\n\n if (fee > 0) {\n //Send the payment to the MultiSig of the Federation\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n }\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n )\n public pure override returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n }\n\n function setFeePercentage(uint amount) external onlyOwner {\n require(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() external view override returns(uint) {\n return feePercentage;\n }\n\n function changeFederation(address newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n require(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n wrappedCurrency = IWrapped(_wrappedCurrency);\n emit WrappedCurrencyChanged(_wrappedCurrency);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionsDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionsDataHashes[transactionHash]];\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an `IERC777` token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See `IERC1820Registry` and\n * `ERC1820Implementer`.\n */\ninterface IERC777 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See `operatorSend` and `operatorBurn`.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor`.\n *\n * Emits an `AuthorizedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor` and `defaultOperators`.\n *\n * Emits a `RevokedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if `authorizeOperator` was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * `revokeOperator`, in which case `isOperatorFor` will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n\n function decimals() external returns (uint8);\n\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n}\n"
+ },
+ "contracts/Bridge/IBridgeV3.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IBridgeV3 {\n\n struct ClaimData {\n address payable to;\n uint256 amount;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) external payable;\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n */\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external returns (uint256 receivedAmount);\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns(bytes32);\n\n event Cross(\n address indexed _tokenAddress,\n address indexed _from,\n address indexed _to,\n uint256 _amount,\n bytes _userData\n );\n event NewSideToken(\n address indexed _newSideTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 _granularity\n );\n event AcceptedCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FeePercentageChanged(uint256 _amount);\n event Claimed(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _reciever,\n address _relayer,\n uint256 _fee\n );\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideToken {\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideTokenFactory {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\n\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../SideToken/SideToken.sol\";\n\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\n external onlyPrimary override returns(address) {\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\n emit SideTokenCreated(sideToken, symbol, granularity);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\nabstract contract Secondary is Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n constructor () {\n _primary = _msgSender();\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(_primary);\n }\n}\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\nimport \"../interface/IERC677Receiver.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../lib/LibEIP712.sol\";\n\ncontract SideToken is ISideToken, ERC777 {\n using SafeMath for uint256;\n\n address public minter;\n uint256 private _granularity;\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n bytes32 public domainSeparator;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n // ERC677 Transfer Event\n event Transfer(address,address,uint256,bytes);\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\n minter = _minterAddr;\n _granularity = _newGranularity;\n\n domainSeparator = LibEIP712.hashEIP712Domain(\n name(),\n \"1\",\n block.chainid,\n address(this)\n );\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter override\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n /**\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\n * @param recipient The address to transfer to.\n * @param amount The amount to be transferred.\n * @param data The extra data to be passed to the receiving contract.\n */\n function transferAndCall(address recipient, uint amount, bytes calldata data)\n external returns (bool success)\n {\n address from = _msgSender();\n\n _send(from, from, recipient, amount, data, \"\", false);\n emit Transfer(from, recipient, amount, data);\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\n return true;\n }\n\n function granularity() public view override returns (uint256) {\n return _granularity;\n }\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\n bytes32 digest = LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../../token/ERC20/IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\n // See https://github.com/ethereum/solidity/issues/4024.\n\n // keccak256(\"ERC777TokensSender\")\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\n\n // keccak256(\"ERC777TokensRecipient\")\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping (address => mapping (address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(\n string memory aName,\n string memory aSymbol,\n address[] memory theDefaultOperators\n ) {\n _name = aName;\n _symbol = aSymbol;\n\n _defaultOperatorsArray = theDefaultOperators;\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\n _defaultOperators[_defaultOperatorsArray[i]] = true;\n }\n\n // register interfaces\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view override(IERC777) returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view override(IERC777) returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20Detailed-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override(IERC777) returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n\n address from = _msgSender();\n\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\n\n _move(from, from, recipient, amount, \"\", \"\");\n\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(\n address operator,\n address tokenHolder\n ) public view override(IERC777) returns (bool) {\n return operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) external override(IERC777) {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) external override(IERC777) {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n )\n external override(IERC777)\n {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {Transfer} events.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\n external override(IERC777) {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\n _burn(_msgSender(), account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender)\n public view override(IERC20) returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {Transfer} and {Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount)\n external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n require(holder != address(0), \"ERC777: transfer from zero address\");\n\n address spender = _msgSender();\n\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\n\n _move(spender, holder, recipient, amount, \"\", \"\");\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\n\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address operator,\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n require(account != address(0), \"ERC777: mint to zero address\");\n\n // Update state variables\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n internal\n {\n require(from != address(0), \"ERC777: send from zero address\");\n require(to != address(0), \"ERC777: send to zero address\");\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param operator address operator requesting the operation\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(\n address operator,\n address from,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n )\n internal\n {\n require(from != address(0), \"ERC777: burn from zero address\");\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n // Update state variables\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\n _balances[to] = _balances[to].add(amount);\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n function _approve(address holder, address spender, uint256 value) internal {\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\n // currently unnecessary.\n //require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n private\n {\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n}\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * `IERC777` Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an `IERC777` token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// import \"hardhat/console.sol\";\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n\tusing SafeMath for uint256;\n\tusing SafeERC20 for IERC20;\n\tusing Address for address;\n\n\taddress constant internal NULL_ADDRESS = address(0);\n\tbytes32 constant internal NULL_HASH = bytes32(0);\n\tIERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n\taddress internal federation;\n\tuint256 internal feePercentage;\n\tstring public deprecatedSymbolPrefix;\n\t// domainSeparator replaces uint256 internal _depprecatedLastDay;\n\tbytes32 public domainSeparator;\n\tuint256 internal _deprecatedSpentToday;\n\n\tmapping (address => address) public deprecatedMappedTokens; // OriginalToken => SideToken\n\tmapping (address => address) public deprecatedOriginalTokens; // SideToken => OriginalToken\n\tmapping (address => bool) public deprecatedKnownTokens; // OriginalToken => true\n\n\t// claimed can use the same of bytes32\n\tmapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n\n\tIAllowTokens public allowTokens;\n\tISideTokenFactory public sideTokenFactory;\n\t//Bridge_v1 variables\n\tbool public isUpgrading;\n\t// Percentage with up to 2 decimals\n\tuint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\n\t//Bridge_v2 variables\n\tbytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\n\tIWrapped public wrappedCurrency;\n\tmapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n\tmapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n\tmapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n\t// keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,uint256 originChainId,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n\tbytes32 public constant CLAIM_TYPEHASH = 0xaf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c;\n\tmapping(address => uint) public nonces;\n\n\t//Bridge_v3 variables multichain\n\tmapping (uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain; // chainId => OriginalToken Address => SideToken Address\n\tmapping (address => OriginalToken) public originalTokenBySideToken; // SideTokenAddress => struct {}\n\tmapping (uint256 => mapping(address => bool)) public knownTokenByChain; // chainId => OriginalToken Address => Know\n\n\tevent AllowTokensChanged(address _newAllowTokens);\n\tevent FederationChanged(address _newFederation);\n\tevent SideTokenFactoryChanged(address _newSideTokenFactory);\n\tevent Upgrading(bool _isUpgrading);\n\tevent WrappedCurrencyChanged(address _wrappedCurrency);\n\n\tfunction initialize(\n\t\taddress _manager,\n\t\taddress _federation,\n\t\taddress _allowTokens,\n\t\taddress _sideTokenFactory\n\t) public initializer {\n\t\tUpgradableOwnable.initialize(_manager);\n\t\tUpgradablePausable.__Pausable_init(_manager);\n\t\tallowTokens = IAllowTokens(_allowTokens);\n\t\tsideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n\t\tfederation = _federation;\n\t\t//keccak256(\"ERC777TokensRecipient\")\n\t\tERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n\t\tinitDomainSeparator();\n\t}\n\n\treceive () external payable {\n\t\t// The fallback function is needed to use WRBTC\n\t\trequire(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n\t}\n\n\tfunction version() override external pure returns (string memory) {\n\t\treturn \"v4\";\n\t}\n\n\tfunction initDomainSeparator() public {\n\t\tdomainSeparator = LibEIP712.hashEIP712Domain(\n\t\t\t\"RSK Token Bridge\",\n\t\t\t\"1\",\n\t\t\tblock.chainid,\n\t\t\taddress(this)\n\t\t);\n\t}\n\n\tmodifier whenNotUpgrading() {\n\t\trequire(!isUpgrading, \"Bridge: Upgrading\");\n\t\t_;\n\t}\n\n\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\n\t\trequire(chainId == block.chainid, \"Bridge: Not block.chainid\");\n\t}\n\n\tfunction sideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\n\t\taddress sideTokenAddr = sideTokenByOriginalTokenByChain[chainId][originalToken];\n\n\t\tif (sideTokenAddr != NULL_ADDRESS) {\n\t\t\treturn sideTokenAddr;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\treturn deprecatedMappedTokens[originalToken];\n\t}\n\n\tfunction setSideTokenByOriginalAddressByChain(uint256 chainId, address originalToken, address sideToken) public onlyOwner {\n\t\tsideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\n\t}\n\n\tfunction getOriginalTokenBySideToken(address sideToken) public view returns(OriginalToken memory originalToken) {\n\t\toriginalToken = originalTokenBySideToken[sideToken];\n\t\tif (originalToken.tokenAddress != NULL_ADDRESS) {\n\t\t\treturn originalToken;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\toriginalToken.originChainId = 1; // ethereum main chain id\n\t\toriginalToken.tokenAddress = deprecatedOriginalTokens[sideToken];\n\t\treturn originalToken;\n\t}\n\n\tfunction setOriginalTokenBySideTokenByChain(address sideToken, OriginalToken memory originalToken) public onlyOwner {\n\t\toriginalTokenBySideToken[sideToken] = originalToken;\n\t}\n\n\tfunction knownToken(uint256 chainId, address originalToken) public view returns(bool) {\n\t\tbool knowToken = knownTokenByChain[chainId][originalToken];\n\t\tif (knowToken) {\n\t\t\treturn knowToken;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\treturn deprecatedKnownTokens[originalToken];\n\t}\n\n\tfunction _setKnownTokenByChain(uint256 chainId, address originalToken, bool knownTokenValue) internal {\n\t\tknownTokenByChain[chainId][originalToken] = knownTokenValue;\n\t}\n\n\tfunction acceptTransfer(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _from,\n\t\taddress payable _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) external whenNotPaused nonReentrant override {\n\t\trequire(_msgSender() == federation, \"Bridge: Not Federation\");\n\t\tcheckChainId(_originChainId);\n\t\tshouldBeCurrentChainId(_destinationChainId);\n\t\trequire(knownToken(_originChainId, _originalTokenAddress) ||\n\t\t\tsideTokenByOriginalToken(_originChainId, _originalTokenAddress) != NULL_ADDRESS,\n\t\t\t\"Bridge: Unknown token\"\n\t\t);\n\t\trequire(_to != NULL_ADDRESS, \"Bridge: Null To\");\n\t\trequire(_amount > 0, \"Bridge: Amount 0\");\n\t\trequire(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n\t\trequire(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n\t\trequire(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n\t\tbytes32 _transactionDataHash = getTransactionDataHash(\n\t\t\t_to,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_transactionHash,\n\t\t\t_logIndex\n\t\t);\n\n\t\tbytes32 _transactionDataHashMultichain = getTransactionDataHash(\n\t\t\t_to,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_transactionHash,\n\t\t\t_logIndex,\n\t\t\t_originChainId,\n\t\t\t_destinationChainId\n\t\t);\n\t\t// Do not remove, claimed also has the previously processed using the older bridge version\n\t\t// https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n\t\trequire(!isClaimed(_transactionDataHash, _transactionDataHashMultichain), \"Bridge: Already claimed\");\n\n\t\ttransactionsDataHashes[_transactionHash] = _transactionDataHashMultichain;\n\t\toriginalTokenAddresses[_transactionHash] = _originalTokenAddress;\n\t\tsenderAddresses[_transactionHash] = _from;\n\n\t\temit AcceptedCrossTransfer(\n\t\t\t_transactionHash,\n\t\t\t_originalTokenAddress,\n\t\t\t_to,\n\t\t\t_from,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_logIndex,\n\t\t\t_originChainId,\n\t\t\t_destinationChainId\n\t\t);\n\t}\n\n\tfunction checkChainId(uint256 chainId) internal pure {\n\t\trequire(chainId > 0, \"Bridge: ChainId is 0\");\n\t}\n\n\tfunction _createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _tokenSymbol,\n\t\tstring calldata _tokenName,\n\t\tuint256 _originChainId\n\t) internal {\n\t\trequire(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n\t\tcheckChainId(_originChainId);\n\t\taddress sideToken = sideTokenByOriginalToken(_originChainId, _originalTokenAddress);\n\t\trequire(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n\n\t\tuint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n\n\t\t// Create side token\n\t\tsideToken = sideTokenFactory.createSideToken(_tokenName, _tokenSymbol, granularity);\n\n\t\tsetSideTokenByOriginalAddressByChain(_originChainId, _originalTokenAddress, sideToken);\n\n\t\tOriginalToken memory originalToken;\n\t\toriginalToken.originChainId = _originChainId;\n\t\toriginalToken.tokenAddress = _originalTokenAddress;\n\t\tsetOriginalTokenBySideTokenByChain(sideToken, originalToken);\n\t\tallowTokens.setToken(sideToken, _typeId);\n\n\t\temit NewSideToken(sideToken, _originalTokenAddress, _tokenSymbol, granularity, _originChainId);\n\t}\n\n\tfunction createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _tokenSymbol,\n\t\tstring calldata _tokenName,\n\t\tuint256 _originChainId\n\t) external onlyOwner override {\n\t\t_createSideToken(\n\t\t\t_typeId,\n\t\t\t_originalTokenAddress,\n\t\t\t_originalTokenDecimals,\n\t\t\t_tokenSymbol,\n\t\t\t_tokenName,\n\t\t\t_originChainId\n\t\t);\n\t}\n\n\tfunction createMultipleSideTokens(\n\t\tCreateSideTokenStruct[] calldata createSideTokenStruct\n\t) external onlyOwner {\n\t\tfor(uint256 i = 0; i < createSideTokenStruct.length; i++) {\n\t\t\t_createSideToken(\n\t\t\t\tcreateSideTokenStruct[i]._typeId,\n\t\t\t\tcreateSideTokenStruct[i]._originalTokenAddress,\n\t\t\t\tcreateSideTokenStruct[i]._originalTokenDecimals,\n\t\t\t\tcreateSideTokenStruct[i]._originalTokenSymbol,\n\t\t\t\tcreateSideTokenStruct[i]._originalTokenName,\n\t\t\t\tcreateSideTokenStruct[i]._originChainId\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction claim(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\n\t\treceivedAmount = _claim(\n\t\t\t_claimData,\n\t\t\t_claimData.to,\n\t\t\tpayable(address(0)),\n\t\t\t0\n\t\t);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction claimFallback(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\n\t\trequire(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n\t\treceivedAmount = _claim(\n\t\t\t_claimData,\n\t\t\t_msgSender(),\n\t\t\tpayable(address(0)),\n\t\t\t0\n\t\t);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction getDigest(\n\t\tClaimData memory _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline\n\t) internal returns (bytes32) {\n\t\treturn LibEIP712.hashEIP712Message(\n\t\t\tdomainSeparator,\n\t\t\tkeccak256(\n\t\t\t\tabi.encode(\n\t\t\t\t\tCLAIM_TYPEHASH,\n\t\t\t\t\t_claimData.to,\n\t\t\t\t\t_claimData.amount,\n\t\t\t\t\t_claimData.transactionHash,\n\t\t\t\t\t_claimData.originChainId,\n\t\t\t\t\t_relayer,\n\t\t\t\t\t_fee,\n\t\t\t\t\tnonces[_claimData.to]++,\n\t\t\t\t\t_deadline\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t}\n\n\t// Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n\tfunction claimGasless(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline,\n\t\tuint8 _v,\n\t\tbytes32 _r,\n\t\tbytes32 _s\n\t) external override returns (uint256 receivedAmount) {\n\t\trequire(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\n\n\t\tbytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n\t\taddress recoveredAddress = ecrecover(digest, _v, _r, _s);\n\t\trequire(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n\t\treturn _claim(\n\t\t\t_claimData,\n\t\t\t_claimData.to,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\t}\n\n\tfunction isClaimed(bytes32 transactionDataHash, bytes32 transactionDataHashMultichain) public view returns(bool) {\n\t\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\n\t}\n\n\tfunction isClaimed(ClaimData calldata _claimData, bytes32 transactionDataHashMultichain) public view returns(bool) {\n\t\tbytes32 transactionDataHash = getTransactionDataHash(\n\t\t\t_claimData.to,\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.transactionHash,\n\t\t\t_claimData.logIndex\n\t\t);\n\n\t\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\n\t}\n\n\tfunction _claim(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _reciever,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal nonReentrant returns (uint256 receivedAmount) {\n\t\taddress originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n\t\trequire(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n\t\tbytes32 transactionDataHash = getTransactionDataHash(\n\t\t\t_claimData.to,\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.transactionHash,\n\t\t\t_claimData.logIndex,\n\t\t\t_claimData.originChainId,\n\t\t\tblock.chainid\n\t\t);\n\n\t\trequire(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n\t\trequire(!isClaimed(_claimData, transactionDataHash), \"Bridge: Already claimed\");\n\t\tclaimed[transactionDataHash] = true;\n\n\t\treceivedAmount = _claimCross(\n\t\t\t_claimData.originChainId,\n\t\t\toriginalTokenAddress,\n\t\t\t_reciever,\n\t\t\t_claimData.amount,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\n\t\temitClaimed(_claimData, originalTokenAddress, _reciever, _relayer, _fee);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction emitClaimed(\n\t\tClaimData calldata _claimData,\n\t\taddress _originalTokenAddress,\n\t\taddress payable _reciever,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal {\n\t\temit Claimed(\n\t\t\t_claimData.transactionHash,\n\t\t\t_originalTokenAddress,\n\t\t\t_claimData.to,\n\t\t\tsenderAddresses[_claimData.transactionHash],\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.logIndex,\n\t\t\t_reciever,\n\t\t\t_relayer,\n\t\t\t_fee,\n\t\t\t_claimData.originChainId,\n\t\t\tblock.chainid\n\t\t);\n\t}\n\n\tfunction _claimCross(\n\t\tuint256 _originalChainId,\n\t\taddress _originalTokenAddress,\n\t\taddress payable _reciever,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256) {\n\t\tcheckChainId(_originalChainId);\n\t\tif (knownToken(_originalChainId, _originalTokenAddress)) {\n\t\t\treturn _claimCrossBackToToken(\n\t\t\t\t_originalTokenAddress,\n\t\t\t\t_reciever,\n\t\t\t\t_amount,\n\t\t\t\t_relayer,\n\t\t\t\t_fee\n\t\t\t);\n\t\t}\n\n\t\treturn _claimCrossToSideToken(\n\t\t\tsideTokenByOriginalToken(_originalChainId, _originalTokenAddress),\n\t\t\t_reciever,\n\t\t\t_amount,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\t}\n\n\tfunction _claimCrossToSideToken(\n\t\taddress _sideToken,\n\t\taddress payable _receiver,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256 receivedAmount) {\n\t\trequire(_sideToken != NULL_ADDRESS, \"Bridge: side token is null\");\n\t\tuint256 granularity = IERC777(_sideToken).granularity();\n\t\tuint256 formattedAmount = _amount.mul(granularity);\n\t\trequire(_fee <= formattedAmount, \"Bridge: fee too high\");\n\t\treceivedAmount = formattedAmount.sub(_fee);\n\t\tISideToken(_sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n\t\tif (_fee > 0) {\n\t\t\tISideToken(_sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n\t\t}\n\t\treturn receivedAmount;\n\t}\n\n\tfunction _claimCrossBackToToken(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _receiver,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256 receivedAmount) {\n\t\tuint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n\t\t//As side tokens are ERC777 they will always have 18 decimals\n\t\tuint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n\t\trequire(_fee <= formattedAmount, \"Bridge: fee too high\");\n\t\treceivedAmount = formattedAmount.sub(_fee);\n\t\tif (address(wrappedCurrency) == _originalTokenAddress) {\n\t\t\twrappedCurrency.withdraw(formattedAmount);\n\t\t\t_receiver.transfer(receivedAmount);\n\t\t\tif(_fee > 0) {\n\t\t\t\t_relayer.transfer(_fee);\n\t\t\t}\n\t\t} else {\n\t\t\tIERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n\t\t\tif(_fee > 0) {\n\t\t\t\tIERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n\t\t\t}\n\t\t}\n\t\treturn receivedAmount;\n\t}\n\n\t/**\n\t\t* ERC-20 tokens approve and transferFrom pattern\n\t\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n\t\t*/\n\tfunction receiveTokensTo(uint256 destinationChainId, address tokenToUse, address to, uint256 amount) external override {\n\t\taddress sender = _msgSender();\n\t\t//Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n\t\tIERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n\t\tcrossTokens(tokenToUse, sender, to, amount, \"\", destinationChainId);\n\t}\n\n\t/**\n\t\t* Use network currency and cross it.\n\t\t*/\n\tfunction depositTo(uint256 chainId, address to) external payable override {\n\t\taddress sender = _msgSender();\n\t\trequire(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n\t\twrappedCurrency.deposit{ value: msg.value }();\n\t\tcrossTokens(address(wrappedCurrency), sender, to, msg.value, \"\", chainId);\n\t}\n\n\t/**\n\t\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n\t\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n\t\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\n\t\t* const userData = web3.eth.abi.encodeParameters(\n * [\"address\", \"uint256\"],\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\n * );\n\t\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\n\t\t* const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\n\t\t*/\n\tfunction tokensReceived(\n\t\taddress operator,\n\t\taddress from,\n\t\taddress to,\n\t\tuint amount,\n\t\tbytes calldata userData, // [address,uint256] user addrest receiver, destinationChainId || [uint256] same as from, destinationChainId\n\t\tbytes calldata\n\t) external override(IBridge, IERC777Recipient) {\n\t\t//Hook from ERC777address\n\t\tif(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n\t\trequire(to == address(this), \"Bridge: Not to this address\");\n\t\taddress tokenToUse = _msgSender();\n\t\trequire(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n\t\trequire(userData.length >= 32, \"Bridge: user data with at least the destinationChainId\");\n\t\trequire(userData.length == 64 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n\t\taddress receiver = userData.length == 32 ? from : LibUtils.toAddress(userData, 12);\n\t\tuint256 destinationChainId = LibUtils.toUint256(userData, userData.length - 32);\n\t\tcrossTokens(tokenToUse, from, receiver, amount, userData, destinationChainId);\n\t}\n\n\tfunction crossTokens(\n\t\taddress tokenToUse,\n\t\taddress from,\n\t\taddress to,\n\t\tuint256 amount,\n\t\tbytes memory userData,\n\t\tuint256 destinationChainId\n\t) internal whenNotUpgrading whenNotPaused nonReentrant {\n\t\trequire(block.chainid != destinationChainId, \"Bridge: destination chain id equal current chain id\");\n\t\tcheckChainId(destinationChainId);\n\t\t_setKnownTokenByChain(destinationChainId, tokenToUse, true);\n\t\tuint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n\t\tuint256 amountMinusFees = amount.sub(fee);\n\t\tuint8 decimals = LibUtils.getDecimals(tokenToUse);\n\t\tuint formattedAmount = amount;\n\t\tif (decimals != 18) {\n\t\t\tformattedAmount = amount.mul(uint256(10)**(18-decimals));\n\t\t}\n\t\t// We consider the amount before fees converted to 18 decimals to check the limits\n\t\t// updateTokenTransfer revert if token not allowed\n\t\tallowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n\n\t\tOriginalToken memory sideToken = getOriginalTokenBySideToken(tokenToUse);\n\t\tif (sideToken.tokenAddress != NULL_ADDRESS) {\n\t\t\t// Side Token Crossing back\n\t\t\t{ // Created scope to avoid stack too deep\n\t\t\t\tuint256 granularity = LibUtils.getGranularity(tokenToUse);\n\t\t\t\tuint256 modulo = amountMinusFees.mod(granularity);\n\t\t\t\tfee = fee.add(modulo);\n\t\t\t\tamountMinusFees = amountMinusFees.sub(modulo);\n\t\t\t\tIERC777(tokenToUse).burn(amountMinusFees, userData);\n\t\t\t}\n\t\t\temit Cross(\n\t\t\t\tsideToken.tokenAddress,\n\t\t\t\tto,\n\t\t\t\tdestinationChainId,\n\t\t\t\tfrom,\n\t\t\t\tblock.chainid,\n\t\t\t\tamountMinusFees,\n\t\t\t\tuserData\n\t\t\t);\n\t\t} else {\n\t\t\temit Cross(\n\t\t\t\ttokenToUse,\n\t\t\t\tto,\n\t\t\t\tdestinationChainId,\n\t\t\t\tfrom,\n\t\t\t\tblock.chainid,\n\t\t\t\tamountMinusFees,\n\t\t\t\tuserData\n\t\t\t);\n\t\t}\n\n\t\tif (fee > 0) {\n\t\t\t//Send the payment to the MultiSig of the Federation\n\t\t\tIERC20(tokenToUse).safeTransfer(owner(), fee);\n\t\t}\n\t}\n\n\t// function for retrocompatibility\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex\n\t) internal pure returns(bytes32) {\n\t\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n\t}\n\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) public pure override returns(bytes32) {\n\t\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex, _originChainId, _destinationChainId));\n\t}\n\n\tfunction setFeePercentage(uint amount) external onlyOwner {\n\t\trequire(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n\t\tfeePercentage = amount;\n\t\temit FeePercentageChanged(feePercentage);\n\t}\n\n\tfunction getFeePercentage() external view override returns(uint) {\n\t\treturn feePercentage;\n\t}\n\n\tfunction changeFederation(address newFederation) external onlyOwner {\n\t\trequire(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n\t\tfederation = newFederation;\n\t\temit FederationChanged(federation);\n\t}\n\n\tfunction changeAllowTokens(address newAllowTokens) external onlyOwner {\n\t\trequire(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n\t\tallowTokens = IAllowTokens(newAllowTokens);\n\t\temit AllowTokensChanged(newAllowTokens);\n\t}\n\n\tfunction getFederation() external view returns(address) {\n\t\treturn federation;\n\t}\n\n\tfunction changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n\t\trequire(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n\t\tsideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n\t\temit SideTokenFactoryChanged(newSideTokenFactory);\n\t}\n\n\tfunction setUpgrading(bool _isUpgrading) external onlyOwner {\n\t\tisUpgrading = _isUpgrading;\n\t\temit Upgrading(isUpgrading);\n\t}\n\n\tfunction setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n\t\trequire(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n\t\twrappedCurrency = IWrapped(_wrappedCurrency);\n\t\temit WrappedCurrencyChanged(_wrappedCurrency);\n\t}\n\n\tfunction hasCrossed(bytes32 transactionHash) public view returns (bool) {\n\t\treturn transactionsDataHashes[transactionHash] != bytes32(0);\n\t}\n\n\tfunction hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n\t\treturn claimed[transactionsDataHashes[transactionHash]];\n\t}\n\n}\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IBridge {\n\n\tstruct ClaimData {\n\t\taddress payable to;\n\t\tuint256 amount;\n\t\tbytes32 blockHash;\n\t\tbytes32 transactionHash;\n\t\tuint32 logIndex;\n\t\tuint256 originChainId;\n\t}\n\n\tstruct OriginalToken {\n\t\taddress tokenAddress;\n\t\tuint256 originChainId;\n\t}\n\t\n\tstruct CreateSideTokenStruct {\n\t\tuint256 _typeId;\n\t\taddress _originalTokenAddress;\n\t\tuint8 _originalTokenDecimals;\n\t\tstring _originalTokenSymbol;\n\t\tstring _originalTokenName;\n\t\tuint256 _originChainId;\n\t}\n\n\tfunction version() external pure returns (string memory);\n\n\tfunction getFeePercentage() external view returns(uint);\n\n\t/**\n\t\t* ERC-20 tokens approve and transferFrom pattern\n\t\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n\t\t*/\n\tfunction receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;\n\n\t/**\n\t\t* Use network currency and cross it.\n\t\t*/\n\tfunction depositTo(uint256 chainId, address to) external payable;\n\n\t/**\n\t\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n\t\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n\t\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\n\t\t* const userData = web3.eth.abi.encodeParameters(\n * [\"address\", \"uint256\"],\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\n * );\n\t\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\n\t\t* const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\n\t\t*/\n\tfunction tokensReceived (\n\t\taddress operator,\n\t\taddress from,\n\t\taddress to,\n\t\tuint amount,\n\t\tbytes calldata userData,\n\t\tbytes calldata operatorData\n\t) external;\n\n\t/**\n\t\t* Accepts the transaction from the other chain that was voted and sent by the Federation contract\n\t\t*/\n\tfunction acceptTransfer(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _from,\n\t\taddress payable _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) external;\n\n\t/**\n\t\t* Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n\t\t*/\n\tfunction claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n\tfunction claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n\tfunction claimGasless(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline,\n\t\tuint8 _v,\n\t\tbytes32 _r,\n\t\tbytes32 _s\n\t) external returns (uint256 receivedAmount);\n\n\tfunction createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _originalTokenSymbol,\n\t\tstring calldata _originalTokenName,\n\t\tuint256 _chainId\n\t) external;\n\n\tfunction createMultipleSideTokens(\n\t\tCreateSideTokenStruct[] calldata createSideTokenStruct\n\t) external;\n\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256 _destinationChainId\n\t) external returns(bytes32);\n\n\tevent Cross(\n\t\taddress indexed _tokenAddress,\n\t\taddress indexed _to,\n\t\tuint256 indexed _destinationChainId,\n\t\taddress _from,\n\t\tuint256 _originChainId,\n\t\tuint256 _amount,\n\t\tbytes _userData\n\t);\n\n\tevent NewSideToken(\n\t\taddress indexed _newSideTokenAddress,\n\t\taddress indexed _originalTokenAddress,\n\t\tstring _newSymbol,\n\t\tuint256 _granularity,\n\t\tuint256 _chainId\n\t);\n\tevent AcceptedCrossTransfer(\n\t\tbytes32 indexed _transactionHash,\n\t\taddress indexed _originalTokenAddress,\n\t\taddress indexed _to,\n\t\taddress _from,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tuint256 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t);\n\tevent FeePercentageChanged(uint256 _amount);\n\tevent Claimed(\n\t\tbytes32 indexed _transactionHash,\n\t\taddress indexed _originalTokenAddress,\n\t\taddress indexed _to,\n\t\taddress _sender,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tuint256 _logIndex,\n\t\taddress _reciever,\n\t\taddress _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _destinationChainId,\n\t\tuint256 _originChainId\n\t);\n}"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IBridge.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockReceiveTokensCall is IERC777Recipient {\n address public bridge;\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor(address _bridge) {\n bridge = _bridge;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount, uint256 destinationChainId) external {\n IERC20(tokenToUse).approve(bridge, amount);\n IBridge(bridge).receiveTokensTo(destinationChainId, tokenToUse, receiver, amount);\n }\n\n function callDepositTo(address receiver, uint256 destinationChainId) external payable {\n IBridge(bridge).depositTo{ value: msg.value }(destinationChainId, receiver);\n }\n\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\n IERC777(tokenToUse).send(bridge, amount, data);\n }\n\n // Mandatory for IERC777Recipient\n function tokensReceived(\n address,\n address,\n address,\n uint,\n bytes calldata,\n bytes calldata\n ) override external view {\n this;\n }\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockERC777Recipient is IERC777Recipient {\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor() {\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\n }\n\n event Success(\n address operator,\n address from,\n address to,\n uint amount,\n bytes userData,\n bytes operatorData);\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) override external {\n emit Success(operator, from, to, amount, userData, operatorData);\n }\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\n\ncontract SideTokenV1 is ERC777 {\n address public minter;\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\n minter = _minterAddr;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../SideToken/SideTokenV1.sol\";\n\ncontract SideTokenFactoryV1 is Secondary {\n event CreatedSideToken(address sideToken, string symbol);\n\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\n emit CreatedSideToken(address(sideToken), symbol);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using SafeMath for uint256;\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping (uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /*\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri_) {\n _setURI(uri_);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) external view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: balance query for the zero address\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(amount);\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, address(0), id, amount);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\n /**\n @dev Handles the receipt of a single ERC1155 token type. This function is\n called at the end of a `safeTransferFrom` after the balance has been updated.\n To accept the transfer, this must return\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n (i.e. 0xf23a6e61, or its own function selector).\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n )\n external\n returns(bytes4);\n\n /**\n @dev Handles the receipt of a multiple ERC1155 token types. This function\n is called at the end of a `safeBatchTransferFrom` after the balances have\n been updated. To accept the transfer(s), this must return\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n (i.e. 0xbc197c81, or its own function selector).\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match values array)\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n )\n external\n returns(bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC1155 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Pausable is ERC1155, Pausable {\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\nimport \"../access/roles/PauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context, PauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n constructor () {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract PauserRole is Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n constructor () {\n _addPauser(_msgSender());\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC721.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC721 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC721Pausable is ERC721, Pausable {\n /**\n * @dev See {ERC721-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../../zeppelin/ownership/Ownable.sol\";\nimport \"../../zeppelin/math/SafeMath.sol\";\nimport \"../../zeppelin/utils/Strings.sol\";\nimport \"./OpenSeaEIP712Base.sol\";\n\n\n/**\n * @title OpenSea721\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\n */\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\n using SafeMath for uint256;\n\n uint256 private _currentTokenId = 0;\n\n constructor(\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n _initializeEIP712(_name);\n }\n\n function baseTokenURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/api/creature/\";\n }\n\n function contractURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\n }\n\n /**\n * @dev Mints a token to an address with a tokenURI.\n * @param _to address of the future owner of the token\n */\n function mintTo(address _to) public onlyOwner {\n uint256 newTokenId = _getNextTokenId();\n _mint(_to, newTokenId);\n _incrementTokenId();\n }\n\n /**\n * @dev calculates the next token ID based on value of _currentTokenId\n * @return uint256 for the next token ID\n */\n function _getNextTokenId() private view returns (uint256) {\n return _currentTokenId.add(1);\n }\n\n /**\n * @dev increments the value of _currentTokenId\n */\n function _incrementTokenId() private {\n _currentTokenId++;\n }\n\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\n }\n\n}"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () {\n _owner = _msgSender();\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../zeppelin/upgradable/Initializable.sol\";\n\ncontract OpenSeaEIP712Base is Initializable {\n struct EIP712Domain {\n string name;\n string version;\n address verifyingContract;\n bytes32 salt;\n }\n\n string constant public ERC712_VERSION = \"1\";\n\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\n bytes(\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\n )\n );\n bytes32 internal domainSeperator;\n\n // supposed to be called once while initializing.\n // one of the contracts that inherits this contract follows proxy pattern\n // so it is not possible to do this in a constructor\n function _initializeEIP712(\n string memory name\n )\n internal\n initializer\n {\n _setDomainSeperator(name);\n }\n\n function _setDomainSeperator(string memory name) internal {\n domainSeperator = keccak256(\n abi.encode(\n EIP712_DOMAIN_TYPEHASH,\n keccak256(bytes(name)),\n keccak256(bytes(ERC712_VERSION)),\n address(this),\n bytes32(block.chainid)\n )\n );\n }\n\n function getDomainSeperator() public view returns (bytes32) {\n return domainSeperator;\n }\n\n /**\n * Accept message hash and returns hash message in EIP712 compatible form\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\n * https://eips.ethereum.org/EIPS/eip-712\n * \"\\\\x19\" makes the encoding deterministic\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\n */\n function toTypedMessageHash(bytes32 messageHash)\n internal\n view\n returns (bytes32)\n {\n return\n keccak256(\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\n );\n }\n}\n"
+ },
+ "contracts/Federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../Bridge/IBridgeV3.sol\";\n\ncontract FederationV2 is Initializable, UpgradableOwnable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridgeV3 public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\n validRequirement(_members.length, _required) public initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n }\n\n function version() external pure returns (string memory) {\n return \"v2\";\n }\n\n function setBridge(address _bridge) external onlyOwner {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridgeV3(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n )\n public onlyMember returns(bool)\n {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32)\n {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}"
+ },
+ "contracts/Federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../nftbridge/INFTBridge.sol\";\nimport \"../interface/IBridge.sol\";\nimport \"../interface/IFederation.sol\";\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\n\tuint constant public MAX_MEMBER_COUNT = 50;\n\taddress constant private NULL_ADDRESS = address(0);\n\n\tIBridge public bridge;\n\taddress[] public members;\n\n\t/**\n\t\t@notice The minimum amount of votes to approve a transaction\n\t\t@dev It should have at least the required amount of members\n\t\t*/\n\tuint public required;\n\n\t/**\n\t\t@notice All the addresses that are members of the federation\n\t\t@dev The address should be a member to vote in transactions\n\t\t*/\n\tmapping (address => bool) public isMember;\n\n\t/**\n\t\t(bytes32) transactionId = keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tamount,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex\n\t\t\t)\n\t\t) => (\n\t\t\t(address) members => (bool) voted\n\t\t)\n\t\t@notice Votes by members by the transaction ID\n\t\t@dev the members should approve the transaction by 50% + 1\n\t\t*/\n\tmapping (bytes32 => mapping (address => bool)) public votes;\n\n\t/**\n\t\t(bytes32) transactionId => (bool) voted\n\t\t@notice Check if that transaction was already processed\n\t*/\n\tmapping(bytes32 => bool) public processed;\n\n\t/** Federator v3 variables */\n\tINFTBridge public bridgeNFT;\n\n\tmodifier onlyMember() {\n\t\trequire(isMember[_msgSender()], \"Federation: Not Federator\");\n\t\t_;\n\t}\n\n\tmodifier validRequirement(uint membersCount, uint _required) {\n\t\trequire(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n\t\t_;\n\t}\n\n\tfunction initialize(\n\t\taddress[] calldata _members,\n\t\tuint _required,\n\t\taddress _bridge,\n\t\taddress owner,\n\t\taddress _bridgeNFT\n\t) public validRequirement(_members.length, _required) initializer {\n\t\tUpgradableOwnable.initialize(owner);\n\t\trequire(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n\t\tmembers = _members;\n\t\tfor (uint i = 0; i < _members.length; i++) {\n\t\t\trequire(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n\t\t\tisMember[_members[i]] = true;\n\t\t\temit MemberAddition(_members[i]);\n\t\t}\n\t\trequired = _required;\n\t\temit RequirementChange(required);\n\t\t_setBridge(_bridge);\n\t\t_setNFTBridge(_bridgeNFT);\n\t}\n\n\t/**\n\t\t@notice Current version of the contract\n\t\t@return version in v{Number}\n\t\t*/\n\tfunction version() external pure override returns (string memory) {\n\t\treturn \"v3\";\n\t}\n\n\t/**\n\t\t@notice Sets a new bridge contract\n\t\t@dev Emits BridgeChanged event\n\t\t@param _bridge the new bridge contract address that should implement the IBridge interface\n\t\t*/\n\tfunction setBridge(address _bridge) external onlyOwner override {\n\t\t_setBridge(_bridge);\n\t}\n\n\tfunction _setBridge(address _bridge) internal {\n\t\trequire(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n\t\tbridge = IBridge(_bridge);\n\t\temit BridgeChanged(_bridge);\n\t}\n\n\t/**\n\t\t@notice Sets a new NFT bridge contract\n\t\t@dev Emits NFTBridgeChanged event\n\t\t@param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n\t\t*/\n\tfunction setNFTBridge(address _bridgeNFT) external onlyOwner override {\n\t\trequire(_bridgeNFT != NULL_ADDRESS, \"Federation: Empty NFT bridge\");\n\t\t_setNFTBridge(_bridgeNFT);\n\t}\n\n\tfunction _setNFTBridge(address _bridgeNFT) internal {\n\t\tbridgeNFT = INFTBridge(_bridgeNFT);\n\t\temit NFTBridgeChanged(_bridgeNFT);\n\t}\n\n\tfunction validateTransaction(bytes32 transactionId, bytes32 transactionIdMultichain) internal view returns(bool) {\n\t\tuint256 minimumVotes = getMinimalNumberOfVotes();\n\t\tuint256 amountVotes = 0;\n\n for (uint256 i = 0; i < members.length; i++) {\n if (votes[transactionIdMultichain][members[i]]) {\n amountVotes += 1;\n\t\t\t} else if (votes[transactionId][members[i]]) {\n amountVotes += 1;\n\t\t\t}\n\n\t\t\tif (amountVotes >= minimumVotes && amountVotes >= required) {\n\t\t\t\treturn true;\n\t\t\t}\n }\n\n\t\treturn false;\n\t}\n\n\tfunction getMinimalNumberOfVotes() internal view returns(uint256) {\n\t\treturn members.length / 2 + 1;\n\t}\n\n\tfunction isProcessed(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\n\t\treturn processed[transactionIdMultichain] || processed[transactionId];\n\t}\n\n\tfunction isVoted(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\n\t\treturn votes[transactionIdMultichain][_msgSender()] || votes[transactionId][_msgSender()];\n\t}\n\n\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\n\t\trequire(chainId == block.chainid, \"Federation: Not block.chainid\");\n\t}\n\n\t/**\n\t\t@notice Vote in a transaction, if it has enough votes it accepts the transfer\n\t\t@param originalTokenAddress The address of the token in the origin (main) chain\n\t\t@param sender The address who solicited the cross token\n\t\t@param receiver Who is going to receive the token in the opposite chain\n\t\t@param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n\t\t@param blockHash The block hash in which the transaction with the cross event occurred\n\t\t@param transactionHash The transaction in which the cross event occurred\n\t\t@param logIndex Index of the event in the logs\n\t\t@param tokenType Is the type of bridge to be used\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n\t\t*/\n\tfunction voteTransaction(\n\t\taddress originalTokenAddress,\n\t\taddress payable sender,\n\t\taddress payable receiver,\n\t\tuint256 value,\n\t\tbytes32 blockHash,\n\t\tbytes32 transactionHash,\n\t\tuint32 logIndex,\n\t\tTokenType tokenType,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n\t) external onlyMember override {\n\t\tshouldBeCurrentChainId(destinationChainId);\n\t\tbytes32 transactionId = keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex\n\t\t\t)\n\t\t);\n\n\t\tbytes32 transactionIdMultichain = getTransactionId(\n\t\t\toriginalTokenAddress,\n\t\t\tsender,\n\t\t\treceiver,\n\t\t\tvalue,\n\t\t\tblockHash,\n\t\t\ttransactionHash,\n\t\t\tlogIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n\t\t);\n\n\t\tif (isProcessed(transactionId, transactionIdMultichain))\n\t\t\treturn;\n\n\t\tif (isVoted(transactionId, transactionIdMultichain))\n\t\t\treturn;\n\n\t\tvotes[transactionIdMultichain][_msgSender()] = true;\n\t\temit Voted(\n\t\t\t_msgSender(),\n\t\t\ttransactionHash,\n\t\t\ttransactionIdMultichain,\n\t\t\toriginalTokenAddress,\n\t\t\tsender,\n\t\t\treceiver,\n\t\t\tvalue,\n\t\t\tblockHash,\n\t\t\tlogIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n\t\t);\n\n\t\tif (validateTransaction(transactionId, transactionIdMultichain)) {\n\t\t\tprocessed[transactionIdMultichain] = true;\n\n\t\t\tacceptTransfer(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex,\n\t\t\t\ttokenType,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\n\t\t\temit Executed(\n\t\t\t\t_msgSender(),\n\t\t\t\ttransactionHash,\n\t\t\t\ttransactionIdMultichain,\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\tlogIndex,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\t\t}\n\t}\n\n function acceptTransfer(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType,\n\tuint256 originChainId,\n\tuint256\tdestinationChainId\n ) internal {\n if (tokenType == TokenType.NFT) {\n require(address(bridgeNFT) != NULL_ADDRESS, \"Federation: Empty NFTBridge\");\n bridgeNFT.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex,\n\t\toriginChainId,\n\t\tdestinationChainId\n );\n } else {\n\t bridge.acceptTransfer(\n\t\toriginalTokenAddress,\n\t\tsender,\n\t\treceiver,\n\t\tvalue,\n\t\tblockHash,\n\t\ttransactionHash,\n\t\tlogIndex,\n\t\toriginChainId,\n\t\tdestinationChainId\n\t );\n\t}\n }\n\n /**\n @notice Get the amount of approved votes for that transactionId\n @param transactionId The transaction hashed from getTransactionId function\n */\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n\tfunction hasVoted(bytes32 transactionId) external view returns(bool) {\n\t\treturn votes[transactionId][_msgSender()];\n\t}\n\n\tfunction transactionWasProcessed(bytes32 transactionId) external view returns(bool) {\n\t\treturn processed[transactionId];\n\t}\n\n\t/**\n\t\t@notice Gets the hash of transaction from the following parameters encoded and keccaked\n\t\t@dev It encodes and applies keccak256 to the parameters received in the same order\n\t\t@param originalTokenAddress The address of the token in the origin (main) chain\n\t\t@param sender The address who solicited the cross token\n\t\t@param receiver Who is going to receive the token in the opposite chain\n\t\t@param amount Could be the amount or the tokenId\n\t\t@param blockHash The block hash in which the transaction with the cross event occurred\n\t\t@param transactionHash The transaction in which the cross event occurred\n\t\t@param logIndex Index of the event in the logs\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n\t\t@return The hash generated by the parameters.\n\t*/\n\tfunction getTransactionId(\n\t\taddress originalTokenAddress,\n\t\taddress sender,\n\t\taddress receiver,\n\t\tuint256 amount,\n\t\tbytes32 blockHash,\n\t\tbytes32 transactionHash,\n\t\tuint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n\t) public pure returns(bytes32) {\n\t\treturn keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tamount,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t)\n\t\t);\n\t}\n\n\tfunction addMember(address _newMember) external onlyOwner override {\n\t\trequire(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n\t\trequire(!isMember[_newMember], \"Federation: Member already exists\");\n\t\trequire(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n\t\tisMember[_newMember] = true;\n\t\tmembers.push(_newMember);\n\t\temit MemberAddition(_newMember);\n\t}\n\n\tfunction removeMember(address _oldMember) external onlyOwner override {\n\t\trequire(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n\t\trequire(isMember[_oldMember], \"Federation: Member doesn't exists\");\n\t\trequire(members.length > 1, \"Federation: Can't remove all the members\");\n\t\trequire(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n\t\tisMember[_oldMember] = false;\n\t\tfor (uint i = 0; i < members.length - 1; i++) {\n\t\t\tif (members[i] == _oldMember) {\n\t\t\t\tmembers[i] = members[members.length - 1];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tmembers.pop(); // remove an element from the end of the array.\n\t\temit MemberRemoval(_oldMember);\n\t}\n\n\t/**\n\t\t@notice Return all the current members of the federation\n\t\t@return Current members\n\t\t*/\n\tfunction getMembers() external view override returns (address[] memory) {\n\t\treturn members;\n\t}\n\n\t/**\n\t\t@notice Changes the number of required members to vote and approve an transaction\n\t\t@dev Emits the RequirementChange event\n\t\t@param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n\t\t*/\n\tfunction changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\n\t\trequire(_required >= 2, \"Federation: Requires at least 2\");\n\t\trequired = _required;\n\t\temit RequirementChange(_required);\n\t}\n\n\t/**\n\t\t@notice It emits an HeartBeat like an health check\n\t\t@dev Emits HeartBeat event\n\t\t*/\n\tfunction emitHeartbeat(\n\t\tstring calldata fedVersion,\n\t\tuint256[] calldata fedChainsIds,\n\t\tuint256[] calldata fedChainsBlocks,\n\t\tstring[] calldata fedChainsInfo\n\t) external onlyMember override {\n\t\trequire(fedChainsIds.length == fedChainsBlocks.length &&\n\t\t\tfedChainsIds.length == fedChainsInfo.length, \"Federation: Length missmatch\");\n\t\temit HeartBeat(\n\t\t\t_msgSender(),\n\t\t\tblock.chainid,\n\t\t\tblock.number,\n\t\t\tfedVersion,\n\t\t\tfedChainsIds,\n\t\t\tfedChainsBlocks,\n\t\t\tfedChainsInfo\n\t\t);\n\t}\n}\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface IFederation {\n enum TokenType{ COIN, NFT }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure returns (string memory);\n\n /**\n @notice Sets a new bridge contract\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external;\n\n /**\n @notice Sets a new NFT bridge contract\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external;\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType,\n\t uint256 originChainId,\n\t uint256\tdestinationChainId\n ) external;\n\n /**\n @notice Add a new member to the federation\n @param _newMember address of the new member\n */\n function addMember(address _newMember) external;\n\n /**\n @notice Remove a member of the federation\n @param _oldMember address of the member to be removed from federation\n */\n function removeMember(address _oldMember) external;\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view returns (address[] memory);\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external;\n\n /**\n @notice It emmits an HeartBeat like an healthy check\n */\n function emitHeartbeat(\n string calldata federatorVersion,\n\t\tuint256[] calldata fedChainsIds,\n\t\tuint256[] calldata fedChainsBlocks,\n\t\tstring[] calldata fedChainsInfo\n ) external;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event NFTBridgeChanged(address bridgeNFT);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex,\n uint256 originChainId,\n\t\tuint256\tdestinationChainId\n );\n event HeartBeat(\n address indexed sender,\n uint256 currentChainId,\n uint256 currentBlock,\n string fedVersion,\n uint256[] fedChainsIds,\n\t\tuint256[] fedChainsBlocks,\n\t\tstring[] fedChainsInfo\n );\n\n}\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract MinterRole is Context {\n using Roles for Roles.Role;\n\n event MinterAdded(address indexed account);\n event MinterRemoved(address indexed account);\n\n Roles.Role private _minters;\n\n constructor () {\n _addMinter(_msgSender());\n }\n\n modifier onlyMinter() {\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\n _;\n }\n\n function isMinter(address account) public view returns (bool) {\n return _minters.has(account);\n }\n\n function addMinter(address account) public onlyMinter {\n _addMinter(account);\n }\n\n function renounceMinter() public {\n _removeMinter(_msgSender());\n }\n\n function _addMinter(address account) internal {\n _minters.add(account);\n emit MinterAdded(account);\n }\n\n function _removeMinter(address account) internal {\n _minters.remove(account);\n emit MinterRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20Mintable}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() override public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) override public view returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) override public returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) override public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) override public returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal {\n require(sender != address(0), \"ERC20: transfer from zero address\");\n require(recipient != address(0), \"ERC20: transfer to zero address\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: mint to zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: burn from zero address\");\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n *\n * This is internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal {\n require(owner != address(0), \"ERC20: approve from zero address\");\n require(spender != address(0), \"ERC20: approve to zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\n * from the caller's allowance.\n *\n * See {_burn} and {_approve}.\n */\n function _burnFrom(address account, uint256 amount) internal {\n _burn(account, amount);\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\n }\n}\n"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\nimport \"../interface/IERC677Receiver.sol\";\n\ncontract mockERC677Receiver is IERC677Receiver {\n event Success(address _sender, uint _value, bytes _data);\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\n emit Success(_sender, _value, _data);\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Optional functions from the ERC20 standard.\n */\nabstract contract ERC20Detailed is IERC20 {\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\n * these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\n _name = aName;\n _symbol = aSymbol;\n _decimals = theDecimals;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./Proxy.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n *\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\n * {TransparentUpgradeableProxy}.\n */\ncontract UpgradeableProxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _setImplementation(_logic);\n if(_data.length > 0) {\n Address.functionDelegateCall(_logic, _data);\n }\n }\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n bytes32 slot = _IMPLEMENTATION_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n impl := sload(slot)\n }\n }\n\n /**\n * @dev Upgrades the proxy to a new implementation.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal virtual {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\n\n bytes32 slot = _IMPLEMENTATION_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newImplementation)\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./UpgradeableProxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _setAdmin(admin_);\n }\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _admin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _admin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\n emit AdminChanged(_admin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external virtual ifAdmin {\n _upgradeTo(newImplementation);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\n _upgradeTo(newImplementation);\n Address.functionDelegateCall(newImplementation, data);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address adm) {\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n adm := sload(slot)\n }\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n bytes32 slot = _ADMIN_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newAdmin)\n }\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../ownership/Ownable.sol\";\nimport \"./TransparentUpgradeableProxy.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract AllowTokensV0 is Ownable {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n\n mapping (address => bool) public allowedTokens;\n bool private validateAllowedTokens;\n uint256 private maxTokensAllowed;\n uint256 private minTokensAllowed;\n uint256 public dailyLimit;\n\n event AllowedTokenAdded(address indexed _tokenAddress);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event AllowedTokenValidation(bool _enabled);\n event MaxTokensAllowedChanged(uint256 _maxTokens);\n event MinTokensAllowedChanged(uint256 _minTokens);\n event DailyLimitChanged(uint256 dailyLimit);\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\n _;\n }\n\n constructor(address _manager) {\n transferOwnership(_manager);\n validateAllowedTokens = true;\n maxTokensAllowed = 10000 ether;\n minTokensAllowed = 1 ether;\n dailyLimit = 100000 ether;\n }\n\n function isValidatingAllowedTokens() external view returns(bool) {\n return validateAllowedTokens;\n }\n\n function getMaxTokensAllowed() external view returns(uint256) {\n return maxTokensAllowed;\n }\n\n function getMinTokensAllowed() external view returns(uint256) {\n return minTokensAllowed;\n }\n\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\n return allowedTokens[token];\n }\n\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\n if (validateAllowedTokens) {\n return allowedTokenExist(token);\n }\n return true;\n }\n\n function addAllowedToken(address token) external onlyOwner {\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\n allowedTokens[token] = true;\n emit AllowedTokenAdded(token);\n }\n\n function removeAllowedToken(address token) external onlyOwner {\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\n allowedTokens[token] = false;\n emit AllowedTokenRemoved(token);\n }\n\n function enableAllowedTokensValidation() external onlyOwner {\n validateAllowedTokens = true;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function disableAllowedTokensValidation() external onlyOwner {\n // Before disabling Allowed Tokens Validations some kind of contract validation system\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\n validateAllowedTokens = false;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\n maxTokensAllowed = maxTokens;\n emit MaxTokensAllowedChanged(maxTokensAllowed);\n }\n\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\n minTokensAllowed = minTokens;\n emit MinTokensAllowedChanged(minTokensAllowed);\n }\n\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\n dailyLimit = _dailyLimit;\n emit DailyLimitChanged(_dailyLimit);\n }\n\n // solium-disable-next-line max-len\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\n if(amount > maxTokensAllowed)\n return false;\n if(amount < minTokensAllowed)\n return false;\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\n return false;\n if(!isSideToken && !isTokenAllowed(tokenToUse))\n return false;\n return true;\n }\n\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\n uint maxWithrow = dailyLimit - spentToday;\n if (dailyLimit < spentToday)\n return 0;\n if(maxWithrow > maxTokensAllowed)\n maxWithrow = maxTokensAllowed;\n return maxWithrow;\n }\n\n}\n"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\n\ncontract BridgeProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract FederationProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract MainToken is ERC20Detailed, ERC20 {\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\n ERC20Detailed(name, symbol, decimals)\n {\n _mint(msg.sender, totalSupply);\n }\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\n bool result = transfer(_to, _value);\n if (!result) return false;\n\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\n receiver.tokenFallback(msg.sender, _value, _data);\n\n // IMPORTANT: the ERC-677 specification does not say\n // anything about the use of the receiver contract's\n // tokenFallback method return value. Given\n // its return type matches with this method's return\n // type, returning it could be a possibility.\n // We here take the more conservative approach and\n // ignore the return value, returning true\n // to signal a succesful transfer despite tokenFallback's\n // return value -- fact being tokens are transferred\n // in any case.\n return true;\n }\n}\n\ninterface ERC677TransferReceiver {\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\n}"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract AlternativeERC20Detailed is ERC20 {\n string private _name;\n bytes32 private _symbol;\n uint256 private _decimals;\n\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\n {\n _name = aName;\n _symbol = aSymbol;\n _decimals = someDecimals;\n _mint(msg.sender, aTotalSupply);\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (bytes32) {\n return _symbol;\n }\n\n function decimals() public view returns (uint256) {\n return _decimals;\n }\n}"
+ },
+ "contracts/test/nftbridge/NFTERC721TestToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\n\ncontract NFTERC721TestToken is ERC721 {\n\n string private _contractURI;\n\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\n\n function safeMint(address to, uint256 tokenId) public {\n _safeMint(to, tokenId);\n }\n\n function setBaseURI(string memory baseURI) public {\n _setBaseURI(baseURI);\n }\n\n function setContractURI(string memory contractURI_) public {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n function setTokenURI(uint256 tokenId, string memory _tokenURI) public {\n _setTokenURI(tokenId, _tokenURI);\n }\n\n}\n"
+ },
+ "contracts/nftbridge/SideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./ISideNFTToken.sol\";\nimport \"../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\n\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\n address public minter;\n string private _contractURI;\n\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\n require(_minter != address(0), \"SideToken: Empty Minter\");\n minter = _minter;\n _setBaseURI(_baseURI);\n _setContractURI(contractURI_);\n }\n\n function _setContractURI(string memory contractURI_) internal {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(address account, uint256 tokenId) external onlyMinter override {\n _mint(account, tokenId);\n }\n}"
+ },
+ "contracts/nftbridge/SideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"./SideNFTToken.sol\";\n\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external onlyPrimary override returns(address) {\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\n return sideTokenAddress;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() {\n _registerInterface(\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\n );\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Receiver.sol\";\n\n /**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers. \n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Burnable is ERC1155 {\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n}\n"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../lib/LibUtils.sol\";\n\ncontract LibUtilsHarness {\n\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\n return LibUtils.decimalsToGranularity(decimals);\n }\n\n function getDecimals(address tokenToUse) external view returns (uint8) {\n return LibUtils.getDecimals(tokenToUse);\n }\n\n function getGranularity(address tokenToUse) external view returns (uint256) {\n return LibUtils.getGranularity(tokenToUse);\n }\n\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\n return LibUtils.bytesToAddress(bys);\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) external pure returns (uint128) {\n return LibUtils.toUint128(_bytes, _start);\n }\n\n}\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/solcInputs/bd60cbce915f67c6e3ddca09e6c29f99.json b/bridge/deployments/rsktestnet/solcInputs/bd60cbce915f67c6e3ddca09e6c29f99.json
new file mode 100644
index 000000000..75948d241
--- /dev/null
+++ b/bridge/deployments/rsktestnet/solcInputs/bd60cbce915f67c6e3ddca09e6c29f99.json
@@ -0,0 +1,297 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/math/SafeMath.sol\";\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\n\nimport \"../interface/IAllowTokens.sol\";\n\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n uint256 constant public MAX_TYPES = 250;\n mapping (address => TokenInfo) public allowedTokens;\n mapping (uint256 => Limits) public typeLimits;\n uint256 public smallAmountConfirmations;\n uint256 public mediumAmountConfirmations;\n uint256 public largeAmountConfirmations;\n string[] public typeDescriptions;\n\n event SetToken(address indexed _tokenAddress, uint256 _typeId);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\n event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\n event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\n event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\n\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\n _;\n }\n\n function initialize(\n address _manager,\n address _primary,\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations,\n TypeInfo[] memory typesInfo) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradableSecondary.__Secondary_init(_primary);\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n for(uint i = 0; i < typesInfo.length; i = i + 1) {\n _addTokenType(typesInfo[i].description, typesInfo[i].limits);\n }\n }\n\n function version() override external pure returns (string memory) {\n return \"v1\";\n }\n\n function getInfoAndLimits(address token) override public view\n returns (TokenInfo memory info, Limits memory limit) {\n info = allowedTokens[token];\n limit = typeLimits[info.typeId];\n return (info, limit);\n }\n function calcMaxWithdraw(address token) override public view returns (uint256 maxWithdraw) {\n (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\n return _calcMaxWithdraw(info, limits);\n }\n\n function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n info.spentToday = 0;\n }\n if (limits.daily <= info.spentToday)\n return 0;\n maxWithdraw = limits.daily - info.spentToday;\n if(maxWithdraw > limits.max)\n maxWithdraw = limits.max;\n return maxWithdraw;\n }\n\n // solium-disable-next-line max-len\n function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\n (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\n require(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\n require(amount >= limit.min, \"AllowTokens: Lower than limit\");\n\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n // solium-disable-next-line security/no-block-members\n info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n info.spentToday = 0;\n }\n uint maxWithdraw = _calcMaxWithdraw(info, limit);\n require(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\n info.spentToday = info.spentToday.add(amount);\n allowedTokens[token] = info;\n\n emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\n }\n\n function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\n require(bytes(description).length > 0, \"AllowTokens: Empty description\");\n len = typeDescriptions.length;\n require(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\n typeDescriptions.push(description);\n _setTypeLimits(len, limits);\n emit TokenTypeAdded(len, description);\n return len;\n }\n\n function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\n return _addTokenType(description, limits);\n }\n\n function _setTypeLimits(uint256 typeId, Limits memory limits) private {\n require(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\n require(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\n require(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\n require(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\n require(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\n typeLimits[typeId] = limits;\n emit TypeLimitsChanged(typeId, limits);\n }\n\n function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\n _setTypeLimits(typeId, limits);\n }\n\n function getTypesLimits() external view override returns(Limits[] memory limits) {\n limits = new Limits[](typeDescriptions.length);\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\n limits[i] = typeLimits[i];\n }\n return limits;\n }\n\n function getTypeDescriptionsLength() external view override returns(uint256) {\n return typeDescriptions.length;\n }\n\n function getTypeDescriptions() external view override returns(string[] memory descriptions) {\n descriptions = new string[](typeDescriptions.length);\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\n descriptions[i] = typeDescriptions[i];\n }\n return descriptions;\n }\n\n function isTokenAllowed(address token) public view notNull(token) override returns (bool) {\n return allowedTokens[token].allowed;\n }\n\n function setToken(address token, uint256 typeId) override public notNull(token) {\n require(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n require(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\n TokenInfo memory info = allowedTokens[token];\n info.allowed = true;\n info.typeId = typeId;\n allowedTokens[token] = info;\n emit SetToken(token, typeId);\n }\n\n function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\n require(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\n for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\n setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\n }\n }\n\n function removeAllowedToken(address token) external notNull(token) onlyOwner {\n TokenInfo memory info = allowedTokens[token];\n require(info.allowed, \"AllowTokens: Not Allowed\");\n info.allowed = false;\n allowedTokens[token] = info;\n emit AllowedTokenRemoved(token);\n }\n\n function setConfirmations(\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations) external onlyOwner {\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n }\n\n function _setConfirmations(\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations) private {\n require(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\n require(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\n smallAmountConfirmations = _smallAmountConfirmations;\n mediumAmountConfirmations = _mediumAmountConfirmations;\n largeAmountConfirmations = _largeAmountConfirmations;\n emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n }\n\n function getConfirmations() external view override\n returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount) {\n return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\n }\n\n}\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @title Initializable\n *\n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(initializing || !initialized, \"Contract instance is already initialized\");\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\n * the owner.\n */\ncontract UpgradableOwnable is Initializable, Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function initialize(address sender) public initializer {\n _owner = sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * > Note: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\ncontract UpgradableSecondary is Initializable, Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n function __Secondary_init(address sender) public initializer {\n _primary = sender;\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(recipient);\n }\n\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IAllowTokens {\n\n struct Limits {\n uint256 min;\n uint256 max;\n uint256 daily;\n uint256 mediumAmount;\n uint256 largeAmount;\n }\n\n struct TokenInfo {\n bool allowed;\n uint256 typeId;\n uint256 spentToday;\n uint256 lastDay;\n }\n\n struct TypeInfo {\n string description;\n Limits limits;\n }\n\n struct TokensAndType {\n address token;\n uint256 typeId;\n }\n\n function version() external pure returns (string memory);\n\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\n\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\n\n function getTypesLimits() external view returns(Limits[] memory limits);\n\n function getTypeDescriptionsLength() external view returns(uint256);\n\n function getTypeDescriptions() external view returns(string[] memory descriptions);\n\n function setToken(address token, uint256 typeId) external;\n\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\n\n function isTokenAllowed(address token) external view returns (bool);\n\n function updateTokenTransfer(address token, uint256 amount) external;\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n\n function _msgSender() internal view returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
+ },
+ "contracts/nftbridge/NFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC721/IERC721.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Metadata.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Enumerable.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Receiver.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./INFTBridge.sol\";\nimport \"./ISideNFTToken.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract NFTBridge is\n Initializable,\n INFTBridge,\n UpgradablePausable,\n UpgradableOwnable,\n ReentrancyGuard,\n IERC721Receiver {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address internal constant NULL_ADDRESS = address(0);\n bytes32 internal constant NULL_HASH = bytes32(0);\n IERC1820Registry internal constant ERC1820 =\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address payable internal federation;\n uint256 internal fixedFee;\n string public symbolPrefix;\n\n mapping(address => address) public sideTokenAddressByOriginalTokenAddress;\n mapping(address => address) public originalTokenAddressBySideTokenAddress;\n mapping(address => bool) public isAddressFromCrossedOriginalToken; // address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideNFTTokenFactory public sideTokenFactory;\n bool public isUpgrading;\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\n event Upgrading(bool _isUpgrading);\n\n function initialize(\n address _manager,\n address payable _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\n federation = _federation;\n ERC1820.setInterfaceImplementer(\n address(this),\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\n address(this)\n );\n }\n\n function version() external pure override returns (string memory) {\n return \"v1\";\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _tokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external override whenNotPaused nonReentrant {\n require(_msgSender() == federation, \"NFTBridge: Not Federation\");\n require(\n isAddressFromCrossedOriginalToken[_tokenAddress] ||\n sideTokenAddressByOriginalTokenAddress[_tokenAddress] != NULL_ADDRESS,\n \"NFTBridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"NFTBridge: Null To\");\n require(_from != NULL_ADDRESS, \"NFTBridge: Null From\");\n require(_blockHash != NULL_HASH, \"NFTBridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"NFTBridge: Null TxHash\");\n require(\n transactionDataHashes[_transactionHash] == bytes32(0),\n \"NFTBridge: Already accepted\"\n );\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\n require(!claimed[_transactionDataHash], \"NFTBridge: Already claimed\");\n\n transactionDataHashes[_transactionHash] = _transactionDataHash;\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\n// senderAddresses[_transactionHash] = _from;\n\n emit AcceptedNFTCrossTransfer(\n _transactionHash,\n _tokenAddress,\n _to,\n _from,\n _tokenId,\n _blockHash,\n _logIndex\n );\n }\n\n function createSideNFTToken(\n address _originalTokenAddress,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName,\n string calldata _baseURI,\n string calldata _contractURI\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"NFTBridge: Null original token address\");\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[_originalTokenAddress];\n require(sideTokenAddress == NULL_ADDRESS, \"NFTBridge: Side token already exists\");\n string memory sideTokenSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideTokenAddress = sideTokenFactory.createSideNFTToken(_originalTokenName, sideTokenSymbol, _baseURI, _contractURI);\n\n sideTokenAddressByOriginalTokenAddress[_originalTokenAddress] = sideTokenAddress;\n originalTokenAddressBySideTokenAddress[sideTokenAddress] = _originalTokenAddress;\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, sideTokenSymbol);\n }\n\n function claim(NFTClaimData calldata _claimData) external override {\n _claim(_claimData, _claimData.to);\n }\n\n function claimFallback(NFTClaimData calldata _claimData) external override {\n require(_msgSender() == _claimData.from, \"NFTBridge: invalid sender\");\n _claim(_claimData, _msgSender());\n }\n\n function _claim(\n NFTClaimData calldata _claimData,\n address payable _receiver\n ) internal {\n address tokenAddress = _claimData.tokenAddress;\n uint256 tokenId = _claimData.tokenId;\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.from,\n tokenId,\n tokenAddress,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\n \"NFTBridge: Wrong txDataHash\"\n );\n require(!claimed[transactionDataHash], \"NFTBridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n bool isClaimBeingRequestedInMainChain = isAddressFromCrossedOriginalToken[tokenAddress];\n if (isClaimBeingRequestedInMainChain) {\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\n } else {\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[tokenAddress];\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\n }\n\n emit ClaimedNFTToken(\n _claimData.transactionHash,\n tokenAddress,\n _claimData.to,\n _claimData.from,\n _claimData.tokenId,\n _claimData.blockHash,\n _claimData.logIndex,\n _receiver\n );\n }\n\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\"creator()\"));\n if (success) {\n return abi.decode(data, (address));\n }\n\n return IERC721(tokenAddress).ownerOf(tokenId);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId\n ) public payable override {\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\n\n address payable sender = _msgSender();\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\n\n crossTokens(tokenAddress, to, tokenCreator, \"\", tokenId);\n\n if (fixedFee > 0) {\n require(msg.value >= fixedFee, \"NFTBridge: value is smaller than fixed fee\");\n\n // Send the payment to the MultiSig of the Federation\n federation.transfer(fixedFee);\n if (msg.value > fixedFee) { // refund of unused value\n sender.transfer(msg.value.sub(fixedFee));\n }\n }\n }\n\n function crossTokens(\n address tokenAddress,\n address to,\n address tokenCreator,\n bytes memory userData,\n uint256 tokenId\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\n isAddressFromCrossedOriginalToken[tokenAddress] = true;\n\n IERC721Enumerable enumerable = IERC721Enumerable(tokenAddress);\n IERC721Metadata metadataIERC = IERC721Metadata(tokenAddress);\n string memory tokenURI = metadataIERC.tokenURI(tokenId);\n\n address originalTokenAddress = tokenAddress;\n if (originalTokenAddressBySideTokenAddress[tokenAddress] != NULL_ADDRESS) {\n originalTokenAddress = originalTokenAddressBySideTokenAddress[tokenAddress];\n ERC721Burnable(tokenAddress).burn(tokenId);\n }\n\n emit Cross(\n originalTokenAddress,\n _msgSender(),\n to,\n tokenCreator,\n userData,\n enumerable.totalSupply(),\n tokenId,\n tokenURI\n );\n }\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) public pure override returns (bytes32) {\n return keccak256(\n abi.encodePacked(\n _blockHash,\n _transactionHash,\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _logIndex\n )\n );\n }\n\n function setFixedFee(uint256 amount) external onlyOwner {\n fixedFee = amount;\n emit FixedFeeNFTChanged(fixedFee);\n }\n\n function getFixedFee() external view override returns (uint256) {\n return fixedFee;\n }\n\n function changeFederation(address payable newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"NFTBridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"NFTBridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns (address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\n require(\n newSideNFTTokenFactory != NULL_ADDRESS,\n \"NFTBridge: empty SideTokenFactory\"\n );\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionDataHashes[transactionHash]];\n }\n\n /**\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\n/**\n * @title Helps contracts guard against reentrancy attacks.\n * @author Remco Bloemen , Eenae \n * @dev If you mark a function `nonReentrant`, you should also\n * mark it `external`.\n */\ncontract ReentrancyGuard is Initializable {\n /// @dev counter to allow mutex lock with only one SSTORE operation\n uint256 private _guardCounter;\n\n function initialize() public initializer {\n // The counter starts at one to prevent changing it from zero to a non-zero\n // value, which is a more expensive operation.\n _guardCounter = 1;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _guardCounter += 1;\n uint256 localCounter = _guardCounter;\n _;\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\n }\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\nimport \"../access/roles/UpgradablePauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n function __Pausable_init(address sender) public initializer {\n UpgradablePauserRole.__PauserRol_init(sender);\n\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as `account`'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `_account`.\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `_implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\n\n /**\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `_account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {ERC20Detailed}.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeERC20: low-level call failed\");\n\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n */\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./ERC721.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721Burnable is Context, ERC721 {\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n _burn(tokenId);\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\nlibrary LibEIP712 {\n\n // Hash of the EIP712 Domain Separator Schema\n // keccak256(abi.encodePacked(\n // \"EIP712Domain(\",\n // \"string name,\",\n // \"string version,\",\n // \"uint256 chainId,\",\n // \"address verifyingContract\",\n // \")\"\n // ))\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n /// @dev Calculates a EIP712 domain separator.\n /// @param name The EIP712 domain name.\n /// @param version The EIP712 domain version.\n /// @param verifyingContract The EIP712 verifying contract.\n /// @return result EIP712 domain separator.\n function hashEIP712Domain(\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n // keccak256(bytes(name)),\n // keccak256(bytes(version)),\n // chainId,\n // uint256(verifyingContract)\n // ))\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Calculate hashes of dynamic data\n let nameHash := keccak256(add(name, 32), mload(name))\n let versionHash := keccak256(add(version, 32), mload(version))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n // Store params in memory\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), nameHash)\n mstore(add(memPtr, 64), versionHash)\n mstore(add(memPtr, 96), chainId)\n mstore(add(memPtr, 128), verifyingContract)\n\n // Compute hash\n result := keccak256(memPtr, 160)\n }\n return result;\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\n /// with getDomainHash().\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to the given EIP712 Domain.\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n internal\n pure\n returns (bytes32 result)\n {\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct\n // ));\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nlibrary LibUtils {\n\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\n return uint256(10)**(18-decimals);\n }\n\n function getDecimals(address tokenToUse) internal view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"LibUtils: No decimals\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n return uint8(abi.decode(data, (uint256)));\n }\n\n function getGranularity(address tokenToUse) internal view returns (uint256) {\n //support granularity if ERC777\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\n require(success, \"LibUtils: No granularity\");\n\n return abi.decode(data, (uint256));\n }\n\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n addr := mload(add(bys,20))\n }\n }\n\n}\n"
+ },
+ "contracts/nftbridge/INFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface INFTBridge {\n struct NFTClaimData {\n address payable to;\n address from;\n uint256 tokenId;\n address tokenAddress;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFixedFee() external view returns (uint256);\n\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId\n ) external payable;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\n */\n function claim(NFTClaimData calldata _claimData) external;\n\n function claimFallback(NFTClaimData calldata _claimData) external;\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns (bytes32);\n\n event Cross(\n address indexed _originalTokenAddress,\n address indexed _from,\n address indexed _to,\n address _tokenCreator,\n bytes _userData,\n uint256 _totalSupply,\n uint256 _tokenId,\n string _tokenURI\n );\n event NewSideNFTToken(\n address indexed _newSideNFTTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol\n );\n event AcceptedNFTCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FixedFeeNFTChanged(uint256 _amount);\n event ClaimedNFTToken(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _receiver\n );\n}\n"
+ },
+ "contracts/nftbridge/ISideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideNFTToken {\n function mint(address account, uint256 tokenId) external;\n}"
+ },
+ "contracts/nftbridge/ISideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideNFTTokenFactory {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external returns(address);\n\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IWrapped {\n function balanceOf(address) external returns(uint);\n\n function deposit() external payable;\n\n function withdraw(uint wad) external;\n\n function totalSupply() external view returns (uint);\n\n function approve(address guy, uint wad) external returns (bool);\n\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad)\n external\n returns (bool);\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../Initializable.sol\";\n\nimport \"../../../GSN/Context.sol\";\nimport \"../../../access/Roles.sol\";\n\ncontract UpgradablePauserRole is Initializable, Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n function __PauserRol_init(address sender) public initializer {\n if (!isPauser(sender)) {\n _addPauser(sender);\n }\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @title Roles\n * @dev Library for managing addresses assigned to a Role.\n */\nlibrary Roles {\n struct Role {\n mapping (address => bool) bearer;\n }\n\n /**\n * @dev Give an account access to this role.\n */\n function add(Role storage role, address account) internal {\n require(!has(role, account), \"Roles: account already has role\");\n role.bearer[account] = true;\n }\n\n /**\n * @dev Remove an account's access to this role.\n */\n function remove(Role storage role, address account) internal {\n require(has(role, account), \"Roles: account doesn't have role\");\n role.bearer[account] = false;\n }\n\n /**\n * @dev Check if an account has this role.\n * @return bool\n */\n function has(Role storage role, address account) internal view returns (bool) {\n require(account != address(0), \"Roles: account is the zero address\");\n return role.bearer[account];\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _tokenOwners.contains(tokenId);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(tokenId);\n\n emit Transfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n}\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract WRBTC is IWrapped {\n string public name = \"Wrapped RBTC\";\n string public symbol = \"WRBTC\";\n uint8 public decimals = 18;\n\n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n event Deposit(address indexed dst, uint wad);\n event Withdrawal(address indexed src, uint wad);\n\n mapping (address => uint) override public balanceOf;\n mapping (address => mapping (address => uint)) public allowance;\n\n receive () external payable {\n deposit();\n }\n function deposit() override public payable {\n balanceOf[msg.sender] += msg.value;\n emit Deposit(msg.sender, msg.value);\n }\n function withdraw(uint wad) override public {\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\n balanceOf[msg.sender] -= wad;\n msg.sender.transfer(wad);\n emit Withdrawal(msg.sender, wad);\n }\n\n function totalSupply() override public view returns (uint) {\n return address(this).balance;\n }\n\n function approve(address guy, uint wad) override public returns (bool) {\n allowance[msg.sender][guy] = wad;\n emit Approval(msg.sender, guy, wad);\n return true;\n }\n\n function transfer(address dst, uint wad) override public returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad)\n override public\n returns (bool)\n {\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\n\n if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\n allowance[src][msg.sender] -= wad;\n }\n\n balanceOf[src] -= wad;\n balanceOf[dst] += wad;\n\n emit Transfer(src, dst, wad);\n\n return true;\n }\n}"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant internal NULL_ADDRESS = address(0);\n bytes32 constant internal NULL_HASH = bytes32(0);\n IERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address internal federation;\n uint256 internal feePercentage;\n string public symbolPrefix;\n // replaces uint256 internal _depprecatedLastDay;\n bytes32 public domainSeparator;\n uint256 internal _deprecatedSpentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n // Percentage with up to 2 decimals\n uint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\n //Bridge_v3 variables\n bytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\n IWrapped public wrappedCurrency;\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n // keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\n mapping(address => uint) public nonces;\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool _isUpgrading);\n event WrappedCurrencyChanged(address _wrappedCurrency);\n\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n federation = _federation;\n //keccak256(\"ERC777TokensRecipient\")\n ERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n initDomainSeparator();\n }\n\n receive () external payable {\n // The fallback function is needed to use WRBTC\n require(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n }\n\n function version() override external pure returns (string memory) {\n return \"v3\";\n }\n\n function initDomainSeparator() public {\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n domainSeparator = LibEIP712.hashEIP712Domain(\n \"RSK Token Bridge\",\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"Bridge: Not Federation\");\n require(knownTokens[_originalTokenAddress] ||\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\n \"Bridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"Bridge: Null To\");\n require(_amount > 0, \"Bridge: Amount 0\");\n require(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _amount,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed also has the previously processed using the older bridge version\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n require(!claimed[_transactionDataHash], \"Bridge: Already claimed\");\n\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\n senderAddresses[_transactionHash] = _from;\n\n emit AcceptedCrossTransfer(\n _transactionHash,\n _originalTokenAddress,\n _to,\n _from,\n _amount,\n _blockHash,\n _logIndex\n );\n }\n\n\n function createSideToken(\n uint256 _typeId,\n address _originalTokenAddress,\n uint8 _originalTokenDecimals,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n address sideToken = mappedTokens[_originalTokenAddress];\n require(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\n\n mappedTokens[_originalTokenAddress] = sideToken;\n originalTokens[sideToken] = _originalTokenAddress;\n allowTokens.setToken(sideToken, _typeId);\n\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\n }\n\n function claim(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function claimFallback(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n receivedAmount = _claim(\n _claimData,\n _msgSender(),\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function getDigest(\n ClaimData memory _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline\n ) internal returns (bytes32) {\n return LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n CLAIM_TYPEHASH,\n _claimData.to,\n _claimData.amount,\n _claimData.transactionHash,\n _relayer,\n _fee,\n nonces[_claimData.to]++,\n _deadline\n )\n )\n );\n }\n\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external override returns (uint256 receivedAmount) {\n require(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\n\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claim(\n ClaimData calldata _claimData,\n address payable _reciever,\n address payable _relayer,\n uint256 _fee\n ) internal nonReentrant returns (uint256 receivedAmount) {\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n require(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.amount,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n require(!claimed[transactionDataHash], \"Bridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (knownTokens[originalTokenAddress]) {\n receivedAmount =_claimCrossBackToToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n } else {\n receivedAmount =_claimCrossToSideToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n }\n emit Claimed(\n _claimData.transactionHash,\n originalTokenAddress,\n _claimData.to,\n senderAddresses[_claimData.transactionHash],\n _claimData.amount,\n _claimData.blockHash,\n _claimData.logIndex,\n _reciever,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claimCrossToSideToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n address sideToken = mappedTokens[_originalTokenAddress];\n uint256 granularity = IERC777(sideToken).granularity();\n uint256 formattedAmount = _amount.mul(granularity);\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n ISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n if(_fee > 0) {\n ISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n }\n return receivedAmount;\n }\n\n function _claimCrossBackToToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n //As side tokens are ERC777 they will always have 18 decimals\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n if(address(wrappedCurrency) == _originalTokenAddress) {\n wrappedCurrency.withdraw(formattedAmount);\n _receiver.transfer(receivedAmount);\n if(_fee > 0) {\n _relayer.transfer(_fee);\n }\n } else {\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n if(_fee > 0) {\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n }\n }\n return receivedAmount;\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\n address sender = _msgSender();\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, to, amount, \"\");\n }\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) override external payable {\n address sender = _msgSender();\n require(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n wrappedCurrency.deposit{ value: msg.value }();\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \"\");\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external override(IBridge, IERC777Recipient){\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to this address\");\n address tokenToUse = _msgSender();\n require(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n require(userData.length != 0 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\n crossTokens(tokenToUse, from, receiver, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\n internal whenNotUpgrading whenNotPaused nonReentrant {\n knownTokens[tokenToUse] = true;\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n uint256 amountMinusFees = amount.sub(fee);\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n // We consider the amount before fees converted to 18 decimals to check the limits\n // updateTokenTransfer revert if token not allowed\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n address originalTokenAddress = tokenToUse;\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\n //Side Token Crossing\n originalTokenAddress = originalTokens[tokenToUse];\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\n uint256 modulo = amountMinusFees.mod(granularity);\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n }\n\n emit Cross(\n originalTokenAddress,\n from,\n to,\n amountMinusFees,\n userData\n );\n\n if (fee > 0) {\n //Send the payment to the MultiSig of the Federation\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n }\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n )\n public pure override returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n }\n\n function setFeePercentage(uint amount) external onlyOwner {\n require(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() external view override returns(uint) {\n return feePercentage;\n }\n\n function changeFederation(address newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n require(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n wrappedCurrency = IWrapped(_wrappedCurrency);\n emit WrappedCurrencyChanged(_wrappedCurrency);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionsDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionsDataHashes[transactionHash]];\n }\n\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an `IERC777` token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See `IERC1820Registry` and\n * `ERC1820Implementer`.\n */\ninterface IERC777 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See `operatorSend` and `operatorBurn`.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor`.\n *\n * Emits an `AuthorizedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor` and `defaultOperators`.\n *\n * Emits a `RevokedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if `authorizeOperator` was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * `revokeOperator`, in which case `isOperatorFor` will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n\n function decimals() external returns (uint8);\n\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n}\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IBridge {\n\n struct ClaimData {\n address payable to;\n uint256 amount;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) external payable;\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n */\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external returns (uint256 receivedAmount);\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns(bytes32);\n\n event Cross(\n address indexed _tokenAddress,\n address indexed _from,\n address indexed _to,\n uint256 _amount,\n bytes _userData\n );\n event NewSideToken(\n address indexed _newSideTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 _granularity\n );\n event AcceptedCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FeePercentageChanged(uint256 _amount);\n event Claimed(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _reciever,\n address _relayer,\n uint256 _fee\n );\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideToken {\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideTokenFactory {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\n\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../SideToken/SideToken.sol\";\n\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\n external onlyPrimary override returns(address) {\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\n emit SideTokenCreated(sideToken, symbol, granularity);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\nabstract contract Secondary is Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n constructor () {\n _primary = _msgSender();\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(_primary);\n }\n}\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\nimport \"../interface/IERC677Receiver.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../lib/LibEIP712.sol\";\n\ncontract SideToken is ISideToken, ERC777 {\n using Address for address;\n using SafeMath for uint256;\n\n address public minter;\n uint256 private _granularity;\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n bytes32 public domainSeparator;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n // ERC677 Transfer Event\n event Transfer(address,address,uint256,bytes);\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\n minter = _minterAddr;\n _granularity = _newGranularity;\n\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n domainSeparator = LibEIP712.hashEIP712Domain(\n name(),\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter override\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n /**\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\n * @param recipient The address to transfer to.\n * @param amount The amount to be transferred.\n * @param data The extra data to be passed to the receiving contract.\n */\n function transferAndCall(address recipient, uint amount, bytes calldata data)\n external returns (bool success)\n {\n address from = _msgSender();\n\n _send(from, from, recipient, amount, data, \"\", false);\n emit Transfer(from, recipient, amount, data);\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\n return true;\n }\n\n function granularity() public view override returns (uint256) {\n return _granularity;\n }\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\n bytes32 digest = LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../../token/ERC20/IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\n // See https://github.com/ethereum/solidity/issues/4024.\n\n // keccak256(\"ERC777TokensSender\")\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\n\n // keccak256(\"ERC777TokensRecipient\")\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping (address => mapping (address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(\n string memory aName,\n string memory aSymbol,\n address[] memory theDefaultOperators\n ) {\n _name = aName;\n _symbol = aSymbol;\n\n _defaultOperatorsArray = theDefaultOperators;\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\n _defaultOperators[_defaultOperatorsArray[i]] = true;\n }\n\n // register interfaces\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view override(IERC777) returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view override(IERC777) returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20Detailed-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override(IERC777) returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n\n address from = _msgSender();\n\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\n\n _move(from, from, recipient, amount, \"\", \"\");\n\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(\n address operator,\n address tokenHolder\n ) public view override(IERC777) returns (bool) {\n return operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) external override(IERC777) {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) external override(IERC777) {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n )\n external override(IERC777)\n {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {Transfer} events.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\n external override(IERC777) {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\n _burn(_msgSender(), account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender)\n public view override(IERC20) returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {Transfer} and {Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount)\n external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n require(holder != address(0), \"ERC777: transfer from zero address\");\n\n address spender = _msgSender();\n\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\n\n _move(spender, holder, recipient, amount, \"\", \"\");\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\n\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address operator,\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n require(account != address(0), \"ERC777: mint to zero address\");\n\n // Update state variables\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n internal\n {\n require(from != address(0), \"ERC777: send from zero address\");\n require(to != address(0), \"ERC777: send to zero address\");\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param operator address operator requesting the operation\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(\n address operator,\n address from,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n )\n internal\n {\n require(from != address(0), \"ERC777: burn from zero address\");\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n // Update state variables\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\n _balances[to] = _balances[to].add(amount);\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n function _approve(address holder, address spender, uint256 value) internal {\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\n // currently unnecessary.\n //require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n private\n {\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n}\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * `IERC777` Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an `IERC777` token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/Bridge/BridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"./IBridgeV2.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../AllowTokens/AllowTokensV0.sol\";\nimport \"../Utils/UtilsV1.sol\";\n\ncontract BridgeV2 is Initializable, IBridgeV2, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant private NULL_ADDRESS = address(0);\n bytes32 constant private NULL_HASH = bytes32(0);\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address private federation;\n uint256 private feePercentage;\n string public symbolPrefix;\n uint256 public lastDay;\n uint256 public spentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping(bytes32 => bool) public processed; // ProcessedHash => true\n AllowTokensV0 public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n uint256 constant public FEE_PERCENTAGE_DIVIDER = 10000; // Percentage with up to 2 decimals\n bool private alreadyRun;\n\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool isUpgrading);\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = AllowTokensV0(_allowTokens);\n _changeSideTokenFactory(_sideTokenFactory);\n _changeFederation(_federation);\n //keccak256(\"ERC777TokensRecipient\")\n ERC_1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function version() external pure override returns (string memory) {\n return \"v2\";\n }\n\n modifier onlyFederation() {\n require(msg.sender == federation, \"Bridge: Sender not Federation\");\n _;\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address tokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity\n ) external onlyFederation whenNotPaused nonReentrant override returns(bool) {\n require(tokenAddress != NULL_ADDRESS, \"Bridge: Token is null\");\n require(receiver != NULL_ADDRESS, \"Bridge: Receiver is null\");\n require(amount > 0, \"Bridge: Amount 0\");\n require(bytes(symbol).length > 0, \"Bridge: Empty symbol\");\n require(blockHash != NULL_HASH, \"Bridge: BlockHash is null\");\n require(transactionHash != NULL_HASH, \"Bridge: Transaction is null\");\n require(decimals <= 18, \"Bridge: Decimals bigger 18\");\n require(UtilsV1.granularityToDecimals(granularity) <= 18, \"Bridge: invalid granularity\");\n\n _processTransaction(blockHash, transactionHash, receiver, amount, logIndex);\n\n if (knownTokens[tokenAddress]) {\n _acceptCrossBackToToken(receiver, tokenAddress, decimals, granularity, amount);\n } else {\n _acceptCrossToSideToken(receiver, tokenAddress, decimals, granularity, amount, symbol);\n }\n return true;\n }\n\n function _acceptCrossToSideToken(\n address receiver,\n address tokenAddress,\n uint8 decimals,\n uint256 granularity,\n uint256 amount,\n string memory symbol\n ) private {\n\n (uint256 calculatedGranularity,uint256 formattedAmount) = UtilsV1.calculateGranularityAndAmount(decimals, granularity, amount);\n address sideToken = mappedTokens[tokenAddress];\n if (sideToken == NULL_ADDRESS) {\n sideToken = _createSideToken(tokenAddress, symbol, calculatedGranularity);\n } else {\n require(calculatedGranularity == IERC777(sideToken).granularity(), \"Bridge: Granularity differ from side token\");\n }\n ISideToken(sideToken).mint(receiver, formattedAmount, \"\", \"\");\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, 18, calculatedGranularity);\n }\n\n function _acceptCrossBackToToken(address receiver, address tokenAddress, uint8 decimals, uint256 granularity, uint256 amount) private {\n require(decimals == 18, \"Bridge: Invalid decimals cross back\");\n //As side tokens are ERC777 we need to convert granularity to decimals\n (uint8 calculatedDecimals, uint256 formattedAmount) = UtilsV1.calculateDecimalsAndAmount(tokenAddress, granularity, amount);\n IERC20(tokenAddress).safeTransfer(receiver, formattedAmount);\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, calculatedDecimals, 1);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokens(address tokenToUse, uint256 amount) override external whenNotUpgrading whenNotPaused nonReentrant returns(bool) {\n address sender = _msgSender();\n require(!sender.isContract(), \"Bridge: Sender can't be a contract\");\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, amount, \"\");\n return true;\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external whenNotPaused whenNotUpgrading override(IBridgeV2, IERC777Recipient) {\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to address\");\n address tokenToUse = _msgSender();\n //This can only be used with trusted contracts\n crossTokens(tokenToUse, from, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, uint256 amount, bytes memory userData) private {\n bool isASideToken = originalTokens[tokenToUse] != NULL_ADDRESS;\n //Send the payment to the MultiSig of the Federation\n uint256 fee = amount.mul(feePercentage).div(FEE_PERCENTAGE_DIVIDER);\n uint256 amountMinusFees = amount.sub(fee);\n if (isASideToken) {\n uint256 modulo = amountMinusFees.mod(IERC777(tokenToUse).granularity());\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n }\n if(fee > 0) {\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n if (isASideToken) {\n verifyWithAllowTokens(tokenToUse, amount, isASideToken);\n //Side Token Crossing\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n // solium-disable-next-line max-len\n emit Cross(originalTokens[tokenToUse], from, amountMinusFees, IERC777(tokenToUse).symbol(), userData, IERC777(tokenToUse).decimals(), IERC777(tokenToUse).granularity());\n } else {\n //Main Token Crossing\n knownTokens[tokenToUse] = true;\n (uint8 decimals, uint256 granularity, string memory symbol) = UtilsV1.getTokenInfo(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n //We consider the amount before fees converted to 18 decimals to check the limits\n verifyWithAllowTokens(tokenToUse, formattedAmount, isASideToken);\n emit Cross(tokenToUse, from, amountMinusFees, symbol, userData, decimals, granularity);\n }\n }\n\n function _createSideToken(address token, string memory symbol, uint256 granularity) private returns (address sideToken){\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, symbol));\n address sideTokenAddress = sideTokenFactory.createSideToken(newSymbol, newSymbol, granularity);\n sideToken = sideTokenAddress;\n mappedTokens[token] = sideToken;\n originalTokens[sideTokenAddress] = token;\n emit NewSideToken(sideTokenAddress, token, newSymbol, granularity);\n return sideToken;\n }\n\n function verifyWithAllowTokens(address tokenToUse, uint256 amount, bool isASideToken) private {\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n // solium-disable-next-line security/no-block-members\n lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n spentToday = 0;\n }\n require(allowTokens.isValidTokenTransfer(tokenToUse, amount, spentToday, isASideToken), \"Bridge: Bigger than limit\");\n spentToday = spentToday.add(amount);\n }\n\n function getTransactionId(\n bytes32 _blockHash,\n bytes32 _transactionHash,\n address _receiver,\n uint256 _amount,\n uint32 _logIndex\n )\n public pure returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _receiver, _amount, _logIndex));\n }\n\n function _processTransaction(\n bytes32 _blockHash,\n bytes32 _transactionHash,\n address _receiver,\n uint256 _amount,\n uint32 _logIndex\n )\n private\n {\n bytes32 compiledId = getTransactionId(_blockHash, _transactionHash, _receiver, _amount, _logIndex);\n require(!processed[compiledId], \"Bridge: Already processed\");\n processed[compiledId] = true;\n }\n\n function setFeePercentage(uint amount) external onlyOwner whenNotPaused {\n require(amount < (FEE_PERCENTAGE_DIVIDER/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() override external view returns(uint) {\n return feePercentage;\n }\n\n function calcMaxWithdraw() override external view returns (uint) {\n uint spent = spentToday;\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > lastDay + 24 hours) // solhint-disable-line not-rely-on-time\n spent = 0;\n return allowTokens.calcMaxWithdraw(spent);\n }\n\n function changeFederation(address newFederation) external onlyOwner returns(bool) {\n _changeFederation(newFederation);\n return true;\n }\n\n function _changeFederation(address newFederation) internal {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner returns(bool) {\n _changeSideTokenFactory(newSideTokenFactory);\n return true;\n }\n\n function _changeSideTokenFactory(address newSideTokenFactory) internal {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function startUpgrade() external onlyOwner {\n isUpgrading = true;\n emit Upgrading(isUpgrading);\n }\n\n function endUpgrade() external onlyOwner {\n isUpgrading = false;\n emit Upgrading(isUpgrading);\n }\n\n //This method is only to recreate the USDT and USDC tokens on rsk without granularity restrictions.\n function clearSideToken() external onlyOwner returns(bool) {\n require(!alreadyRun, \"already done\");\n alreadyRun = true;\n address payable[4] memory sideTokens = [\n 0xe506F698b31a66049BD4653ed934E7a07Cbc5549,\n 0x5a42221D7AaE8e185BC0054Bb036D9757eC18857,\n 0xcdc8ccBbFB6407c53118fE47259e8d00C81F42CD,\n 0x6117C9529F15c52e2d3188d5285C745B757b5825\n ];\n for (uint i = 0; i < sideTokens.length; i++) {\n address originalToken = address(originalTokens[sideTokens[i]]);\n originalTokens[sideTokens[i]] = NULL_ADDRESS;\n mappedTokens[originalToken] = address(NULL_ADDRESS);\n }\n return true;\n }\n\n}\n"
+ },
+ "contracts/Bridge/IBridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\ninterface IBridgeV2 {function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n function calcMaxWithdraw() external view returns (uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokens(address tokenToUse, uint256 amount) external returns(bool);\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the federation contract\n */\n function acceptTransfer(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity\n ) external returns(bool);\n\n event Cross(address indexed _tokenAddress, address indexed _to, uint256 _amount, string _symbol, bytes _userData,\n uint8 _decimals, uint256 _granularity);\n event NewSideToken(address indexed _newSideTokenAddress, address indexed _originalTokenAddress, string _newSymbol, uint256 _granularity);\n event AcceptedCrossTransfer(address indexed _tokenAddress, address indexed _to, uint256 _amount, uint8 _decimals, uint256 _granularity,\n uint256 _formattedAmount, uint8 _calculatedDecimals, uint256 _calculatedGranularity);\n event FeePercentageChanged(uint256 _amount);\n}"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract AllowTokensV0 is Ownable {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n\n mapping (address => bool) public allowedTokens;\n bool private validateAllowedTokens;\n uint256 private maxTokensAllowed;\n uint256 private minTokensAllowed;\n uint256 public dailyLimit;\n\n event AllowedTokenAdded(address indexed _tokenAddress);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event AllowedTokenValidation(bool _enabled);\n event MaxTokensAllowedChanged(uint256 _maxTokens);\n event MinTokensAllowedChanged(uint256 _minTokens);\n event DailyLimitChanged(uint256 dailyLimit);\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\n _;\n }\n\n constructor(address _manager) {\n transferOwnership(_manager);\n validateAllowedTokens = true;\n maxTokensAllowed = 10000 ether;\n minTokensAllowed = 1 ether;\n dailyLimit = 100000 ether;\n }\n\n function isValidatingAllowedTokens() external view returns(bool) {\n return validateAllowedTokens;\n }\n\n function getMaxTokensAllowed() external view returns(uint256) {\n return maxTokensAllowed;\n }\n\n function getMinTokensAllowed() external view returns(uint256) {\n return minTokensAllowed;\n }\n\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\n return allowedTokens[token];\n }\n\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\n if (validateAllowedTokens) {\n return allowedTokenExist(token);\n }\n return true;\n }\n\n function addAllowedToken(address token) external onlyOwner {\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\n allowedTokens[token] = true;\n emit AllowedTokenAdded(token);\n }\n\n function removeAllowedToken(address token) external onlyOwner {\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\n allowedTokens[token] = false;\n emit AllowedTokenRemoved(token);\n }\n\n function enableAllowedTokensValidation() external onlyOwner {\n validateAllowedTokens = true;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function disableAllowedTokensValidation() external onlyOwner {\n // Before disabling Allowed Tokens Validations some kind of contract validation system\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\n validateAllowedTokens = false;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\n maxTokensAllowed = maxTokens;\n emit MaxTokensAllowedChanged(maxTokensAllowed);\n }\n\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\n minTokensAllowed = minTokens;\n emit MinTokensAllowedChanged(minTokensAllowed);\n }\n\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\n dailyLimit = _dailyLimit;\n emit DailyLimitChanged(_dailyLimit);\n }\n\n // solium-disable-next-line max-len\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\n if(amount > maxTokensAllowed)\n return false;\n if(amount < minTokensAllowed)\n return false;\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\n return false;\n if(!isSideToken && !isTokenAllowed(tokenToUse))\n return false;\n return true;\n }\n\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\n uint maxWithrow = dailyLimit - spentToday;\n if (dailyLimit < spentToday)\n return 0;\n if(maxWithrow > maxTokensAllowed)\n maxWithrow = maxTokensAllowed;\n return maxWithrow;\n }\n\n}\n"
+ },
+ "contracts/Utils/UtilsV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nlibrary UtilsV1 {\n using SafeMath for uint256;\n\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n // keccak256(\"ERC777Token\")\n bytes32 constant private TOKENS_ERC777_HASH = 0xac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054;\n\n function getTokenInfo(address tokenToUse) external view returns (uint8 decimals, uint256 granularity, string memory symbol) {\n decimals = getDecimals(tokenToUse);\n granularity = getGranularity(tokenToUse);\n symbol = getSymbol(tokenToUse);\n }\n\n function getSymbol(address tokenToUse) public view returns (string memory symbol) {\n //support 32 bytes or string symbol\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"symbol()\"));\n require(success, \"Utils: Token hasn't symbol()\");\n if (data.length == 32) {\n symbol = bytes32ToString(abi.decode(data, (bytes32)));\n } else {\n symbol = abi.decode(data, (string));\n }\n require(bytes(symbol).length > 0, \"Utils: Token empty symbol\");\n return symbol;\n }\n\n function getDecimals(address tokenToUse) public view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"Utils: No decimals\");\n require(data.length == 32, \"Utils: Decimals not uint\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n uint256 decimalsDecoded = abi.decode(data, (uint256));\n require(decimalsDecoded <= 18, \"Utils: Decimals not in 0 to 18\");\n return uint8(decimalsDecoded);\n }\n\n function getGranularity(address tokenToUse) public view returns (uint256 granularity) {\n granularity = 1;\n //support granularity if ERC777\n address implementer = ERC_1820.getInterfaceImplementer(tokenToUse, TOKENS_ERC777_HASH);\n if (implementer != address(0)) {\n granularity = IERC777(implementer).granularity();\n //Verify granularity is power of 10 to keep it compatible with ERC20 decimals\n granularityToDecimals(granularity);\n }\n return granularity;\n }\n\n /* bytes32 (fixed-size array) to string (dynamically-sized array) */\n function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) {\n uint8 i = 0;\n while(i < 32 && _bytes32[i] != 0) {\n i++;\n }\n bytes memory bytesArray = new bytes(i);\n for (i = 0; i < 32 && _bytes32[i] != 0; i++) {\n bytesArray[i] = _bytes32[i];\n }\n return string(bytesArray);\n }\n\n function decimalsToGranularity(uint8 decimals) public pure returns (uint256) {\n require(decimals <= 18, \"Utils: Decimals not in 0 to 18\");\n return uint256(10)**(18-decimals);\n }\n\n function granularityToDecimals(uint256 granularity) public pure returns (uint8) {\n if(granularity == 1) return 18;\n if(granularity == 10) return 17;\n if(granularity == 100) return 16;\n if(granularity == 1000) return 15;\n if(granularity == 10000) return 14;\n if(granularity == 100000) return 13;\n if(granularity == 1000000) return 12;\n if(granularity == 10000000) return 11;\n if(granularity == 100000000) return 10;\n if(granularity == 1000000000) return 9;\n if(granularity == 10000000000) return 8;\n if(granularity == 100000000000) return 7;\n if(granularity == 1000000000000) return 6;\n if(granularity == 10000000000000) return 5;\n if(granularity == 100000000000000) return 4;\n if(granularity == 1000000000000000) return 3;\n if(granularity == 10000000000000000) return 2;\n if(granularity == 100000000000000000) return 1;\n if(granularity == 1000000000000000000) return 0;\n require(false, \"Utils: invalid granularity\");\n return 0;\n }\n\n function calculateGranularityAndAmount(uint8 decimals, uint256 granularity, uint256 amount) external pure\n returns(uint256 calculatedGranularity, uint256 formattedAmount) {\n\n if(decimals == 18) {\n //tokenAddress is a ERC20 with 18 decimals should have 1 granularity\n //tokenAddress is a ERC777 token we give the same granularity\n calculatedGranularity = granularity;\n formattedAmount = amount;\n } else {\n //tokenAddress is a ERC20 with other than 18 decimals\n calculatedGranularity = decimalsToGranularity(decimals);\n formattedAmount = amount.mul(calculatedGranularity);\n }\n }\n\n function calculateDecimalsAndAmount(address tokenAddress, uint256 granularity, uint256 amount)\n external view returns (uint8 calculatedDecimals, uint256 formattedAmount) {\n uint8 tokenDecimals = getDecimals(tokenAddress);\n //As side tokens are ERC777 we need to convert granularity to decimals\n calculatedDecimals = granularityToDecimals(granularity);\n require(tokenDecimals == calculatedDecimals, \"Utils: Token decimals differ from decimals - granularity\");\n formattedAmount = amount.div(granularity);\n }\n\n}\n"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () {\n _owner = _msgSender();\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../interface/IBridge.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockReceiveTokensCall is IERC777Recipient {\n address public bridge;\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor(address _bridge) {\n bridge = _bridge;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount) external {\n IERC20(tokenToUse).approve(bridge, amount);\n IBridge(bridge).receiveTokensTo(tokenToUse, receiver, amount);\n }\n\n function callDepositTo(address receiver) external payable {\n IBridge(bridge).depositTo{ value: msg.value }(receiver);\n }\n\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\n IERC777(tokenToUse).send(bridge, amount, data);\n }\n\n // Mandatory for IERC777Recipient\n function tokensReceived(\n address,\n address,\n address,\n uint,\n bytes calldata,\n bytes calldata\n ) override external view {\n this;\n }\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockERC777Recipient is IERC777Recipient {\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor() {\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\n }\n\n event Success(\n address operator,\n address from,\n address to,\n uint amount,\n bytes userData,\n bytes operatorData);\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) override external {\n emit Success(operator, from, to, amount, userData, operatorData);\n }\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\n\ncontract SideTokenV1 is ERC777 {\n address public minter;\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\n minter = _minterAddr;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../SideToken/SideTokenV1.sol\";\n\ncontract SideTokenFactoryV1 is Secondary {\n event CreatedSideToken(address sideToken, string symbol);\n\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\n emit CreatedSideToken(address(sideToken), symbol);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using SafeMath for uint256;\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping (uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /*\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri_) {\n _setURI(uri_);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) external view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: balance query for the zero address\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(amount);\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, address(0), id, amount);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\n /**\n @dev Handles the receipt of a single ERC1155 token type. This function is\n called at the end of a `safeTransferFrom` after the balance has been updated.\n To accept the transfer, this must return\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n (i.e. 0xf23a6e61, or its own function selector).\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n )\n external\n returns(bytes4);\n\n /**\n @dev Handles the receipt of a multiple ERC1155 token types. This function\n is called at the end of a `safeBatchTransferFrom` after the balances have\n been updated. To accept the transfer(s), this must return\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n (i.e. 0xbc197c81, or its own function selector).\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match values array)\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n )\n external\n returns(bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC1155 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Pausable is ERC1155, Pausable {\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\nimport \"../access/roles/PauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context, PauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n constructor () {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract PauserRole is Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n constructor () {\n _addPauser(_msgSender());\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC721.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC721 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC721Pausable is ERC721, Pausable {\n /**\n * @dev See {ERC721-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../../zeppelin/ownership/Ownable.sol\";\nimport \"../../zeppelin/math/SafeMath.sol\";\nimport \"../../zeppelin/utils/Strings.sol\";\nimport \"./OpenSeaEIP712Base.sol\";\n\n\n/**\n * @title OpenSea721\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\n */\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\n using SafeMath for uint256;\n\n uint256 private _currentTokenId = 0;\n\n constructor(\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n _initializeEIP712(_name);\n }\n\n function baseTokenURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/api/creature/\";\n }\n\n function contractURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\n }\n\n /**\n * @dev Mints a token to an address with a tokenURI.\n * @param _to address of the future owner of the token\n */\n function mintTo(address _to) public onlyOwner {\n uint256 newTokenId = _getNextTokenId();\n _mint(_to, newTokenId);\n _incrementTokenId();\n }\n\n /**\n * @dev calculates the next token ID based on value of _currentTokenId\n * @return uint256 for the next token ID\n */\n function _getNextTokenId() private view returns (uint256) {\n return _currentTokenId.add(1);\n }\n\n /**\n * @dev increments the value of _currentTokenId\n */\n function _incrementTokenId() private {\n _currentTokenId++;\n }\n\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\n }\n\n}"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../zeppelin/upgradable/Initializable.sol\";\n\ncontract OpenSeaEIP712Base is Initializable {\n struct EIP712Domain {\n string name;\n string version;\n address verifyingContract;\n bytes32 salt;\n }\n\n string constant public ERC712_VERSION = \"1\";\n\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\n bytes(\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\n )\n );\n bytes32 internal domainSeperator;\n\n // supposed to be called once while initializing.\n // one of the contracts that inherits this contract follows proxy pattern\n // so it is not possible to do this in a constructor\n function _initializeEIP712(\n string memory name\n )\n internal\n initializer\n {\n _setDomainSeperator(name);\n }\n\n function _setDomainSeperator(string memory name) internal {\n domainSeperator = keccak256(\n abi.encode(\n EIP712_DOMAIN_TYPEHASH,\n keccak256(bytes(name)),\n keccak256(bytes(ERC712_VERSION)),\n address(this),\n bytes32(getChainId())\n )\n );\n }\n\n function getDomainSeperator() public view returns (bytes32) {\n return domainSeperator;\n }\n\n function getChainId() public pure returns (uint256) {\n uint256 id;\n assembly {\n id := chainid()\n }\n return id;\n }\n\n /**\n * Accept message hash and returns hash message in EIP712 compatible form\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\n * https://eips.ethereum.org/EIPS/eip-712\n * \"\\\\x19\" makes the encoding deterministic\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\n */\n function toTypedMessageHash(bytes32 messageHash)\n internal\n view\n returns (bytes32)\n {\n return\n keccak256(\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\n );\n }\n}\n"
+ },
+ "contracts/Federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../interface/IBridge.sol\";\n\ncontract FederationV2 is Initializable, UpgradableOwnable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridge public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\n public validRequirement(_members.length, _required) initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n }\n\n function version() external pure returns (string memory) {\n return \"v2\";\n }\n\n function setBridge(address _bridge) external onlyOwner {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridge(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n )\n public onlyMember returns(bool)\n {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32)\n {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}"
+ },
+ "contracts/Federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../nftbridge/INFTBridge.sol\";\nimport \"../interface/IBridge.sol\";\nimport \"../interface/IFederation.sol\";\n\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridge public bridge;\n address[] public members;\n\n /**\n @notice The minimum amount of votes to approve a transaction\n @dev It should have more members than the required amount\n */\n uint public required;\n\n /**\n @notice All the addresses that are members of the federation\n @dev The address should be a member to vote in transactions\n */\n mapping (address => bool) public isMember;\n\n /**\n (bytes32) transactionId = keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n ) => (\n (address) members => (bool) voted\n )\n @notice Votes by members by the transaction ID\n @dev usually the members should approve the transaction by 50% + 1\n */\n mapping (bytes32 => mapping (address => bool)) public votes;\n\n /**\n (bytes32) transactionId => (bool) voted\n @notice Check if that transaction was already processed\n */\n mapping(bytes32 => bool) public processed;\n\n /** Federator v3 variables */\n INFTBridge public bridgeNFT;\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner, address _bridgeNFT) public\n validRequirement(_members.length, _required) initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n _setNFTBridge(_bridgeNFT);\n }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure override returns (string memory) {\n return \"v3\";\n }\n\n /**\n @notice Sets a new bridge contract\n @dev Emits BridgeChanged event\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external onlyOwner override {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridge(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n /**\n @notice Sets a new NFT bridge contract\n @dev Emits NFTBridgeChanged event\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external onlyOwner override {\n _setNFTBridge(_bridgeNFT);\n }\n\n function _setNFTBridge(address _bridgeNFT) internal {\n require(_bridgeNFT != NULL_ADDRESS, \"Federation: Empty NFT bridge\");\n bridgeNFT = INFTBridge(_bridgeNFT);\n emit NFTBridgeChanged(_bridgeNFT);\n }\n\n function validateTransaction(bytes32 transactionId) internal view returns(bool) {\n uint transactionCount = getTransactionCount(transactionId);\n return transactionCount >= required && transactionCount >= members.length / 2 + 1;\n }\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) external onlyMember override {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return;\n\n if (votes[transactionId][_msgSender()])\n return;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n logIndex\n );\n\n if (validateTransaction(transactionId)) {\n processed[transactionId] = true;\n acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex,\n tokenType\n );\n\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n logIndex\n );\n return;\n }\n }\n\n function acceptTransfer(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) internal {\n if (tokenType == TokenType.NFT) {\n require(address(bridgeNFT) != NULL_ADDRESS, \"Federation: Empty NFTBridge\");\n bridgeNFT.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n return;\n }\n\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n }\n\n /**\n @notice Get the amount of approved votes for that transactionId\n @param transactionId The transaction hashed from getTransactionId function\n */\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n /**\n @notice Gets the hash of transaction from the following parameters encoded and keccaked\n @dev It encodes and applies keccak256 to the parameters received in the same order\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param amount Could be the amount or the tokenId\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @return The hash generated by the parameters.\n */\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32) {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner override\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner override\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view override returns (address[] memory) {\n return members;\n }\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @dev Emits the RequirementChange event\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n /**\n @notice It emits an HeartBeat like an health check\n @dev Emits HeartBeat event\n */\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember override {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface IFederation {\n enum TokenType{ COIN, NFT }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure returns (string memory);\n\n /**\n @notice Sets a new bridge contract\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external;\n\n /**\n @notice Sets a new NFT bridge contract\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external;\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) external;\n\n /**\n @notice Add a new member to the federation\n @param _newMember address of the new member\n */\n function addMember(address _newMember) external;\n\n /**\n @notice Remove a member of the federation\n @param _oldMember address of the member to be removed from federation\n */\n function removeMember(address _oldMember) external;\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view returns (address[] memory);\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external;\n\n /**\n @notice It emmits an HeartBeat like an healthy check\n */\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event NFTBridgeChanged(address bridgeNFT);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n}\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract MinterRole is Context {\n using Roles for Roles.Role;\n\n event MinterAdded(address indexed account);\n event MinterRemoved(address indexed account);\n\n Roles.Role private _minters;\n\n constructor () {\n _addMinter(_msgSender());\n }\n\n modifier onlyMinter() {\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\n _;\n }\n\n function isMinter(address account) public view returns (bool) {\n return _minters.has(account);\n }\n\n function addMinter(address account) public onlyMinter {\n _addMinter(account);\n }\n\n function renounceMinter() public {\n _removeMinter(_msgSender());\n }\n\n function _addMinter(address account) internal {\n _minters.add(account);\n emit MinterAdded(account);\n }\n\n function _removeMinter(address account) internal {\n _minters.remove(account);\n emit MinterRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20Mintable}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() override public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) override public view returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) override public returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) override public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) override public returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal {\n require(sender != address(0), \"ERC20: transfer from zero address\");\n require(recipient != address(0), \"ERC20: transfer to zero address\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: mint to zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: burn from zero address\");\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n *\n * This is internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal {\n require(owner != address(0), \"ERC20: approve from zero address\");\n require(spender != address(0), \"ERC20: approve to zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\n * from the caller's allowance.\n *\n * See {_burn} and {_approve}.\n */\n function _burnFrom(address account, uint256 amount) internal {\n _burn(account, amount);\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\n }\n}\n"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\nimport \"../interface/IERC677Receiver.sol\";\n\ncontract mockERC677Receiver is IERC677Receiver {\n event Success(address _sender, uint _value, bytes _data);\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\n emit Success(_sender, _value, _data);\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Optional functions from the ERC20 standard.\n */\nabstract contract ERC20Detailed is IERC20 {\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\n * these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\n _name = aName;\n _symbol = aSymbol;\n _decimals = theDecimals;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./Proxy.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n *\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\n * {TransparentUpgradeableProxy}.\n */\ncontract UpgradeableProxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _setImplementation(_logic);\n if(_data.length > 0) {\n Address.functionDelegateCall(_logic, _data);\n }\n }\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n bytes32 slot = _IMPLEMENTATION_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n impl := sload(slot)\n }\n }\n\n /**\n * @dev Upgrades the proxy to a new implementation.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal virtual {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\n\n bytes32 slot = _IMPLEMENTATION_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newImplementation)\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./UpgradeableProxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _setAdmin(admin_);\n }\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _admin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _admin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\n emit AdminChanged(_admin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external virtual ifAdmin {\n _upgradeTo(newImplementation);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\n _upgradeTo(newImplementation);\n Address.functionDelegateCall(newImplementation, data);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address adm) {\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n adm := sload(slot)\n }\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n bytes32 slot = _ADMIN_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newAdmin)\n }\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../ownership/Ownable.sol\";\nimport \"./TransparentUpgradeableProxy.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
+ },
+ "contracts/Federation/FederationV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../Bridge/IBridgeV2.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract FederationV1 is Ownable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridgeV2 public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n // solium-disable-next-line max-len\n event Voted(address indexed sender, bytes32 indexed transactionId, address originalTokenAddress, address receiver, uint256 amount, string symbol, bytes32 blockHash, bytes32 indexed transactionHash, uint32 logIndex, uint8 decimals, uint256 granularity);\n event Executed(bytes32 indexed transactionId);\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Caller not a Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n constructor(address[] memory _members, uint _required) validRequirement(_members.length, _required) {\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Members larger than max allowed\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n }\n\n function setBridge(address _bridge) external onlyOwner {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridgeV2(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity)\n external onlyMember returns(bool)\n {\n // solium-disable-next-line max-len\n bytes32 transactionId = getTransactionId(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n // solium-disable-next-line max-len\n emit Voted(_msgSender(), transactionId, originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bool acceptTransfer = bridge.acceptTransfer(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n require(acceptTransfer, \"Federation: Bridge acceptTransfer error\");\n emit Executed(transactionId);\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string memory symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity)\n public pure returns(bytes32)\n {\n // solium-disable-next-line max-len\n return keccak256(abi.encodePacked(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity));\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove last element\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n}"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\n\ncontract BridgeProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract FederationProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract MainToken is ERC20Detailed, ERC20 {\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\n ERC20Detailed(name, symbol, decimals)\n {\n _mint(msg.sender, totalSupply);\n }\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\n bool result = transfer(_to, _value);\n if (!result) return false;\n\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\n receiver.tokenFallback(msg.sender, _value, _data);\n\n // IMPORTANT: the ERC-677 specification does not say\n // anything about the use of the receiver contract's\n // tokenFallback method return value. Given\n // its return type matches with this method's return\n // type, returning it could be a possibility.\n // We here take the more conservative approach and\n // ignore the return value, returning true\n // to signal a succesful transfer despite tokenFallback's\n // return value -- fact being tokens are transferred\n // in any case.\n return true;\n }\n}\n\ninterface ERC677TransferReceiver {\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\n}"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract AlternativeERC20Detailed is ERC20 {\n string private _name;\n bytes32 private _symbol;\n uint256 private _decimals;\n\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\n {\n _name = aName;\n _symbol = aSymbol;\n _decimals = someDecimals;\n _mint(msg.sender, aTotalSupply);\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (bytes32) {\n return _symbol;\n }\n\n function decimals() public view returns (uint256) {\n return _decimals;\n }\n}"
+ },
+ "contracts/test/nftbridge/NFTERC721TestToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.6;\n\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\n\ncontract NFTERC721TestToken is ERC721 {\n\n string private _contractURI;\n\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\n\n function safeMint(address to, uint256 tokenId) public {\n _safeMint(to, tokenId);\n }\n\n function setBaseURI(string memory baseURI) public {\n _setBaseURI(baseURI);\n }\n\n function setContractURI(string memory contractURI_) public {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n function setTokenURI(uint256 tokenId, string memory _tokenURI) public {\n _setTokenURI(tokenId, _tokenURI);\n }\n\n}\n"
+ },
+ "contracts/nftbridge/SideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./ISideNFTToken.sol\";\nimport \"../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\n\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\n address public minter;\n string private _contractURI;\n\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\n require(_minter != address(0), \"SideToken: Empty Minter\");\n minter = _minter;\n _setBaseURI(_baseURI);\n _setContractURI(contractURI_);\n }\n\n function _setContractURI(string memory contractURI_) internal {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(address account, uint256 tokenId) external onlyMinter override {\n _mint(account, tokenId);\n }\n}"
+ },
+ "contracts/nftbridge/SideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"./SideNFTToken.sol\";\n\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external onlyPrimary override returns(address) {\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\n return sideTokenAddress;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() {\n _registerInterface(\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\n );\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721Receiver.sol\";\n\n /**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers. \n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Burnable is ERC1155 {\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n}\n"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../lib/LibUtils.sol\";\n\ncontract LibUtilsHarness {\n\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\n return LibUtils.decimalsToGranularity(decimals);\n }\n\n function getDecimals(address tokenToUse) external view returns (uint8) {\n return LibUtils.getDecimals(tokenToUse);\n }\n\n function getGranularity(address tokenToUse) external view returns (uint256) {\n return LibUtils.getGranularity(tokenToUse);\n }\n\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\n return LibUtils.bytesToAddress(bys);\n }\n\n}\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/solcInputs/c9c50994c7f4ed6c6a7c2f652aca7adb.json b/bridge/deployments/rsktestnet/solcInputs/c9c50994c7f4ed6c6a7c2f652aca7adb.json
new file mode 100644
index 000000000..c7008191d
--- /dev/null
+++ b/bridge/deployments/rsktestnet/solcInputs/c9c50994c7f4ed6c6a7c2f652aca7adb.json
@@ -0,0 +1,297 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/math/SafeMath.sol\";\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\n\nimport \"../interface/IAllowTokens.sol\";\n\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n uint256 constant public MAX_TYPES = 250;\n mapping (address => TokenInfo) public allowedTokens;\n mapping (uint256 => Limits) public typeLimits;\n uint256 public smallAmountConfirmations;\n uint256 public mediumAmountConfirmations;\n uint256 public largeAmountConfirmations;\n string[] public typeDescriptions;\n\n event SetToken(address indexed _tokenAddress, uint256 _typeId);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\n event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\n event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\n event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\n\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\n _;\n }\n\n function initialize(\n address _manager,\n address _primary,\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations,\n TypeInfo[] memory typesInfo) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradableSecondary.__Secondary_init(_primary);\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n for(uint i = 0; i < typesInfo.length; i = i + 1) {\n _addTokenType(typesInfo[i].description, typesInfo[i].limits);\n }\n }\n\n function version() override external pure returns (string memory) {\n return \"v1\";\n }\n\n function getInfoAndLimits(address token) override public view\n returns (TokenInfo memory info, Limits memory limit) {\n info = allowedTokens[token];\n limit = typeLimits[info.typeId];\n return (info, limit);\n }\n function calcMaxWithdraw(address token) override public view returns (uint256 maxWithdraw) {\n (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\n return _calcMaxWithdraw(info, limits);\n }\n\n function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n info.spentToday = 0;\n }\n if (limits.daily <= info.spentToday)\n return 0;\n maxWithdraw = limits.daily - info.spentToday;\n if(maxWithdraw > limits.max)\n maxWithdraw = limits.max;\n return maxWithdraw;\n }\n\n // solium-disable-next-line max-len\n function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\n (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\n require(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\n require(amount >= limit.min, \"AllowTokens: Lower than limit\");\n\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n // solium-disable-next-line security/no-block-members\n info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n info.spentToday = 0;\n }\n uint maxWithdraw = _calcMaxWithdraw(info, limit);\n require(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\n info.spentToday = info.spentToday.add(amount);\n allowedTokens[token] = info;\n\n emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\n }\n\n function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\n require(bytes(description).length > 0, \"AllowTokens: Empty description\");\n len = typeDescriptions.length;\n require(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\n typeDescriptions.push(description);\n _setTypeLimits(len, limits);\n emit TokenTypeAdded(len, description);\n return len;\n }\n\n function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\n return _addTokenType(description, limits);\n }\n\n function _setTypeLimits(uint256 typeId, Limits memory limits) private {\n require(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\n require(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\n require(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\n require(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\n require(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\n typeLimits[typeId] = limits;\n emit TypeLimitsChanged(typeId, limits);\n }\n\n function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\n _setTypeLimits(typeId, limits);\n }\n\n function getTypesLimits() external view override returns(Limits[] memory limits) {\n limits = new Limits[](typeDescriptions.length);\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\n limits[i] = typeLimits[i];\n }\n return limits;\n }\n\n function getTypeDescriptionsLength() external view override returns(uint256) {\n return typeDescriptions.length;\n }\n\n function getTypeDescriptions() external view override returns(string[] memory descriptions) {\n descriptions = new string[](typeDescriptions.length);\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\n descriptions[i] = typeDescriptions[i];\n }\n return descriptions;\n }\n\n function isTokenAllowed(address token) public view notNull(token) override returns (bool) {\n return allowedTokens[token].allowed;\n }\n\n function setToken(address token, uint256 typeId) override public notNull(token) {\n require(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n require(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\n TokenInfo memory info = allowedTokens[token];\n info.allowed = true;\n info.typeId = typeId;\n allowedTokens[token] = info;\n emit SetToken(token, typeId);\n }\n\n function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\n require(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\n for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\n setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\n }\n }\n\n function removeAllowedToken(address token) external notNull(token) onlyOwner {\n TokenInfo memory info = allowedTokens[token];\n require(info.allowed, \"AllowTokens: Not Allowed\");\n info.allowed = false;\n allowedTokens[token] = info;\n emit AllowedTokenRemoved(token);\n }\n\n function setConfirmations(\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations) external onlyOwner {\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n }\n\n function _setConfirmations(\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations) private {\n require(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\n require(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\n smallAmountConfirmations = _smallAmountConfirmations;\n mediumAmountConfirmations = _mediumAmountConfirmations;\n largeAmountConfirmations = _largeAmountConfirmations;\n emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n }\n\n function getConfirmations() external view override\n returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount) {\n return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\n }\n\n}\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @title Initializable\n *\n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(initializing || !initialized, \"Contract instance is already initialized\");\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\n * the owner.\n */\ncontract UpgradableOwnable is Initializable, Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function initialize(address sender) public initializer {\n _owner = sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * > Note: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\ncontract UpgradableSecondary is Initializable, Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n function __Secondary_init(address sender) public initializer {\n _primary = sender;\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(recipient);\n }\n\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IAllowTokens {\n\n struct Limits {\n uint256 min;\n uint256 max;\n uint256 daily;\n uint256 mediumAmount;\n uint256 largeAmount;\n }\n\n struct TokenInfo {\n bool allowed;\n uint256 typeId;\n uint256 spentToday;\n uint256 lastDay;\n }\n\n struct TypeInfo {\n string description;\n Limits limits;\n }\n\n struct TokensAndType {\n address token;\n uint256 typeId;\n }\n\n function version() external pure returns (string memory);\n\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\n\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\n\n function getTypesLimits() external view returns(Limits[] memory limits);\n\n function getTypeDescriptionsLength() external view returns(uint256);\n\n function getTypeDescriptions() external view returns(string[] memory descriptions);\n\n function setToken(address token, uint256 typeId) external;\n\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\n\n function isTokenAllowed(address token) external view returns (bool);\n\n function updateTokenTransfer(address token, uint256 amount) external;\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n\n function _msgSender() internal view returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
+ },
+ "contracts/nftbridge/NFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC721/IERC721.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Metadata.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Enumerable.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Receiver.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./INFTBridge.sol\";\nimport \"./ISideNFTToken.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract NFTBridge is\n Initializable,\n INFTBridge,\n UpgradablePausable,\n UpgradableOwnable,\n ReentrancyGuard,\n IERC721Receiver {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address internal constant NULL_ADDRESS = address(0);\n bytes32 internal constant NULL_HASH = bytes32(0);\n IERC1820Registry internal constant ERC1820 =\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address payable internal federation;\n uint256 internal fixedFee;\n string public symbolPrefix;\n\n mapping(address => address) public sideTokenAddressByOriginalTokenAddress;\n mapping(address => address) public originalTokenAddressBySideTokenAddress;\n mapping(address => bool) public isAddressFromCrossedOriginalToken; // address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideNFTTokenFactory public sideTokenFactory;\n bool public isUpgrading;\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\n event Upgrading(bool _isUpgrading);\n\n function initialize(\n address _manager,\n address payable _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\n federation = _federation;\n ERC1820.setInterfaceImplementer(\n address(this),\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\n address(this)\n );\n }\n\n function version() external pure override returns (string memory) {\n return \"v1\";\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _tokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external override whenNotPaused nonReentrant {\n require(_msgSender() == federation, \"NFTBridge: Not Federation\");\n require(\n isAddressFromCrossedOriginalToken[_tokenAddress] ||\n sideTokenAddressByOriginalTokenAddress[_tokenAddress] != NULL_ADDRESS,\n \"NFTBridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"NFTBridge: Null To\");\n require(_from != NULL_ADDRESS, \"NFTBridge: Null From\");\n require(_blockHash != NULL_HASH, \"NFTBridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"NFTBridge: Null TxHash\");\n require(\n transactionDataHashes[_transactionHash] == bytes32(0),\n \"NFTBridge: Already accepted\"\n );\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\n require(!claimed[_transactionDataHash], \"NFTBridge: Already claimed\");\n\n transactionDataHashes[_transactionHash] = _transactionDataHash;\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\n// senderAddresses[_transactionHash] = _from;\n\n emit AcceptedNFTCrossTransfer(\n _transactionHash,\n _tokenAddress,\n _to,\n _from,\n _tokenId,\n _blockHash,\n _logIndex\n );\n }\n\n function createSideNFTToken(\n address _originalTokenAddress,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName,\n string calldata _baseURI,\n string calldata _contractURI\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"NFTBridge: Null original token address\");\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[_originalTokenAddress];\n require(sideTokenAddress == NULL_ADDRESS, \"NFTBridge: Side token already exists\");\n string memory sideTokenSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideTokenAddress = sideTokenFactory.createSideNFTToken(_originalTokenName, sideTokenSymbol, _baseURI, _contractURI);\n\n sideTokenAddressByOriginalTokenAddress[_originalTokenAddress] = sideTokenAddress;\n originalTokenAddressBySideTokenAddress[sideTokenAddress] = _originalTokenAddress;\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, sideTokenSymbol);\n }\n\n function claim(NFTClaimData calldata _claimData) external override {\n _claim(_claimData, _claimData.to);\n }\n\n function claimFallback(NFTClaimData calldata _claimData) external override {\n require(_msgSender() == _claimData.from, \"NFTBridge: invalid sender\");\n _claim(_claimData, _msgSender());\n }\n\n function _claim(\n NFTClaimData calldata _claimData,\n address payable _receiver\n ) internal {\n address tokenAddress = _claimData.tokenAddress;\n uint256 tokenId = _claimData.tokenId;\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.from,\n tokenId,\n tokenAddress,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\n \"NFTBridge: Wrong txDataHash\"\n );\n require(!claimed[transactionDataHash], \"NFTBridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n bool isClaimBeingRequestedInMainChain = isAddressFromCrossedOriginalToken[tokenAddress];\n if (isClaimBeingRequestedInMainChain) {\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\n } else {\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[tokenAddress];\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\n }\n\n emit ClaimedNFTToken(\n _claimData.transactionHash,\n tokenAddress,\n _claimData.to,\n _claimData.from,\n _claimData.tokenId,\n _claimData.blockHash,\n _claimData.logIndex,\n _receiver\n );\n }\n\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\"creator()\"));\n if (success) {\n return abi.decode(data, (address));\n }\n\n return IERC721(tokenAddress).ownerOf(tokenId);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId\n ) public payable override {\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\n\n address payable sender = _msgSender();\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\n\n crossTokens(tokenAddress, to, tokenCreator, \"\", tokenId);\n\n if (fixedFee > 0) {\n require(msg.value >= fixedFee, \"NFTBridge: value is smaller than fixed fee\");\n\n // Send the payment to the MultiSig of the Federation\n federation.transfer(fixedFee);\n if (msg.value > fixedFee) { // refund of unused value\n sender.transfer(msg.value.sub(fixedFee));\n }\n }\n }\n\n function crossTokens(\n address tokenAddress,\n address to,\n address tokenCreator,\n bytes memory userData,\n uint256 tokenId\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\n isAddressFromCrossedOriginalToken[tokenAddress] = true;\n\n IERC721Enumerable enumerable = IERC721Enumerable(tokenAddress);\n IERC721Metadata metadataIERC = IERC721Metadata(tokenAddress);\n string memory tokenURI = metadataIERC.tokenURI(tokenId);\n\n address originalTokenAddress = tokenAddress;\n if (originalTokenAddressBySideTokenAddress[tokenAddress] != NULL_ADDRESS) {\n originalTokenAddress = originalTokenAddressBySideTokenAddress[tokenAddress];\n ERC721Burnable(tokenAddress).burn(tokenId);\n }\n\n emit Cross(\n originalTokenAddress,\n _msgSender(),\n to,\n tokenCreator,\n userData,\n enumerable.totalSupply(),\n tokenId,\n tokenURI\n );\n }\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) public pure override returns (bytes32) {\n return keccak256(\n abi.encodePacked(\n _blockHash,\n _transactionHash,\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _logIndex\n )\n );\n }\n\n function setFixedFee(uint256 amount) external onlyOwner {\n fixedFee = amount;\n emit FixedFeeNFTChanged(fixedFee);\n }\n\n function getFixedFee() external view override returns (uint256) {\n return fixedFee;\n }\n\n function changeFederation(address payable newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"NFTBridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"NFTBridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns (address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\n require(\n newSideNFTTokenFactory != NULL_ADDRESS,\n \"NFTBridge: empty SideTokenFactory\"\n );\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionDataHashes[transactionHash]];\n }\n\n /**\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\n/**\n * @title Helps contracts guard against reentrancy attacks.\n * @author Remco Bloemen , Eenae \n * @dev If you mark a function `nonReentrant`, you should also\n * mark it `external`.\n */\ncontract ReentrancyGuard is Initializable {\n /// @dev counter to allow mutex lock with only one SSTORE operation\n uint256 private _guardCounter;\n\n function initialize() public initializer {\n // The counter starts at one to prevent changing it from zero to a non-zero\n // value, which is a more expensive operation.\n _guardCounter = 1;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _guardCounter += 1;\n uint256 localCounter = _guardCounter;\n _;\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\n }\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\nimport \"../access/roles/UpgradablePauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n function __Pausable_init(address sender) public initializer {\n UpgradablePauserRole.__PauserRol_init(sender);\n\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as `account`'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `_account`.\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `_implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\n\n /**\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `_account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {ERC20Detailed}.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeERC20: low-level call failed\");\n\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n */\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./ERC721.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721Burnable is Context, ERC721 {\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n _burn(tokenId);\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\nlibrary LibEIP712 {\n\n // Hash of the EIP712 Domain Separator Schema\n // keccak256(abi.encodePacked(\n // \"EIP712Domain(\",\n // \"string name,\",\n // \"string version,\",\n // \"uint256 chainId,\",\n // \"address verifyingContract\",\n // \")\"\n // ))\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n /// @dev Calculates a EIP712 domain separator.\n /// @param name The EIP712 domain name.\n /// @param version The EIP712 domain version.\n /// @param verifyingContract The EIP712 verifying contract.\n /// @return result EIP712 domain separator.\n function hashEIP712Domain(\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n // keccak256(bytes(name)),\n // keccak256(bytes(version)),\n // chainId,\n // uint256(verifyingContract)\n // ))\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Calculate hashes of dynamic data\n let nameHash := keccak256(add(name, 32), mload(name))\n let versionHash := keccak256(add(version, 32), mload(version))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n // Store params in memory\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), nameHash)\n mstore(add(memPtr, 64), versionHash)\n mstore(add(memPtr, 96), chainId)\n mstore(add(memPtr, 128), verifyingContract)\n\n // Compute hash\n result := keccak256(memPtr, 160)\n }\n return result;\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\n /// with getDomainHash().\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to the given EIP712 Domain.\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n internal\n pure\n returns (bytes32 result)\n {\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct\n // ));\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nlibrary LibUtils {\n\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\n return uint256(10)**(18-decimals);\n }\n\n function getDecimals(address tokenToUse) internal view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"LibUtils: No decimals\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n return uint8(abi.decode(data, (uint256)));\n }\n\n function getGranularity(address tokenToUse) internal view returns (uint256) {\n //support granularity if ERC777\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\n require(success, \"LibUtils: No granularity\");\n\n return abi.decode(data, (uint256));\n }\n\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n addr := mload(add(bys,20))\n }\n }\n\n}\n"
+ },
+ "contracts/nftbridge/INFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface INFTBridge {\n struct NFTClaimData {\n address payable to;\n address from;\n uint256 tokenId;\n address tokenAddress;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFixedFee() external view returns (uint256);\n\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId\n ) external payable;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\n */\n function claim(NFTClaimData calldata _claimData) external;\n\n function claimFallback(NFTClaimData calldata _claimData) external;\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns (bytes32);\n\n event Cross(\n address indexed _originalTokenAddress,\n address indexed _from,\n address indexed _to,\n address _tokenCreator,\n bytes _userData,\n uint256 _totalSupply,\n uint256 _tokenId,\n string _tokenURI\n );\n event NewSideNFTToken(\n address indexed _newSideNFTTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol\n );\n event AcceptedNFTCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FixedFeeNFTChanged(uint256 _amount);\n event ClaimedNFTToken(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _receiver\n );\n}\n"
+ },
+ "contracts/nftbridge/ISideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\ninterface ISideNFTToken {\n function mint(address account, uint256 tokenId) external;\n}"
+ },
+ "contracts/nftbridge/ISideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\ninterface ISideNFTTokenFactory {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external returns(address);\n\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IWrapped {\n function balanceOf(address) external returns(uint);\n\n function deposit() external payable;\n\n function withdraw(uint wad) external;\n\n function totalSupply() external view returns (uint);\n\n function approve(address guy, uint wad) external returns (bool);\n\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad)\n external\n returns (bool);\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../Initializable.sol\";\n\nimport \"../../../GSN/Context.sol\";\nimport \"../../../access/Roles.sol\";\n\ncontract UpgradablePauserRole is Initializable, Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n function __PauserRol_init(address sender) public initializer {\n if (!isPauser(sender)) {\n _addPauser(sender);\n }\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @title Roles\n * @dev Library for managing addresses assigned to a Role.\n */\nlibrary Roles {\n struct Role {\n mapping (address => bool) bearer;\n }\n\n /**\n * @dev Give an account access to this role.\n */\n function add(Role storage role, address account) internal {\n require(!has(role, account), \"Roles: account already has role\");\n role.bearer[account] = true;\n }\n\n /**\n * @dev Remove an account's access to this role.\n */\n function remove(Role storage role, address account) internal {\n require(has(role, account), \"Roles: account doesn't have role\");\n role.bearer[account] = false;\n }\n\n /**\n * @dev Check if an account has this role.\n * @return bool\n */\n function has(Role storage role, address account) internal view returns (bool) {\n require(account != address(0), \"Roles: account is the zero address\");\n return role.bearer[account];\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _tokenOwners.contains(tokenId);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(tokenId);\n\n emit Transfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n}\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract WRBTC is IWrapped {\n string public name = \"Wrapped RBTC\";\n string public symbol = \"WRBTC\";\n uint8 public decimals = 18;\n\n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n event Deposit(address indexed dst, uint wad);\n event Withdrawal(address indexed src, uint wad);\n\n mapping (address => uint) override public balanceOf;\n mapping (address => mapping (address => uint)) public allowance;\n\n receive () external payable {\n deposit();\n }\n function deposit() override public payable {\n balanceOf[msg.sender] += msg.value;\n emit Deposit(msg.sender, msg.value);\n }\n function withdraw(uint wad) override public {\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\n balanceOf[msg.sender] -= wad;\n msg.sender.transfer(wad);\n emit Withdrawal(msg.sender, wad);\n }\n\n function totalSupply() override public view returns (uint) {\n return address(this).balance;\n }\n\n function approve(address guy, uint wad) override public returns (bool) {\n allowance[msg.sender][guy] = wad;\n emit Approval(msg.sender, guy, wad);\n return true;\n }\n\n function transfer(address dst, uint wad) override public returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad)\n override public\n returns (bool)\n {\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\n\n if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\n allowance[src][msg.sender] -= wad;\n }\n\n balanceOf[src] -= wad;\n balanceOf[dst] += wad;\n\n emit Transfer(src, dst, wad);\n\n return true;\n }\n}"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant internal NULL_ADDRESS = address(0);\n bytes32 constant internal NULL_HASH = bytes32(0);\n IERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address internal federation;\n uint256 internal feePercentage;\n string public symbolPrefix;\n // replaces uint256 internal _depprecatedLastDay;\n bytes32 public domainSeparator;\n uint256 internal _deprecatedSpentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n // Percentage with up to 2 decimals\n uint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\n //Bridge_v3 variables\n bytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\n IWrapped public wrappedCurrency;\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n // keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\n mapping(address => uint) public nonces;\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool _isUpgrading);\n event WrappedCurrencyChanged(address _wrappedCurrency);\n\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n federation = _federation;\n //keccak256(\"ERC777TokensRecipient\")\n ERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n initDomainSeparator();\n }\n\n receive () external payable {\n // The fallback function is needed to use WRBTC\n require(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n }\n\n function version() override external pure returns (string memory) {\n return \"v3\";\n }\n\n function initDomainSeparator() public {\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n domainSeparator = LibEIP712.hashEIP712Domain(\n \"RSK Token Bridge\",\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"Bridge: Not Federation\");\n require(knownTokens[_originalTokenAddress] ||\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\n \"Bridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"Bridge: Null To\");\n require(_amount > 0, \"Bridge: Amount 0\");\n require(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _amount,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed also has the previously processed using the older bridge version\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n require(!claimed[_transactionDataHash], \"Bridge: Already claimed\");\n\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\n senderAddresses[_transactionHash] = _from;\n\n emit AcceptedCrossTransfer(\n _transactionHash,\n _originalTokenAddress,\n _to,\n _from,\n _amount,\n _blockHash,\n _logIndex\n );\n }\n\n\n function createSideToken(\n uint256 _typeId,\n address _originalTokenAddress,\n uint8 _originalTokenDecimals,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n address sideToken = mappedTokens[_originalTokenAddress];\n require(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\n\n mappedTokens[_originalTokenAddress] = sideToken;\n originalTokens[sideToken] = _originalTokenAddress;\n allowTokens.setToken(sideToken, _typeId);\n\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\n }\n\n function claim(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function claimFallback(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n receivedAmount = _claim(\n _claimData,\n _msgSender(),\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function getDigest(\n ClaimData memory _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline\n ) internal returns (bytes32) {\n return LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n CLAIM_TYPEHASH,\n _claimData.to,\n _claimData.amount,\n _claimData.transactionHash,\n _relayer,\n _fee,\n nonces[_claimData.to]++,\n _deadline\n )\n )\n );\n }\n\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external override returns (uint256 receivedAmount) {\n require(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\n\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claim(\n ClaimData calldata _claimData,\n address payable _reciever,\n address payable _relayer,\n uint256 _fee\n ) internal nonReentrant returns (uint256 receivedAmount) {\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n require(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.amount,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n require(!claimed[transactionDataHash], \"Bridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (knownTokens[originalTokenAddress]) {\n receivedAmount =_claimCrossBackToToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n } else {\n receivedAmount =_claimCrossToSideToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n }\n emit Claimed(\n _claimData.transactionHash,\n originalTokenAddress,\n _claimData.to,\n senderAddresses[_claimData.transactionHash],\n _claimData.amount,\n _claimData.blockHash,\n _claimData.logIndex,\n _reciever,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claimCrossToSideToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n address sideToken = mappedTokens[_originalTokenAddress];\n uint256 granularity = IERC777(sideToken).granularity();\n uint256 formattedAmount = _amount.mul(granularity);\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n ISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n if(_fee > 0) {\n ISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n }\n return receivedAmount;\n }\n\n function _claimCrossBackToToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n //As side tokens are ERC777 they will always have 18 decimals\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n if(address(wrappedCurrency) == _originalTokenAddress) {\n wrappedCurrency.withdraw(formattedAmount);\n _receiver.transfer(receivedAmount);\n if(_fee > 0) {\n _relayer.transfer(_fee);\n }\n } else {\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n if(_fee > 0) {\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n }\n }\n return receivedAmount;\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\n address sender = _msgSender();\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, to, amount, \"\");\n }\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) override external payable {\n address sender = _msgSender();\n require(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n wrappedCurrency.deposit{ value: msg.value }();\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \"\");\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external override(IBridge, IERC777Recipient){\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to this address\");\n address tokenToUse = _msgSender();\n require(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n require(userData.length != 0 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\n crossTokens(tokenToUse, from, receiver, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\n internal whenNotUpgrading whenNotPaused nonReentrant {\n knownTokens[tokenToUse] = true;\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n uint256 amountMinusFees = amount.sub(fee);\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n // We consider the amount before fees converted to 18 decimals to check the limits\n // updateTokenTransfer revert if token not allowed\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n address originalTokenAddress = tokenToUse;\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\n //Side Token Crossing\n originalTokenAddress = originalTokens[tokenToUse];\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\n uint256 modulo = amountMinusFees.mod(granularity);\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n }\n\n emit Cross(\n originalTokenAddress,\n from,\n to,\n amountMinusFees,\n userData\n );\n\n if (fee > 0) {\n //Send the payment to the MultiSig of the Federation\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n }\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n )\n public pure override returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n }\n\n function setFeePercentage(uint amount) external onlyOwner {\n require(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() external view override returns(uint) {\n return feePercentage;\n }\n\n function changeFederation(address newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n require(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n wrappedCurrency = IWrapped(_wrappedCurrency);\n emit WrappedCurrencyChanged(_wrappedCurrency);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionsDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionsDataHashes[transactionHash]];\n }\n\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an `IERC777` token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See `IERC1820Registry` and\n * `ERC1820Implementer`.\n */\ninterface IERC777 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See `operatorSend` and `operatorBurn`.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor`.\n *\n * Emits an `AuthorizedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor` and `defaultOperators`.\n *\n * Emits a `RevokedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if `authorizeOperator` was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * `revokeOperator`, in which case `isOperatorFor` will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n\n function decimals() external returns (uint8);\n\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n}\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IBridge {\n\n struct ClaimData {\n address payable to;\n uint256 amount;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) external payable;\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n */\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external returns (uint256 receivedAmount);\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns(bytes32);\n\n event Cross(\n address indexed _tokenAddress,\n address indexed _from,\n address indexed _to,\n uint256 _amount,\n bytes _userData\n );\n event NewSideToken(\n address indexed _newSideTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 _granularity\n );\n event AcceptedCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FeePercentageChanged(uint256 _amount);\n event Claimed(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _reciever,\n address _relayer,\n uint256 _fee\n );\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideToken {\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideTokenFactory {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\n\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../SideToken/SideToken.sol\";\n\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\n external onlyPrimary override returns(address) {\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\n emit SideTokenCreated(sideToken, symbol, granularity);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\nabstract contract Secondary is Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n constructor () {\n _primary = _msgSender();\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(_primary);\n }\n}\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\nimport \"../interface/IERC677Receiver.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../lib/LibEIP712.sol\";\n\ncontract SideToken is ISideToken, ERC777 {\n using Address for address;\n using SafeMath for uint256;\n\n address public minter;\n uint256 private _granularity;\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n bytes32 public domainSeparator;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n // ERC677 Transfer Event\n event Transfer(address,address,uint256,bytes);\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\n minter = _minterAddr;\n _granularity = _newGranularity;\n\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n domainSeparator = LibEIP712.hashEIP712Domain(\n name(),\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter override\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n /**\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\n * @param recipient The address to transfer to.\n * @param amount The amount to be transferred.\n * @param data The extra data to be passed to the receiving contract.\n */\n function transferAndCall(address recipient, uint amount, bytes calldata data)\n external returns (bool success)\n {\n address from = _msgSender();\n\n _send(from, from, recipient, amount, data, \"\", false);\n emit Transfer(from, recipient, amount, data);\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\n return true;\n }\n\n function granularity() public view override returns (uint256) {\n return _granularity;\n }\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\n bytes32 digest = LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../../token/ERC20/IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\n // See https://github.com/ethereum/solidity/issues/4024.\n\n // keccak256(\"ERC777TokensSender\")\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\n\n // keccak256(\"ERC777TokensRecipient\")\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping (address => mapping (address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(\n string memory aName,\n string memory aSymbol,\n address[] memory theDefaultOperators\n ) {\n _name = aName;\n _symbol = aSymbol;\n\n _defaultOperatorsArray = theDefaultOperators;\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\n _defaultOperators[_defaultOperatorsArray[i]] = true;\n }\n\n // register interfaces\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view override(IERC777) returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view override(IERC777) returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20Detailed-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override(IERC777) returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n\n address from = _msgSender();\n\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\n\n _move(from, from, recipient, amount, \"\", \"\");\n\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(\n address operator,\n address tokenHolder\n ) public view override(IERC777) returns (bool) {\n return operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) external override(IERC777) {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) external override(IERC777) {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n )\n external override(IERC777)\n {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {Transfer} events.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\n external override(IERC777) {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\n _burn(_msgSender(), account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender)\n public view override(IERC20) returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {Transfer} and {Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount)\n external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n require(holder != address(0), \"ERC777: transfer from zero address\");\n\n address spender = _msgSender();\n\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\n\n _move(spender, holder, recipient, amount, \"\", \"\");\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\n\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address operator,\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n require(account != address(0), \"ERC777: mint to zero address\");\n\n // Update state variables\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n internal\n {\n require(from != address(0), \"ERC777: send from zero address\");\n require(to != address(0), \"ERC777: send to zero address\");\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param operator address operator requesting the operation\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(\n address operator,\n address from,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n )\n internal\n {\n require(from != address(0), \"ERC777: burn from zero address\");\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n // Update state variables\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\n _balances[to] = _balances[to].add(amount);\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n function _approve(address holder, address spender, uint256 value) internal {\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\n // currently unnecessary.\n //require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n private\n {\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n}\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * `IERC777` Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an `IERC777` token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/Bridge/BridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"./IBridgeV2.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../AllowTokens/AllowTokensV0.sol\";\nimport \"../Utils/UtilsV1.sol\";\n\ncontract BridgeV2 is Initializable, IBridgeV2, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant private NULL_ADDRESS = address(0);\n bytes32 constant private NULL_HASH = bytes32(0);\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address private federation;\n uint256 private feePercentage;\n string public symbolPrefix;\n uint256 public lastDay;\n uint256 public spentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping(bytes32 => bool) public processed; // ProcessedHash => true\n AllowTokensV0 public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n uint256 constant public FEE_PERCENTAGE_DIVIDER = 10000; // Percentage with up to 2 decimals\n bool private alreadyRun;\n\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool isUpgrading);\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = AllowTokensV0(_allowTokens);\n _changeSideTokenFactory(_sideTokenFactory);\n _changeFederation(_federation);\n //keccak256(\"ERC777TokensRecipient\")\n ERC_1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function version() external pure override returns (string memory) {\n return \"v2\";\n }\n\n modifier onlyFederation() {\n require(msg.sender == federation, \"Bridge: Sender not Federation\");\n _;\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address tokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity\n ) external onlyFederation whenNotPaused nonReentrant override returns(bool) {\n require(tokenAddress != NULL_ADDRESS, \"Bridge: Token is null\");\n require(receiver != NULL_ADDRESS, \"Bridge: Receiver is null\");\n require(amount > 0, \"Bridge: Amount 0\");\n require(bytes(symbol).length > 0, \"Bridge: Empty symbol\");\n require(blockHash != NULL_HASH, \"Bridge: BlockHash is null\");\n require(transactionHash != NULL_HASH, \"Bridge: Transaction is null\");\n require(decimals <= 18, \"Bridge: Decimals bigger 18\");\n require(UtilsV1.granularityToDecimals(granularity) <= 18, \"Bridge: invalid granularity\");\n\n _processTransaction(blockHash, transactionHash, receiver, amount, logIndex);\n\n if (knownTokens[tokenAddress]) {\n _acceptCrossBackToToken(receiver, tokenAddress, decimals, granularity, amount);\n } else {\n _acceptCrossToSideToken(receiver, tokenAddress, decimals, granularity, amount, symbol);\n }\n return true;\n }\n\n function _acceptCrossToSideToken(\n address receiver,\n address tokenAddress,\n uint8 decimals,\n uint256 granularity,\n uint256 amount,\n string memory symbol\n ) private {\n\n (uint256 calculatedGranularity,uint256 formattedAmount) = UtilsV1.calculateGranularityAndAmount(decimals, granularity, amount);\n address sideToken = mappedTokens[tokenAddress];\n if (sideToken == NULL_ADDRESS) {\n sideToken = _createSideToken(tokenAddress, symbol, calculatedGranularity);\n } else {\n require(calculatedGranularity == IERC777(sideToken).granularity(), \"Bridge: Granularity differ from side token\");\n }\n ISideToken(sideToken).mint(receiver, formattedAmount, \"\", \"\");\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, 18, calculatedGranularity);\n }\n\n function _acceptCrossBackToToken(address receiver, address tokenAddress, uint8 decimals, uint256 granularity, uint256 amount) private {\n require(decimals == 18, \"Bridge: Invalid decimals cross back\");\n //As side tokens are ERC777 we need to convert granularity to decimals\n (uint8 calculatedDecimals, uint256 formattedAmount) = UtilsV1.calculateDecimalsAndAmount(tokenAddress, granularity, amount);\n IERC20(tokenAddress).safeTransfer(receiver, formattedAmount);\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, calculatedDecimals, 1);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokens(address tokenToUse, uint256 amount) override external whenNotUpgrading whenNotPaused nonReentrant returns(bool) {\n address sender = _msgSender();\n require(!sender.isContract(), \"Bridge: Sender can't be a contract\");\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, amount, \"\");\n return true;\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external whenNotPaused whenNotUpgrading override(IBridgeV2, IERC777Recipient) {\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to address\");\n address tokenToUse = _msgSender();\n //This can only be used with trusted contracts\n crossTokens(tokenToUse, from, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, uint256 amount, bytes memory userData) private {\n bool isASideToken = originalTokens[tokenToUse] != NULL_ADDRESS;\n //Send the payment to the MultiSig of the Federation\n uint256 fee = amount.mul(feePercentage).div(FEE_PERCENTAGE_DIVIDER);\n uint256 amountMinusFees = amount.sub(fee);\n if (isASideToken) {\n uint256 modulo = amountMinusFees.mod(IERC777(tokenToUse).granularity());\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n }\n if(fee > 0) {\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n if (isASideToken) {\n verifyWithAllowTokens(tokenToUse, amount, isASideToken);\n //Side Token Crossing\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n // solium-disable-next-line max-len\n emit Cross(originalTokens[tokenToUse], from, amountMinusFees, IERC777(tokenToUse).symbol(), userData, IERC777(tokenToUse).decimals(), IERC777(tokenToUse).granularity());\n } else {\n //Main Token Crossing\n knownTokens[tokenToUse] = true;\n (uint8 decimals, uint256 granularity, string memory symbol) = UtilsV1.getTokenInfo(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n //We consider the amount before fees converted to 18 decimals to check the limits\n verifyWithAllowTokens(tokenToUse, formattedAmount, isASideToken);\n emit Cross(tokenToUse, from, amountMinusFees, symbol, userData, decimals, granularity);\n }\n }\n\n function _createSideToken(address token, string memory symbol, uint256 granularity) private returns (address sideToken){\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, symbol));\n address sideTokenAddress = sideTokenFactory.createSideToken(newSymbol, newSymbol, granularity);\n sideToken = sideTokenAddress;\n mappedTokens[token] = sideToken;\n originalTokens[sideTokenAddress] = token;\n emit NewSideToken(sideTokenAddress, token, newSymbol, granularity);\n return sideToken;\n }\n\n function verifyWithAllowTokens(address tokenToUse, uint256 amount, bool isASideToken) private {\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n // solium-disable-next-line security/no-block-members\n lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n spentToday = 0;\n }\n require(allowTokens.isValidTokenTransfer(tokenToUse, amount, spentToday, isASideToken), \"Bridge: Bigger than limit\");\n spentToday = spentToday.add(amount);\n }\n\n function getTransactionId(\n bytes32 _blockHash,\n bytes32 _transactionHash,\n address _receiver,\n uint256 _amount,\n uint32 _logIndex\n )\n public pure returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _receiver, _amount, _logIndex));\n }\n\n function _processTransaction(\n bytes32 _blockHash,\n bytes32 _transactionHash,\n address _receiver,\n uint256 _amount,\n uint32 _logIndex\n )\n private\n {\n bytes32 compiledId = getTransactionId(_blockHash, _transactionHash, _receiver, _amount, _logIndex);\n require(!processed[compiledId], \"Bridge: Already processed\");\n processed[compiledId] = true;\n }\n\n function setFeePercentage(uint amount) external onlyOwner whenNotPaused {\n require(amount < (FEE_PERCENTAGE_DIVIDER/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() override external view returns(uint) {\n return feePercentage;\n }\n\n function calcMaxWithdraw() override external view returns (uint) {\n uint spent = spentToday;\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > lastDay + 24 hours) // solhint-disable-line not-rely-on-time\n spent = 0;\n return allowTokens.calcMaxWithdraw(spent);\n }\n\n function changeFederation(address newFederation) external onlyOwner returns(bool) {\n _changeFederation(newFederation);\n return true;\n }\n\n function _changeFederation(address newFederation) internal {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner returns(bool) {\n _changeSideTokenFactory(newSideTokenFactory);\n return true;\n }\n\n function _changeSideTokenFactory(address newSideTokenFactory) internal {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function startUpgrade() external onlyOwner {\n isUpgrading = true;\n emit Upgrading(isUpgrading);\n }\n\n function endUpgrade() external onlyOwner {\n isUpgrading = false;\n emit Upgrading(isUpgrading);\n }\n\n //This method is only to recreate the USDT and USDC tokens on rsk without granularity restrictions.\n function clearSideToken() external onlyOwner returns(bool) {\n require(!alreadyRun, \"already done\");\n alreadyRun = true;\n address payable[4] memory sideTokens = [\n 0xe506F698b31a66049BD4653ed934E7a07Cbc5549,\n 0x5a42221D7AaE8e185BC0054Bb036D9757eC18857,\n 0xcdc8ccBbFB6407c53118fE47259e8d00C81F42CD,\n 0x6117C9529F15c52e2d3188d5285C745B757b5825\n ];\n for (uint i = 0; i < sideTokens.length; i++) {\n address originalToken = address(originalTokens[sideTokens[i]]);\n originalTokens[sideTokens[i]] = NULL_ADDRESS;\n mappedTokens[originalToken] = address(NULL_ADDRESS);\n }\n return true;\n }\n\n}\n"
+ },
+ "contracts/Bridge/IBridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\ninterface IBridgeV2 {function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n function calcMaxWithdraw() external view returns (uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokens(address tokenToUse, uint256 amount) external returns(bool);\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the federation contract\n */\n function acceptTransfer(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity\n ) external returns(bool);\n\n event Cross(address indexed _tokenAddress, address indexed _to, uint256 _amount, string _symbol, bytes _userData,\n uint8 _decimals, uint256 _granularity);\n event NewSideToken(address indexed _newSideTokenAddress, address indexed _originalTokenAddress, string _newSymbol, uint256 _granularity);\n event AcceptedCrossTransfer(address indexed _tokenAddress, address indexed _to, uint256 _amount, uint8 _decimals, uint256 _granularity,\n uint256 _formattedAmount, uint8 _calculatedDecimals, uint256 _calculatedGranularity);\n event FeePercentageChanged(uint256 _amount);\n}"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract AllowTokensV0 is Ownable {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n\n mapping (address => bool) public allowedTokens;\n bool private validateAllowedTokens;\n uint256 private maxTokensAllowed;\n uint256 private minTokensAllowed;\n uint256 public dailyLimit;\n\n event AllowedTokenAdded(address indexed _tokenAddress);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event AllowedTokenValidation(bool _enabled);\n event MaxTokensAllowedChanged(uint256 _maxTokens);\n event MinTokensAllowedChanged(uint256 _minTokens);\n event DailyLimitChanged(uint256 dailyLimit);\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\n _;\n }\n\n constructor(address _manager) {\n transferOwnership(_manager);\n validateAllowedTokens = true;\n maxTokensAllowed = 10000 ether;\n minTokensAllowed = 1 ether;\n dailyLimit = 100000 ether;\n }\n\n function isValidatingAllowedTokens() external view returns(bool) {\n return validateAllowedTokens;\n }\n\n function getMaxTokensAllowed() external view returns(uint256) {\n return maxTokensAllowed;\n }\n\n function getMinTokensAllowed() external view returns(uint256) {\n return minTokensAllowed;\n }\n\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\n return allowedTokens[token];\n }\n\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\n if (validateAllowedTokens) {\n return allowedTokenExist(token);\n }\n return true;\n }\n\n function addAllowedToken(address token) external onlyOwner {\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\n allowedTokens[token] = true;\n emit AllowedTokenAdded(token);\n }\n\n function removeAllowedToken(address token) external onlyOwner {\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\n allowedTokens[token] = false;\n emit AllowedTokenRemoved(token);\n }\n\n function enableAllowedTokensValidation() external onlyOwner {\n validateAllowedTokens = true;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function disableAllowedTokensValidation() external onlyOwner {\n // Before disabling Allowed Tokens Validations some kind of contract validation system\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\n validateAllowedTokens = false;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\n maxTokensAllowed = maxTokens;\n emit MaxTokensAllowedChanged(maxTokensAllowed);\n }\n\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\n minTokensAllowed = minTokens;\n emit MinTokensAllowedChanged(minTokensAllowed);\n }\n\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\n dailyLimit = _dailyLimit;\n emit DailyLimitChanged(_dailyLimit);\n }\n\n // solium-disable-next-line max-len\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\n if(amount > maxTokensAllowed)\n return false;\n if(amount < minTokensAllowed)\n return false;\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\n return false;\n if(!isSideToken && !isTokenAllowed(tokenToUse))\n return false;\n return true;\n }\n\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\n uint maxWithrow = dailyLimit - spentToday;\n if (dailyLimit < spentToday)\n return 0;\n if(maxWithrow > maxTokensAllowed)\n maxWithrow = maxTokensAllowed;\n return maxWithrow;\n }\n\n}\n"
+ },
+ "contracts/Utils/UtilsV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nlibrary UtilsV1 {\n using SafeMath for uint256;\n\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n // keccak256(\"ERC777Token\")\n bytes32 constant private TOKENS_ERC777_HASH = 0xac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054;\n\n function getTokenInfo(address tokenToUse) external view returns (uint8 decimals, uint256 granularity, string memory symbol) {\n decimals = getDecimals(tokenToUse);\n granularity = getGranularity(tokenToUse);\n symbol = getSymbol(tokenToUse);\n }\n\n function getSymbol(address tokenToUse) public view returns (string memory symbol) {\n //support 32 bytes or string symbol\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"symbol()\"));\n require(success, \"Utils: Token hasn't symbol()\");\n if (data.length == 32) {\n symbol = bytes32ToString(abi.decode(data, (bytes32)));\n } else {\n symbol = abi.decode(data, (string));\n }\n require(bytes(symbol).length > 0, \"Utils: Token empty symbol\");\n return symbol;\n }\n\n function getDecimals(address tokenToUse) public view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"Utils: No decimals\");\n require(data.length == 32, \"Utils: Decimals not uint\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n uint256 decimalsDecoded = abi.decode(data, (uint256));\n require(decimalsDecoded <= 18, \"Utils: Decimals not in 0 to 18\");\n return uint8(decimalsDecoded);\n }\n\n function getGranularity(address tokenToUse) public view returns (uint256 granularity) {\n granularity = 1;\n //support granularity if ERC777\n address implementer = ERC_1820.getInterfaceImplementer(tokenToUse, TOKENS_ERC777_HASH);\n if (implementer != address(0)) {\n granularity = IERC777(implementer).granularity();\n //Verify granularity is power of 10 to keep it compatible with ERC20 decimals\n granularityToDecimals(granularity);\n }\n return granularity;\n }\n\n /* bytes32 (fixed-size array) to string (dynamically-sized array) */\n function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) {\n uint8 i = 0;\n while(i < 32 && _bytes32[i] != 0) {\n i++;\n }\n bytes memory bytesArray = new bytes(i);\n for (i = 0; i < 32 && _bytes32[i] != 0; i++) {\n bytesArray[i] = _bytes32[i];\n }\n return string(bytesArray);\n }\n\n function decimalsToGranularity(uint8 decimals) public pure returns (uint256) {\n require(decimals <= 18, \"Utils: Decimals not in 0 to 18\");\n return uint256(10)**(18-decimals);\n }\n\n function granularityToDecimals(uint256 granularity) public pure returns (uint8) {\n if(granularity == 1) return 18;\n if(granularity == 10) return 17;\n if(granularity == 100) return 16;\n if(granularity == 1000) return 15;\n if(granularity == 10000) return 14;\n if(granularity == 100000) return 13;\n if(granularity == 1000000) return 12;\n if(granularity == 10000000) return 11;\n if(granularity == 100000000) return 10;\n if(granularity == 1000000000) return 9;\n if(granularity == 10000000000) return 8;\n if(granularity == 100000000000) return 7;\n if(granularity == 1000000000000) return 6;\n if(granularity == 10000000000000) return 5;\n if(granularity == 100000000000000) return 4;\n if(granularity == 1000000000000000) return 3;\n if(granularity == 10000000000000000) return 2;\n if(granularity == 100000000000000000) return 1;\n if(granularity == 1000000000000000000) return 0;\n require(false, \"Utils: invalid granularity\");\n return 0;\n }\n\n function calculateGranularityAndAmount(uint8 decimals, uint256 granularity, uint256 amount) external pure\n returns(uint256 calculatedGranularity, uint256 formattedAmount) {\n\n if(decimals == 18) {\n //tokenAddress is a ERC20 with 18 decimals should have 1 granularity\n //tokenAddress is a ERC777 token we give the same granularity\n calculatedGranularity = granularity;\n formattedAmount = amount;\n } else {\n //tokenAddress is a ERC20 with other than 18 decimals\n calculatedGranularity = decimalsToGranularity(decimals);\n formattedAmount = amount.mul(calculatedGranularity);\n }\n }\n\n function calculateDecimalsAndAmount(address tokenAddress, uint256 granularity, uint256 amount)\n external view returns (uint8 calculatedDecimals, uint256 formattedAmount) {\n uint8 tokenDecimals = getDecimals(tokenAddress);\n //As side tokens are ERC777 we need to convert granularity to decimals\n calculatedDecimals = granularityToDecimals(granularity);\n require(tokenDecimals == calculatedDecimals, \"Utils: Token decimals differ from decimals - granularity\");\n formattedAmount = amount.div(granularity);\n }\n\n}\n"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () {\n _owner = _msgSender();\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../interface/IBridge.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockReceiveTokensCall is IERC777Recipient {\n address public bridge;\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor(address _bridge) {\n bridge = _bridge;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount) external {\n IERC20(tokenToUse).approve(bridge, amount);\n IBridge(bridge).receiveTokensTo(tokenToUse, receiver, amount);\n }\n\n function callDepositTo(address receiver) external payable {\n IBridge(bridge).depositTo{ value: msg.value }(receiver);\n }\n\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\n IERC777(tokenToUse).send(bridge, amount, data);\n }\n\n // Mandatory for IERC777Recipient\n function tokensReceived(\n address,\n address,\n address,\n uint,\n bytes calldata,\n bytes calldata\n ) override external view {\n this;\n }\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockERC777Recipient is IERC777Recipient {\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor() {\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\n }\n\n event Success(\n address operator,\n address from,\n address to,\n uint amount,\n bytes userData,\n bytes operatorData);\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) override external {\n emit Success(operator, from, to, amount, userData, operatorData);\n }\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\n\ncontract SideTokenV1 is ERC777 {\n address public minter;\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\n minter = _minterAddr;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../SideToken/SideTokenV1.sol\";\n\ncontract SideTokenFactoryV1 is Secondary {\n event CreatedSideToken(address sideToken, string symbol);\n\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\n emit CreatedSideToken(address(sideToken), symbol);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using SafeMath for uint256;\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping (uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /*\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri_) {\n _setURI(uri_);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) external view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: balance query for the zero address\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(amount);\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, address(0), id, amount);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\n /**\n @dev Handles the receipt of a single ERC1155 token type. This function is\n called at the end of a `safeTransferFrom` after the balance has been updated.\n To accept the transfer, this must return\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n (i.e. 0xf23a6e61, or its own function selector).\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n )\n external\n returns(bytes4);\n\n /**\n @dev Handles the receipt of a multiple ERC1155 token types. This function\n is called at the end of a `safeBatchTransferFrom` after the balances have\n been updated. To accept the transfer(s), this must return\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n (i.e. 0xbc197c81, or its own function selector).\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match values array)\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n )\n external\n returns(bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC1155 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Pausable is ERC1155, Pausable {\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\nimport \"../access/roles/PauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context, PauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n constructor () {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract PauserRole is Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n constructor () {\n _addPauser(_msgSender());\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC721.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC721 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC721Pausable is ERC721, Pausable {\n /**\n * @dev See {ERC721-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../../zeppelin/ownership/Ownable.sol\";\nimport \"../../zeppelin/math/SafeMath.sol\";\nimport \"../../zeppelin/utils/Strings.sol\";\nimport \"./OpenSeaEIP712Base.sol\";\n\n\n/**\n * @title OpenSea721\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\n */\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\n using SafeMath for uint256;\n\n uint256 private _currentTokenId = 0;\n\n constructor(\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n _initializeEIP712(_name);\n }\n\n function baseTokenURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/api/creature/\";\n }\n\n function contractURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\n }\n\n /**\n * @dev Mints a token to an address with a tokenURI.\n * @param _to address of the future owner of the token\n */\n function mintTo(address _to) public onlyOwner {\n uint256 newTokenId = _getNextTokenId();\n _mint(_to, newTokenId);\n _incrementTokenId();\n }\n\n /**\n * @dev calculates the next token ID based on value of _currentTokenId\n * @return uint256 for the next token ID\n */\n function _getNextTokenId() private view returns (uint256) {\n return _currentTokenId.add(1);\n }\n\n /**\n * @dev increments the value of _currentTokenId\n */\n function _incrementTokenId() private {\n _currentTokenId++;\n }\n\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\n }\n\n}"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../zeppelin/upgradable/Initializable.sol\";\n\ncontract OpenSeaEIP712Base is Initializable {\n struct EIP712Domain {\n string name;\n string version;\n address verifyingContract;\n bytes32 salt;\n }\n\n string constant public ERC712_VERSION = \"1\";\n\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\n bytes(\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\n )\n );\n bytes32 internal domainSeperator;\n\n // supposed to be called once while initializing.\n // one of the contracts that inherits this contract follows proxy pattern\n // so it is not possible to do this in a constructor\n function _initializeEIP712(\n string memory name\n )\n internal\n initializer\n {\n _setDomainSeperator(name);\n }\n\n function _setDomainSeperator(string memory name) internal {\n domainSeperator = keccak256(\n abi.encode(\n EIP712_DOMAIN_TYPEHASH,\n keccak256(bytes(name)),\n keccak256(bytes(ERC712_VERSION)),\n address(this),\n bytes32(getChainId())\n )\n );\n }\n\n function getDomainSeperator() public view returns (bytes32) {\n return domainSeperator;\n }\n\n function getChainId() public pure returns (uint256) {\n uint256 id;\n assembly {\n id := chainid()\n }\n return id;\n }\n\n /**\n * Accept message hash and returns hash message in EIP712 compatible form\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\n * https://eips.ethereum.org/EIPS/eip-712\n * \"\\\\x19\" makes the encoding deterministic\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\n */\n function toTypedMessageHash(bytes32 messageHash)\n internal\n view\n returns (bytes32)\n {\n return\n keccak256(\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\n );\n }\n}\n"
+ },
+ "contracts/Federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../interface/IBridge.sol\";\n\ncontract FederationV2 is Initializable, UpgradableOwnable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridge public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\n public validRequirement(_members.length, _required) initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n }\n\n function version() external pure returns (string memory) {\n return \"v2\";\n }\n\n function setBridge(address _bridge) external onlyOwner {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridge(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n )\n public onlyMember returns(bool)\n {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32)\n {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}"
+ },
+ "contracts/Federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../nftbridge/INFTBridge.sol\";\nimport \"../interface/IBridge.sol\";\nimport \"../interface/IFederation.sol\";\n\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridge public bridge;\n address[] public members;\n\n /**\n @notice The minimum amount of votes to approve a transaction\n @dev It should have more members than the required amount\n */\n uint public required;\n\n /**\n @notice All the addresses that are members of the federation\n @dev The address should be a member to vote in transactions\n */\n mapping (address => bool) public isMember;\n\n /**\n (bytes32) transactionId = keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n ) => (\n (address) members => (bool) voted\n )\n @notice Votes by members by the transaction ID\n @dev usually the members should approve the transaction by 50% + 1\n */\n mapping (bytes32 => mapping (address => bool)) public votes;\n\n /**\n (bytes32) transactionId => (bool) voted\n @notice Check if that transaction was already processed\n */\n mapping(bytes32 => bool) public processed;\n\n /** Federator v3 variables */\n INFTBridge public bridgeNFT;\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner, address _bridgeNFT) public\n validRequirement(_members.length, _required) initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n _setNFTBridge(_bridgeNFT);\n }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure override returns (string memory) {\n return \"v3\";\n }\n\n /**\n @notice Sets a new bridge contract\n @dev Emits BridgeChanged event\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external onlyOwner override {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridge(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n /**\n @notice Sets a new NFT bridge contract\n @dev Emits NFTBridgeChanged event\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external onlyOwner override {\n _setNFTBridge(_bridgeNFT);\n }\n\n function _setNFTBridge(address _bridgeNFT) internal {\n require(_bridgeNFT != NULL_ADDRESS, \"Federation: Empty NFT bridge\");\n bridgeNFT = INFTBridge(_bridgeNFT);\n emit NFTBridgeChanged(_bridgeNFT);\n }\n\n function validateTransaction(bytes32 transactionId) internal view returns(bool) {\n uint transactionCount = getTransactionCount(transactionId);\n return transactionCount >= required && transactionCount >= members.length / 2 + 1;\n }\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) external onlyMember override {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return;\n\n if (votes[transactionId][_msgSender()])\n return;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n logIndex\n );\n\n if (validateTransaction(transactionId)) {\n processed[transactionId] = true;\n acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex,\n tokenType\n );\n\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n logIndex\n );\n return;\n }\n }\n\n function acceptTransfer(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) internal {\n if (tokenType == TokenType.NFT) {\n require(address(bridgeNFT) != NULL_ADDRESS, \"Federation: Empty NFTBridge\");\n bridgeNFT.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n return;\n }\n\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n }\n\n /**\n @notice Get the amount of approved votes for that transactionId\n @param transactionId The transaction hashed from getTransactionId function\n */\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n /**\n @notice Gets the hash of transaction from the following parameters encoded and keccaked\n @dev It encodes and applies keccak256 to the parameters received in the same order\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param amount Could be the amount or the tokenId\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @return The hash generated by the parameters.\n */\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32) {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner override\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner override\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view override returns (address[] memory) {\n return members;\n }\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @dev Emits the RequirementChange event\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n /**\n @notice It emits an HeartBeat like an health check\n @dev Emits HeartBeat event\n */\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember override {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface IFederation {\n enum TokenType{ COIN, NFT }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure returns (string memory);\n\n /**\n @notice Sets a new bridge contract\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external;\n\n /**\n @notice Sets a new NFT bridge contract\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external;\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) external;\n\n /**\n @notice Add a new member to the federation\n @param _newMember address of the new member\n */\n function addMember(address _newMember) external;\n\n /**\n @notice Remove a member of the federation\n @param _oldMember address of the member to be removed from federation\n */\n function removeMember(address _oldMember) external;\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view returns (address[] memory);\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external;\n\n /**\n @notice It emmits an HeartBeat like an healthy check\n */\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event NFTBridgeChanged(address bridgeNFT);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n}\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract MinterRole is Context {\n using Roles for Roles.Role;\n\n event MinterAdded(address indexed account);\n event MinterRemoved(address indexed account);\n\n Roles.Role private _minters;\n\n constructor () {\n _addMinter(_msgSender());\n }\n\n modifier onlyMinter() {\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\n _;\n }\n\n function isMinter(address account) public view returns (bool) {\n return _minters.has(account);\n }\n\n function addMinter(address account) public onlyMinter {\n _addMinter(account);\n }\n\n function renounceMinter() public {\n _removeMinter(_msgSender());\n }\n\n function _addMinter(address account) internal {\n _minters.add(account);\n emit MinterAdded(account);\n }\n\n function _removeMinter(address account) internal {\n _minters.remove(account);\n emit MinterRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20Mintable}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() override public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) override public view returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) override public returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) override public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) override public returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal {\n require(sender != address(0), \"ERC20: transfer from zero address\");\n require(recipient != address(0), \"ERC20: transfer to zero address\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: mint to zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: burn from zero address\");\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n *\n * This is internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal {\n require(owner != address(0), \"ERC20: approve from zero address\");\n require(spender != address(0), \"ERC20: approve to zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\n * from the caller's allowance.\n *\n * See {_burn} and {_approve}.\n */\n function _burnFrom(address account, uint256 amount) internal {\n _burn(account, amount);\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\n }\n}\n"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\nimport \"../interface/IERC677Receiver.sol\";\n\ncontract mockERC677Receiver is IERC677Receiver {\n event Success(address _sender, uint _value, bytes _data);\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\n emit Success(_sender, _value, _data);\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Optional functions from the ERC20 standard.\n */\nabstract contract ERC20Detailed is IERC20 {\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\n * these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\n _name = aName;\n _symbol = aSymbol;\n _decimals = theDecimals;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./Proxy.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n *\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\n * {TransparentUpgradeableProxy}.\n */\ncontract UpgradeableProxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _setImplementation(_logic);\n if(_data.length > 0) {\n Address.functionDelegateCall(_logic, _data);\n }\n }\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n bytes32 slot = _IMPLEMENTATION_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n impl := sload(slot)\n }\n }\n\n /**\n * @dev Upgrades the proxy to a new implementation.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal virtual {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\n\n bytes32 slot = _IMPLEMENTATION_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newImplementation)\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./UpgradeableProxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _setAdmin(admin_);\n }\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _admin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _admin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\n emit AdminChanged(_admin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external virtual ifAdmin {\n _upgradeTo(newImplementation);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\n _upgradeTo(newImplementation);\n Address.functionDelegateCall(newImplementation, data);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address adm) {\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n adm := sload(slot)\n }\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n bytes32 slot = _ADMIN_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newAdmin)\n }\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../ownership/Ownable.sol\";\nimport \"./TransparentUpgradeableProxy.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
+ },
+ "contracts/Federation/FederationV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../Bridge/IBridgeV2.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract FederationV1 is Ownable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridgeV2 public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n // solium-disable-next-line max-len\n event Voted(address indexed sender, bytes32 indexed transactionId, address originalTokenAddress, address receiver, uint256 amount, string symbol, bytes32 blockHash, bytes32 indexed transactionHash, uint32 logIndex, uint8 decimals, uint256 granularity);\n event Executed(bytes32 indexed transactionId);\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Caller not a Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n constructor(address[] memory _members, uint _required) validRequirement(_members.length, _required) {\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Members larger than max allowed\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n }\n\n function setBridge(address _bridge) external onlyOwner {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridgeV2(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity)\n external onlyMember returns(bool)\n {\n // solium-disable-next-line max-len\n bytes32 transactionId = getTransactionId(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n // solium-disable-next-line max-len\n emit Voted(_msgSender(), transactionId, originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bool acceptTransfer = bridge.acceptTransfer(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n require(acceptTransfer, \"Federation: Bridge acceptTransfer error\");\n emit Executed(transactionId);\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string memory symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity)\n public pure returns(bytes32)\n {\n // solium-disable-next-line max-len\n return keccak256(abi.encodePacked(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity));\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove last element\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n}"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\n\ncontract BridgeProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract FederationProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract MainToken is ERC20Detailed, ERC20 {\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\n ERC20Detailed(name, symbol, decimals)\n {\n _mint(msg.sender, totalSupply);\n }\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\n bool result = transfer(_to, _value);\n if (!result) return false;\n\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\n receiver.tokenFallback(msg.sender, _value, _data);\n\n // IMPORTANT: the ERC-677 specification does not say\n // anything about the use of the receiver contract's\n // tokenFallback method return value. Given\n // its return type matches with this method's return\n // type, returning it could be a possibility.\n // We here take the more conservative approach and\n // ignore the return value, returning true\n // to signal a succesful transfer despite tokenFallback's\n // return value -- fact being tokens are transferred\n // in any case.\n return true;\n }\n}\n\ninterface ERC677TransferReceiver {\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\n}"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract AlternativeERC20Detailed is ERC20 {\n string private _name;\n bytes32 private _symbol;\n uint256 private _decimals;\n\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\n {\n _name = aName;\n _symbol = aSymbol;\n _decimals = someDecimals;\n _mint(msg.sender, aTotalSupply);\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (bytes32) {\n return _symbol;\n }\n\n function decimals() public view returns (uint256) {\n return _decimals;\n }\n}"
+ },
+ "contracts/test/nftbridge/NFTERC721TestToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.6;\n\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\n\ncontract NFTERC721TestToken is ERC721 {\n\n string private _contractURI;\n\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\n\n function safeMint(address to, uint256 tokenId) public {\n _safeMint(to, tokenId);\n }\n\n function setBaseURI(string memory baseURI) public {\n _setBaseURI(baseURI);\n }\n\n function setContractURI(string memory contractURI_) public {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n function setTokenURI(uint256 tokenId, string memory _tokenURI) public {\n _setTokenURI(tokenId, _tokenURI);\n }\n\n}\n"
+ },
+ "contracts/nftbridge/SideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ISideNFTToken.sol\";\nimport \"../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\n\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\n address public minter;\n string private _contractURI;\n\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\n require(_minter != address(0), \"SideToken: Empty Minter\");\n minter = _minter;\n _setBaseURI(_baseURI);\n _setContractURI(contractURI_);\n }\n\n function _setContractURI(string memory contractURI_) internal {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(address account, uint256 tokenId) external onlyMinter override {\n _mint(account, tokenId);\n }\n}"
+ },
+ "contracts/nftbridge/SideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"./SideNFTToken.sol\";\n\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external onlyPrimary override returns(address) {\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\n return sideTokenAddress;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() {\n _registerInterface(\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\n );\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721Receiver.sol\";\n\n /**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers. \n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Burnable is ERC1155 {\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n}\n"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../lib/LibUtils.sol\";\n\ncontract LibUtilsHarness {\n\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\n return LibUtils.decimalsToGranularity(decimals);\n }\n\n function getDecimals(address tokenToUse) external view returns (uint8) {\n return LibUtils.getDecimals(tokenToUse);\n }\n\n function getGranularity(address tokenToUse) external view returns (uint256) {\n return LibUtils.getGranularity(tokenToUse);\n }\n\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\n return LibUtils.bytesToAddress(bys);\n }\n\n}\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnet/solcInputs/f27c8e19ddc2cd2a95162a1eabc0e272.json b/bridge/deployments/rsktestnet/solcInputs/f27c8e19ddc2cd2a95162a1eabc0e272.json
new file mode 100644
index 000000000..3b6294411
--- /dev/null
+++ b/bridge/deployments/rsktestnet/solcInputs/f27c8e19ddc2cd2a95162a1eabc0e272.json
@@ -0,0 +1,294 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/math/SafeMath.sol\";\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\n\nimport \"../interface/IAllowTokens.sol\";\n\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\n\tusing SafeMath for uint256;\n\n\taddress constant private NULL_ADDRESS = address(0);\n\tuint256 constant public MAX_TYPES = 250;\n\tmapping (address => TokenInfo) public allowedTokens;\n\tmapping (uint256 => Limits) public typeLimits;\n\tuint256 public smallAmountConfirmations;\n\tuint256 public mediumAmountConfirmations;\n\tuint256 public largeAmountConfirmations;\n\tstring[] public typeDescriptions;\n\n\tevent SetToken(address indexed _tokenAddress, uint256 _typeId);\n\tevent AllowedTokenRemoved(address indexed _tokenAddress);\n\tevent TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\n\tevent TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\n\tevent UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\n\tevent ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\n\n\tmodifier notNull(address _address) {\n\t\trequire(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\n\t\t_;\n\t}\n\n\tfunction initialize(\n\t\taddress _manager,\n\t\taddress _primary,\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations,\n\t\tTypeInfo[] memory typesInfo) public initializer {\n\t\tUpgradableOwnable.initialize(_manager);\n\t\tUpgradableSecondary.__Secondary_init(_primary);\n\t\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t\tfor(uint i = 0; i < typesInfo.length; i = i + 1) {\n\t\t\t_addTokenType(typesInfo[i].description, typesInfo[i].limits);\n\t\t}\n\t}\n\n\tfunction version() override external pure returns (string memory) {\n\t\treturn \"v1\";\n\t}\n\n\tfunction tokenInfo(address tokenAddress) public view returns(TokenInfo memory) {\n\t\treturn allowedTokens[tokenAddress];\n\t}\n\n\tfunction setTokenInfoByTokenAddress(address tokenAddress, TokenInfo memory info) public {\n\t\trequire(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n\t\tallowedTokens[tokenAddress] = info;\n\t}\n\n\tfunction getInfoAndLimits(\n\t\taddress tokenAddress\n\t) public view override returns (\n\t\tTokenInfo memory info,\n\t\tLimits memory limit\n\t) {\n\t\tinfo = tokenInfo(tokenAddress);\n\t\tlimit = typeLimits[info.typeId];\n\t\treturn (info, limit);\n\t}\n\n\tfunction calcMaxWithdraw(address token) public view override returns (uint256 maxWithdraw) {\n\t\t(TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\n\t\treturn _calcMaxWithdraw(info, limits);\n\t}\n\n\tfunction _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\n\t\t// solium-disable-next-line security/no-block-members\n\t\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n\t\t\tinfo.spentToday = 0;\n\t\t}\n\t\tif (limits.daily <= info.spentToday) {\n\t\t\treturn 0;\n\t\t}\n\t\tmaxWithdraw = limits.daily - info.spentToday;\n\t\tif (maxWithdraw > limits.max) {\n\t\t\tmaxWithdraw = limits.max;\n\t\t}\n\t\treturn maxWithdraw;\n\t}\n\n\tfunction updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\n\t\t(TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\n\t\trequire(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\n\t\trequire(amount >= limit.min, \"AllowTokens: Lower than limit\");\n\n\t\t// solium-disable-next-line security/no-block-members\n\t\tif (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n\t\t\t// solium-disable-next-line security/no-block-members\n\t\t\tinfo.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n\t\t\tinfo.spentToday = 0;\n\t\t}\n\t\tuint maxWithdraw = _calcMaxWithdraw(info, limit);\n\t\trequire(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\n\t\tinfo.spentToday = info.spentToday.add(amount);\n\t\tsetTokenInfoByTokenAddress(token, info);\n\n\t\temit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\n\t}\n\n\tfunction _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\n\t\trequire(bytes(description).length > 0, \"AllowTokens: Empty description\");\n\t\tlen = typeDescriptions.length;\n\t\trequire(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\n\t\ttypeDescriptions.push(description);\n\t\t_setTypeLimits(len, limits);\n\t\temit TokenTypeAdded(len, description);\n\t\treturn len;\n\t}\n\n\tfunction addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\n\t\treturn _addTokenType(description, limits);\n\t}\n\n\tfunction _setTypeLimits(uint256 typeId, Limits memory limits) private {\n\t\trequire(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\n\t\trequire(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\n\t\trequire(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\n\t\trequire(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\n\t\trequire(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\n\t\ttypeLimits[typeId] = limits;\n\t\temit TypeLimitsChanged(typeId, limits);\n\t}\n\n\tfunction setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\n\t\t_setTypeLimits(typeId, limits);\n\t}\n\n\tfunction getTypesLimits() external view override returns(Limits[] memory limits) {\n\t\tlimits = new Limits[](typeDescriptions.length);\n\t\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\n\t\t\tlimits[i] = typeLimits[i];\n\t\t}\n\t\treturn limits;\n\t}\n\n\tfunction getTypeDescriptionsLength() external view override returns(uint256) {\n\t\treturn typeDescriptions.length;\n\t}\n\n\tfunction getTypeDescriptions() external view override returns(string[] memory descriptions) {\n\t\tdescriptions = new string[](typeDescriptions.length);\n\t\tfor (uint256 i = 0; i < typeDescriptions.length; i++) {\n\t\t\tdescriptions[i] = typeDescriptions[i];\n\t\t}\n\t\treturn descriptions;\n\t}\n\n\tfunction isTokenAllowed(address token) public view notNull(token) override returns (bool) {\n\t\treturn tokenInfo(token).allowed;\n\t}\n\n\tfunction setToken(address token, uint256 typeId) override public notNull(token) {\n\t\trequire(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n\t\trequire(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\n\t\tTokenInfo memory info = tokenInfo(token);\n\t\tinfo.allowed = true;\n\t\tinfo.typeId = typeId;\n\t\tsetTokenInfoByTokenAddress(token, info);\n\t\temit SetToken(token, typeId);\n\t}\n\n\tfunction setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\n\t\trequire(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\n\t\tfor(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\n\t\t\tsetToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\n\t\t}\n\t}\n\n\tfunction removeAllowedToken(address token) external notNull(token) onlyOwner {\n\t\tTokenInfo memory info = tokenInfo(token);\n\t\trequire(info.allowed, \"AllowTokens: Not Allowed\");\n\t\tinfo.allowed = false;\n\t\tsetTokenInfoByTokenAddress(token, info);\n\t\temit AllowedTokenRemoved(token);\n\t}\n\n\tfunction setConfirmations(\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations) external onlyOwner {\n\t\t_setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t}\n\n\tfunction _setConfirmations(\n\t\tuint256 _smallAmountConfirmations,\n\t\tuint256 _mediumAmountConfirmations,\n\t\tuint256 _largeAmountConfirmations) private {\n\t\trequire(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\n\t\trequire(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\n\t\tsmallAmountConfirmations = _smallAmountConfirmations;\n\t\tmediumAmountConfirmations = _mediumAmountConfirmations;\n\t\tlargeAmountConfirmations = _largeAmountConfirmations;\n\t\temit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n\t}\n\n\tfunction getConfirmations() external view override\n\t\treturns (\n\t\tuint256 smallAmount,\n\t\tuint256 mediumAmount,\n\t\tuint256 largeAmount\n\t) {\n\t\treturn (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\n\t}\n\n}\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @title Initializable\n *\n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(initializing || !initialized, \"Contract instance is already initialized\");\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\n * the owner.\n */\ncontract UpgradableOwnable is Initializable, Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function initialize(address sender) public initializer {\n _owner = sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * > Note: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\ncontract UpgradableSecondary is Initializable, Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n function __Secondary_init(address sender) public initializer {\n _primary = sender;\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(recipient);\n }\n\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IAllowTokens {\n\n\tstruct Limits {\n\t\tuint256 min;\n\t\tuint256 max;\n\t\tuint256 daily;\n\t\tuint256 mediumAmount;\n\t\tuint256 largeAmount;\n\t}\n\n\tstruct TokenInfo {\n\t\tbool allowed;\n\t\tuint256 typeId;\n\t\tuint256 spentToday;\n\t\tuint256 lastDay;\n\t}\n\n\tstruct TypeInfo {\n\t\tstring description;\n\t\tLimits limits;\n\t}\n\n\tstruct TokensAndType {\n\t\taddress token;\n\t\tuint256 typeId;\n\t}\n\n\tfunction version() external pure returns (string memory);\n\n\tfunction getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\n\n\tfunction calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\n\n\tfunction getTypesLimits() external view returns(Limits[] memory limits);\n\n\tfunction getTypeDescriptionsLength() external view returns(uint256);\n\n\tfunction getTypeDescriptions() external view returns(string[] memory descriptions);\n\n\tfunction setToken(address token, uint256 typeId) external;\n\n\tfunction getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\n\n\tfunction isTokenAllowed(address token) external view returns (bool);\n\n\tfunction updateTokenTransfer(address token, uint256 amount) external;\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n\n function _msgSender() internal view returns (address payable) {\n return payable(msg.sender);\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
+ },
+ "contracts/nftbridge/NFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC721/IERC721.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Metadata.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Enumerable.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Receiver.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./INFTBridge.sol\";\nimport \"./ISideNFTToken.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract NFTBridge is\n Initializable,\n INFTBridge,\n UpgradablePausable,\n UpgradableOwnable,\n ReentrancyGuard,\n IERC721Receiver {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address internal constant NULL_ADDRESS = address(0);\n bytes32 internal constant NULL_HASH = bytes32(0);\n IERC1820Registry internal constant ERC1820 =\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address payable internal federation;\n uint256 internal fixedFee;\n\n mapping(uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain;\n mapping(address => OriginalNft) public originalTokenBySideToken;\n mapping(uint256 => mapping(address => bool)) public isAddressFromCrossedOriginalTokenByChain; // uint256 => address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n\n IAllowTokens public allowTokens;\n ISideNFTTokenFactory public sideTokenFactory;\n bool public isUpgrading;\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\n event Upgrading(bool _isUpgrading);\n\n function initialize(\n address _manager,\n address payable _federation,\n address _allowTokens,\n address _sideTokenFactory\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\n federation = _federation;\n ERC1820.setInterfaceImplementer(\n address(this),\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\n address(this)\n );\n }\n\n function version() external pure override returns (string memory) {\n return \"v1\";\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _tokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n uint256\t_destinationChainId\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"NFTBridge: Not Federation\");\n checkChainId(_originChainId);\n shouldBeCurrentChainId(_destinationChainId);\n require(\n isAddressFromCrossedOriginalToken(_originChainId, _tokenAddress) ||\n getSideTokenByOriginalToken(_originChainId, _tokenAddress) != NULL_ADDRESS,\n \"NFTBridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"NFTBridge: Null To\");\n require(_from != NULL_ADDRESS, \"NFTBridge: Null From\");\n require(_blockHash != NULL_HASH, \"NFTBridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"NFTBridge: Null TxHash\");\n require(\n transactionDataHashes[_transactionHash] == bytes32(0),\n \"NFTBridge: Already accepted\"\n );\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _blockHash,\n _transactionHash,\n _logIndex,\n _originChainId,\n\t _destinationChainId\n );\n\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\n require(!claimed[_transactionDataHash], \"NFTBridge: Already claimed\");\n transactionDataHashes[_transactionHash] = _transactionDataHash;\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\n// senderAddresses[_transactionHash] = _from;\n\n emit AcceptedNFTCrossTransfer(\n _transactionHash,\n _tokenAddress,\n _to,\n _from,\n _tokenId,\n _blockHash,\n _logIndex,\n _originChainId,\n\t _destinationChainId\n );\n }\n\n function shouldBeCurrentChainId(uint256 chainId) internal view {\n require(chainId == block.chainid, \"NFTBridge: Not block.chainid\");\n }\n\n function getSideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\n return sideTokenByOriginalTokenByChain[chainId][originalToken];\n }\n\n function _setSideTokenByOriginalToken(uint256 chainId, address originalToken, address sideToken) internal {\n sideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\n }\n\n function getOriginalTokenBySideToken(address sideToken) public view returns(OriginalNft memory) {\n return originalTokenBySideToken[sideToken];\n }\n\n function _setOriginalTokenBySideToken(address sideToken, OriginalNft memory originalToken) internal {\n originalTokenBySideToken[sideToken] = originalToken;\n }\n\n function isAddressFromCrossedOriginalToken(uint256 chainId, address originalToken) public view returns(bool addressHasCrossed) {\n return isAddressFromCrossedOriginalTokenByChain[chainId][originalToken];\n }\n\n function _setAddressFromCrossedOriginalToken(uint256 chainId, address originalToken, bool addressHasCrossed) internal {\n isAddressFromCrossedOriginalTokenByChain[chainId][originalToken] = addressHasCrossed;\n }\n\n function createSideNFTToken(\n address _originalTokenAddress,\n string calldata _tokenSymbol,\n string calldata _tokenName,\n string calldata _baseURI,\n string calldata _contractURI,\n uint256 originChainId\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"NFTBridge: Null original token address\");\n\n require(getSideTokenByOriginalToken(originChainId, _originalTokenAddress) == NULL_ADDRESS, \"NFTBridge: Side token already exists\");\n\n // Create side token\n address sideTokenAddress = sideTokenFactory.createSideNFTToken(_tokenName, _tokenSymbol, _baseURI, _contractURI);\n\n _setSideTokenByOriginalToken(originChainId, _originalTokenAddress, sideTokenAddress);\n\n OriginalNft memory originalNft;\n originalNft.originChainId = originChainId;\n originalNft.nftAddress = _originalTokenAddress;\n _setOriginalTokenBySideToken(sideTokenAddress, originalNft);\n\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, _tokenSymbol, originChainId);\n }\n\n function checkChainId(uint256 chainId) internal pure {\n require(chainId > 0, \"NFTBridge: ChainId is 0\");\n }\n\n function claim(NFTClaimData calldata _claimData) external override {\n _claim(_claimData, _claimData.to);\n }\n\n function claimFallback(NFTClaimData calldata _claimData) external override {\n require(_msgSender() == _claimData.from, \"NFTBridge: invalid sender\");\n _claim(_claimData, _msgSender());\n }\n\n function _claim(\n NFTClaimData calldata _claimData,\n address payable _receiver\n ) internal {\n address tokenAddress = _claimData.tokenAddress;\n uint256 tokenId = _claimData.tokenId;\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.from,\n tokenId,\n tokenAddress,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex,\n _claimData.originChainId,\n block.chainid\n );\n\n\n require(\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\n \"NFTBridge: Wrong txDataHash\"\n );\n require(!claimed[transactionDataHash], \"NFTBridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (isAddressFromCrossedOriginalToken(_claimData.originChainId, tokenAddress)) {\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\n } else {\n address sideTokenAddress = getSideTokenByOriginalToken(_claimData.originChainId, tokenAddress);\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\n }\n\n emit ClaimedNFTToken(\n _claimData.transactionHash,\n tokenAddress,\n _claimData.to,\n _claimData.from,\n _claimData.tokenId,\n _claimData.blockHash,\n _claimData.logIndex,\n _receiver,\n _claimData.originChainId,\n block.chainid\n );\n }\n\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\"creator()\"));\n if (success) {\n return abi.decode(data, (address));\n }\n\n return IERC721(tokenAddress).ownerOf(tokenId);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId,\n uint256 destinationChainId\n ) public payable override {\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\n address payable sender = _msgSender();\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\n\n crossTokens(tokenAddress, to, tokenCreator, tokenId, destinationChainId, \"\");\n\n if (fixedFee == 0) {\n return;\n }\n uint256 msgValue = msg.value;\n require(msgValue >= fixedFee, \"NFTBridge: value is smaller than fixed fee\");\n\n // Send the payment to the MultiSig of the Federation\n federation.transfer(fixedFee);\n\n if (msgValue > fixedFee) { // refund of unused value\n sender.transfer(msgValue.sub(fixedFee));\n }\n }\n\n function crossTokens(\n address tokenAddress,\n address to,\n address tokenCreator,\n uint256 tokenId,\n uint256 destinationChainId,\n bytes memory userData\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\n require(block.chainid != destinationChainId, \"NFTBridge: destination chain id equal current chain id\");\n _setAddressFromCrossedOriginalToken(destinationChainId, tokenAddress, true);\n\n string memory tokenURI = IERC721Metadata(tokenAddress).tokenURI(tokenId);\n\n OriginalNft memory originalToken = getOriginalTokenBySideToken(tokenAddress);\n address originalTokenAddress = tokenAddress;\n if (originalToken.nftAddress != NULL_ADDRESS) {\n ERC721Burnable(tokenAddress).burn(tokenId);\n originalTokenAddress = originalToken.nftAddress;\n }\n\n uint256 totalSupply = IERC721Enumerable(tokenAddress).totalSupply();\n emit Cross(\n originalTokenAddress,\n to,\n destinationChainId,\n _msgSender(),\n block.chainid,\n tokenCreator,\n totalSupply,\n tokenId,\n tokenURI,\n userData\n );\n }\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n ) public pure override returns (bytes32) {\n return keccak256(\n abi.encodePacked(\n _blockHash,\n _transactionHash,\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _logIndex,\n _originChainId,\n _destinationChainId\n )\n );\n }\n\n function setFixedFee(uint256 amount) external onlyOwner {\n fixedFee = amount;\n emit FixedFeeNFTChanged(fixedFee);\n }\n\n function getFixedFee() external view override returns (uint256) {\n return fixedFee;\n }\n\n function changeFederation(address payable newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"NFTBridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"NFTBridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns (address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\n require(\n newSideNFTTokenFactory != NULL_ADDRESS,\n \"NFTBridge: empty SideTokenFactory\"\n );\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionDataHashes[transactionHash]];\n }\n\n /**\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\n/**\n * @title Helps contracts guard against reentrancy attacks.\n * @author Remco Bloemen , Eenae \n * @dev If you mark a function `nonReentrant`, you should also\n * mark it `external`.\n */\ncontract ReentrancyGuard is Initializable {\n /// @dev counter to allow mutex lock with only one SSTORE operation\n uint256 private _guardCounter;\n\n function initialize() public initializer {\n // The counter starts at one to prevent changing it from zero to a non-zero\n // value, which is a more expensive operation.\n _guardCounter = 1;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _guardCounter += 1;\n uint256 localCounter = _guardCounter;\n _;\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\n }\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\nimport \"../access/roles/UpgradablePauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n function __Pausable_init(address sender) public initializer {\n UpgradablePauserRole.__PauserRol_init(sender);\n\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as `account`'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `_account`.\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `_implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\n\n /**\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `_account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {ERC20Detailed}.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeERC20: low-level call failed\");\n\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n */\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./ERC721.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721Burnable is Context, ERC721 {\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n _burn(tokenId);\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\nlibrary LibEIP712 {\n\n // Hash of the EIP712 Domain Separator Schema\n // keccak256(abi.encodePacked(\n // \"EIP712Domain(\",\n // \"string name,\",\n // \"string version,\",\n // \"uint256 chainId,\",\n // \"address verifyingContract\",\n // \")\"\n // ))\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n /// @dev Calculates a EIP712 domain separator.\n /// @param name The EIP712 domain name.\n /// @param version The EIP712 domain version.\n /// @param verifyingContract The EIP712 verifying contract.\n /// @return result EIP712 domain separator.\n function hashEIP712Domain(\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n // keccak256(bytes(name)),\n // keccak256(bytes(version)),\n // chainId,\n // uint256(verifyingContract)\n // ))\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Calculate hashes of dynamic data\n let nameHash := keccak256(add(name, 32), mload(name))\n let versionHash := keccak256(add(version, 32), mload(version))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n // Store params in memory\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), nameHash)\n mstore(add(memPtr, 64), versionHash)\n mstore(add(memPtr, 96), chainId)\n mstore(add(memPtr, 128), verifyingContract)\n\n // Compute hash\n result := keccak256(memPtr, 160)\n }\n return result;\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\n /// with getDomainHash().\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to the given EIP712 Domain.\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n internal\n pure\n returns (bytes32 result)\n {\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct\n // ));\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nlibrary LibUtils {\n\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\n return uint256(10)**(18-decimals);\n }\n\n function getDecimals(address tokenToUse) internal view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"LibUtils: No decimals\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n return uint8(abi.decode(data, (uint256)));\n }\n\n function getGranularity(address tokenToUse) internal view returns (uint256) {\n //support granularity if ERC777\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\n require(success, \"LibUtils: No granularity\");\n\n return abi.decode(data, (uint256));\n }\n\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n addr := mload(add(bys,20))\n }\n }\n\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\n require(_bytes.length >= _start + 20, \"LibUtils: toAddress_outOfBounds\");\n address tempAddress;\n\n assembly {\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n }\n\n return tempAddress;\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\n require(_bytes.length >= _start + 16, \"LibUtils: toUint128_outOfBounds\");\n uint128 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x10), _start))\n }\n\n return tempUint;\n }\n\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\n\t\trequire(_bytes.length >= _start + 32, \"LibUtils: toUint256_outOfBounds\");\n\t\tuint256 tempUint;\n\n // solium-disable-next-line security/no-inline-assembly\n\t\tassembly {\n\t\t\ttempUint := mload(add(add(_bytes, 0x20), _start))\n\t\t}\n\n\t\treturn tempUint;\n\t}\n}\n"
+ },
+ "contracts/nftbridge/INFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface INFTBridge {\n\n struct NFTClaimData {\n address payable to;\n address from;\n uint256 tokenId;\n address tokenAddress;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n uint256 originChainId;\n }\n\n\tstruct OriginalNft {\n\t\taddress nftAddress;\n\t\tuint256 originChainId;\n\t}\n\n function version() external pure returns (string memory);\n\n function getFixedFee() external view returns (uint256);\n\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId,\n uint256 destinationChainId\n ) external payable;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\n */\n function claim(NFTClaimData calldata _claimData) external;\n\n function claimFallback(NFTClaimData calldata _claimData) external;\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex,\n uint256 _originChainId,\n\t\tuint256\t_destinationChainId\n ) external returns (bytes32);\n\n event Cross(\n address indexed _originalTokenAddress,\n address indexed _to,\n uint256 indexed _destinationChainId,\n address _from,\n uint256 _originChainId,\n address _tokenCreator,\n uint256 _totalSupply,\n uint256 _tokenId,\n string _tokenURI,\n bytes _userData\n );\n\n event NewSideNFTToken(\n address indexed _newSideNFTTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 originChainId\n );\n event AcceptedNFTCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n );\n event FixedFeeNFTChanged(uint256 _amount);\n event ClaimedNFTToken(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _receiver,\n uint256 _originChainId,\n\t uint256\t_destinationChainId\n );\n}\n"
+ },
+ "contracts/nftbridge/ISideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideNFTToken {\n function mint(address account, uint256 tokenId) external;\n}"
+ },
+ "contracts/nftbridge/ISideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideNFTTokenFactory {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external returns(address);\n\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IWrapped {\n function balanceOf(address) external returns(uint);\n\n function deposit() external payable;\n\n function withdraw(uint wad) external;\n\n function totalSupply() external view returns (uint);\n\n function approve(address guy, uint wad) external returns (bool);\n\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad)\n external\n returns (bool);\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../Initializable.sol\";\n\nimport \"../../../GSN/Context.sol\";\nimport \"../../../access/Roles.sol\";\n\ncontract UpgradablePauserRole is Initializable, Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n function __PauserRol_init(address sender) public initializer {\n if (!isPauser(sender)) {\n _addPauser(sender);\n }\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @title Roles\n * @dev Library for managing addresses assigned to a Role.\n */\nlibrary Roles {\n struct Role {\n mapping (address => bool) bearer;\n }\n\n /**\n * @dev Give an account access to this role.\n */\n function add(Role storage role, address account) internal {\n require(!has(role, account), \"Roles: account already has role\");\n role.bearer[account] = true;\n }\n\n /**\n * @dev Remove an account's access to this role.\n */\n function remove(Role storage role, address account) internal {\n require(has(role, account), \"Roles: account doesn't have role\");\n role.bearer[account] = false;\n }\n\n /**\n * @dev Check if an account has this role.\n * @return bool\n */\n function has(Role storage role, address account) internal view returns (bool) {\n require(account != address(0), \"Roles: account is the zero address\");\n return role.bearer[account];\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _tokenOwners.contains(tokenId);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(tokenId);\n\n emit Transfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n}\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n}\n"
+ },
+ "contracts/test/nftbridge/NFTInheritedBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport \"../../nftbridge/NFTBridge.sol\";\n\ncontract NFTInheritedBridge is NFTBridge {\n function checkChainIdExposed(uint256 chainId) public pure {\n return checkChainId(chainId);\n } \n\n function shouldBeCurrentChainIdExposed(uint256 chainId) public view {\n return shouldBeCurrentChainId(chainId);\n } \n}"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract WRBTC is IWrapped {\n string public name = \"Wrapped RBTC\";\n string public symbol = \"WRBTC\";\n uint8 public decimals = 18;\n\n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n event Deposit(address indexed dst, uint wad);\n event Withdrawal(address indexed src, uint wad);\n\n mapping (address => uint) override public balanceOf;\n mapping (address => mapping (address => uint)) public allowance;\n\n receive () external payable {\n deposit();\n }\n function deposit() override public payable {\n balanceOf[msg.sender] += msg.value;\n emit Deposit(msg.sender, msg.value);\n }\n function withdraw(uint wad) override public {\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\n balanceOf[msg.sender] -= wad;\n (bool success, ) = msg.sender.call{value:wad, gas:23000}(\"\");\n require(success, \"WRBTC: transfer fail\");\n emit Withdrawal(msg.sender, wad);\n }\n\n function totalSupply() override public view returns (uint) {\n return address(this).balance;\n }\n\n function approve(address guy, uint wad) override public returns (bool) {\n allowance[msg.sender][guy] = wad;\n emit Approval(msg.sender, guy, wad);\n return true;\n }\n\n function transfer(address dst, uint wad) override public returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad)\n override public\n returns (bool)\n {\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\n\n if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\n allowance[src][msg.sender] -= wad;\n }\n\n balanceOf[src] -= wad;\n balanceOf[dst] += wad;\n\n emit Transfer(src, dst, wad);\n\n return true;\n }\n}"
+ },
+ "contracts/Bridge/BridgeV3.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// import \"hardhat/console.sol\";\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./IBridgeV3.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n\ncontract BridgeV3 is Initializable, IBridgeV3, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant internal NULL_ADDRESS = address(0);\n bytes32 constant internal NULL_HASH = bytes32(0);\n IERC1820Registry constant internal erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address internal federation;\n uint256 internal feePercentage;\n string public symbolPrefix;\n bytes32 public DOMAIN_SEPARATOR; // replaces uint256 internal _depprecatedLastDay;\n uint256 internal _deprecatedSpentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n uint256 constant public feePercentageDivider = 10000; // Porcentage with up to 2 decimals\n //Bridge_v3 variables\n bytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\");\n IWrapped public wrappedCurrency;\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n // keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\n mapping(address => uint) public nonces;\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool _isUpgrading);\n event WrappedCurrencyChanged(address _wrappedCurrency);\n\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n federation = _federation;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n initDomainSeparator();\n }\n\n receive () external payable {\n // The fallback function is needed to use WRBTC\n require(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n }\n\n function version() override external pure returns (string memory) {\n return \"v3\";\n }\n\n function initDomainSeparator() public {\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n DOMAIN_SEPARATOR = LibEIP712.hashEIP712Domain(\n \"RSK Token Bridge\",\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"Bridge: Not Federation\");\n require(knownTokens[_originalTokenAddress] ||\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\n \"Bridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"Bridge: Null To\");\n require(_amount > 0, \"Bridge: Amount 0\");\n require(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _amount,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed also has the previously processed using the older bridge version\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n require(!claimed[_transactionDataHash], \"Bridge: Already claimed\");\n\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\n senderAddresses[_transactionHash] = _from;\n\n emit AcceptedCrossTransfer(\n _transactionHash,\n _originalTokenAddress,\n _to,\n _from,\n _amount,\n _blockHash,\n _logIndex\n );\n }\n\n\n function createSideToken(\n uint256 _typeId,\n address _originalTokenAddress,\n uint8 _originalTokenDecimals,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n address sideToken = mappedTokens[_originalTokenAddress];\n require(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\n\n mappedTokens[_originalTokenAddress] = sideToken;\n originalTokens[sideToken] = _originalTokenAddress;\n allowTokens.setToken(sideToken, _typeId);\n\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\n }\n\n function claim(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function claimFallback(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n receivedAmount = _claim(\n _claimData,\n _msgSender(),\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function getDigest(\n ClaimData memory _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline\n ) internal returns (bytes32) {\n return LibEIP712.hashEIP712Message(\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n CLAIM_TYPEHASH,\n _claimData.to,\n _claimData.amount,\n _claimData.transactionHash,\n _relayer,\n _fee,\n nonces[_claimData.to]++,\n _deadline\n )\n )\n );\n }\n\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external override returns (uint256 receivedAmount) {\n require(_deadline >= block.timestamp, \"Bridge: EXPIRED\");\n\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claim(\n ClaimData calldata _claimData,\n address payable _reciever,\n address payable _relayer,\n uint256 _fee\n ) internal nonReentrant returns (uint256 receivedAmount) {\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n require(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.amount,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n require(!claimed[transactionDataHash], \"Bridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (knownTokens[originalTokenAddress]) {\n receivedAmount =_claimCrossBackToToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n } else {\n receivedAmount =_claimCrossToSideToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n }\n emit Claimed(\n _claimData.transactionHash,\n originalTokenAddress,\n _claimData.to,\n senderAddresses[_claimData.transactionHash],\n _claimData.amount,\n _claimData.blockHash,\n _claimData.logIndex,\n _reciever,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claimCrossToSideToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n address sideToken = mappedTokens[_originalTokenAddress];\n uint256 granularity = IERC777(sideToken).granularity();\n uint256 formattedAmount = _amount.mul(granularity);\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n ISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n if(_fee > 0) {\n ISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n }\n return receivedAmount;\n }\n\n function _claimCrossBackToToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n //As side tokens are ERC777 they will always have 18 decimals\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n if(address(wrappedCurrency) == _originalTokenAddress) {\n wrappedCurrency.withdraw(formattedAmount);\n _receiver.transfer(receivedAmount);\n if(_fee > 0) {\n _relayer.transfer(_fee);\n }\n } else {\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n if(_fee > 0) {\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n }\n }\n return receivedAmount;\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\n address sender = _msgSender();\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, to, amount, \"\");\n }\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) override external payable {\n address sender = _msgSender();\n require(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n wrappedCurrency.deposit{ value: msg.value }();\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \"\");\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external override(IBridgeV3, IERC777Recipient){\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to this address\");\n address tokenToUse = _msgSender();\n require(erc1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n require(userData.length != 0 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\n crossTokens(tokenToUse, from, receiver, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\n internal whenNotUpgrading whenNotPaused nonReentrant {\n knownTokens[tokenToUse] = true;\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n uint256 amountMinusFees = amount.sub(fee);\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n // We consider the amount before fees converted to 18 decimals to check the limits\n // updateTokenTransfer revert if token not allowed\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n address originalTokenAddress = tokenToUse;\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\n //Side Token Crossing\n originalTokenAddress = originalTokens[tokenToUse];\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\n uint256 modulo = amountMinusFees.mod(granularity);\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n }\n\n emit Cross(\n originalTokenAddress,\n from,\n to,\n amountMinusFees,\n userData\n );\n\n if (fee > 0) {\n //Send the payment to the MultiSig of the Federation\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n }\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n )\n public pure override returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n }\n\n function setFeePercentage(uint amount) external onlyOwner {\n require(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() external view override returns(uint) {\n return feePercentage;\n }\n\n function changeFederation(address newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n require(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n wrappedCurrency = IWrapped(_wrappedCurrency);\n emit WrappedCurrencyChanged(_wrappedCurrency);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionsDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionsDataHashes[transactionHash]];\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an `IERC777` token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See `IERC1820Registry` and\n * `ERC1820Implementer`.\n */\ninterface IERC777 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See `operatorSend` and `operatorBurn`.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor`.\n *\n * Emits an `AuthorizedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor` and `defaultOperators`.\n *\n * Emits a `RevokedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if `authorizeOperator` was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * `revokeOperator`, in which case `isOperatorFor` will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n\n function decimals() external returns (uint8);\n\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n}\n"
+ },
+ "contracts/Bridge/IBridgeV3.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IBridgeV3 {\n\n struct ClaimData {\n address payable to;\n uint256 amount;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) external payable;\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n */\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external returns (uint256 receivedAmount);\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns(bytes32);\n\n event Cross(\n address indexed _tokenAddress,\n address indexed _from,\n address indexed _to,\n uint256 _amount,\n bytes _userData\n );\n event NewSideToken(\n address indexed _newSideTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 _granularity\n );\n event AcceptedCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FeePercentageChanged(uint256 _amount);\n event Claimed(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _reciever,\n address _relayer,\n uint256 _fee\n );\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideToken {\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface ISideTokenFactory {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\n\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../SideToken/SideToken.sol\";\n\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\n external onlyPrimary override returns(address) {\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\n emit SideTokenCreated(sideToken, symbol, granularity);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\nabstract contract Secondary is Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n constructor () {\n _primary = _msgSender();\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(_primary);\n }\n}\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\nimport \"../interface/IERC677Receiver.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../lib/LibEIP712.sol\";\n\ncontract SideToken is ISideToken, ERC777 {\n using SafeMath for uint256;\n\n address public minter;\n uint256 private _granularity;\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n bytes32 public domainSeparator;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n // ERC677 Transfer Event\n event Transfer(address,address,uint256,bytes);\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\n minter = _minterAddr;\n _granularity = _newGranularity;\n\n domainSeparator = LibEIP712.hashEIP712Domain(\n name(),\n \"1\",\n block.chainid,\n address(this)\n );\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter override\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n /**\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\n * @param recipient The address to transfer to.\n * @param amount The amount to be transferred.\n * @param data The extra data to be passed to the receiving contract.\n */\n function transferAndCall(address recipient, uint amount, bytes calldata data)\n external returns (bool success)\n {\n address from = _msgSender();\n\n _send(from, from, recipient, amount, data, \"\", false);\n emit Transfer(from, recipient, amount, data);\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\n return true;\n }\n\n function granularity() public view override returns (uint256) {\n return _granularity;\n }\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\n bytes32 digest = LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../../token/ERC20/IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\n // See https://github.com/ethereum/solidity/issues/4024.\n\n // keccak256(\"ERC777TokensSender\")\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\n\n // keccak256(\"ERC777TokensRecipient\")\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping (address => mapping (address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(\n string memory aName,\n string memory aSymbol,\n address[] memory theDefaultOperators\n ) {\n _name = aName;\n _symbol = aSymbol;\n\n _defaultOperatorsArray = theDefaultOperators;\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\n _defaultOperators[_defaultOperatorsArray[i]] = true;\n }\n\n // register interfaces\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view override(IERC777) returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view override(IERC777) returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20Detailed-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override(IERC777) returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n\n address from = _msgSender();\n\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\n\n _move(from, from, recipient, amount, \"\", \"\");\n\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(\n address operator,\n address tokenHolder\n ) public view override(IERC777) returns (bool) {\n return operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) external override(IERC777) {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) external override(IERC777) {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n )\n external override(IERC777)\n {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {Transfer} events.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\n external override(IERC777) {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\n _burn(_msgSender(), account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender)\n public view override(IERC20) returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {Transfer} and {Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount)\n external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n require(holder != address(0), \"ERC777: transfer from zero address\");\n\n address spender = _msgSender();\n\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\n\n _move(spender, holder, recipient, amount, \"\", \"\");\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\n\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address operator,\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n require(account != address(0), \"ERC777: mint to zero address\");\n\n // Update state variables\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n internal\n {\n require(from != address(0), \"ERC777: send from zero address\");\n require(to != address(0), \"ERC777: send to zero address\");\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param operator address operator requesting the operation\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(\n address operator,\n address from,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n )\n internal\n {\n require(from != address(0), \"ERC777: burn from zero address\");\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n // Update state variables\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\n _balances[to] = _balances[to].add(amount);\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n function _approve(address holder, address spender, uint256 value) internal {\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\n // currently unnecessary.\n //require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n private\n {\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n}\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * `IERC777` Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an `IERC777` token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// import \"hardhat/console.sol\";\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n\tusing SafeMath for uint256;\n\tusing SafeERC20 for IERC20;\n\tusing Address for address;\n\n\taddress constant internal NULL_ADDRESS = address(0);\n\tbytes32 constant internal NULL_HASH = bytes32(0);\n\tIERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n\taddress internal federation;\n\tuint256 internal feePercentage;\n\tstring public deprecatedSymbolPrefix;\n\t// domainSeparator replaces uint256 internal _depprecatedLastDay;\n\tbytes32 public domainSeparator;\n\tuint256 internal _deprecatedSpentToday;\n\n\tmapping (address => address) public deprecatedMappedTokens; // OriginalToken => SideToken\n\tmapping (address => address) public deprecatedOriginalTokens; // SideToken => OriginalToken\n\tmapping (address => bool) public deprecatedKnownTokens; // OriginalToken => true\n\n\t// claimed can use the same of bytes32\n\tmapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n\n\tIAllowTokens public allowTokens;\n\tISideTokenFactory public sideTokenFactory;\n\t//Bridge_v1 variables\n\tbool public isUpgrading;\n\t// Percentage with up to 2 decimals\n\tuint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\n\t//Bridge_v2 variables\n\tbytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\n\tIWrapped public wrappedCurrency;\n\tmapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n\tmapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n\tmapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n\t// keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,uint256 originChainId,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n\tbytes32 public constant CLAIM_TYPEHASH = 0xaf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c;\n\tmapping(address => uint) public nonces;\n\n\t//Bridge_v3 variables multichain\n\tmapping (uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain; // chainId => OriginalToken Address => SideToken Address\n\tmapping (address => OriginalToken) public originalTokenBySideToken; // SideTokenAddress => struct {}\n\tmapping (uint256 => mapping(address => bool)) public knownTokenByChain; // chainId => OriginalToken Address => Know\n\n\tevent AllowTokensChanged(address _newAllowTokens);\n\tevent FederationChanged(address _newFederation);\n\tevent SideTokenFactoryChanged(address _newSideTokenFactory);\n\tevent Upgrading(bool _isUpgrading);\n\tevent WrappedCurrencyChanged(address _wrappedCurrency);\n\n\tfunction initialize(\n\t\taddress _manager,\n\t\taddress _federation,\n\t\taddress _allowTokens,\n\t\taddress _sideTokenFactory\n\t) public initializer {\n\t\tUpgradableOwnable.initialize(_manager);\n\t\tUpgradablePausable.__Pausable_init(_manager);\n\t\tallowTokens = IAllowTokens(_allowTokens);\n\t\tsideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n\t\tfederation = _federation;\n\t\t//keccak256(\"ERC777TokensRecipient\")\n\t\tERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n\t\tinitDomainSeparator();\n\t}\n\n\treceive () external payable {\n\t\t// The fallback function is needed to use WRBTC\n\t\trequire(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n\t}\n\n\tfunction version() override external pure returns (string memory) {\n\t\treturn \"v4\";\n\t}\n\n\tfunction initDomainSeparator() public {\n\t\tdomainSeparator = LibEIP712.hashEIP712Domain(\n\t\t\t\"RSK Token Bridge\",\n\t\t\t\"1\",\n\t\t\tblock.chainid,\n\t\t\taddress(this)\n\t\t);\n\t}\n\n\tmodifier whenNotUpgrading() {\n\t\trequire(!isUpgrading, \"Bridge: Upgrading\");\n\t\t_;\n\t}\n\n\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\n\t\trequire(chainId == block.chainid, \"Bridge: Not block.chainid\");\n\t}\n\n\tfunction sideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {\n\t\taddress sideTokenAddr = sideTokenByOriginalTokenByChain[chainId][originalToken];\n\n\t\tif (sideTokenAddr != NULL_ADDRESS) {\n\t\t\treturn sideTokenAddr;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\treturn deprecatedMappedTokens[originalToken];\n\t}\n\n\tfunction setSideTokenByOriginalAddressByChain(uint256 chainId, address originalToken, address sideToken) public onlyOwner {\n\t\tsideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;\n\t}\n\n\tfunction getOriginalTokenBySideToken(address sideToken) public view returns(OriginalToken memory originalToken) {\n\t\toriginalToken = originalTokenBySideToken[sideToken];\n\t\tif (originalToken.tokenAddress != NULL_ADDRESS) {\n\t\t\treturn originalToken;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\toriginalToken.originChainId = 1; // ethereum main chain id\n\t\toriginalToken.tokenAddress = deprecatedOriginalTokens[sideToken];\n\t\treturn originalToken;\n\t}\n\n\tfunction setOriginalTokenBySideTokenByChain(address sideToken, OriginalToken memory originalToken) public onlyOwner {\n\t\toriginalTokenBySideToken[sideToken] = originalToken;\n\t}\n\n\tfunction knownToken(uint256 chainId, address originalToken) public view returns(bool) {\n\t\tbool knowToken = knownTokenByChain[chainId][originalToken];\n\t\tif (knowToken) {\n\t\t\treturn knowToken;\n\t\t}\n\n\t\t// specification for retrocompatibility\n\t\treturn deprecatedKnownTokens[originalToken];\n\t}\n\n\tfunction _setKnownTokenByChain(uint256 chainId, address originalToken, bool knownTokenValue) internal {\n\t\tknownTokenByChain[chainId][originalToken] = knownTokenValue;\n\t}\n\n\tfunction acceptTransfer(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _from,\n\t\taddress payable _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) external whenNotPaused nonReentrant override {\n\t\trequire(_msgSender() == federation, \"Bridge: Not Federation\");\n\t\tcheckChainId(_originChainId);\n\t\tshouldBeCurrentChainId(_destinationChainId);\n\t\trequire(knownToken(_originChainId, _originalTokenAddress) ||\n\t\t\tsideTokenByOriginalToken(_originChainId, _originalTokenAddress) != NULL_ADDRESS,\n\t\t\t\"Bridge: Unknown token\"\n\t\t);\n\t\trequire(_to != NULL_ADDRESS, \"Bridge: Null To\");\n\t\trequire(_amount > 0, \"Bridge: Amount 0\");\n\t\trequire(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n\t\trequire(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n\t\trequire(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n\t\tbytes32 _transactionDataHash = getTransactionDataHash(\n\t\t\t_to,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_transactionHash,\n\t\t\t_logIndex\n\t\t);\n\n\t\tbytes32 _transactionDataHashMultichain = getTransactionDataHash(\n\t\t\t_to,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_transactionHash,\n\t\t\t_logIndex,\n\t\t\t_originChainId,\n\t\t\t_destinationChainId\n\t\t);\n\t\t// Do not remove, claimed also has the previously processed using the older bridge version\n\t\t// https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n\t\trequire(!isClaimed(_transactionDataHash, _transactionDataHashMultichain), \"Bridge: Already claimed\");\n\n\t\ttransactionsDataHashes[_transactionHash] = _transactionDataHashMultichain;\n\t\toriginalTokenAddresses[_transactionHash] = _originalTokenAddress;\n\t\tsenderAddresses[_transactionHash] = _from;\n\n\t\temit AcceptedCrossTransfer(\n\t\t\t_transactionHash,\n\t\t\t_originalTokenAddress,\n\t\t\t_to,\n\t\t\t_from,\n\t\t\t_amount,\n\t\t\t_blockHash,\n\t\t\t_logIndex,\n\t\t\t_originChainId,\n\t\t\t_destinationChainId\n\t\t);\n\t}\n\n\tfunction checkChainId(uint256 chainId) internal pure {\n\t\trequire(chainId > 0, \"Bridge: ChainId is 0\");\n\t}\n\n\tfunction createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _tokenSymbol,\n\t\tstring calldata _tokenName,\n\t\tuint256 _originChainId\n\t) external onlyOwner override {\n\t\trequire(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n\t\tcheckChainId(_originChainId);\n\t\taddress sideToken = sideTokenByOriginalToken(_originChainId, _originalTokenAddress);\n\t\trequire(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n\n\t\tuint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n\n\t\t// Create side token\n\t\tsideToken = sideTokenFactory.createSideToken(_tokenName, _tokenSymbol, granularity);\n\n\t\tsetSideTokenByOriginalAddressByChain(_originChainId, _originalTokenAddress, sideToken);\n\n\t\tOriginalToken memory originalToken;\n\t\toriginalToken.originChainId = _originChainId;\n\t\toriginalToken.tokenAddress = _originalTokenAddress;\n\t\tsetOriginalTokenBySideTokenByChain(sideToken, originalToken);\n\t\tallowTokens.setToken(sideToken, _typeId);\n\n\t\temit NewSideToken(sideToken, _originalTokenAddress, _tokenSymbol, granularity, _originChainId);\n\t}\n\n\tfunction claim(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\n\t\treceivedAmount = _claim(\n\t\t\t_claimData,\n\t\t\t_claimData.to,\n\t\t\tpayable(address(0)),\n\t\t\t0\n\t\t);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction claimFallback(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {\n\t\trequire(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n\t\treceivedAmount = _claim(\n\t\t\t_claimData,\n\t\t\t_msgSender(),\n\t\t\tpayable(address(0)),\n\t\t\t0\n\t\t);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction getDigest(\n\t\tClaimData memory _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline\n\t) internal returns (bytes32) {\n\t\treturn LibEIP712.hashEIP712Message(\n\t\t\tdomainSeparator,\n\t\t\tkeccak256(\n\t\t\t\tabi.encode(\n\t\t\t\t\tCLAIM_TYPEHASH,\n\t\t\t\t\t_claimData.to,\n\t\t\t\t\t_claimData.amount,\n\t\t\t\t\t_claimData.transactionHash,\n\t\t\t\t\t_claimData.originChainId,\n\t\t\t\t\t_relayer,\n\t\t\t\t\t_fee,\n\t\t\t\t\tnonces[_claimData.to]++,\n\t\t\t\t\t_deadline\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t}\n\n\t// Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n\tfunction claimGasless(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline,\n\t\tuint8 _v,\n\t\tbytes32 _r,\n\t\tbytes32 _s\n\t) external override returns (uint256 receivedAmount) {\n\t\trequire(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\n\n\t\tbytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n\t\taddress recoveredAddress = ecrecover(digest, _v, _r, _s);\n\t\trequire(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n\t\treturn _claim(\n\t\t\t_claimData,\n\t\t\t_claimData.to,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\t}\n\n\tfunction isClaimed(bytes32 transactionDataHash, bytes32 transactionDataHashMultichain) public view returns(bool) {\n\t\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\n\t}\n\n\tfunction isClaimed(ClaimData calldata _claimData, bytes32 transactionDataHashMultichain) public view returns(bool) {\n\t\tbytes32 transactionDataHash = getTransactionDataHash(\n\t\t\t_claimData.to,\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.transactionHash,\n\t\t\t_claimData.logIndex\n\t\t);\n\n\t\treturn claimed[transactionDataHash] || claimed[transactionDataHashMultichain];\n\t}\n\n\tfunction _claim(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _reciever,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal nonReentrant returns (uint256 receivedAmount) {\n\t\taddress originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n\t\trequire(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n\t\tbytes32 transactionDataHash = getTransactionDataHash(\n\t\t\t_claimData.to,\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.transactionHash,\n\t\t\t_claimData.logIndex,\n\t\t\t_claimData.originChainId,\n\t\t\tblock.chainid\n\t\t);\n\n\t\trequire(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n\t\trequire(!isClaimed(_claimData, transactionDataHash), \"Bridge: Already claimed\");\n\t\tclaimed[transactionDataHash] = true;\n\n\t\treceivedAmount = _claimCross(\n\t\t\t_claimData.originChainId,\n\t\t\toriginalTokenAddress,\n\t\t\t_reciever,\n\t\t\t_claimData.amount,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\n\t\temitClaimed(_claimData, originalTokenAddress, _reciever, _relayer, _fee);\n\t\treturn receivedAmount;\n\t}\n\n\tfunction emitClaimed(\n\t\tClaimData calldata _claimData,\n\t\taddress _originalTokenAddress,\n\t\taddress payable _reciever,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal {\n\t\temit Claimed(\n\t\t\t_claimData.transactionHash,\n\t\t\t_originalTokenAddress,\n\t\t\t_claimData.to,\n\t\t\tsenderAddresses[_claimData.transactionHash],\n\t\t\t_claimData.amount,\n\t\t\t_claimData.blockHash,\n\t\t\t_claimData.logIndex,\n\t\t\t_reciever,\n\t\t\t_relayer,\n\t\t\t_fee,\n\t\t\t_claimData.originChainId,\n\t\t\tblock.chainid\n\t\t);\n\t}\n\n\tfunction _claimCross(\n\t\tuint256 _originalChainId,\n\t\taddress _originalTokenAddress,\n\t\taddress payable _reciever,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256) {\n\t\tcheckChainId(_originalChainId);\n\t\tif (knownToken(_originalChainId, _originalTokenAddress)) {\n\t\t\treturn _claimCrossBackToToken(\n\t\t\t\t_originalTokenAddress,\n\t\t\t\t_reciever,\n\t\t\t\t_amount,\n\t\t\t\t_relayer,\n\t\t\t\t_fee\n\t\t\t);\n\t\t}\n\n\t\treturn _claimCrossToSideToken(\n\t\t\tsideTokenByOriginalToken(_originalChainId, _originalTokenAddress),\n\t\t\t_reciever,\n\t\t\t_amount,\n\t\t\t_relayer,\n\t\t\t_fee\n\t\t);\n\t}\n\n\tfunction _claimCrossToSideToken(\n\t\taddress _sideToken,\n\t\taddress payable _receiver,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256 receivedAmount) {\n\t\trequire(_sideToken != NULL_ADDRESS, \"Bridge: side token is null\");\n\t\tuint256 granularity = IERC777(_sideToken).granularity();\n\t\tuint256 formattedAmount = _amount.mul(granularity);\n\t\trequire(_fee <= formattedAmount, \"Bridge: fee too high\");\n\t\treceivedAmount = formattedAmount.sub(_fee);\n\t\tISideToken(_sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n\t\tif (_fee > 0) {\n\t\t\tISideToken(_sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n\t\t}\n\t\treturn receivedAmount;\n\t}\n\n\tfunction _claimCrossBackToToken(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _receiver,\n\t\tuint256 _amount,\n\t\taddress payable _relayer,\n\t\tuint256 _fee\n\t) internal returns (uint256 receivedAmount) {\n\t\tuint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n\t\t//As side tokens are ERC777 they will always have 18 decimals\n\t\tuint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n\t\trequire(_fee <= formattedAmount, \"Bridge: fee too high\");\n\t\treceivedAmount = formattedAmount.sub(_fee);\n\t\tif (address(wrappedCurrency) == _originalTokenAddress) {\n\t\t\twrappedCurrency.withdraw(formattedAmount);\n\t\t\t_receiver.transfer(receivedAmount);\n\t\t\tif(_fee > 0) {\n\t\t\t\t_relayer.transfer(_fee);\n\t\t\t}\n\t\t} else {\n\t\t\tIERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n\t\t\tif(_fee > 0) {\n\t\t\t\tIERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n\t\t\t}\n\t\t}\n\t\treturn receivedAmount;\n\t}\n\n\t/**\n\t\t* ERC-20 tokens approve and transferFrom pattern\n\t\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n\t\t*/\n\tfunction receiveTokensTo(uint256 destinationChainId, address tokenToUse, address to, uint256 amount) external override {\n\t\taddress sender = _msgSender();\n\t\t//Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n\t\tIERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n\t\tcrossTokens(tokenToUse, sender, to, amount, \"\", destinationChainId);\n\t}\n\n\t/**\n\t\t* Use network currency and cross it.\n\t\t*/\n\tfunction depositTo(uint256 chainId, address to) external payable override {\n\t\taddress sender = _msgSender();\n\t\trequire(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n\t\twrappedCurrency.deposit{ value: msg.value }();\n\t\tcrossTokens(address(wrappedCurrency), sender, to, msg.value, \"\", chainId);\n\t}\n\n\t/**\n\t\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n\t\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n\t\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\n\t\t* const userData = web3.eth.abi.encodeParameters(\n * [\"address\", \"uint256\"],\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\n * );\n\t\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\n\t\t* const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\n\t\t*/\n\tfunction tokensReceived(\n\t\taddress operator,\n\t\taddress from,\n\t\taddress to,\n\t\tuint amount,\n\t\tbytes calldata userData, // [address,uint256] user addrest receiver, destinationChainId || [uint256] same as from, destinationChainId\n\t\tbytes calldata\n\t) external override(IBridge, IERC777Recipient) {\n\t\t//Hook from ERC777address\n\t\tif(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n\t\trequire(to == address(this), \"Bridge: Not to this address\");\n\t\taddress tokenToUse = _msgSender();\n\t\trequire(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n\t\trequire(userData.length >= 32, \"Bridge: user data with at least the destinationChainId\");\n\t\trequire(userData.length == 64 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n\t\taddress receiver = userData.length == 32 ? from : LibUtils.toAddress(userData, 12);\n\t\tuint256 destinationChainId = LibUtils.toUint256(userData, userData.length - 32);\n\t\tcrossTokens(tokenToUse, from, receiver, amount, userData, destinationChainId);\n\t}\n\n\tfunction crossTokens(\n\t\taddress tokenToUse,\n\t\taddress from,\n\t\taddress to,\n\t\tuint256 amount,\n\t\tbytes memory userData,\n\t\tuint256 destinationChainId\n\t) internal whenNotUpgrading whenNotPaused nonReentrant {\n\t\trequire(block.chainid != destinationChainId, \"Bridge: destination chain id equal current chain id\");\n\t\tcheckChainId(destinationChainId);\n\t\t_setKnownTokenByChain(destinationChainId, tokenToUse, true);\n\t\tuint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n\t\tuint256 amountMinusFees = amount.sub(fee);\n\t\tuint8 decimals = LibUtils.getDecimals(tokenToUse);\n\t\tuint formattedAmount = amount;\n\t\tif (decimals != 18) {\n\t\t\tformattedAmount = amount.mul(uint256(10)**(18-decimals));\n\t\t}\n\t\t// We consider the amount before fees converted to 18 decimals to check the limits\n\t\t// updateTokenTransfer revert if token not allowed\n\t\tallowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n\n\t\tOriginalToken memory sideToken = getOriginalTokenBySideToken(tokenToUse);\n\t\tif (sideToken.tokenAddress != NULL_ADDRESS) {\n\t\t\t// Side Token Crossing back\n\t\t\t{ // Created scope to avoid stack too deep\n\t\t\t\tuint256 granularity = LibUtils.getGranularity(tokenToUse);\n\t\t\t\tuint256 modulo = amountMinusFees.mod(granularity);\n\t\t\t\tfee = fee.add(modulo);\n\t\t\t\tamountMinusFees = amountMinusFees.sub(modulo);\n\t\t\t\tIERC777(tokenToUse).burn(amountMinusFees, userData);\n\t\t\t}\n\t\t\temit Cross(\n\t\t\t\tsideToken.tokenAddress,\n\t\t\t\tto,\n\t\t\t\tdestinationChainId,\n\t\t\t\tfrom,\n\t\t\t\tblock.chainid,\n\t\t\t\tamountMinusFees,\n\t\t\t\tuserData\n\t\t\t);\n\t\t} else {\n\t\t\temit Cross(\n\t\t\t\ttokenToUse,\n\t\t\t\tto,\n\t\t\t\tdestinationChainId,\n\t\t\t\tfrom,\n\t\t\t\tblock.chainid,\n\t\t\t\tamountMinusFees,\n\t\t\t\tuserData\n\t\t\t);\n\t\t}\n\n\t\tif (fee > 0) {\n\t\t\t//Send the payment to the MultiSig of the Federation\n\t\t\tIERC20(tokenToUse).safeTransfer(owner(), fee);\n\t\t}\n\t}\n\n\t// function for retrocompatibility\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex\n\t) internal pure returns(bytes32) {\n\t\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n\t}\n\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) public pure override returns(bytes32) {\n\t\treturn keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex, _originChainId, _destinationChainId));\n\t}\n\n\tfunction setFeePercentage(uint amount) external onlyOwner {\n\t\trequire(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n\t\tfeePercentage = amount;\n\t\temit FeePercentageChanged(feePercentage);\n\t}\n\n\tfunction getFeePercentage() external view override returns(uint) {\n\t\treturn feePercentage;\n\t}\n\n\tfunction changeFederation(address newFederation) external onlyOwner {\n\t\trequire(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n\t\tfederation = newFederation;\n\t\temit FederationChanged(federation);\n\t}\n\n\tfunction changeAllowTokens(address newAllowTokens) external onlyOwner {\n\t\trequire(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n\t\tallowTokens = IAllowTokens(newAllowTokens);\n\t\temit AllowTokensChanged(newAllowTokens);\n\t}\n\n\tfunction getFederation() external view returns(address) {\n\t\treturn federation;\n\t}\n\n\tfunction changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n\t\trequire(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n\t\tsideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n\t\temit SideTokenFactoryChanged(newSideTokenFactory);\n\t}\n\n\tfunction setUpgrading(bool _isUpgrading) external onlyOwner {\n\t\tisUpgrading = _isUpgrading;\n\t\temit Upgrading(isUpgrading);\n\t}\n\n\tfunction setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n\t\trequire(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n\t\twrappedCurrency = IWrapped(_wrappedCurrency);\n\t\temit WrappedCurrencyChanged(_wrappedCurrency);\n\t}\n\n\tfunction hasCrossed(bytes32 transactionHash) public view returns (bool) {\n\t\treturn transactionsDataHashes[transactionHash] != bytes32(0);\n\t}\n\n\tfunction hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n\t\treturn claimed[transactionsDataHashes[transactionHash]];\n\t}\n\n}\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\ninterface IBridge {\n\n\tstruct ClaimData {\n\t\taddress payable to;\n\t\tuint256 amount;\n\t\tbytes32 blockHash;\n\t\tbytes32 transactionHash;\n\t\tuint32 logIndex;\n\t\tuint256 originChainId;\n\t}\n\n\tstruct OriginalToken {\n\t\taddress tokenAddress;\n\t\tuint256 originChainId;\n\t}\n\n\tfunction version() external pure returns (string memory);\n\n\tfunction getFeePercentage() external view returns(uint);\n\n\t/**\n\t\t* ERC-20 tokens approve and transferFrom pattern\n\t\t* See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n\t\t*/\n\tfunction receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;\n\n\t/**\n\t\t* Use network currency and cross it.\n\t\t*/\n\tfunction depositTo(uint256 chainId, address to) external payable;\n\n\t/**\n\t\t* ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n\t\t* See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n\t\t* @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination\n\t\t* const userData = web3.eth.abi.encodeParameters(\n * [\"address\", \"uint256\"],\n * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]\n * );\n\t\t* or you also can send only the destination chain id, and the receiver would be the same as the from parameter\n\t\t* const userData = web3.eth.abi.encodeParameters([\"uint256\"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);\n\t\t*/\n\tfunction tokensReceived (\n\t\taddress operator,\n\t\taddress from,\n\t\taddress to,\n\t\tuint amount,\n\t\tbytes calldata userData,\n\t\tbytes calldata operatorData\n\t) external;\n\n\t/**\n\t\t* Accepts the transaction from the other chain that was voted and sent by the Federation contract\n\t\t*/\n\tfunction acceptTransfer(\n\t\taddress _originalTokenAddress,\n\t\taddress payable _from,\n\t\taddress payable _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t) external;\n\n\t/**\n\t\t* Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n\t\t*/\n\tfunction claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n\tfunction claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n\tfunction claimGasless(\n\t\tClaimData calldata _claimData,\n\t\taddress payable _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _deadline,\n\t\tuint8 _v,\n\t\tbytes32 _r,\n\t\tbytes32 _s\n\t) external returns (uint256 receivedAmount);\n\n\tfunction createSideToken(\n\t\tuint256 _typeId,\n\t\taddress _originalTokenAddress,\n\t\tuint8 _originalTokenDecimals,\n\t\tstring calldata _originalTokenSymbol,\n\t\tstring calldata _originalTokenName,\n\t\tuint256 _chainId\n\t) external;\n\n\tfunction getTransactionDataHash(\n\t\taddress _to,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tbytes32 _transactionHash,\n\t\tuint32 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256 _destinationChainId\n\t) external returns(bytes32);\n\n\tevent Cross(\n\t\taddress indexed _tokenAddress,\n\t\taddress indexed _to,\n\t\tuint256 indexed _destinationChainId,\n\t\taddress _from,\n\t\tuint256 _originChainId,\n\t\tuint256 _amount,\n\t\tbytes _userData\n\t);\n\n\tevent NewSideToken(\n\t\taddress indexed _newSideTokenAddress,\n\t\taddress indexed _originalTokenAddress,\n\t\tstring _newSymbol,\n\t\tuint256 _granularity,\n\t\tuint256 _chainId\n\t);\n\tevent AcceptedCrossTransfer(\n\t\tbytes32 indexed _transactionHash,\n\t\taddress indexed _originalTokenAddress,\n\t\taddress indexed _to,\n\t\taddress _from,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tuint256 _logIndex,\n\t\tuint256 _originChainId,\n\t\tuint256\t_destinationChainId\n\t);\n\tevent FeePercentageChanged(uint256 _amount);\n\tevent Claimed(\n\t\tbytes32 indexed _transactionHash,\n\t\taddress indexed _originalTokenAddress,\n\t\taddress indexed _to,\n\t\taddress _sender,\n\t\tuint256 _amount,\n\t\tbytes32 _blockHash,\n\t\tuint256 _logIndex,\n\t\taddress _reciever,\n\t\taddress _relayer,\n\t\tuint256 _fee,\n\t\tuint256 _destinationChainId,\n\t\tuint256 _originChainId\n\t);\n}"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../interface/IBridge.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockReceiveTokensCall is IERC777Recipient {\n address public bridge;\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor(address _bridge) {\n bridge = _bridge;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount, uint256 destinationChainId) external {\n IERC20(tokenToUse).approve(bridge, amount);\n IBridge(bridge).receiveTokensTo(destinationChainId, tokenToUse, receiver, amount);\n }\n\n function callDepositTo(address receiver, uint256 destinationChainId) external payable {\n IBridge(bridge).depositTo{ value: msg.value }(destinationChainId, receiver);\n }\n\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\n IERC777(tokenToUse).send(bridge, amount, data);\n }\n\n // Mandatory for IERC777Recipient\n function tokensReceived(\n address,\n address,\n address,\n uint,\n bytes calldata,\n bytes calldata\n ) override external view {\n this;\n }\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockERC777Recipient is IERC777Recipient {\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor() {\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\n }\n\n event Success(\n address operator,\n address from,\n address to,\n uint amount,\n bytes userData,\n bytes operatorData);\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) override external {\n emit Success(operator, from, to, amount, userData, operatorData);\n }\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\n\ncontract SideTokenV1 is ERC777 {\n address public minter;\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\n minter = _minterAddr;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../SideToken/SideTokenV1.sol\";\n\ncontract SideTokenFactoryV1 is Secondary {\n event CreatedSideToken(address sideToken, string symbol);\n\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\n emit CreatedSideToken(address(sideToken), symbol);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using SafeMath for uint256;\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping (uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /*\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri_) {\n _setURI(uri_);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) external view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: balance query for the zero address\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(amount);\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, address(0), id, amount);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\n /**\n @dev Handles the receipt of a single ERC1155 token type. This function is\n called at the end of a `safeTransferFrom` after the balance has been updated.\n To accept the transfer, this must return\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n (i.e. 0xf23a6e61, or its own function selector).\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n )\n external\n returns(bytes4);\n\n /**\n @dev Handles the receipt of a multiple ERC1155 token types. This function\n is called at the end of a `safeBatchTransferFrom` after the balances have\n been updated. To accept the transfer(s), this must return\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n (i.e. 0xbc197c81, or its own function selector).\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match values array)\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n )\n external\n returns(bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC1155 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Pausable is ERC1155, Pausable {\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\nimport \"../access/roles/PauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context, PauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n constructor () {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract PauserRole is Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n constructor () {\n _addPauser(_msgSender());\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC721.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC721 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC721Pausable is ERC721, Pausable {\n /**\n * @dev See {ERC721-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../../zeppelin/ownership/Ownable.sol\";\nimport \"../../zeppelin/math/SafeMath.sol\";\nimport \"../../zeppelin/utils/Strings.sol\";\nimport \"./OpenSeaEIP712Base.sol\";\n\n\n/**\n * @title OpenSea721\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\n */\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\n using SafeMath for uint256;\n\n uint256 private _currentTokenId = 0;\n\n constructor(\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n _initializeEIP712(_name);\n }\n\n function baseTokenURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/api/creature/\";\n }\n\n function contractURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\n }\n\n /**\n * @dev Mints a token to an address with a tokenURI.\n * @param _to address of the future owner of the token\n */\n function mintTo(address _to) public onlyOwner {\n uint256 newTokenId = _getNextTokenId();\n _mint(_to, newTokenId);\n _incrementTokenId();\n }\n\n /**\n * @dev calculates the next token ID based on value of _currentTokenId\n * @return uint256 for the next token ID\n */\n function _getNextTokenId() private view returns (uint256) {\n return _currentTokenId.add(1);\n }\n\n /**\n * @dev increments the value of _currentTokenId\n */\n function _incrementTokenId() private {\n _currentTokenId++;\n }\n\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\n }\n\n}"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () {\n _owner = _msgSender();\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../zeppelin/upgradable/Initializable.sol\";\n\ncontract OpenSeaEIP712Base is Initializable {\n struct EIP712Domain {\n string name;\n string version;\n address verifyingContract;\n bytes32 salt;\n }\n\n string constant public ERC712_VERSION = \"1\";\n\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\n bytes(\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\n )\n );\n bytes32 internal domainSeperator;\n\n // supposed to be called once while initializing.\n // one of the contracts that inherits this contract follows proxy pattern\n // so it is not possible to do this in a constructor\n function _initializeEIP712(\n string memory name\n )\n internal\n initializer\n {\n _setDomainSeperator(name);\n }\n\n function _setDomainSeperator(string memory name) internal {\n domainSeperator = keccak256(\n abi.encode(\n EIP712_DOMAIN_TYPEHASH,\n keccak256(bytes(name)),\n keccak256(bytes(ERC712_VERSION)),\n address(this),\n bytes32(block.chainid)\n )\n );\n }\n\n function getDomainSeperator() public view returns (bytes32) {\n return domainSeperator;\n }\n\n /**\n * Accept message hash and returns hash message in EIP712 compatible form\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\n * https://eips.ethereum.org/EIPS/eip-712\n * \"\\\\x19\" makes the encoding deterministic\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\n */\n function toTypedMessageHash(bytes32 messageHash)\n internal\n view\n returns (bytes32)\n {\n return\n keccak256(\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\n );\n }\n}\n"
+ },
+ "contracts/federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../Bridge/IBridgeV3.sol\";\n\ncontract FederationV2 is Initializable, UpgradableOwnable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridgeV3 public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\n validRequirement(_members.length, _required) public initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n }\n\n function version() external pure returns (string memory) {\n return \"v2\";\n }\n\n function setBridge(address _bridge) external onlyOwner {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridgeV3(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n )\n public onlyMember returns(bool)\n {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32)\n {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}"
+ },
+ "contracts/federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../nftbridge/INFTBridge.sol\";\nimport \"../interface/IBridge.sol\";\nimport \"../interface/IFederation.sol\";\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\n\tuint constant public MAX_MEMBER_COUNT = 50;\n\taddress constant private NULL_ADDRESS = address(0);\n\n\tIBridge public bridge;\n\taddress[] public members;\n\n\t/**\n\t\t@notice The minimum amount of votes to approve a transaction\n\t\t@dev It should have at least the required amount of members\n\t\t*/\n\tuint public required;\n\n\t/**\n\t\t@notice All the addresses that are members of the federation\n\t\t@dev The address should be a member to vote in transactions\n\t\t*/\n\tmapping (address => bool) public isMember;\n\n\t/**\n\t\t(bytes32) transactionId = keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tamount,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex\n\t\t\t)\n\t\t) => (\n\t\t\t(address) members => (bool) voted\n\t\t)\n\t\t@notice Votes by members by the transaction ID\n\t\t@dev the members should approve the transaction by 50% + 1\n\t\t*/\n\tmapping (bytes32 => mapping (address => bool)) public votes;\n\n\t/**\n\t\t(bytes32) transactionId => (bool) voted\n\t\t@notice Check if that transaction was already processed\n\t*/\n\tmapping(bytes32 => bool) public processed;\n\n\t/** Federator v3 variables */\n\tINFTBridge public bridgeNFT;\n\n\tmodifier onlyMember() {\n\t\trequire(isMember[_msgSender()], \"Federation: Not Federator\");\n\t\t_;\n\t}\n\n\tmodifier validRequirement(uint membersCount, uint _required) {\n\t\trequire(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n\t\t_;\n\t}\n\n\tfunction initialize(\n\t\taddress[] calldata _members,\n\t\tuint _required,\n\t\taddress _bridge,\n\t\taddress owner,\n\t\taddress _bridgeNFT\n\t) public validRequirement(_members.length, _required) initializer {\n\t\tUpgradableOwnable.initialize(owner);\n\t\trequire(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n\t\tmembers = _members;\n\t\tfor (uint i = 0; i < _members.length; i++) {\n\t\t\trequire(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n\t\t\tisMember[_members[i]] = true;\n\t\t\temit MemberAddition(_members[i]);\n\t\t}\n\t\trequired = _required;\n\t\temit RequirementChange(required);\n\t\t_setBridge(_bridge);\n\t\t_setNFTBridge(_bridgeNFT);\n\t}\n\n\t/**\n\t\t@notice Current version of the contract\n\t\t@return version in v{Number}\n\t\t*/\n\tfunction version() external pure override returns (string memory) {\n\t\treturn \"v3\";\n\t}\n\n\t/**\n\t\t@notice Sets a new bridge contract\n\t\t@dev Emits BridgeChanged event\n\t\t@param _bridge the new bridge contract address that should implement the IBridge interface\n\t\t*/\n\tfunction setBridge(address _bridge) external onlyOwner override {\n\t\t_setBridge(_bridge);\n\t}\n\n\tfunction _setBridge(address _bridge) internal {\n\t\trequire(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n\t\tbridge = IBridge(_bridge);\n\t\temit BridgeChanged(_bridge);\n\t}\n\n\t/**\n\t\t@notice Sets a new NFT bridge contract\n\t\t@dev Emits NFTBridgeChanged event\n\t\t@param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n\t\t*/\n\tfunction setNFTBridge(address _bridgeNFT) external onlyOwner override {\n\t\trequire(_bridgeNFT != NULL_ADDRESS, \"Federation: Empty NFT bridge\");\n\t\t_setNFTBridge(_bridgeNFT);\n\t}\n\n\tfunction _setNFTBridge(address _bridgeNFT) internal {\n\t\tbridgeNFT = INFTBridge(_bridgeNFT);\n\t\temit NFTBridgeChanged(_bridgeNFT);\n\t}\n\n\tfunction validateTransaction(bytes32 transactionId, bytes32 transactionIdMultichain) internal view returns(bool) {\n\t\tuint256 minimumVotes = getMinimalNumberOfVotes();\n\t\tuint256 amountVotes = 0;\n\n for (uint256 i = 0; i < members.length; i++) {\n if (votes[transactionIdMultichain][members[i]]) {\n amountVotes += 1;\n\t\t\t} else if (votes[transactionId][members[i]]) {\n amountVotes += 1;\n\t\t\t}\n\n\t\t\tif (amountVotes >= minimumVotes && amountVotes >= required) {\n\t\t\t\treturn true;\n\t\t\t}\n }\n\n\t\treturn false;\n\t}\n\n\tfunction getMinimalNumberOfVotes() internal view returns(uint256) {\n\t\treturn members.length / 2 + 1;\n\t}\n\n\tfunction isProcessed(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\n\t\treturn processed[transactionIdMultichain] || processed[transactionId];\n\t}\n\n\tfunction isVoted(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {\n\t\treturn votes[transactionIdMultichain][_msgSender()] || votes[transactionId][_msgSender()];\n\t}\n\n\tfunction shouldBeCurrentChainId(uint256 chainId) internal view {\n\t\trequire(chainId == block.chainid, \"Federation: Not block.chainid\");\n\t}\n\n\t/**\n\t\t@notice Vote in a transaction, if it has enough votes it accepts the transfer\n\t\t@param originalTokenAddress The address of the token in the origin (main) chain\n\t\t@param sender The address who solicited the cross token\n\t\t@param receiver Who is going to receive the token in the opposite chain\n\t\t@param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n\t\t@param blockHash The block hash in which the transaction with the cross event occurred\n\t\t@param transactionHash The transaction in which the cross event occurred\n\t\t@param logIndex Index of the event in the logs\n\t\t@param tokenType Is the type of bridge to be used\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n\t\t*/\n\tfunction voteTransaction(\n\t\taddress originalTokenAddress,\n\t\taddress payable sender,\n\t\taddress payable receiver,\n\t\tuint256 value,\n\t\tbytes32 blockHash,\n\t\tbytes32 transactionHash,\n\t\tuint32 logIndex,\n\t\tTokenType tokenType,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n\t) external onlyMember override {\n\t\tshouldBeCurrentChainId(destinationChainId);\n\t\tbytes32 transactionId = keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex\n\t\t\t)\n\t\t);\n\n\t\tbytes32 transactionIdMultichain = getTransactionId(\n\t\t\toriginalTokenAddress,\n\t\t\tsender,\n\t\t\treceiver,\n\t\t\tvalue,\n\t\t\tblockHash,\n\t\t\ttransactionHash,\n\t\t\tlogIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n\t\t);\n\n\t\tif (isProcessed(transactionId, transactionIdMultichain))\n\t\t\treturn;\n\n\t\tif (isVoted(transactionId, transactionIdMultichain))\n\t\t\treturn;\n\n\t\tvotes[transactionIdMultichain][_msgSender()] = true;\n\t\temit Voted(\n\t\t\t_msgSender(),\n\t\t\ttransactionHash,\n\t\t\ttransactionIdMultichain,\n\t\t\toriginalTokenAddress,\n\t\t\tsender,\n\t\t\treceiver,\n\t\t\tvalue,\n\t\t\tblockHash,\n\t\t\tlogIndex,\n\t\t\toriginChainId,\n\t\t\tdestinationChainId\n\t\t);\n\n\t\tif (validateTransaction(transactionId, transactionIdMultichain)) {\n\t\t\tprocessed[transactionIdMultichain] = true;\n\n\t\t\tacceptTransfer(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex,\n\t\t\t\ttokenType,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\n\t\t\temit Executed(\n\t\t\t\t_msgSender(),\n\t\t\t\ttransactionHash,\n\t\t\t\ttransactionIdMultichain,\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tvalue,\n\t\t\t\tblockHash,\n\t\t\t\tlogIndex,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t);\n\t\t}\n\t}\n\n function acceptTransfer(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType,\n\tuint256 originChainId,\n\tuint256\tdestinationChainId\n ) internal {\n if (tokenType == TokenType.NFT) {\n require(address(bridgeNFT) != NULL_ADDRESS, \"Federation: Empty NFTBridge\");\n bridgeNFT.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex,\n\t\toriginChainId,\n\t\tdestinationChainId\n );\n } else {\n\t bridge.acceptTransfer(\n\t\toriginalTokenAddress,\n\t\tsender,\n\t\treceiver,\n\t\tvalue,\n\t\tblockHash,\n\t\ttransactionHash,\n\t\tlogIndex,\n\t\toriginChainId,\n\t\tdestinationChainId\n\t );\n\t}\n }\n\n /**\n @notice Get the amount of approved votes for that transactionId\n @param transactionId The transaction hashed from getTransactionId function\n */\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n\tfunction hasVoted(bytes32 transactionId) external view returns(bool) {\n\t\treturn votes[transactionId][_msgSender()];\n\t}\n\n\tfunction transactionWasProcessed(bytes32 transactionId) external view returns(bool) {\n\t\treturn processed[transactionId];\n\t}\n\n\t/**\n\t\t@notice Gets the hash of transaction from the following parameters encoded and keccaked\n\t\t@dev It encodes and applies keccak256 to the parameters received in the same order\n\t\t@param originalTokenAddress The address of the token in the origin (main) chain\n\t\t@param sender The address who solicited the cross token\n\t\t@param receiver Who is going to receive the token in the opposite chain\n\t\t@param amount Could be the amount or the tokenId\n\t\t@param blockHash The block hash in which the transaction with the cross event occurred\n\t\t@param transactionHash The transaction in which the cross event occurred\n\t\t@param logIndex Index of the event in the logs\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n\t\t@return The hash generated by the parameters.\n\t*/\n\tfunction getTransactionId(\n\t\taddress originalTokenAddress,\n\t\taddress sender,\n\t\taddress receiver,\n\t\tuint256 amount,\n\t\tbytes32 blockHash,\n\t\tbytes32 transactionHash,\n\t\tuint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n\t) public pure returns(bytes32) {\n\t\treturn keccak256(\n\t\t\tabi.encodePacked(\n\t\t\t\toriginalTokenAddress,\n\t\t\t\tsender,\n\t\t\t\treceiver,\n\t\t\t\tamount,\n\t\t\t\tblockHash,\n\t\t\t\ttransactionHash,\n\t\t\t\tlogIndex,\n\t\t\t\toriginChainId,\n\t\t\t\tdestinationChainId\n\t\t\t)\n\t\t);\n\t}\n\n\tfunction addMember(address _newMember) external onlyOwner override {\n\t\trequire(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n\t\trequire(!isMember[_newMember], \"Federation: Member already exists\");\n\t\trequire(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n\t\tisMember[_newMember] = true;\n\t\tmembers.push(_newMember);\n\t\temit MemberAddition(_newMember);\n\t}\n\n\tfunction removeMember(address _oldMember) external onlyOwner override {\n\t\trequire(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n\t\trequire(isMember[_oldMember], \"Federation: Member doesn't exists\");\n\t\trequire(members.length > 1, \"Federation: Can't remove all the members\");\n\t\trequire(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n\t\tisMember[_oldMember] = false;\n\t\tfor (uint i = 0; i < members.length - 1; i++) {\n\t\t\tif (members[i] == _oldMember) {\n\t\t\t\tmembers[i] = members[members.length - 1];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tmembers.pop(); // remove an element from the end of the array.\n\t\temit MemberRemoval(_oldMember);\n\t}\n\n\t/**\n\t\t@notice Return all the current members of the federation\n\t\t@return Current members\n\t\t*/\n\tfunction getMembers() external view override returns (address[] memory) {\n\t\treturn members;\n\t}\n\n\t/**\n\t\t@notice Changes the number of required members to vote and approve an transaction\n\t\t@dev Emits the RequirementChange event\n\t\t@param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n\t\t*/\n\tfunction changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\n\t\trequire(_required >= 2, \"Federation: Requires at least 2\");\n\t\trequired = _required;\n\t\temit RequirementChange(_required);\n\t}\n\n\t/**\n\t\t@notice It emits an HeartBeat like an health check\n\t\t@dev Emits HeartBeat event\n\t\t*/\n\tfunction emitHeartbeat(\n\t\tstring calldata fedVersion,\n\t\tuint256[] calldata fedChainsIds,\n\t\tuint256[] calldata fedChainsBlocks,\n\t\tstring[] calldata fedChainsInfo\n\t) external onlyMember override {\n\t\trequire(fedChainsIds.length == fedChainsBlocks.length &&\n\t\t\tfedChainsIds.length == fedChainsInfo.length, \"Federation: Length missmatch\");\n\t\temit HeartBeat(\n\t\t\t_msgSender(),\n\t\t\tblock.chainid,\n\t\t\tblock.number,\n\t\t\tfedVersion,\n\t\t\tfedChainsIds,\n\t\t\tfedChainsBlocks,\n\t\t\tfedChainsInfo\n\t\t);\n\t}\n}\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\ninterface IFederation {\n enum TokenType{ COIN, NFT }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure returns (string memory);\n\n /**\n @notice Sets a new bridge contract\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external;\n\n /**\n @notice Sets a new NFT bridge contract\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external;\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n\t\t@param originChainId Is chainId of the original chain\n\t\t@param destinationChainId Is chainId of the destination chain\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType,\n\t uint256 originChainId,\n\t uint256\tdestinationChainId\n ) external;\n\n /**\n @notice Add a new member to the federation\n @param _newMember address of the new member\n */\n function addMember(address _newMember) external;\n\n /**\n @notice Remove a member of the federation\n @param _oldMember address of the member to be removed from federation\n */\n function removeMember(address _oldMember) external;\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view returns (address[] memory);\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external;\n\n /**\n @notice It emmits an HeartBeat like an healthy check\n */\n function emitHeartbeat(\n string calldata federatorVersion,\n\t\tuint256[] calldata fedChainsIds,\n\t\tuint256[] calldata fedChainsBlocks,\n\t\tstring[] calldata fedChainsInfo\n ) external;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex,\n\t\tuint256 originChainId,\n\t\tuint256\tdestinationChainId\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event NFTBridgeChanged(address bridgeNFT);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex,\n uint256 originChainId,\n\t\tuint256\tdestinationChainId\n );\n event HeartBeat(\n address indexed sender,\n uint256 currentChainId,\n uint256 currentBlock,\n string fedVersion,\n uint256[] fedChainsIds,\n\t\tuint256[] fedChainsBlocks,\n\t\tstring[] fedChainsInfo\n );\n\n}\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract MinterRole is Context {\n using Roles for Roles.Role;\n\n event MinterAdded(address indexed account);\n event MinterRemoved(address indexed account);\n\n Roles.Role private _minters;\n\n constructor () {\n _addMinter(_msgSender());\n }\n\n modifier onlyMinter() {\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\n _;\n }\n\n function isMinter(address account) public view returns (bool) {\n return _minters.has(account);\n }\n\n function addMinter(address account) public onlyMinter {\n _addMinter(account);\n }\n\n function renounceMinter() public {\n _removeMinter(_msgSender());\n }\n\n function _addMinter(address account) internal {\n _minters.add(account);\n emit MinterAdded(account);\n }\n\n function _removeMinter(address account) internal {\n _minters.remove(account);\n emit MinterRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20Mintable}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() override public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) override public view returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) override public returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) override public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) override public returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal {\n require(sender != address(0), \"ERC20: transfer from zero address\");\n require(recipient != address(0), \"ERC20: transfer to zero address\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: mint to zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: burn from zero address\");\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n *\n * This is internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal {\n require(owner != address(0), \"ERC20: approve from zero address\");\n require(spender != address(0), \"ERC20: approve to zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\n * from the caller's allowance.\n *\n * See {_burn} and {_approve}.\n */\n function _burnFrom(address account, uint256 amount) internal {\n _burn(account, amount);\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\n }\n}\n"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\nimport \"../interface/IERC677Receiver.sol\";\n\ncontract mockERC677Receiver is IERC677Receiver {\n event Success(address _sender, uint _value, bytes _data);\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\n emit Success(_sender, _value, _data);\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Optional functions from the ERC20 standard.\n */\nabstract contract ERC20Detailed is IERC20 {\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\n * these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\n _name = aName;\n _symbol = aSymbol;\n _decimals = theDecimals;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./Proxy.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n *\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\n * {TransparentUpgradeableProxy}.\n */\ncontract UpgradeableProxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _setImplementation(_logic);\n if(_data.length > 0) {\n Address.functionDelegateCall(_logic, _data);\n }\n }\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n bytes32 slot = _IMPLEMENTATION_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n impl := sload(slot)\n }\n }\n\n /**\n * @dev Upgrades the proxy to a new implementation.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal virtual {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\n\n bytes32 slot = _IMPLEMENTATION_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newImplementation)\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./UpgradeableProxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _setAdmin(admin_);\n }\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _admin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _admin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\n emit AdminChanged(_admin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external virtual ifAdmin {\n _upgradeTo(newImplementation);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\n _upgradeTo(newImplementation);\n Address.functionDelegateCall(newImplementation, data);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address adm) {\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n adm := sload(slot)\n }\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n bytes32 slot = _ADMIN_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newAdmin)\n }\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../../ownership/Ownable.sol\";\nimport \"./TransparentUpgradeableProxy.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract AllowTokensV0 is Ownable {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n\n mapping (address => bool) public allowedTokens;\n bool private validateAllowedTokens;\n uint256 private maxTokensAllowed;\n uint256 private minTokensAllowed;\n uint256 public dailyLimit;\n\n event AllowedTokenAdded(address indexed _tokenAddress);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event AllowedTokenValidation(bool _enabled);\n event MaxTokensAllowedChanged(uint256 _maxTokens);\n event MinTokensAllowedChanged(uint256 _minTokens);\n event DailyLimitChanged(uint256 dailyLimit);\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\n _;\n }\n\n constructor(address _manager) {\n transferOwnership(_manager);\n validateAllowedTokens = true;\n maxTokensAllowed = 10000 ether;\n minTokensAllowed = 1 ether;\n dailyLimit = 100000 ether;\n }\n\n function isValidatingAllowedTokens() external view returns(bool) {\n return validateAllowedTokens;\n }\n\n function getMaxTokensAllowed() external view returns(uint256) {\n return maxTokensAllowed;\n }\n\n function getMinTokensAllowed() external view returns(uint256) {\n return minTokensAllowed;\n }\n\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\n return allowedTokens[token];\n }\n\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\n if (validateAllowedTokens) {\n return allowedTokenExist(token);\n }\n return true;\n }\n\n function addAllowedToken(address token) external onlyOwner {\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\n allowedTokens[token] = true;\n emit AllowedTokenAdded(token);\n }\n\n function removeAllowedToken(address token) external onlyOwner {\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\n allowedTokens[token] = false;\n emit AllowedTokenRemoved(token);\n }\n\n function enableAllowedTokensValidation() external onlyOwner {\n validateAllowedTokens = true;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function disableAllowedTokensValidation() external onlyOwner {\n // Before disabling Allowed Tokens Validations some kind of contract validation system\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\n validateAllowedTokens = false;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\n maxTokensAllowed = maxTokens;\n emit MaxTokensAllowedChanged(maxTokensAllowed);\n }\n\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\n minTokensAllowed = minTokens;\n emit MinTokensAllowedChanged(minTokensAllowed);\n }\n\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\n dailyLimit = _dailyLimit;\n emit DailyLimitChanged(_dailyLimit);\n }\n\n // solium-disable-next-line max-len\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\n if(amount > maxTokensAllowed)\n return false;\n if(amount < minTokensAllowed)\n return false;\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\n return false;\n if(!isSideToken && !isTokenAllowed(tokenToUse))\n return false;\n return true;\n }\n\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\n uint maxWithrow = dailyLimit - spentToday;\n if (dailyLimit < spentToday)\n return 0;\n if(maxWithrow > maxTokensAllowed)\n maxWithrow = maxTokensAllowed;\n return maxWithrow;\n }\n\n}\n"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\n\ncontract BridgeProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract FederationProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract MainToken is ERC20Detailed, ERC20 {\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\n ERC20Detailed(name, symbol, decimals)\n {\n _mint(msg.sender, totalSupply);\n }\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\n bool result = transfer(_to, _value);\n if (!result) return false;\n\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\n receiver.tokenFallback(msg.sender, _value, _data);\n\n // IMPORTANT: the ERC-677 specification does not say\n // anything about the use of the receiver contract's\n // tokenFallback method return value. Given\n // its return type matches with this method's return\n // type, returning it could be a possibility.\n // We here take the more conservative approach and\n // ignore the return value, returning true\n // to signal a succesful transfer despite tokenFallback's\n // return value -- fact being tokens are transferred\n // in any case.\n return true;\n }\n}\n\ninterface ERC677TransferReceiver {\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\n}"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract AlternativeERC20Detailed is ERC20 {\n string private _name;\n bytes32 private _symbol;\n uint256 private _decimals;\n\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\n {\n _name = aName;\n _symbol = aSymbol;\n _decimals = someDecimals;\n _mint(msg.sender, aTotalSupply);\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (bytes32) {\n return _symbol;\n }\n\n function decimals() public view returns (uint256) {\n return _decimals;\n }\n}"
+ },
+ "contracts/test/nftbridge/NFTERC721TestToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\n\ncontract NFTERC721TestToken is ERC721 {\n\n string private _contractURI;\n\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\n\n function safeMint(address to, uint256 tokenId) public {\n _safeMint(to, tokenId);\n }\n\n function setBaseURI(string memory baseURI) public {\n _setBaseURI(baseURI);\n }\n\n function setContractURI(string memory contractURI_) public {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n function setTokenURI(uint256 tokenId, string memory _tokenURI) public {\n _setTokenURI(tokenId, _tokenURI);\n }\n\n}\n"
+ },
+ "contracts/nftbridge/SideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./ISideNFTToken.sol\";\nimport \"../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\n\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\n address public minter;\n string private _contractURI;\n\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\n require(_minter != address(0), \"SideToken: Empty Minter\");\n minter = _minter;\n _setBaseURI(_baseURI);\n _setContractURI(contractURI_);\n }\n\n function _setContractURI(string memory contractURI_) internal {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(address account, uint256 tokenId) external onlyMinter override {\n _mint(account, tokenId);\n }\n}"
+ },
+ "contracts/nftbridge/SideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"./SideNFTToken.sol\";\n\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external onlyPrimary override returns(address) {\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\n return sideTokenAddress;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() {\n _registerInterface(\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\n );\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Receiver.sol\";\n\n /**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers. \n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Burnable is ERC1155 {\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n}\n"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../lib/LibUtils.sol\";\n\ncontract LibUtilsHarness {\n\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\n return LibUtils.decimalsToGranularity(decimals);\n }\n\n function getDecimals(address tokenToUse) external view returns (uint8) {\n return LibUtils.getDecimals(tokenToUse);\n }\n\n function getGranularity(address tokenToUse) external view returns (uint256) {\n return LibUtils.getGranularity(tokenToUse);\n }\n\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\n return LibUtils.bytesToAddress(bys);\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) external pure returns (uint128) {\n return LibUtils.toUint128(_bytes, _start);\n }\n\n}\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/.chainId b/bridge/deployments/rsktestnetbsc/.chainId
new file mode 100644
index 000000000..b74e882ae
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/.chainId
@@ -0,0 +1 @@
+31
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/AllowTokens.json b/bridge/deployments/rsktestnetbsc/AllowTokens.json
new file mode 100644
index 000000000..275c8e697
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/AllowTokens.json
@@ -0,0 +1,1196 @@
+{
+ "address": "0x11804f8DeADb1803603278156AA1e6602949e8b2",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ }
+ ],
+ "name": "AllowedTokenRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "ConfirmationsChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ }
+ ],
+ "name": "SetToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_typeDescription",
+ "type": "string"
+ }
+ ],
+ "name": "TokenTypeAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "indexed": false,
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "TypeLimitsChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_lastDay",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_spentToday",
+ "type": "uint256"
+ }
+ ],
+ "name": "UpdateTokensTransfered",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_TYPES",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Secondary_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "description",
+ "type": "string"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "addTokenType",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "len",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "allowedTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "calcMaxWithdraw",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "maxWithdraw",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "smallAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "getInfoAndLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokenInfo",
+ "name": "info",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limit",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypeDescriptions",
+ "outputs": [
+ {
+ "internalType": "string[]",
+ "name": "descriptions",
+ "type": "string[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypeDescriptionsLength",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypesLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits[]",
+ "name": "limits",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_primary",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "string",
+ "name": "description",
+ "type": "string"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TypeInfo[]",
+ "name": "typesInfo",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "isTokenAllowed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "largeAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "mediumAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "removeAllowedToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "setConfirmations",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokensAndType[]",
+ "name": "tokensAndTypes",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "setMultipleTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ }
+ ],
+ "name": "setToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "setTypeLimits",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "smallAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "typeDescriptions",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "typeLimits",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "updateTokenTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x2d1158799ed192bce68c3676ba7833a087251423290c4423e3a16134a6fa6978",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x11804f8DeADb1803603278156AA1e6602949e8b2",
+ "transactionIndex": 0,
+ "gasUsed": "2459902",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x09f2374a7b81dbe264dfb6095f10fe185c7c9a4e0cb0457a68f63b30f06121b2",
+ "transactionHash": "0x2d1158799ed192bce68c3676ba7833a087251423290c4423e3a16134a6fa6978",
+ "logs": [],
+ "blockNumber": 2152254,
+ "cumulativeGasUsed": "2459902",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"}],\"name\":\"AllowedTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"}],\"name\":\"ConfirmationsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"}],\"name\":\"SetToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_typeDescription\",\"type\":\"string\"}],\"name\":\"TokenTypeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"TypeLimitsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_lastDay\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_spentToday\",\"type\":\"uint256\"}],\"name\":\"UpdateTokensTransfered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_TYPES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__Secondary_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"addTokenType\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"len\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowedTokens\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"spentToday\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastDay\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"calcMaxWithdraw\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"maxWithdraw\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"smallAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getInfoAndLimits\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"spentToday\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastDay\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.TokenInfo\",\"name\":\"info\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limit\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypeDescriptions\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"descriptions\",\"type\":\"string[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypeDescriptionsLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypesLimits\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits[]\",\"name\":\"limits\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_primary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"internalType\":\"struct IAllowTokens.TypeInfo[]\",\"name\":\"typesInfo\",\"type\":\"tuple[]\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isTokenAllowed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"largeAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mediumAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"removeAllowedToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"}],\"name\":\"setConfirmations\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.TokensAndType[]\",\"name\":\"tokensAndTypes\",\"type\":\"tuple[]\"}],\"name\":\"setMultipleTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"}],\"name\":\"setToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"setTypeLimits\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"smallAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"typeDescriptions\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"typeLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"updateTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"__Secondary_init(address)\":{\"details\":\"Sets the primary account to the one that is creating the Secondary contract.\"},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/AllowTokens/AllowTokens.sol\":\"AllowTokens\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/AllowTokens/AllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../zeppelin/math/SafeMath.sol\\\";\\n// Upgradables\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\\\";\\n\\nimport \\\"../interface/IAllowTokens.sol\\\";\\n\\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\\n using SafeMath for uint256;\\n\\n address constant private NULL_ADDRESS = address(0);\\n uint256 constant public MAX_TYPES = 250;\\n mapping (address => TokenInfo) public allowedTokens;\\n mapping (uint256 => Limits) public typeLimits;\\n uint256 public smallAmountConfirmations;\\n uint256 public mediumAmountConfirmations;\\n uint256 public largeAmountConfirmations;\\n string[] public typeDescriptions;\\n\\n event SetToken(address indexed _tokenAddress, uint256 _typeId);\\n event AllowedTokenRemoved(address indexed _tokenAddress);\\n event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\\n event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\\n event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\\n event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\\n\\n\\n modifier notNull(address _address) {\\n require(_address != NULL_ADDRESS, \\\"AllowTokens: Null Address\\\");\\n _;\\n }\\n\\n function initialize(\\n address _manager,\\n address _primary,\\n uint256 _smallAmountConfirmations,\\n uint256 _mediumAmountConfirmations,\\n uint256 _largeAmountConfirmations,\\n TypeInfo[] memory typesInfo) public initializer {\\n UpgradableOwnable.initialize(_manager);\\n UpgradableSecondary.__Secondary_init(_primary);\\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\n for(uint i = 0; i < typesInfo.length; i = i + 1) {\\n _addTokenType(typesInfo[i].description, typesInfo[i].limits);\\n }\\n }\\n\\n function version() override external pure returns (string memory) {\\n return \\\"v1\\\";\\n }\\n\\n function getInfoAndLimits(address token) override public view\\n returns (TokenInfo memory info, Limits memory limit) {\\n info = allowedTokens[token];\\n limit = typeLimits[info.typeId];\\n return (info, limit);\\n }\\n function calcMaxWithdraw(address token) override public view returns (uint256 maxWithdraw) {\\n (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\\n return _calcMaxWithdraw(info, limits);\\n }\\n\\n function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\\n // solium-disable-next-line security/no-block-members\\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\\n info.spentToday = 0;\\n }\\n if (limits.daily <= info.spentToday)\\n return 0;\\n maxWithdraw = limits.daily - info.spentToday;\\n if(maxWithdraw > limits.max)\\n maxWithdraw = limits.max;\\n return maxWithdraw;\\n }\\n\\n // solium-disable-next-line max-len\\n function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\\n (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\\n require(isTokenAllowed(token), \\\"AllowTokens: Not whitelisted\\\");\\n require(amount >= limit.min, \\\"AllowTokens: Lower than limit\\\");\\n\\n // solium-disable-next-line security/no-block-members\\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\\n // solium-disable-next-line security/no-block-members\\n info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\\n info.spentToday = 0;\\n }\\n uint maxWithdraw = _calcMaxWithdraw(info, limit);\\n require(amount <= maxWithdraw, \\\"AllowTokens: Exceeded limit\\\");\\n info.spentToday = info.spentToday.add(amount);\\n allowedTokens[token] = info;\\n\\n emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\\n }\\n\\n function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\\n require(bytes(description).length > 0, \\\"AllowTokens: Empty description\\\");\\n len = typeDescriptions.length;\\n require(len + 1 <= MAX_TYPES, \\\"AllowTokens: Reached MAX_TYPES\\\");\\n typeDescriptions.push(description);\\n _setTypeLimits(len, limits);\\n emit TokenTypeAdded(len, description);\\n return len;\\n }\\n\\n function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\\n return _addTokenType(description, limits);\\n }\\n\\n function _setTypeLimits(uint256 typeId, Limits memory limits) private {\\n require(typeId < typeDescriptions.length, \\\"AllowTokens: bigger than typeDescriptions\\\");\\n require(limits.max >= limits.min, \\\"AllowTokens: maxTokens smaller than minTokens\\\");\\n require(limits.daily >= limits.max, \\\"AllowTokens: dailyLimit smaller than maxTokens\\\");\\n require(limits.mediumAmount > limits.min, \\\"AllowTokens: limits.mediumAmount smaller than min\\\");\\n require(limits.largeAmount > limits.mediumAmount, \\\"AllowTokens: limits.largeAmount smaller than mediumAmount\\\");\\n typeLimits[typeId] = limits;\\n emit TypeLimitsChanged(typeId, limits);\\n }\\n\\n function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\\n _setTypeLimits(typeId, limits);\\n }\\n\\n function getTypesLimits() external view override returns(Limits[] memory limits) {\\n limits = new Limits[](typeDescriptions.length);\\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\\n limits[i] = typeLimits[i];\\n }\\n return limits;\\n }\\n\\n function getTypeDescriptionsLength() external view override returns(uint256) {\\n return typeDescriptions.length;\\n }\\n\\n function getTypeDescriptions() external view override returns(string[] memory descriptions) {\\n descriptions = new string[](typeDescriptions.length);\\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\\n descriptions[i] = typeDescriptions[i];\\n }\\n return descriptions;\\n }\\n\\n function isTokenAllowed(address token) public view notNull(token) override returns (bool) {\\n return allowedTokens[token].allowed;\\n }\\n\\n function setToken(address token, uint256 typeId) override public notNull(token) {\\n require(isOwner() || _msgSender() == primary(), \\\"AllowTokens: unauthorized sender\\\");\\n require(typeId < typeDescriptions.length, \\\"AllowTokens: typeId does not exist\\\");\\n TokenInfo memory info = allowedTokens[token];\\n info.allowed = true;\\n info.typeId = typeId;\\n allowedTokens[token] = info;\\n emit SetToken(token, typeId);\\n }\\n\\n function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\\n require(tokensAndTypes.length > 0, \\\"AllowTokens: empty tokens\\\");\\n for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\\n setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\\n }\\n }\\n\\n function removeAllowedToken(address token) external notNull(token) onlyOwner {\\n TokenInfo memory info = allowedTokens[token];\\n require(info.allowed, \\\"AllowTokens: Not Allowed\\\");\\n info.allowed = false;\\n allowedTokens[token] = info;\\n emit AllowedTokenRemoved(token);\\n }\\n\\n function setConfirmations(\\n uint256 _smallAmountConfirmations,\\n uint256 _mediumAmountConfirmations,\\n uint256 _largeAmountConfirmations) external onlyOwner {\\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\n }\\n\\n function _setConfirmations(\\n uint256 _smallAmountConfirmations,\\n uint256 _mediumAmountConfirmations,\\n uint256 _largeAmountConfirmations) private {\\n require(_smallAmountConfirmations <= _mediumAmountConfirmations, \\\"AllowTokens: small bigger than medium confirmations\\\");\\n require(_mediumAmountConfirmations <= _largeAmountConfirmations, \\\"AllowTokens: medium bigger than large confirmations\\\");\\n smallAmountConfirmations = _smallAmountConfirmations;\\n mediumAmountConfirmations = _mediumAmountConfirmations;\\n largeAmountConfirmations = _largeAmountConfirmations;\\n emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\n }\\n\\n function getConfirmations() external view override\\n returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount) {\\n return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\\n }\\n\\n}\\n\",\"keccak256\":\"0x0d9f9d1c4e2185846e9c2f9aa41db513f647983d3497366ab327872f99010b65\",\"license\":\"MIT\"},\"contracts/interface/IAllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\ninterface IAllowTokens {\\n\\n struct Limits {\\n uint256 min;\\n uint256 max;\\n uint256 daily;\\n uint256 mediumAmount;\\n uint256 largeAmount;\\n }\\n\\n struct TokenInfo {\\n bool allowed;\\n uint256 typeId;\\n uint256 spentToday;\\n uint256 lastDay;\\n }\\n\\n struct TypeInfo {\\n string description;\\n Limits limits;\\n }\\n\\n struct TokensAndType {\\n address token;\\n uint256 typeId;\\n }\\n\\n function version() external pure returns (string memory);\\n\\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\\n\\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\\n\\n function getTypesLimits() external view returns(Limits[] memory limits);\\n\\n function getTypeDescriptionsLength() external view returns(uint256);\\n\\n function getTypeDescriptions() external view returns(string[] memory descriptions);\\n\\n function setToken(address token, uint256 typeId) external;\\n\\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\\n\\n function isTokenAllowed(address token) external view returns (bool);\\n\\n function updateTokenTransfer(address token, uint256 amount) external;\\n}\",\"keccak256\":\"0x5a2aaa285c400917cd72fafe61ce409f200c3fc13d984843bccfb97563489a61\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x09ca2716452528a6e69ac9f83f874292a1e547630473f3133038314a2f16029e\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\",\"keccak256\":\"0x3eeeb5ea6bf7d3458bb36acebd4268b406e6a1525e009d4d8a90626c277a37d1\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract UpgradableOwnable is Initializable, Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function initialize(address sender) public initializer {\\n _owner = sender;\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * > Note: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n\\n}\\n\",\"keccak256\":\"0x2e0e58f4a3991801550e6a52512a3c1bbcaa5cb824120c177cb6ec1b4fa0ce97\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\n */\\ncontract UpgradableSecondary is Initializable, Context {\\n address private _primary;\\n\\n /**\\n * @dev Emitted when the primary contract changes.\\n */\\n event PrimaryTransferred(\\n address recipient\\n );\\n\\n /**\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\n */\\n function __Secondary_init(address sender) public initializer {\\n _primary = sender;\\n emit PrimaryTransferred(_primary);\\n }\\n\\n /**\\n * @dev Reverts if called from any account other than the primary.\\n */\\n modifier onlyPrimary() {\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\n _;\\n }\\n\\n /**\\n * @return the address of the primary.\\n */\\n function primary() public view returns (address) {\\n return _primary;\\n }\\n\\n /**\\n * @dev Transfers contract to a new primary.\\n * @param recipient The address of new primary.\\n */\\n function transferPrimary(address recipient) public onlyPrimary {\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\n _primary = recipient;\\n emit PrimaryTransferred(recipient);\\n }\\n\\n}\",\"keccak256\":\"0x156eff0cfa1a0b99fcc5a710688fd8d3038552a380e3687a70e9d75e4bb59315\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50612331806100206000396000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80638f32d59b1161010f578063c4d66de8116100a2578063e4f89ae411610071578063e4f89ae4146103e3578063e744092e146103f6578063f2fde38b14610419578063f9eaee0d1461042c576101e5565b8063c4d66de8146103ad578063c6dbdf61146103c0578063d4164b5d146103c8578063d7516faa146103db576101e5565b8063adfeb5eb116100de578063adfeb5eb1461035d578063b348a29f14610370578063bb698dad14610383578063c361ce8314610396576101e5565b80638f32d59b1461030c57806390469a9d146103215780639d27d22614610334578063a81a8b1f14610355576101e5565b806354fd4d50116101875780637d496be9116101565780637d496be9146102d45780638c34bc55146102dc5780638da5cb5b146102ef5780638de52dd714610304576101e5565b806354fd4d501461029e578063601ad4c9146102a6578063715018a6146102b957806378bf2b53146102c1576101e5565b80632348238c116101c35780632348238c1461024c578063250540cf146102615780633777804f1461027457806353a8b57414610289576101e5565b806307fc9eb9146101ea5780630a9763d7146102175780631c21a08f1461022c575b600080fd5b6101fd6101f8366004611a65565b61043f565b60405161020e9594939291906122b4565b60405180910390f35b61021f61046e565b60405161020e9190612287565b61023f61023a366004611a65565b610473565b60405161020e9190611c39565b61025f61025a366004611725565b61051c565b005b61021f61026f366004611725565b6105db565b61027c610601565b60405161020e9190611bc3565b6102916106da565b60405161020e9190611b63565b61023f6107f9565b61025f6102b4366004611aa9565b610815565b61025f610849565b61025f6102cf366004611928565b6108b7565b61021f610a00565b61025f6102ea366004611928565b610a06565b6102f7610b7f565b60405161020e9190611b4f565b61021f610b8e565b610314610b94565b60405161020e9190611c11565b61025f61032f366004611725565b610bba565b610347610342366004611725565b610ce7565b60405161020e92919061224d565b61021f610d93565b61025f61036b366004611725565b610d99565b61025f61037e366004611a7d565b610e68565b61021f6103913660046119c1565b610e96565b61039e610f14565b60405161020e9392919061229e565b61025f6103bb366004611725565b610f22565b6102f7610fe6565b61025f6103d636600461173f565b610ff5565b61021f6110db565b61025f6103f1366004611951565b6110e1565b610409610404366004611725565b611175565b60405161020e9493929190611c1c565b61025f610427366004611725565b6111a0565b61031461043a366004611725565b6111d0565b603660205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b60fa81565b603a818154811061048357600080fd5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152935090918301828280156105145780601f106104e957610100808354040283529160200191610514565b820191906000526020600020905b8154815290600101906020018083116104f757829003601f168201915b505050505081565b6034546001600160a01b0316610530611219565b6001600160a01b03161461055f5760405162461bcd60e51b815260040161055690612143565b60405180910390fd5b6001600160a01b0381166105855760405162461bcd60e51b815260040161055690611f4b565b603480546001600160a01b0319166001600160a01b0383161790556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9906105d0908390611b4f565b60405180910390a150565b60008060006105e984610ce7565b915091506105f7828261121d565b925050505b919050565b603a5460609067ffffffffffffffff8111801561061d57600080fd5b5060405190808252806020026020018201604052801561065757816020015b6106446115b4565b81526020019060019003908161063c5790505b50905060005b603a548110156106d657603660008281526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250508282815181106106c357fe5b602090810291909101015260010161065d565b5090565b603a5460609067ffffffffffffffff811180156106f657600080fd5b5060405190808252806020026020018201604052801561072a57816020015b60608152602001906001900390816107155790505b50905060005b603a548110156106d657603a818154811061074757fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156107d55780601f106107aa576101008083540402835291602001916107d5565b820191906000526020600020905b8154815290600101906020018083116107b857829003601f168201915b50505050508282815181106107e657fe5b6020908102919091010152600101610730565b604080518082019091526002815261763160f01b602082015290565b61081d610b94565b6108395760405162461bcd60e51b815260040161055690611eb9565b610844838383611275565b505050565b610851610b94565b61086d5760405162461bcd60e51b815260040161055690611eb9565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b816001600160a01b0381166108de5760405162461bcd60e51b815260040161055690611e4d565b6108e6610b94565b8061091057506108f4610fe6565b6001600160a01b0316610905611219565b6001600160a01b0316145b61092c5760405162461bcd60e51b815260040161055690611e84565b603a54821061094d5760405162461bcd60e51b815260040161055690611cf1565b6001600160a01b038316600081815260356020818152604080842081516080810183528154600283018054838601908152600385018054606086019081526001808752868a018f81529b8d9052999098528451151560ff1990941693909317855597519690930195909555945190559051909155519091907f720764556647dd167f4229d6a4255ac86018e302a50fc29dd67a70edb7b314d0906109f2908690612287565b60405180910390a250505050565b60395481565b6034546001600160a01b0316610a1a611219565b6001600160a01b031614610a405760405162461bcd60e51b815260040161055690612143565b600080610a4c84610ce7565b91509150610a59846111d0565b610a755760405162461bcd60e51b8152600401610556906121d1565b8051831015610a965760405162461bcd60e51b815260040161055690612208565b81606001516201518001421115610ab557426060830152600060408301525b6000610ac1838361121d565b905080841115610ae35760405162461bcd60e51b815260040161055690611c4c565b6040830151610af29085611305565b60408481019182526001600160a01b038716600081815260356020908152908390208751815460ff191690151517815590870151600182015592516002840181905560608701516003909401849055915190927f84480cc6a063ffd72c3eddf21e3ffd30db3e2b8e386ec3abf09c98ee9e0e8d3492610b7092612290565b60405180910390a25050505050565b6033546001600160a01b031690565b60385481565b6033546000906001600160a01b0316610bab611219565b6001600160a01b031614905090565b806001600160a01b038116610be15760405162461bcd60e51b815260040161055690611e4d565b610be9610b94565b610c055760405162461bcd60e51b815260040161055690611eb9565b6001600160a01b0382166000908152603560209081526040918290208251608081018452815460ff161515808252600183015493820193909352600282015493810193909352600301546060830152610c705760405162461bcd60e51b815260040161055690612068565b60008082526001600160a01b0384168082526035602090815260408084208551815460ff191690151517815591850151600183015580850151600283015560608501516003909201919091555190917fbf996b4fd74f0c7159bb017b1db415b0d9a6f13129f46d0b93309d170b78df3191a2505050565b610cef6115e3565b610cf76115b4565b50506001600160a01b03166000908152603560209081526040808320815160808082018452825460ff1615158252600180840154838701819052600280860154858801526003958601546060808701919091529189526036885297869020865160a08101885281548152928101549783019790975296860154948101949094529184015494830194909452600490920154918101919091529091565b60375481565b600054610100900460ff1680610db2575060005460ff16155b610dce5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610df9576000805460ff1961ff0019909116610100171660011790555b603480546001600160a01b0319166001600160a01b0384811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610e4a921690611b4f565b60405180910390a18015610e64576000805461ff00191690555b5050565b610e70610b94565b610e8c5760405162461bcd60e51b815260040161055690611eb9565b610e64828261132a565b6000610ea0610b94565b610ebc5760405162461bcd60e51b815260040161055690611eb9565b610f0a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f059250505036859003850185611a4a565b61145c565b90505b9392505050565b603754603854603954909192565b600054610100900460ff1680610f3b575060005460ff16155b610f575760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610f82576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e64576000805461ff00191690555050565b6034546001600160a01b031690565b600054610100900460ff168061100e575060005460ff16155b61102a5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015611055576000805460ff1961ff0019909116610100171660011790555b61105e87610f22565b61106786610d99565b611072858585611275565b60005b82518110156110bf576110b683828151811061108d57fe5b6020026020010151600001518483815181106110a557fe5b60200260200101516020015161145c565b50600101611075565b5080156110d2576000805461ff00191690555b50505050505050565b603a5490565b6110e9610b94565b6111055760405162461bcd60e51b815260040161055690611eb9565b806111225760405162461bcd60e51b815260040161055690611dc8565b60005b818110156108445761116d83838381811061113c57fe5b6111529260206040909202019081019150611725565b84848481811061115e57fe5b905060400201602001356108b7565b600101611125565b603560205260009081526040902080546001820154600283015460039093015460ff90921692909184565b6111a8610b94565b6111c45760405162461bcd60e51b815260040161055690611eb9565b6111cd81611532565b50565b6000816001600160a01b0381166111f95760405162461bcd60e51b815260040161055690611e4d565b50506001600160a01b031660009081526035602052604090205460ff1690565b3390565b60008260600151620151800142111561123857600060408401525b826040015182604001511161124f5750600061126f565b82604001518260400151039050816020015181111561126f575060208101515b92915050565b818311156112955760405162461bcd60e51b815260040161055690611fde565b808211156112b55760405162461bcd60e51b8152600401610556906120f0565b6037839055603882905560398190556040517ffcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219906112f89085908590859061229e565b60405180910390a1505050565b600082820183811015610f0d5760405162461bcd60e51b815260040161055690611cba565b603a54821061134b5760405162461bcd60e51b815260040161055690611f95565b8051602082015110156113705760405162461bcd60e51b815260040161055690611d7b565b8060200151816040015110156113985760405162461bcd60e51b815260040161055690611dff565b80516060820151116113bc5760405162461bcd60e51b81526004016105569061209f565b80606001518160800151116113e35760405162461bcd60e51b815260040161055690611eee565b600082815260366020908152604091829020835181559083015160018201558183015160028201556060830151600382015560808301516004909101555182907f1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb9061145090849061223f565b60405180910390a25050565b60008083511161147e5760405162461bcd60e51b815260040161055690611c83565b50603a5460fa6001820111156114a65760405162461bcd60e51b815260040161055690612031565b603a805460018101825560009190915283516114e9917fa2999d817b6757290b50e8ecf3fa939673403dd35c97de392fdb343b4015ce9e0190602086019061160d565b506114f4818361132a565b807fb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0846040516115249190611c39565b60405180910390a292915050565b6001600160a01b0381166115585760405162461bcd60e51b81526004016105569061218f565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806000151581526020016000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826116435760008555611689565b82601f1061165c57805160ff1916838001178555611689565b82800160010185558215611689579182015b8281111561168957825182559160200191906001019061166e565b506106d69291505b808211156106d65760008155600101611691565b80356001600160a01b03811681146105fc57600080fd5b600060a082840312156116cd578081fd5b60405160a0810181811067ffffffffffffffff821117156116ea57fe5b806040525080915082358152602083013560208201526040830135604082015260608301356060820152608083013560808201525092915050565b600060208284031215611736578081fd5b610f0d826116a5565b60008060008060008060c08789031215611757578182fd5b611760876116a5565b955061176e602088016116a5565b945060408701359350606087013592506080870135915067ffffffffffffffff60a0880135111561179d578081fd5b60a0870135870188601f8201126117b2578182fd5b67ffffffffffffffff813511156117c557fe5b6117d4602080833502016122d7565b81358152602080820191908301845b84358110156119165760c0823586018e03601f19011215611802578586fd5b60405180604082011067ffffffffffffffff6040830111171561182157fe5b6040810160405267ffffffffffffffff60208435880101351115611843578687fd5b82358601602081013501603f018e1361185a578687fd5b67ffffffffffffffff60208435880181810135010135111561187857fe5b61189883358701602081810135909101810135601f01601f1916016122d7565b60208435880181810135019081013580835260409101018f10156118ba578788fd5b602084358801818101350180820135916040909101908301378335870160208181013582018101358301018990529082526118f9908f906040016116bc565b6020828101919091529085529384019391909101906001016117e3565b50508093505050509295509295509295565b6000806040838503121561193a578182fd5b611943836116a5565b946020939093013593505050565b60008060208385031215611963578182fd5b823567ffffffffffffffff8082111561197a578384fd5b818501915085601f83011261198d578384fd5b81358181111561199b578485fd5b8660206040830285010111156119af578485fd5b60209290920196919550909350505050565b600080600083850360c08112156119d6578384fd5b843567ffffffffffffffff808211156119ed578586fd5b818701915087601f830112611a00578586fd5b813581811115611a0e578687fd5b886020828501011115611a1f578687fd5b60209290920195509093505060a0601f1982011215611a3c578182fd5b506020840190509250925092565b600060a08284031215611a5b578081fd5b610f0d83836116bc565b600060208284031215611a76578081fd5b5035919050565b60008060c08385031215611a8f578182fd5b82359150611aa084602085016116bc565b90509250929050565b600080600060608486031215611abd578283fd5b505081359360208301359350604090920135919050565b60008151808452815b81811015611af957602081850181015186830182015201611add565b81811115611b0a5782602083870101525b50601f01601f19169290920160200192915050565b80518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b6001600160a01b0391909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611bb657603f19888603018452611ba4858351611ad4565b94509285019290850190600101611b88565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611c0557611bf2838551611b1f565b9284019260a09290920191600101611bdf565b50909695505050505050565b901515815260200190565b931515845260208401929092526040830152606082015260800190565b600060208252610f0d6020830184611ad4565b6020808252601b908201527f416c6c6f77546f6b656e733a204578636565646564206c696d69740000000000604082015260600190565b6020808252601e908201527f416c6c6f77546f6b656e733a20456d707479206465736372697074696f6e0000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526022908201527f416c6c6f77546f6b656e733a2074797065496420646f6573206e6f74206578696040820152611cdd60f21b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252602d908201527f416c6c6f77546f6b656e733a206d6178546f6b656e7320736d616c6c6572207460408201526c68616e206d696e546f6b656e7360981b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a20656d70747920746f6b656e7300000000000000604082015260600190565b6020808252602e908201527f416c6c6f77546f6b656e733a206461696c794c696d697420736d616c6c65722060408201526d7468616e206d6178546f6b656e7360901b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a204e756c6c204164647265737300000000000000604082015260600190565b6020808252818101527f416c6c6f77546f6b656e733a20756e617574686f72697a65642073656e646572604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526039908201527f416c6c6f77546f6b656e733a206c696d6974732e6c61726765416d6f756e742060408201527f736d616c6c6572207468616e206d656469756d416d6f756e7400000000000000606082015260800190565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f416c6c6f77546f6b656e733a20626967676572207468616e20747970654465736040820152686372697074696f6e7360b81b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a20736d616c6c20626967676572207468616e206d604082015272656469756d20636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252601e908201527f416c6c6f77546f6b656e733a2052656163686564204d41585f54595045530000604082015260600190565b60208082526018908201527f416c6c6f77546f6b656e733a204e6f7420416c6c6f7765640000000000000000604082015260600190565b60208082526031908201527f416c6c6f77546f6b656e733a206c696d6974732e6d656469756d416d6f756e746040820152701039b6b0b63632b9103a3430b71036b4b760791b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a206d656469756d20626967676572207468616e206040820152726c6172676520636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601c908201527f416c6c6f77546f6b656e733a204e6f742077686974656c697374656400000000604082015260600190565b6020808252601d908201527f416c6c6f77546f6b656e733a204c6f776572207468616e206c696d6974000000604082015260600190565b60a0810161126f8284611b1f565b600061012082019050835115158252602084015160208301526040840151604083015260608401516060830152610f0d6080830184611b1f565b90815260200190565b918252602082015260400190565b9283526020830191909152604082015260600190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff811182821017156122f357fe5b60405291905056fea26469706673582212201e8e7daaf66204df917383a3310c7fd1c18b921bb77f19ca1a9103a1dcd8335864736f6c63430007060033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101e55760003560e01c80638f32d59b1161010f578063c4d66de8116100a2578063e4f89ae411610071578063e4f89ae4146103e3578063e744092e146103f6578063f2fde38b14610419578063f9eaee0d1461042c576101e5565b8063c4d66de8146103ad578063c6dbdf61146103c0578063d4164b5d146103c8578063d7516faa146103db576101e5565b8063adfeb5eb116100de578063adfeb5eb1461035d578063b348a29f14610370578063bb698dad14610383578063c361ce8314610396576101e5565b80638f32d59b1461030c57806390469a9d146103215780639d27d22614610334578063a81a8b1f14610355576101e5565b806354fd4d50116101875780637d496be9116101565780637d496be9146102d45780638c34bc55146102dc5780638da5cb5b146102ef5780638de52dd714610304576101e5565b806354fd4d501461029e578063601ad4c9146102a6578063715018a6146102b957806378bf2b53146102c1576101e5565b80632348238c116101c35780632348238c1461024c578063250540cf146102615780633777804f1461027457806353a8b57414610289576101e5565b806307fc9eb9146101ea5780630a9763d7146102175780631c21a08f1461022c575b600080fd5b6101fd6101f8366004611a65565b61043f565b60405161020e9594939291906122b4565b60405180910390f35b61021f61046e565b60405161020e9190612287565b61023f61023a366004611a65565b610473565b60405161020e9190611c39565b61025f61025a366004611725565b61051c565b005b61021f61026f366004611725565b6105db565b61027c610601565b60405161020e9190611bc3565b6102916106da565b60405161020e9190611b63565b61023f6107f9565b61025f6102b4366004611aa9565b610815565b61025f610849565b61025f6102cf366004611928565b6108b7565b61021f610a00565b61025f6102ea366004611928565b610a06565b6102f7610b7f565b60405161020e9190611b4f565b61021f610b8e565b610314610b94565b60405161020e9190611c11565b61025f61032f366004611725565b610bba565b610347610342366004611725565b610ce7565b60405161020e92919061224d565b61021f610d93565b61025f61036b366004611725565b610d99565b61025f61037e366004611a7d565b610e68565b61021f6103913660046119c1565b610e96565b61039e610f14565b60405161020e9392919061229e565b61025f6103bb366004611725565b610f22565b6102f7610fe6565b61025f6103d636600461173f565b610ff5565b61021f6110db565b61025f6103f1366004611951565b6110e1565b610409610404366004611725565b611175565b60405161020e9493929190611c1c565b61025f610427366004611725565b6111a0565b61031461043a366004611725565b6111d0565b603660205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b60fa81565b603a818154811061048357600080fd5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152935090918301828280156105145780601f106104e957610100808354040283529160200191610514565b820191906000526020600020905b8154815290600101906020018083116104f757829003601f168201915b505050505081565b6034546001600160a01b0316610530611219565b6001600160a01b03161461055f5760405162461bcd60e51b815260040161055690612143565b60405180910390fd5b6001600160a01b0381166105855760405162461bcd60e51b815260040161055690611f4b565b603480546001600160a01b0319166001600160a01b0383161790556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9906105d0908390611b4f565b60405180910390a150565b60008060006105e984610ce7565b915091506105f7828261121d565b925050505b919050565b603a5460609067ffffffffffffffff8111801561061d57600080fd5b5060405190808252806020026020018201604052801561065757816020015b6106446115b4565b81526020019060019003908161063c5790505b50905060005b603a548110156106d657603660008281526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250508282815181106106c357fe5b602090810291909101015260010161065d565b5090565b603a5460609067ffffffffffffffff811180156106f657600080fd5b5060405190808252806020026020018201604052801561072a57816020015b60608152602001906001900390816107155790505b50905060005b603a548110156106d657603a818154811061074757fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156107d55780601f106107aa576101008083540402835291602001916107d5565b820191906000526020600020905b8154815290600101906020018083116107b857829003601f168201915b50505050508282815181106107e657fe5b6020908102919091010152600101610730565b604080518082019091526002815261763160f01b602082015290565b61081d610b94565b6108395760405162461bcd60e51b815260040161055690611eb9565b610844838383611275565b505050565b610851610b94565b61086d5760405162461bcd60e51b815260040161055690611eb9565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b816001600160a01b0381166108de5760405162461bcd60e51b815260040161055690611e4d565b6108e6610b94565b8061091057506108f4610fe6565b6001600160a01b0316610905611219565b6001600160a01b0316145b61092c5760405162461bcd60e51b815260040161055690611e84565b603a54821061094d5760405162461bcd60e51b815260040161055690611cf1565b6001600160a01b038316600081815260356020818152604080842081516080810183528154600283018054838601908152600385018054606086019081526001808752868a018f81529b8d9052999098528451151560ff1990941693909317855597519690930195909555945190559051909155519091907f720764556647dd167f4229d6a4255ac86018e302a50fc29dd67a70edb7b314d0906109f2908690612287565b60405180910390a250505050565b60395481565b6034546001600160a01b0316610a1a611219565b6001600160a01b031614610a405760405162461bcd60e51b815260040161055690612143565b600080610a4c84610ce7565b91509150610a59846111d0565b610a755760405162461bcd60e51b8152600401610556906121d1565b8051831015610a965760405162461bcd60e51b815260040161055690612208565b81606001516201518001421115610ab557426060830152600060408301525b6000610ac1838361121d565b905080841115610ae35760405162461bcd60e51b815260040161055690611c4c565b6040830151610af29085611305565b60408481019182526001600160a01b038716600081815260356020908152908390208751815460ff191690151517815590870151600182015592516002840181905560608701516003909401849055915190927f84480cc6a063ffd72c3eddf21e3ffd30db3e2b8e386ec3abf09c98ee9e0e8d3492610b7092612290565b60405180910390a25050505050565b6033546001600160a01b031690565b60385481565b6033546000906001600160a01b0316610bab611219565b6001600160a01b031614905090565b806001600160a01b038116610be15760405162461bcd60e51b815260040161055690611e4d565b610be9610b94565b610c055760405162461bcd60e51b815260040161055690611eb9565b6001600160a01b0382166000908152603560209081526040918290208251608081018452815460ff161515808252600183015493820193909352600282015493810193909352600301546060830152610c705760405162461bcd60e51b815260040161055690612068565b60008082526001600160a01b0384168082526035602090815260408084208551815460ff191690151517815591850151600183015580850151600283015560608501516003909201919091555190917fbf996b4fd74f0c7159bb017b1db415b0d9a6f13129f46d0b93309d170b78df3191a2505050565b610cef6115e3565b610cf76115b4565b50506001600160a01b03166000908152603560209081526040808320815160808082018452825460ff1615158252600180840154838701819052600280860154858801526003958601546060808701919091529189526036885297869020865160a08101885281548152928101549783019790975296860154948101949094529184015494830194909452600490920154918101919091529091565b60375481565b600054610100900460ff1680610db2575060005460ff16155b610dce5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610df9576000805460ff1961ff0019909116610100171660011790555b603480546001600160a01b0319166001600160a01b0384811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610e4a921690611b4f565b60405180910390a18015610e64576000805461ff00191690555b5050565b610e70610b94565b610e8c5760405162461bcd60e51b815260040161055690611eb9565b610e64828261132a565b6000610ea0610b94565b610ebc5760405162461bcd60e51b815260040161055690611eb9565b610f0a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f059250505036859003850185611a4a565b61145c565b90505b9392505050565b603754603854603954909192565b600054610100900460ff1680610f3b575060005460ff16155b610f575760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610f82576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e64576000805461ff00191690555050565b6034546001600160a01b031690565b600054610100900460ff168061100e575060005460ff16155b61102a5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015611055576000805460ff1961ff0019909116610100171660011790555b61105e87610f22565b61106786610d99565b611072858585611275565b60005b82518110156110bf576110b683828151811061108d57fe5b6020026020010151600001518483815181106110a557fe5b60200260200101516020015161145c565b50600101611075565b5080156110d2576000805461ff00191690555b50505050505050565b603a5490565b6110e9610b94565b6111055760405162461bcd60e51b815260040161055690611eb9565b806111225760405162461bcd60e51b815260040161055690611dc8565b60005b818110156108445761116d83838381811061113c57fe5b6111529260206040909202019081019150611725565b84848481811061115e57fe5b905060400201602001356108b7565b600101611125565b603560205260009081526040902080546001820154600283015460039093015460ff90921692909184565b6111a8610b94565b6111c45760405162461bcd60e51b815260040161055690611eb9565b6111cd81611532565b50565b6000816001600160a01b0381166111f95760405162461bcd60e51b815260040161055690611e4d565b50506001600160a01b031660009081526035602052604090205460ff1690565b3390565b60008260600151620151800142111561123857600060408401525b826040015182604001511161124f5750600061126f565b82604001518260400151039050816020015181111561126f575060208101515b92915050565b818311156112955760405162461bcd60e51b815260040161055690611fde565b808211156112b55760405162461bcd60e51b8152600401610556906120f0565b6037839055603882905560398190556040517ffcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219906112f89085908590859061229e565b60405180910390a1505050565b600082820183811015610f0d5760405162461bcd60e51b815260040161055690611cba565b603a54821061134b5760405162461bcd60e51b815260040161055690611f95565b8051602082015110156113705760405162461bcd60e51b815260040161055690611d7b565b8060200151816040015110156113985760405162461bcd60e51b815260040161055690611dff565b80516060820151116113bc5760405162461bcd60e51b81526004016105569061209f565b80606001518160800151116113e35760405162461bcd60e51b815260040161055690611eee565b600082815260366020908152604091829020835181559083015160018201558183015160028201556060830151600382015560808301516004909101555182907f1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb9061145090849061223f565b60405180910390a25050565b60008083511161147e5760405162461bcd60e51b815260040161055690611c83565b50603a5460fa6001820111156114a65760405162461bcd60e51b815260040161055690612031565b603a805460018101825560009190915283516114e9917fa2999d817b6757290b50e8ecf3fa939673403dd35c97de392fdb343b4015ce9e0190602086019061160d565b506114f4818361132a565b807fb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0846040516115249190611c39565b60405180910390a292915050565b6001600160a01b0381166115585760405162461bcd60e51b81526004016105569061218f565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806000151581526020016000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826116435760008555611689565b82601f1061165c57805160ff1916838001178555611689565b82800160010185558215611689579182015b8281111561168957825182559160200191906001019061166e565b506106d69291505b808211156106d65760008155600101611691565b80356001600160a01b03811681146105fc57600080fd5b600060a082840312156116cd578081fd5b60405160a0810181811067ffffffffffffffff821117156116ea57fe5b806040525080915082358152602083013560208201526040830135604082015260608301356060820152608083013560808201525092915050565b600060208284031215611736578081fd5b610f0d826116a5565b60008060008060008060c08789031215611757578182fd5b611760876116a5565b955061176e602088016116a5565b945060408701359350606087013592506080870135915067ffffffffffffffff60a0880135111561179d578081fd5b60a0870135870188601f8201126117b2578182fd5b67ffffffffffffffff813511156117c557fe5b6117d4602080833502016122d7565b81358152602080820191908301845b84358110156119165760c0823586018e03601f19011215611802578586fd5b60405180604082011067ffffffffffffffff6040830111171561182157fe5b6040810160405267ffffffffffffffff60208435880101351115611843578687fd5b82358601602081013501603f018e1361185a578687fd5b67ffffffffffffffff60208435880181810135010135111561187857fe5b61189883358701602081810135909101810135601f01601f1916016122d7565b60208435880181810135019081013580835260409101018f10156118ba578788fd5b602084358801818101350180820135916040909101908301378335870160208181013582018101358301018990529082526118f9908f906040016116bc565b6020828101919091529085529384019391909101906001016117e3565b50508093505050509295509295509295565b6000806040838503121561193a578182fd5b611943836116a5565b946020939093013593505050565b60008060208385031215611963578182fd5b823567ffffffffffffffff8082111561197a578384fd5b818501915085601f83011261198d578384fd5b81358181111561199b578485fd5b8660206040830285010111156119af578485fd5b60209290920196919550909350505050565b600080600083850360c08112156119d6578384fd5b843567ffffffffffffffff808211156119ed578586fd5b818701915087601f830112611a00578586fd5b813581811115611a0e578687fd5b886020828501011115611a1f578687fd5b60209290920195509093505060a0601f1982011215611a3c578182fd5b506020840190509250925092565b600060a08284031215611a5b578081fd5b610f0d83836116bc565b600060208284031215611a76578081fd5b5035919050565b60008060c08385031215611a8f578182fd5b82359150611aa084602085016116bc565b90509250929050565b600080600060608486031215611abd578283fd5b505081359360208301359350604090920135919050565b60008151808452815b81811015611af957602081850181015186830182015201611add565b81811115611b0a5782602083870101525b50601f01601f19169290920160200192915050565b80518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b6001600160a01b0391909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611bb657603f19888603018452611ba4858351611ad4565b94509285019290850190600101611b88565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611c0557611bf2838551611b1f565b9284019260a09290920191600101611bdf565b50909695505050505050565b901515815260200190565b931515845260208401929092526040830152606082015260800190565b600060208252610f0d6020830184611ad4565b6020808252601b908201527f416c6c6f77546f6b656e733a204578636565646564206c696d69740000000000604082015260600190565b6020808252601e908201527f416c6c6f77546f6b656e733a20456d707479206465736372697074696f6e0000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526022908201527f416c6c6f77546f6b656e733a2074797065496420646f6573206e6f74206578696040820152611cdd60f21b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252602d908201527f416c6c6f77546f6b656e733a206d6178546f6b656e7320736d616c6c6572207460408201526c68616e206d696e546f6b656e7360981b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a20656d70747920746f6b656e7300000000000000604082015260600190565b6020808252602e908201527f416c6c6f77546f6b656e733a206461696c794c696d697420736d616c6c65722060408201526d7468616e206d6178546f6b656e7360901b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a204e756c6c204164647265737300000000000000604082015260600190565b6020808252818101527f416c6c6f77546f6b656e733a20756e617574686f72697a65642073656e646572604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526039908201527f416c6c6f77546f6b656e733a206c696d6974732e6c61726765416d6f756e742060408201527f736d616c6c6572207468616e206d656469756d416d6f756e7400000000000000606082015260800190565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f416c6c6f77546f6b656e733a20626967676572207468616e20747970654465736040820152686372697074696f6e7360b81b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a20736d616c6c20626967676572207468616e206d604082015272656469756d20636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252601e908201527f416c6c6f77546f6b656e733a2052656163686564204d41585f54595045530000604082015260600190565b60208082526018908201527f416c6c6f77546f6b656e733a204e6f7420416c6c6f7765640000000000000000604082015260600190565b60208082526031908201527f416c6c6f77546f6b656e733a206c696d6974732e6d656469756d416d6f756e746040820152701039b6b0b63632b9103a3430b71036b4b760791b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a206d656469756d20626967676572207468616e206040820152726c6172676520636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601c908201527f416c6c6f77546f6b656e733a204e6f742077686974656c697374656400000000604082015260600190565b6020808252601d908201527f416c6c6f77546f6b656e733a204c6f776572207468616e206c696d6974000000604082015260600190565b60a0810161126f8284611b1f565b600061012082019050835115158252602084015160208301526040840151604083015260608401516060830152610f0d6080830184611b1f565b90815260200190565b918252602082015260400190565b9283526020830191909152604082015260600190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff811182821017156122f357fe5b60405291905056fea26469706673582212201e8e7daaf66204df917383a3310c7fd1c18b921bb77f19ca1a9103a1dcd8335864736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "__Secondary_init(address)": {
+ "details": "Sets the primary account to the one that is creating the Secondary contract."
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15785,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15788,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15828,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16072,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 16205,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_address"
+ },
+ {
+ "astId": 31,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "allowedTokens",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_mapping(t_address,t_struct(TokenInfo)7131_storage)"
+ },
+ {
+ "astId": 35,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeLimits",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_mapping(t_uint256,t_struct(Limits)7122_storage)"
+ },
+ {
+ "astId": 37,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "smallAmountConfirmations",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 39,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "mediumAmountConfirmations",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 41,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "largeAmountConfirmations",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 44,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeDescriptions",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_array(t_string_storage)dyn_storage"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "base": "t_string_storage",
+ "encoding": "dynamic_array",
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_struct(TokenInfo)7131_storage)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => struct IAllowTokens.TokenInfo)",
+ "numberOfBytes": "32",
+ "value": "t_struct(TokenInfo)7131_storage"
+ },
+ "t_mapping(t_uint256,t_struct(Limits)7122_storage)": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => struct IAllowTokens.Limits)",
+ "numberOfBytes": "32",
+ "value": "t_struct(Limits)7122_storage"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(Limits)7122_storage": {
+ "encoding": "inplace",
+ "label": "struct IAllowTokens.Limits",
+ "members": [
+ {
+ "astId": 7113,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "min",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7115,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "max",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7117,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "daily",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7119,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "mediumAmount",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7121,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "largeAmount",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "160"
+ },
+ "t_struct(TokenInfo)7131_storage": {
+ "encoding": "inplace",
+ "label": "struct IAllowTokens.TokenInfo",
+ "members": [
+ {
+ "astId": 7124,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "allowed",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 7126,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeId",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7128,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "spentToday",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7130,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "lastDay",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/AllowTokensProxy.json b/bridge/deployments/rsktestnetbsc/AllowTokensProxy.json
new file mode 100644
index 000000000..c6e7f254d
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/AllowTokensProxy.json
@@ -0,0 +1,426 @@
+{
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "transactionIndex": 0,
+ "gasUsed": "1808069",
+ "logsBloom": "0x04000000000000000000000000010000000100000000200000800000000000000000000000000000000000000000000000002000020400000000000000040000000010000000000000000000000000000001000100040000000000000100000008000000020000000000800000000800000000000000000000000000000000400004000400000000000000000004001800000800000000000000000000000000000000000000000000000100000004000000000000c00000002000080000400000000000000004000000000000000000000008008000000000000000000060200000000080200000000000000000000000000000008000000000000000100000",
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f",
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ],
+ "data": "0x0000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf63",
+ "logIndex": 1,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xfcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 2,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "data": "0x00000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000015af1d78b58c400000000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a0000",
+ "logIndex": 3,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034254430000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 4,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000001"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000028a857425466f800000000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000429d069189e0000",
+ "logIndex": 5,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000001"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034554480000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 6,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000002"
+ ],
+ "data": "0x00000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000878678326eac90000000000000000000000000000000000000000000000000010f0cf064dd59200000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a0000",
+ "logIndex": 7,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000002"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000083c31303030757364000000000000000000000000000000000000000000000000",
+ "logIndex": 8,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000003"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000054b40b1f852bda00000000000000000000000000000000000000000000000000a968163f0a57b4000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000008ac7230489e80000",
+ "logIndex": 9,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000003"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000073c31303075736400000000000000000000000000000000000000000000000000",
+ "logIndex": 10,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000004"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000002116545850052128000000000000000000000000000000000000000000000000422ca8b0a00a4250000000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000056bc75e2d63100000",
+ "logIndex": 11,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000004"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000053d31757364000000000000000000000000000000000000000000000000000000",
+ "logIndex": 12,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000005"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000cecb8f27f4200f3a0000000000000000000000000000000000000000000000019d971e4fe8401e740000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea00000",
+ "logIndex": 13,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000005"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000053c31757364000000000000000000000000000000000000000000000000000000",
+ "logIndex": 14,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000006"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000050c783eb9b5c85f2a80000000000000000000000000000000000000000000000a18f07d736b90be5500000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea00000",
+ "logIndex": 15,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152255,
+ "transactionHash": "0xe42d2c15c1337ab8969e8e0e98326010375c70ed9afdbf54e19ab7786a1e8f11",
+ "address": "0xd5343aafd8bfe2960d4E832201CB69CD04E531d5",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000006"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000063c3163656e740000000000000000000000000000000000000000000000000000",
+ "logIndex": 16,
+ "blockHash": "0xcfdfff8608c3b1ddb273d727b70bf394e1405984a4e8e91f7ceac85e80712a8f"
+ }
+ ],
+ "blockNumber": 2152255,
+ "cumulativeGasUsed": "1808069",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0x11804f8DeADb1803603278156AA1e6602949e8b2",
+ "0x8c35e166d2dea7a8a28aaea11ad7933cdae4b0ab",
+ "0xd4164b5d000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e80000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf6300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000015af1d78b58c400000000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000000003425443000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000028a857425466f800000000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000429d069189e00000000000000000000000000000000000000000000000000000000000000000003455448000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000878678326eac90000000000000000000000000000000000000000000000000010f0cf064dd59200000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000083c3130303075736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000054b40b1f852bda00000000000000000000000000000000000000000000000000a968163f0a57b4000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000073c3130307573640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000002116545850052128000000000000000000000000000000000000000000000000422ca8b0a00a4250000000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000053d3175736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000cecb8f27f4200f3a0000000000000000000000000000000000000000000000019d971e4fe8401e740000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000053c3175736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000050c783eb9b5c85f2a80000000000000000000000000000000000000000000000a18f07d736b90be5500000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000063c3163656e740000000000000000000000000000000000000000000000000000"
+ ],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"stateVariables\":{\"_ADMIN_SLOT\":{\"details\":\"Storage slot with the admin of the contract. This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0x590a4d952d39a99972cbcb691b472c5d58af9ae8fd142355ad26200affdd2a51\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x0d5202a38732881d576fe3831605fe2633e1bc9f981ebea9c3a368af027e0b71\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x53b00bc48bd4eac1e100195c494267c0ca082bd91ac3018e2ee6155fbcbbb14f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000c9f38038062000c9f83398101604081905262000026916200022e565b8281620000338262000071565b8051156200005457620000528282620000d360201b620002ca1760201c565b505b506200005d9050565b620000688262000102565b5050506200041d565b62000087816200012660201b620002f61760201c565b620000af5760405162461bcd60e51b8152600401620000a69062000347565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6060620000fb838360405180606001604052806027815260200162000c786027913962000130565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b60606200013d8462000126565b6200015c5760405162461bcd60e51b8152600401620000a690620003a4565b600080856001600160a01b031685604051620001799190620002f4565b600060405180830381855af49150503d8060008114620001b6576040519150601f19603f3d011682016040523d82523d6000602084013e620001bb565b606091505b509092509050620001ce828286620001d8565b9695505050505050565b60608315620001e9575081620000fb565b825115620001fa5782518084602001fd5b8160405162461bcd60e51b8152600401620000a6919062000312565b80516001600160a01b03811681146200012b57600080fd5b60008060006060848603121562000243578283fd5b6200024e8462000216565b92506200025e6020850162000216565b60408501519092506001600160401b03808211156200027b578283fd5b818601915086601f8301126200028f578283fd5b8151818111156200029c57fe5b604051601f8201601f191681016020018381118282101715620002bb57fe5b604052818152838201602001891015620002d3578485fd5b620002e6826020830160208701620003ea565b809450505050509250925092565b6000825162000308818460208701620003ea565b9190910192915050565b600060208252825180602084015262000333816040850160208701620003ea565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b8381101562000407578181015183820152602001620003ed565b8381111562000417576000848401525b50505050565b61084b806200042d6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fabbc30a04f636413f38ca4eda3e460473659576ddb6aaf9066d31235c793fc064736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fabbc30a04f636413f38ca4eda3e460473659576ddb6aaf9066d31235c793fc064736f6c63430007060033",
+ "devdoc": {
+ "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.",
+ "events": {
+ "AdminChanged(address,address)": {
+ "details": "Emitted when the admin account has changed."
+ }
+ },
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "constructor": {
+ "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "stateVariables": {
+ "_ADMIN_SLOT": {
+ "details": "Storage slot with the admin of the contract. This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/Bridge.json b/bridge/deployments/rsktestnetbsc/Bridge.json
new file mode 100644
index 000000000..c1cafd524
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/Bridge.json
@@ -0,0 +1,1684 @@
+{
+ "address": "0xCEA4F7E9a2080D206be1fa7E4245BDecff7102dF",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ }
+ ],
+ "name": "AcceptedCrossTransfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "AllowTokensChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_reciever",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ }
+ ],
+ "name": "Claimed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "_userData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Cross",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "FederationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "FeePercentageChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_newSideTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_newSymbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "NewSideToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Paused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "SideTokenFactoryChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Unpaused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "Upgrading",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "WrappedCurrencyChanged",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "CLAIM_TYPEHASH",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Pausable_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__PauserRol_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "acceptTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "addPauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "allowTokens",
+ "outputs": [
+ {
+ "internalType": "contract IAllowTokens",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "changeAllowTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "changeFederation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "changeSideTokenFactory",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claim",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claimFallback",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_deadline",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_v",
+ "type": "uint8"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_r",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_s",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimGasless",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_originalTokenDecimals",
+ "type": "uint8"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenName",
+ "type": "string"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "domainSeparator",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "feePercentageDivider",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFederation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFeePercentage",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "getTransactionDataHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasBeenClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasCrossed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initDomainSeparator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_federation",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_allowTokens",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_sideTokenFactory",
+ "type": "address"
+ },
+ {
+ "internalType": "string",
+ "name": "_symbolPrefix",
+ "type": "string"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isPauser",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isUpgrading",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "knownTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "mappedTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "nonces",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "originalTokenAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "originalTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "pause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "paused",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenToUse",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "receiveTokensTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renouncePauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "senderAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "setFeePercentage",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "setUpgrading",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "setWrappedCurrency",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "sideTokenFactory",
+ "outputs": [
+ {
+ "internalType": "contract ISideTokenFactory",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbolPrefix",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "userData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "tokensReceived",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionsDataHashes",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unpause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "wrappedCurrency",
+ "outputs": [
+ {
+ "internalType": "contract IWrapped",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x38fdc5eacd9cc4724fc21e6e0e5a313ba9df00f102275d5b4fd08bd4f3e3a93c",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0xCEA4F7E9a2080D206be1fa7E4245BDecff7102dF",
+ "transactionIndex": 0,
+ "gasUsed": "4545139",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x9d43131dcaae51cb2363f7a4909618d8d3a27337af44da3b2b775d18f4afb0b0",
+ "transactionHash": "0x38fdc5eacd9cc4724fc21e6e0e5a313ba9df00f102275d5b4fd08bd4f3e3a93c",
+ "logs": [],
+ "blockNumber": 2152179,
+ "cumulativeGasUsed": "4545139",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"}],\"name\":\"AcceptedCrossTransfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newAllowTokens\",\"type\":\"address\"}],\"name\":\"AllowTokensChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_reciever\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_relayer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"Claimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_userData\",\"type\":\"bytes\"}],\"name\":\"Cross\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newFederation\",\"type\":\"address\"}],\"name\":\"FederationChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"FeePercentageChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newSideTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_newSymbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_granularity\",\"type\":\"uint256\"}],\"name\":\"NewSideToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newSideTokenFactory\",\"type\":\"address\"}],\"name\":\"SideTokenFactoryChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"Upgrading\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_wrappedCurrency\",\"type\":\"address\"}],\"name\":\"WrappedCurrencyChanged\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"CLAIM_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__Pausable_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__PauserRol_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"}],\"name\":\"acceptTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"addPauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allowTokens\",\"outputs\":[{\"internalType\":\"contract IAllowTokens\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAllowTokens\",\"type\":\"address\"}],\"name\":\"changeAllowTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFederation\",\"type\":\"address\"}],\"name\":\"changeFederation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newSideTokenFactory\",\"type\":\"address\"}],\"name\":\"changeSideTokenFactory\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claim\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claimFallback\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"},{\"internalType\":\"address payable\",\"name\":\"_relayer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_s\",\"type\":\"bytes32\"}],\"name\":\"claimGasless\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"claimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"_originalTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"_originalTokenSymbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_originalTokenName\",\"type\":\"string\"}],\"name\":\"createSideToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"domainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePercentageDivider\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFederation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeePercentage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"}],\"name\":\"getTransactionDataHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasBeenClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasCrossed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initDomainSeparator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_federation\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_allowTokens\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_sideTokenFactory\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbolPrefix\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isPauser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUpgrading\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"knownTokens\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mappedTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"originalTokenAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"originalTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenToUse\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"receiveTokensTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renouncePauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"senderAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"setFeePercentage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"setUpgrading\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_wrappedCurrency\",\"type\":\"address\"}],\"name\":\"setWrappedCurrency\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sideTokenFactory\",\"outputs\":[{\"internalType\":\"contract ISideTokenFactory\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbolPrefix\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"userData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transactionsDataHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wrappedCurrency\",\"outputs\":[{\"internalType\":\"contract IWrapped\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"__Pausable_init(address)\":{\"details\":\"Initializes the contract in unpaused state. Assigns the Pauser role to the deployer.\"},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pause()\":{\"details\":\"Called by a pauser to pause, triggers stopped state.\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"unpause()\":{\"details\":\"Called by a pauser to unpause, returns to normal state.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"acceptTransfer(address,address,address,uint256,bytes32,bytes32,uint32)\":{\"notice\":\"Accepts the transaction from the other chain that was voted and sent by the Federation contract\"},\"claim((address,uint256,bytes32,bytes32,uint32))\":{\"notice\":\"Claims the crossed transaction using the hash, this sends the funds to the address indicated in\"},\"depositTo(address)\":{\"notice\":\"Use network currency and cross it.\"},\"receiveTokensTo(address,address,uint256)\":{\"notice\":\"ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction See https://eips.ethereum.org/EIPS/eip-777#motivation for details\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Bridge/Bridge.sol\":\"Bridge\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Bridge/Bridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n// Import base Initializable contract\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\n// Import interface and library from OpenZeppelin contracts\\nimport \\\"../zeppelin/upgradable/utils/ReentrancyGuard.sol\\\";\\nimport \\\"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\n\\nimport \\\"../zeppelin/introspection/IERC1820Registry.sol\\\";\\nimport \\\"../zeppelin/token/ERC777/IERC777Recipient.sol\\\";\\nimport \\\"../zeppelin/token/ERC20/IERC20.sol\\\";\\nimport \\\"../zeppelin/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"../zeppelin/utils/Address.sol\\\";\\nimport \\\"../zeppelin/math/SafeMath.sol\\\";\\nimport \\\"../zeppelin/token/ERC777/IERC777.sol\\\";\\n\\nimport \\\"../lib/LibEIP712.sol\\\";\\nimport \\\"../lib/LibUtils.sol\\\";\\n\\nimport \\\"../interface/IBridge.sol\\\";\\nimport \\\"../interface/ISideToken.sol\\\";\\nimport \\\"../interface/ISideTokenFactory.sol\\\";\\nimport \\\"../interface/IAllowTokens.sol\\\";\\nimport \\\"../interface/IWrapped.sol\\\";\\n\\n// solhint-disable-next-line max-states-count\\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\\n using SafeMath for uint256;\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n address constant internal NULL_ADDRESS = address(0);\\n bytes32 constant internal NULL_HASH = bytes32(0);\\n IERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\n\\n address internal federation;\\n uint256 internal feePercentage;\\n string public symbolPrefix;\\n // replaces uint256 internal _depprecatedLastDay;\\n bytes32 public domainSeparator;\\n uint256 internal _deprecatedSpentToday;\\n\\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\\n mapping (address => bool) public knownTokens; // OriginalToken => true\\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\\n IAllowTokens public allowTokens;\\n ISideTokenFactory public sideTokenFactory;\\n //Bridge_v1 variables\\n bool public isUpgrading;\\n // Percentage with up to 2 decimals\\n uint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\\n //Bridge_v3 variables\\n bytes32 constant internal _erc777Interface = keccak256(\\\"ERC777Token\\\"); // solhint-disable-line const-name-snakecase\\n IWrapped public wrappedCurrency;\\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\\n\\n // keccak256(\\\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\\\");\\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\\n mapping(address => uint) public nonces;\\n\\n event AllowTokensChanged(address _newAllowTokens);\\n event FederationChanged(address _newFederation);\\n event SideTokenFactoryChanged(address _newSideTokenFactory);\\n event Upgrading(bool _isUpgrading);\\n event WrappedCurrencyChanged(address _wrappedCurrency);\\n\\n function initialize(\\n address _manager,\\n address _federation,\\n address _allowTokens,\\n address _sideTokenFactory,\\n string memory _symbolPrefix\\n ) public initializer {\\n UpgradableOwnable.initialize(_manager);\\n UpgradablePausable.__Pausable_init(_manager);\\n symbolPrefix = _symbolPrefix;\\n allowTokens = IAllowTokens(_allowTokens);\\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\\n federation = _federation;\\n //keccak256(\\\"ERC777TokensRecipient\\\")\\n ERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\\n initDomainSeparator();\\n }\\n\\n receive () external payable {\\n // The fallback function is needed to use WRBTC\\n require(_msgSender() == address(wrappedCurrency), \\\"Bridge: not wrappedCurrency\\\");\\n }\\n\\n function version() override external pure returns (string memory) {\\n return \\\"v3\\\";\\n }\\n\\n function initDomainSeparator() public {\\n uint chainId;\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n chainId := chainid()\\n }\\n domainSeparator = LibEIP712.hashEIP712Domain(\\n \\\"RSK Token Bridge\\\",\\n \\\"1\\\",\\n chainId,\\n address(this)\\n );\\n }\\n\\n modifier whenNotUpgrading() {\\n require(!isUpgrading, \\\"Bridge: Upgrading\\\");\\n _;\\n }\\n\\n function acceptTransfer(\\n address _originalTokenAddress,\\n address payable _from,\\n address payable _to,\\n uint256 _amount,\\n bytes32 _blockHash,\\n bytes32 _transactionHash,\\n uint32 _logIndex\\n ) external whenNotPaused nonReentrant override {\\n require(_msgSender() == federation, \\\"Bridge: Not Federation\\\");\\n require(knownTokens[_originalTokenAddress] ||\\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\\n \\\"Bridge: Unknown token\\\"\\n );\\n require(_to != NULL_ADDRESS, \\\"Bridge: Null To\\\");\\n require(_amount > 0, \\\"Bridge: Amount 0\\\");\\n require(_blockHash != NULL_HASH, \\\"Bridge: Null BlockHash\\\");\\n require(_transactionHash != NULL_HASH, \\\"Bridge: Null TxHash\\\");\\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \\\"Bridge: Already accepted\\\");\\n\\n bytes32 _transactionDataHash = getTransactionDataHash(\\n _to,\\n _amount,\\n _blockHash,\\n _transactionHash,\\n _logIndex\\n );\\n // Do not remove, claimed also has the previously processed using the older bridge version\\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\\n require(!claimed[_transactionDataHash], \\\"Bridge: Already claimed\\\");\\n\\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\\n senderAddresses[_transactionHash] = _from;\\n\\n emit AcceptedCrossTransfer(\\n _transactionHash,\\n _originalTokenAddress,\\n _to,\\n _from,\\n _amount,\\n _blockHash,\\n _logIndex\\n );\\n }\\n\\n\\n function createSideToken(\\n uint256 _typeId,\\n address _originalTokenAddress,\\n uint8 _originalTokenDecimals,\\n string calldata _originalTokenSymbol,\\n string calldata _originalTokenName\\n ) external onlyOwner {\\n require(_originalTokenAddress != NULL_ADDRESS, \\\"Bridge: Null token\\\");\\n address sideToken = mappedTokens[_originalTokenAddress];\\n require(sideToken == NULL_ADDRESS, \\\"Bridge: Already exists\\\");\\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\\n\\n // Create side token\\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\\n\\n mappedTokens[_originalTokenAddress] = sideToken;\\n originalTokens[sideToken] = _originalTokenAddress;\\n allowTokens.setToken(sideToken, _typeId);\\n\\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\\n }\\n\\n function claim(ClaimData calldata _claimData)\\n external override returns (uint256 receivedAmount) {\\n\\n receivedAmount = _claim(\\n _claimData,\\n _claimData.to,\\n payable(address(0)),\\n 0\\n );\\n return receivedAmount;\\n }\\n\\n function claimFallback(ClaimData calldata _claimData)\\n external override returns (uint256 receivedAmount) {\\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\\\"Bridge: invalid sender\\\");\\n receivedAmount = _claim(\\n _claimData,\\n _msgSender(),\\n payable(address(0)),\\n 0\\n );\\n return receivedAmount;\\n }\\n\\n function getDigest(\\n ClaimData memory _claimData,\\n address payable _relayer,\\n uint256 _fee,\\n uint256 _deadline\\n ) internal returns (bytes32) {\\n return LibEIP712.hashEIP712Message(\\n domainSeparator,\\n keccak256(\\n abi.encode(\\n CLAIM_TYPEHASH,\\n _claimData.to,\\n _claimData.amount,\\n _claimData.transactionHash,\\n _relayer,\\n _fee,\\n nonces[_claimData.to]++,\\n _deadline\\n )\\n )\\n );\\n }\\n\\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\\n function claimGasless(\\n ClaimData calldata _claimData,\\n address payable _relayer,\\n uint256 _fee,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external override returns (uint256 receivedAmount) {\\n require(_deadline >= block.timestamp, \\\"Bridge: EXPIRED\\\"); // solhint-disable-line not-rely-on-time\\n\\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \\\"Bridge: INVALID_SIGNATURE\\\");\\n\\n receivedAmount = _claim(\\n _claimData,\\n _claimData.to,\\n _relayer,\\n _fee\\n );\\n return receivedAmount;\\n }\\n\\n function _claim(\\n ClaimData calldata _claimData,\\n address payable _reciever,\\n address payable _relayer,\\n uint256 _fee\\n ) internal nonReentrant returns (uint256 receivedAmount) {\\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\\n require(originalTokenAddress != NULL_ADDRESS, \\\"Bridge: Tx not crossed\\\");\\n\\n bytes32 transactionDataHash = getTransactionDataHash(\\n _claimData.to,\\n _claimData.amount,\\n _claimData.blockHash,\\n _claimData.transactionHash,\\n _claimData.logIndex\\n );\\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \\\"Bridge: Wrong transactionDataHash\\\");\\n require(!claimed[transactionDataHash], \\\"Bridge: Already claimed\\\");\\n\\n claimed[transactionDataHash] = true;\\n if (knownTokens[originalTokenAddress]) {\\n receivedAmount =_claimCrossBackToToken(\\n originalTokenAddress,\\n _reciever,\\n _claimData.amount,\\n _relayer,\\n _fee\\n );\\n } else {\\n receivedAmount =_claimCrossToSideToken(\\n originalTokenAddress,\\n _reciever,\\n _claimData.amount,\\n _relayer,\\n _fee\\n );\\n }\\n emit Claimed(\\n _claimData.transactionHash,\\n originalTokenAddress,\\n _claimData.to,\\n senderAddresses[_claimData.transactionHash],\\n _claimData.amount,\\n _claimData.blockHash,\\n _claimData.logIndex,\\n _reciever,\\n _relayer,\\n _fee\\n );\\n return receivedAmount;\\n }\\n\\n function _claimCrossToSideToken(\\n address _originalTokenAddress,\\n address payable _receiver,\\n uint256 _amount,\\n address payable _relayer,\\n uint256 _fee\\n ) internal returns (uint256 receivedAmount) {\\n address sideToken = mappedTokens[_originalTokenAddress];\\n uint256 granularity = IERC777(sideToken).granularity();\\n uint256 formattedAmount = _amount.mul(granularity);\\n require(_fee <= formattedAmount, \\\"Bridge: fee too high\\\");\\n receivedAmount = formattedAmount - _fee;\\n ISideToken(sideToken).mint(_receiver, receivedAmount, \\\"\\\", \\\"\\\");\\n if(_fee > 0) {\\n ISideToken(sideToken).mint(_relayer, _fee, \\\"\\\", \\\"relayer fee\\\");\\n }\\n return receivedAmount;\\n }\\n\\n function _claimCrossBackToToken(\\n address _originalTokenAddress,\\n address payable _receiver,\\n uint256 _amount,\\n address payable _relayer,\\n uint256 _fee\\n ) internal returns (uint256 receivedAmount) {\\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\\n //As side tokens are ERC777 they will always have 18 decimals\\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\\n require(_fee <= formattedAmount, \\\"Bridge: fee too high\\\");\\n receivedAmount = formattedAmount - _fee;\\n if(address(wrappedCurrency) == _originalTokenAddress) {\\n wrappedCurrency.withdraw(formattedAmount);\\n _receiver.transfer(receivedAmount);\\n if(_fee > 0) {\\n _relayer.transfer(_fee);\\n }\\n } else {\\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\\n if(_fee > 0) {\\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\\n }\\n }\\n return receivedAmount;\\n }\\n\\n /**\\n * ERC-20 tokens approve and transferFrom pattern\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\n */\\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\\n address sender = _msgSender();\\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\\n crossTokens(tokenToUse, sender, to, amount, \\\"\\\");\\n }\\n\\n /**\\n * Use network currency and cross it.\\n */\\n function depositTo(address to) override external payable {\\n address sender = _msgSender();\\n require(address(wrappedCurrency) != NULL_ADDRESS, \\\"Bridge: wrappedCurrency empty\\\");\\n wrappedCurrency.deposit{ value: msg.value }();\\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \\\"\\\");\\n }\\n\\n /**\\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\n */\\n function tokensReceived (\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata\\n ) external override(IBridge, IERC777Recipient){\\n //Hook from ERC777address\\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\\n require(to == address(this), \\\"Bridge: Not to this address\\\");\\n address tokenToUse = _msgSender();\\n require(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \\\"Bridge: Not ERC777 token\\\");\\n require(userData.length != 0 || !from.isContract(), \\\"Bridge: Specify receiver address in data\\\");\\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\\n crossTokens(tokenToUse, from, receiver, amount, userData);\\n }\\n\\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\\n internal whenNotUpgrading whenNotPaused nonReentrant {\\n knownTokens[tokenToUse] = true;\\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\\n uint256 amountMinusFees = amount.sub(fee);\\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\\n uint formattedAmount = amount;\\n if(decimals != 18) {\\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\\n }\\n // We consider the amount before fees converted to 18 decimals to check the limits\\n // updateTokenTransfer revert if token not allowed\\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\\n address originalTokenAddress = tokenToUse;\\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\\n //Side Token Crossing\\n originalTokenAddress = originalTokens[tokenToUse];\\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\\n uint256 modulo = amountMinusFees.mod(granularity);\\n fee = fee.add(modulo);\\n amountMinusFees = amountMinusFees.sub(modulo);\\n IERC777(tokenToUse).burn(amountMinusFees, userData);\\n }\\n\\n emit Cross(\\n originalTokenAddress,\\n from,\\n to,\\n amountMinusFees,\\n userData\\n );\\n\\n if (fee > 0) {\\n //Send the payment to the MultiSig of the Federation\\n IERC20(tokenToUse).safeTransfer(owner(), fee);\\n }\\n }\\n\\n function getTransactionDataHash(\\n address _to,\\n uint256 _amount,\\n bytes32 _blockHash,\\n bytes32 _transactionHash,\\n uint32 _logIndex\\n )\\n public pure override returns(bytes32)\\n {\\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\\n }\\n\\n function setFeePercentage(uint amount) external onlyOwner {\\n require(amount < (feePercentageDivider/10), \\\"Bridge: bigger than 10%\\\");\\n feePercentage = amount;\\n emit FeePercentageChanged(feePercentage);\\n }\\n\\n function getFeePercentage() external view override returns(uint) {\\n return feePercentage;\\n }\\n\\n function changeFederation(address newFederation) external onlyOwner {\\n require(newFederation != NULL_ADDRESS, \\\"Bridge: Federation is empty\\\");\\n federation = newFederation;\\n emit FederationChanged(federation);\\n }\\n\\n\\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\\n require(newAllowTokens != NULL_ADDRESS, \\\"Bridge: AllowTokens is empty\\\");\\n allowTokens = IAllowTokens(newAllowTokens);\\n emit AllowTokensChanged(newAllowTokens);\\n }\\n\\n function getFederation() external view returns(address) {\\n return federation;\\n }\\n\\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\\n require(newSideTokenFactory != NULL_ADDRESS, \\\"Bridge: SideTokenFactory is empty\\\");\\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\\n emit SideTokenFactoryChanged(newSideTokenFactory);\\n }\\n\\n function setUpgrading(bool _isUpgrading) external onlyOwner {\\n isUpgrading = _isUpgrading;\\n emit Upgrading(isUpgrading);\\n }\\n\\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\\n require(_wrappedCurrency != NULL_ADDRESS, \\\"Bridge: wrapp is empty\\\");\\n wrappedCurrency = IWrapped(_wrappedCurrency);\\n emit WrappedCurrencyChanged(_wrappedCurrency);\\n }\\n\\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\\n return transactionsDataHashes[transactionHash] != bytes32(0);\\n }\\n\\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\\n return claimed[transactionsDataHashes[transactionHash]];\\n }\\n\\n}\\n\",\"keccak256\":\"0xc5b2b30dc3507f78d5d784859e92cb70f13f64677c6affafa802cb3af3e566c4\",\"license\":\"MIT\"},\"contracts/interface/IAllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\ninterface IAllowTokens {\\n\\n struct Limits {\\n uint256 min;\\n uint256 max;\\n uint256 daily;\\n uint256 mediumAmount;\\n uint256 largeAmount;\\n }\\n\\n struct TokenInfo {\\n bool allowed;\\n uint256 typeId;\\n uint256 spentToday;\\n uint256 lastDay;\\n }\\n\\n struct TypeInfo {\\n string description;\\n Limits limits;\\n }\\n\\n struct TokensAndType {\\n address token;\\n uint256 typeId;\\n }\\n\\n function version() external pure returns (string memory);\\n\\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\\n\\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\\n\\n function getTypesLimits() external view returns(Limits[] memory limits);\\n\\n function getTypeDescriptionsLength() external view returns(uint256);\\n\\n function getTypeDescriptions() external view returns(string[] memory descriptions);\\n\\n function setToken(address token, uint256 typeId) external;\\n\\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\\n\\n function isTokenAllowed(address token) external view returns (bool);\\n\\n function updateTokenTransfer(address token, uint256 amount) external;\\n}\",\"keccak256\":\"0x5a2aaa285c400917cd72fafe61ce409f200c3fc13d984843bccfb97563489a61\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\ninterface IBridge {\\n\\n struct ClaimData {\\n address payable to;\\n uint256 amount;\\n bytes32 blockHash;\\n bytes32 transactionHash;\\n uint32 logIndex;\\n }\\n\\n function version() external pure returns (string memory);\\n\\n function getFeePercentage() external view returns(uint);\\n\\n /**\\n * ERC-20 tokens approve and transferFrom pattern\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\n */\\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\\n\\n /**\\n * Use network currency and cross it.\\n */\\n function depositTo(address to) external payable;\\n\\n /**\\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\n */\\n function tokensReceived (\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n\\n /**\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\n */\\n function acceptTransfer(\\n address _originalTokenAddress,\\n address payable _from,\\n address payable _to,\\n uint256 _amount,\\n bytes32 _blockHash,\\n bytes32 _transactionHash,\\n uint32 _logIndex\\n ) external;\\n\\n /**\\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\n */\\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n function claimGasless(\\n ClaimData calldata _claimData,\\n address payable _relayer,\\n uint256 _fee,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external returns (uint256 receivedAmount);\\n\\n function getTransactionDataHash(\\n address _to,\\n uint256 _amount,\\n bytes32 _blockHash,\\n bytes32 _transactionHash,\\n uint32 _logIndex\\n ) external returns(bytes32);\\n\\n event Cross(\\n address indexed _tokenAddress,\\n address indexed _from,\\n address indexed _to,\\n uint256 _amount,\\n bytes _userData\\n );\\n event NewSideToken(\\n address indexed _newSideTokenAddress,\\n address indexed _originalTokenAddress,\\n string _newSymbol,\\n uint256 _granularity\\n );\\n event AcceptedCrossTransfer(\\n bytes32 indexed _transactionHash,\\n address indexed _originalTokenAddress,\\n address indexed _to,\\n address _from,\\n uint256 _amount,\\n bytes32 _blockHash,\\n uint256 _logIndex\\n );\\n event FeePercentageChanged(uint256 _amount);\\n event Claimed(\\n bytes32 indexed _transactionHash,\\n address indexed _originalTokenAddress,\\n address indexed _to,\\n address _sender,\\n uint256 _amount,\\n bytes32 _blockHash,\\n uint256 _logIndex,\\n address _reciever,\\n address _relayer,\\n uint256 _fee\\n );\\n}\",\"keccak256\":\"0x188bdd14d3e1d1eaddd5d86a4d957a8c6a7e6c4571058b6db13a974db3ab5f39\",\"license\":\"MIT\"},\"contracts/interface/ISideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\ninterface ISideToken {\\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\\n}\",\"keccak256\":\"0xf01477bc820f57970d7d8384417ac0aead22bd336077e371c48da917270013b4\",\"license\":\"MIT\"},\"contracts/interface/ISideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\ninterface ISideTokenFactory {\\n\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\\n\\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\\n}\",\"keccak256\":\"0x550c1af5fa52739ac28f58c36f04ba634213c5307ae95b412e41f3ee1d2e7217\",\"license\":\"MIT\"},\"contracts/interface/IWrapped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\ninterface IWrapped {\\n function balanceOf(address) external returns(uint);\\n\\n function deposit() external payable;\\n\\n function withdraw(uint wad) external;\\n\\n function totalSupply() external view returns (uint);\\n\\n function approve(address guy, uint wad) external returns (bool);\\n\\n function transfer(address dst, uint wad) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint wad)\\n external\\n returns (bool);\\n}\",\"keccak256\":\"0x2d8a99b6a030e37f01dba86db80e3bd29d1d01e592e399c8635df3fb636ec0d1\",\"license\":\"MIT\"},\"contracts/lib/LibEIP712.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\\nlibrary LibEIP712 {\\n\\n // Hash of the EIP712 Domain Separator Schema\\n // keccak256(abi.encodePacked(\\n // \\\"EIP712Domain(\\\",\\n // \\\"string name,\\\",\\n // \\\"string version,\\\",\\n // \\\"uint256 chainId,\\\",\\n // \\\"address verifyingContract\\\",\\n // \\\")\\\"\\n // ))\\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\\n\\n /// @dev Calculates a EIP712 domain separator.\\n /// @param name The EIP712 domain name.\\n /// @param version The EIP712 domain version.\\n /// @param verifyingContract The EIP712 verifying contract.\\n /// @return result EIP712 domain separator.\\n function hashEIP712Domain(\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract\\n )\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\\n\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\\n // keccak256(bytes(name)),\\n // keccak256(bytes(version)),\\n // chainId,\\n // uint256(verifyingContract)\\n // ))\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Calculate hashes of dynamic data\\n let nameHash := keccak256(add(name, 32), mload(name))\\n let versionHash := keccak256(add(version, 32), mload(version))\\n\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n // Store params in memory\\n mstore(memPtr, schemaHash)\\n mstore(add(memPtr, 32), nameHash)\\n mstore(add(memPtr, 64), versionHash)\\n mstore(add(memPtr, 96), chainId)\\n mstore(add(memPtr, 128), verifyingContract)\\n\\n // Compute hash\\n result := keccak256(memPtr, 160)\\n }\\n return result;\\n }\\n\\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\\n /// with getDomainHash().\\n /// @param hashStruct The EIP712 hash struct.\\n /// @return result EIP712 hash applied to the given EIP712 Domain.\\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // EIP191_HEADER,\\n // EIP712_DOMAIN_HASH,\\n // hashStruct\\n // ));\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\\n\\n // Compute hash\\n result := keccak256(memPtr, 66)\\n }\\n return result;\\n }\\n}\",\"keccak256\":\"0x6116e22c413fc65e87bf7db958d5c1f301b493494813f76dce512f8254c3b012\",\"license\":\"MIT\"},\"contracts/lib/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nlibrary LibUtils {\\n\\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\\n require(decimals <= 18, \\\"LibUtils: Decimals not <= 18\\\");\\n return uint256(10)**(18-decimals);\\n }\\n\\n function getDecimals(address tokenToUse) internal view returns (uint8) {\\n //support decimals as uint256 or uint8\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"decimals()\\\"));\\n require(success, \\\"LibUtils: No decimals\\\");\\n // uint: enc(X) is the big-endian encoding of X,\\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\\n return uint8(abi.decode(data, (uint256)));\\n }\\n\\n function getGranularity(address tokenToUse) internal view returns (uint256) {\\n //support granularity if ERC777\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"granularity()\\\"));\\n require(success, \\\"LibUtils: No granularity\\\");\\n\\n return abi.decode(data, (uint256));\\n }\\n\\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n addr := mload(add(bys,20))\\n }\\n }\\n\\n}\\n\",\"keccak256\":\"0xc888bccaec06ac8103257667388d83bac9f2fe24cfc445676003088a5a339897\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/access/Roles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Roles\\n * @dev Library for managing addresses assigned to a Role.\\n */\\nlibrary Roles {\\n struct Role {\\n mapping (address => bool) bearer;\\n }\\n\\n /**\\n * @dev Give an account access to this role.\\n */\\n function add(Role storage role, address account) internal {\\n require(!has(role, account), \\\"Roles: account already has role\\\");\\n role.bearer[account] = true;\\n }\\n\\n /**\\n * @dev Remove an account's access to this role.\\n */\\n function remove(Role storage role, address account) internal {\\n require(has(role, account), \\\"Roles: account doesn't have role\\\");\\n role.bearer[account] = false;\\n }\\n\\n /**\\n * @dev Check if an account has this role.\\n * @return bool\\n */\\n function has(Role storage role, address account) internal view returns (bool) {\\n require(account != address(0), \\\"Roles: account is the zero address\\\");\\n return role.bearer[account];\\n }\\n}\\n\",\"keccak256\":\"0xfa806d08d8b499296b170e1cf6a8870bfb25fd4dbf67bca2e6b327f8fe5c2d1e\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC1820Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\n * implementers for interfaces in this registry, as well as query support.\\n *\\n * Implementers may be shared by multiple accounts, and can also implement more\\n * than a single interface for each account. Contracts can implement interfaces\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\n * contract.\\n *\\n * {IERC165} interfaces can also be queried via the registry.\\n *\\n * For an in-depth explanation and source code analysis, see the EIP text.\\n */\\ninterface IERC1820Registry {\\n /**\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\n * account is able to set interface implementers for it.\\n *\\n * By default, each account is its own manager. Passing a value of `0x0` in\\n * `newManager` will reset the manager to this initial state.\\n *\\n * Emits a {ManagerChanged} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `account`.\\n */\\n function setManager(address account, address newManager) external;\\n\\n /**\\n * @dev Returns the manager for `account`.\\n *\\n * See {setManager}.\\n */\\n function getManager(address account) external view returns (address);\\n\\n /**\\n * @dev Sets the `implementer` contract as `account`'s implementer for\\n * `interfaceHash`.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n * The zero address can also be used in `implementer` to remove an old one.\\n *\\n * See {interfaceHash} to learn how these are created.\\n *\\n * Emits an {InterfaceImplementerSet} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `_account`.\\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\n * end in 28 zeroes).\\n * - `_implementer` must implement {IERC1820Implementer} and return true when\\n * queried for support, unless `implementer` is the caller. See\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\n */\\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\\n\\n /**\\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\\n * implementer is registered, returns the zero address.\\n *\\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\n * zeroes), `_account` will be queried for support of it.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n */\\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\\n\\n /**\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\n * corresponding\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\n */\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\n\\n /**\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\n * @param account Address of the contract for which to update the cache.\\n * @param interfaceId ERC165 interface for which to update the cache.\\n */\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\n * If the result is not cached a direct lookup on the contract address is performed.\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\n * {updateERC165Cache} with the contract address.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\n\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\n\\n event ManagerChanged(address indexed account, address indexed newManager);\\n}\\n\",\"keccak256\":\"0x1b44f619ae588fd201e93b126b80576e1244ef468e8b4e54e62fbad6a805cc87\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x09ca2716452528a6e69ac9f83f874292a1e547630473f3133038314a2f16029e\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {ERC20Detailed}.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x1bc9527655c4be58541c2fb90c0a05952938961c289f505c70160f87e08aef33\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeERC20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeERC20: low-level call failed\\\");\\n\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc22dd16f0cffdfddf9caa4643752b4b4e7fb41390f4a3ccb11b4eec501920980\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777Token standard as defined in the EIP.\\n *\\n * This contract uses the\\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\\n * token holders and recipients react to token movements by using setting implementers\\n * for the associated interfaces in said registry. See `IERC1820Registry` and\\n * `ERC1820Implementer`.\\n */\\ninterface IERC777 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the smallest part of the token that is not divisible. This\\n * means all token operations (creation, movement and destruction) must have\\n * amounts that are a multiple of this number.\\n *\\n * For most token contracts, this value will equal 1.\\n */\\n function granularity() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by an account (`owner`).\\n */\\n function balanceOf(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * If send or receive hooks are registered for the caller and `recipient`,\\n * the corresponding functions will be called with `data` and empty\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function send(address recipient, uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Destroys `amount` tokens from the caller's account, reducing the\\n * total supply.\\n *\\n * If a send hook is registered for the caller, the corresponding function\\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n */\\n function burn(uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Returns true if an account is an operator of `tokenHolder`.\\n * Operators can send and burn tokens on behalf of their owners. All\\n * accounts are their own operator.\\n *\\n * See `operatorSend` and `operatorBurn`.\\n */\\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor`.\\n *\\n * Emits an `AuthorizedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function authorizeOperator(address operator) external;\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor` and `defaultOperators`.\\n *\\n * Emits a `RevokedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function revokeOperator(address operator) external;\\n\\n /**\\n * @dev Returns the list of default operators. These accounts are operators\\n * for all token holders, even if `authorizeOperator` was never called on\\n * them.\\n *\\n * This list is immutable, but individual holders may revoke these via\\n * `revokeOperator`, in which case `isOperatorFor` will return false.\\n */\\n function defaultOperators() external view returns (address[] memory);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\\n * be an operator of `sender`.\\n *\\n * If send or receive hooks are registered for `sender` and `recipient`,\\n * the corresponding functions will be called with `data` and\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - `sender` cannot be the zero address.\\n * - `sender` must have at least `amount` tokens.\\n * - the caller must be an operator for `sender`.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function operatorSend(\\n address sender,\\n address recipient,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n /**\\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\\n * The caller must be an operator of `account`.\\n *\\n * If a send hook is registered for `account`, the corresponding function\\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n * - the caller must be an operator for `account`.\\n */\\n function operatorBurn(\\n address account,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n event Sent(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256 amount,\\n bytes data,\\n bytes operatorData\\n );\\n\\n function decimals() external returns (uint8);\\n\\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\\n\\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\\n\\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\\n\\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\\n}\\n\",\"keccak256\":\"0x9ace3cf83443ae90a995a8e33652238fa2b5afb258897757f85467d5fb437c1a\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\n *\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an `IERC777` token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0xc8dae3544a459d13f23ba0c7737f6e279e06d83ef86b8f7a0318d83bcf4147e3\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\",\"keccak256\":\"0x3eeeb5ea6bf7d3458bb36acebd4268b406e6a1525e009d4d8a90626c277a37d1\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../../Initializable.sol\\\";\\n\\nimport \\\"../../../GSN/Context.sol\\\";\\nimport \\\"../../../access/Roles.sol\\\";\\n\\ncontract UpgradablePauserRole is Initializable, Context {\\n using Roles for Roles.Role;\\n\\n event PauserAdded(address indexed account);\\n event PauserRemoved(address indexed account);\\n\\n Roles.Role private _pausers;\\n\\n function __PauserRol_init(address sender) public initializer {\\n if (!isPauser(sender)) {\\n _addPauser(sender);\\n }\\n }\\n\\n modifier onlyPauser() {\\n require(isPauser(_msgSender()), \\\"PauserRole: caller doesn't have the role\\\");\\n _;\\n }\\n\\n function isPauser(address account) public view returns (bool) {\\n return _pausers.has(account);\\n }\\n\\n function addPauser(address account) public onlyPauser {\\n _addPauser(account);\\n }\\n\\n function renouncePauser() public {\\n _removePauser(_msgSender());\\n }\\n\\n function _addPauser(address account) internal {\\n _pausers.add(account);\\n emit PauserAdded(account);\\n }\\n\\n function _removePauser(address account) internal {\\n _pausers.remove(account);\\n emit PauserRemoved(account);\\n }\\n}\\n\",\"keccak256\":\"0x8944b1fc00760a83b652c14b9891d7e0a43b860fb13725480359e10979a23e15\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"../access/roles/UpgradablePauserRole.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\\n /**\\n * @dev Emitted when the pause is triggered by a pauser (`account`).\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by a pauser (`account`).\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\\n * to the deployer.\\n */\\n function __Pausable_init(address sender) public initializer {\\n UpgradablePauserRole.__PauserRol_init(sender);\\n\\n _paused = false;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n */\\n modifier whenNotPaused() {\\n require(!_paused, \\\"Pausable: paused\\\");\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n */\\n modifier whenPaused() {\\n require(_paused, \\\"Pausable: not paused\\\");\\n _;\\n }\\n\\n /**\\n * @dev Called by a pauser to pause, triggers stopped state.\\n */\\n function pause() public onlyPauser whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Called by a pauser to unpause, returns to normal state.\\n */\\n function unpause() public onlyPauser whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n}\\n\",\"keccak256\":\"0x97aa1a11fb3dc9d9e1478f846196f98296e46cc05202c986f6c60a3417951520\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract UpgradableOwnable is Initializable, Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function initialize(address sender) public initializer {\\n _owner = sender;\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * > Note: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n\\n}\\n\",\"keccak256\":\"0x2e0e58f4a3991801550e6a52512a3c1bbcaa5cb824120c177cb6ec1b4fa0ce97\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\n/**\\n * @title Helps contracts guard against reentrancy attacks.\\n * @author Remco Bloemen , Eenae \\n * @dev If you mark a function `nonReentrant`, you should also\\n * mark it `external`.\\n */\\ncontract ReentrancyGuard is Initializable {\\n /// @dev counter to allow mutex lock with only one SSTORE operation\\n uint256 private _guardCounter;\\n\\n function initialize() public initializer {\\n // The counter starts at one to prevent changing it from zero to a non-zero\\n // value, which is a more expensive operation.\\n _guardCounter = 1;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n _guardCounter += 1;\\n uint256 localCounter = _guardCounter;\\n _;\\n require(localCounter == _guardCounter, \\\"ReentrancyGuard: no reentrant allowed\\\");\\n }\\n}\",\"keccak256\":\"0x55fdfe1504f54e18aaf3da306bfb46498d1baf54e371d14a3ace8a5adf25bbe1\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b506141d0806100206000396000f3fe6080604052600436106103025760003560e01c80638456cb5911610190578063c4d66de8116100dc578063e6fc774411610095578063f2fde38b1161006f578063f2fde38b146108b0578063f698da25146108d0578063f74032f0146108e5578063fa0caa16146109055761034c565b8063e6fc774414610866578063ea2170911461087b578063eb16136f146108905761034c565b8063c4d66de8146107b1578063ca07140c146107d1578063cc3c0f06146107f1578063d12e825d14610811578063da67703714610826578063e6ede14d146108465761034c565b8063ae06c1b711610149578063b50277bb11610123578063b50277bb14610754578063b760faf914610774578063b794726214610787578063b86f60d21461079c5761034c565b8063ae06c1b7146106ff578063afad80ac1461071f578063b0e1268e1461073f5761034c565b80638456cb591461066b5780638da5cb5b146106805780638f32d59b14610695578063916dc59d146106aa578063a53d6e6e146106ca578063adc5fb64146106df5761034c565b80634beea5061161024f5780636b0509b1116102085780637813bea2116101e25780637813bea2146105f65780637ecebe00146106165780638129fc1c1461063657806382dc1ec41461064b5761034c565b80636b0509b1146105b75780636ef8d66d146105cc578063715018a6146105e15761034c565b80634beea5061461050b57806354fd4d501461052b57806359a8a8671461054d5780635c975abb146105625780635d447129146105775780636a863191146105975761034c565b80632fb3b361116102bc5780633cf3058b116102965780633cf3058b146104895780633f4ba83a146104b657806342cdb2c6146104cb57806346fbf68e146104eb5761034c565b80632fb3b3611461041c5780633500c1dc1461043c57806337e761091461045c5761034c565b806223de2914610351578063026976191461037157806307c8f7b0146103a757806311efbf61146103c757806320e3bb00146103dc5780632f3cca4e146103fc5761034c565b3661034c576041546001600160a01b031661031b610925565b6001600160a01b03161461034a5760405162461bcd60e51b815260040161034190613e39565b60405180910390fd5b005b600080fd5b34801561035d57600080fd5b5061034a61036c3660046130c0565b610929565b34801561037d57600080fd5b5061039161038c366004613237565b610b20565b60405161039e9190613693565b60405180910390f35b3480156103b357600080fd5b5061034a6103c23660046131ff565b610b32565b3480156103d357600080fd5b50610391610bb0565b3480156103e857600080fd5b5061034a6103f7366004613368565b610bb6565b34801561040857600080fd5b5061034a610417366004612f3e565b610df1565b34801561042857600080fd5b5061034a610437366004612fec565b610e7a565b34801561044857600080fd5b5061034a610457366004612f3e565b610fea565b34801561046857600080fd5b5061047c610477366004613237565b61107f565b60405161039e9190613688565b34801561049557600080fd5b506104a96104a4366004613237565b6110a4565b60405161039e919061351f565b3480156104c257600080fd5b5061034a6110bf565b3480156104d757600080fd5b5061034a6104e6366004612f3e565b611152565b3480156104f757600080fd5b5061047c610506366004612f3e565b6111e5565b34801561051757600080fd5b5061039161052636600461326a565b6111f8565b34801561053757600080fd5b50610540611312565b60405161039e919061374f565b34801561055957600080fd5b5061054061132e565b34801561056e57600080fd5b5061047c6113bc565b34801561058357600080fd5b5061047c610592366004612f3e565b6113c5565b3480156105a357600080fd5b5061034a6105b2366004612f76565b6113da565b3480156105c357600080fd5b5061039161163e565b3480156105d857600080fd5b5061034a611662565b3480156105ed57600080fd5b5061034a611674565b34801561060257600080fd5b5061034a61061136600461316e565b6116e8565b34801561062257600080fd5b50610391610631366004612f3e565b61172b565b34801561064257600080fd5b5061034a61173d565b34801561065757600080fd5b5061034a610666366004612f3e565b6117b7565b34801561067757600080fd5b5061034a6117e7565b34801561068c57600080fd5b506104a9611867565b3480156106a157600080fd5b5061047c61187b565b3480156106b657600080fd5b5061034a6106c5366004612f3e565b6118a6565b3480156106d657600080fd5b506104a961193b565b3480156106eb57600080fd5b506103916106fa36600461324f565b61194a565b34801561070b57600080fd5b5061034a61071a366004613237565b6119a9565b34801561072b57600080fd5b5061039161073a3660046131ae565b611a23565b34801561074b57600080fd5b506104a9611a5f565b34801561076057600080fd5b5061039161076f36600461324f565b611a6e565b61034a610782366004612f3e565b611a81565b34801561079357600080fd5b5061047c611b50565b3480156107a857600080fd5b506104a9611b60565b3480156107bd57600080fd5b5061034a6107cc366004612f3e565b611b6f565b3480156107dd57600080fd5b506104a96107ec366004613237565b611c3a565b3480156107fd57600080fd5b5061047c61080c366004613237565b611c55565b34801561081d57600080fd5b5061034a611c6a565b34801561083257600080fd5b5061047c610841366004613237565b611cc2565b34801561085257600080fd5b506104a9610861366004612f3e565b611cd6565b34801561087257600080fd5b50610391611cf1565b34801561088757600080fd5b506104a9611cf7565b34801561089c57600080fd5b5061034a6108ab366004612f3e565b611d06565b3480156108bc57600080fd5b5061034a6108cb366004612f3e565b611d91565b3480156108dc57600080fd5b50610391611dbe565b3480156108f157600080fd5b506104a9610900366004612f3e565b611dc4565b34801561091157600080fd5b5061034a610920366004612f3e565b611ddf565b3390565b6001600160a01b03881630141561093f57610b16565b6001600160a01b03861630146109675760405162461bcd60e51b815260040161034190613b0d565b6000610971610925565b60405163555ddc6560e11b8152909150600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906109d09085907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce217705490600401613627565b60206040518083038186803b1580156109e857600080fd5b505afa1580156109fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a209190612f5a565b6001600160a01b03161415610a475760405162461bcd60e51b815260040161034190613f0e565b83151580610a645750610a62886001600160a01b0316611e7a565b155b610a805760405162461bcd60e51b815260040161034190613b74565b60008415610acc57610ac786868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e8092505050565b610ace565b885b9050610b13828a838a8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e8792505050565b50505b5050505050505050565b60426020526000908152604090205481565b610b3a61187b565b610b565760405162461bcd60e51b815260040161034190613d8b565b6040805460ff60a01b1916600160a01b83151581029190911780835591517f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad992610ba59260ff91041690613688565b60405180910390a150565b60375490565b610bbe61187b565b610bda5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b038616610c005760405162461bcd60e51b815260040161034190613d5f565b6001600160a01b038087166000908152603b6020526040902054168015610c395760405162461bcd60e51b81526004016103419061402f565b6000610c448761213a565b9050600060388787604051602001610c5e939291906134a6565b60408051601f1981840301815282825290546326d9e96360e01b83529092506001600160a01b0316906326d9e96390610ca1908890889086908890600401613700565b602060405180830381600087803b158015610cbb57600080fd5b505af1158015610ccf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf39190612f5a565b6001600160a01b03808b166000818152603b6020908152604080832080548688166001600160a01b03199182168117909255908452603c909252918290208054909116909217909155603f5490516378bf2b5360e01b815292955016906378bf2b5390610d669086908e90600401613627565b600060405180830381600087803b158015610d8057600080fd5b505af1158015610d94573d6000803e3d6000fd5b50505050886001600160a01b0316836001600160a01b03167f2ef93c4e96a4ef0b19497ff60c9e7360a8734f3d2cd27ae5318e43851734d17f8385604051610ddd929190613762565b60405180910390a350505050505050505050565b600054610100900460ff1680610e0a575060005460ff16155b610e265760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015610e51576000805460ff1961ff0019909116610100171660011790555b610e5a82611d06565b6034805460ff191690558015610e76576000805461ff00191690555b5050565b600054610100900460ff1680610e93575060005460ff16155b610eaf5760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015610eda576000805460ff1961ff0019909116610100171660011790555b610ee386611b6f565b610eec86610df1565b8151610eff906038906020850190612e1a565b50603f80546001600160a01b038087166001600160a01b031992831617909255604080548684169083161781556036805493891693909216929092179055516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90610f969030907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b908290600401613533565b600060405180830381600087803b158015610fb057600080fd5b505af1158015610fc4573d6000803e3d6000fd5b50505050610fd0611c6a565b8015610fe2576000805461ff00191690555b505050505050565b610ff261187b565b61100e5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b0381166110345760405162461bcd60e51b815260040161034190613aae565b604180546001600160a01b0319166001600160a01b0383161790556040517f0966c958966f6fac9ff807af074f8117eb2e9ce2b76390db7a158e9bdeb2485c90610ba590839061351f565b6000818152604260209081526040808320548352603e90915290205460ff165b919050565b6044602052600090815260409020546001600160a01b031681565b6110ca610506610925565b6110e65760405162461bcd60e51b815260040161034190613a05565b60345460ff166111085760405162461bcd60e51b8152600401610341906137c9565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61113b610925565b604051611148919061351f565b60405180910390a1565b61115a61187b565b6111765760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b03811661119c5760405162461bcd60e51b815260040161034190613ca6565b604080546001600160a01b0319166001600160a01b038316178155517f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e318369252162590610ba590839061351f565b60006111f260338361216d565b92915050565b60004285101561121a5760405162461bcd60e51b815260040161034190613c7d565b600061123661122e368b90038b018b6132da565b8989896121b5565b905060006001828787876040516000815260200160405260405161125d94939291906136e2565b6020604051602081039080840390855afa15801561127f573d6000803e3d6000fd5b5050604051601f19015191506000905061129c60208c018c612f3e565b6001600160a01b0316141580156112d057506112bb60208b018b612f3e565b6001600160a01b0316816001600160a01b0316145b6112ec5760405162461bcd60e51b815260040161034190613a4d565b6113048a6112fd6020820182612f3e565b8b8b61224a565b9a9950505050505050505050565b604080518082019091526002815261763360f01b602082015290565b6038805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156113b45780601f10611389576101008083540402835291602001916113b4565b820191906000526020600020905b81548152906001019060200180831161139757829003601f168201915b505050505081565b60345460ff1690565b603d6020526000908152604090205460ff1681565b60345460ff16156113fd5760405162461bcd60e51b815260040161034190613c1c565b60358054600101908190556036546001600160a01b031661141c610925565b6001600160a01b0316146114425760405162461bcd60e51b815260040161034190613b44565b6001600160a01b0388166000908152603d602052604090205460ff168061148257506001600160a01b038881166000908152603b60205260409020541615155b61149e5760405162461bcd60e51b815260040161034190613ade565b6001600160a01b0386166114c45760405162461bcd60e51b815260040161034190613bf3565b600085116114e45760405162461bcd60e51b815260040161034190613a84565b836115015760405162461bcd60e51b815260040161034190613ea7565b8261151e5760405162461bcd60e51b815260040161034190613926565b6000838152604260205260409020541561154a5760405162461bcd60e51b815260040161034190613e70565b60006115598787878787611a23565b6000818152603e602052604090205490915060ff161561158b5760405162461bcd60e51b815260040161034190613e02565b60008481526042602090815260408083208490556043825280832080546001600160a01b03199081166001600160a01b038f811691821790935560449094529382902080549094168c821617909355519189169186907f2858b8803acb87882fd2de49ce7572ae3e741fb8073cbe772fa50ce00bdfba2290611614908d908c908c908b90613556565b60405180910390a4506035548114610b165760405162461bcd60e51b815260040161034190613784565b7ff18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd8043381565b61167261166d610925565b612463565b565b61167c61187b565b6116985760405162461bcd60e51b815260040161034190613d8b565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b60006116f2610925565b90506117096001600160a01b0385168230856124a5565b6117258482858560405180602001604052806000815250611e87565b50505050565b60456020526000908152604090205481565b600054610100900460ff1680611756575060005460ff16155b6117725760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff1615801561179d576000805460ff1961ff0019909116610100171660011790555b600160355580156117b4576000805461ff00191690555b50565b6117c2610506610925565b6117de5760405162461bcd60e51b815260040161034190613a05565b6117b4816124fd565b6117f2610506610925565b61180e5760405162461bcd60e51b815260040161034190613a05565b60345460ff16156118315760405162461bcd60e51b815260040161034190613c1c565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861113b610925565b60345461010090046001600160a01b031690565b60345460009061010090046001600160a01b0316611897610925565b6001600160a01b031614905090565b6118ae61187b565b6118ca5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b0381166118f05760405162461bcd60e51b815260040161034190613ed7565b603f80546001600160a01b0319166001600160a01b0383161790556040517f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e390610ba590839061351f565b603f546001600160a01b031681565b60608101356000908152604460205260408120546001600160a01b031661196f610925565b6001600160a01b0316146119955760405162461bcd60e51b8152600401610341906138f6565b6111f2826119a1610925565b60008061224a565b6119b161187b565b6119cd5760405162461bcd60e51b815260040161034190613d8b565b6103e881106119ee5760405162461bcd60e51b81526004016103419061405f565b60378190556040517f97e97c577f03bda90e2c9739011ec065ed5fbfb36ae217d20bb0d9be95e160cd90610ba5908390613693565b60008383878785604051602001611a3e959493929190613448565b60405160208183030381529060405280519060200120905095945050505050565b6041546001600160a01b031681565b60006111f2826119a16020820182612f3e565b6000611a8b610925565b6041549091506001600160a01b0316611ab65760405162461bcd60e51b815260040161034190613c46565b604160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611b0657600080fd5b505af1158015611b1a573d6000803e3d6000fd5b5050505050610e76604160009054906101000a90046001600160a01b031682843460405180602001604052806000815250611e87565b604054600160a01b900460ff1681565b6040546001600160a01b031681565b600054610100900460ff1680611b88575060005460ff16155b611ba45760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015611bcf576000805460ff1961ff0019909116610100171660011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e76576000805461ff00191690555050565b6043602052600090815260409020546001600160a01b031681565b603e6020526000908152604090205460ff1681565b6000469050611cbc6040518060400160405280601081526020016f52534b20546f6b656e2042726964676560801b815250604051806040016040528060018152602001603160f81b815250833061253f565b60395550565b600090815260426020526040902054151590565b603b602052600090815260409020546001600160a01b031681565b61271081565b6036546001600160a01b031690565b600054610100900460ff1680611d1f575060005460ff16155b611d3b5760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015611d66576000805460ff1961ff0019909116610100171660011790555b611d6f826111e5565b611d7c57611d7c826124fd565b8015610e76576000805461ff00191690555050565b611d9961187b565b611db55760405162461bcd60e51b815260040161034190613d8b565b6117b481612596565b60395481565b603c602052600090815260409020546001600160a01b031681565b611de761187b565b611e035760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b038116611e295760405162461bcd60e51b81526004016103419061385d565b603680546001600160a01b0319166001600160a01b0383811691909117918290556040517f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb92610ba592169061351f565b3b151590565b6014015190565b604054600160a01b900460ff1615611eb15760405162461bcd60e51b8152600401610341906138cb565b60345460ff1615611ed45760405162461bcd60e51b815260040161034190613c1c565b603580546001908101918290556001600160a01b0387166000908152603d60205260408120805460ff1916909217909155603754611f219061271090611f1b908790612623565b90612664565b90506000611f2f85836126a6565b90506000611f3c896126e8565b905085601260ff831614611f6157611f5e8760ff601285900316600a0a612623565b90505b603f54604051638c34bc5560e01b81526001600160a01b0390911690638c34bc5590611f93908d908590600401613627565b600060405180830381600087803b158015611fad57600080fd5b505af1158015611fc1573d6000803e3d6000fd5b5050506001600160a01b03808c166000908152603c60205260409020548c9250161561209b57506001600160a01b03808b166000908152603c60205260408120549091169061200f8c6127ac565b9050600061201d8683612854565b90506120298782612896565b965061203586826126a6565b60405163fe9d930360e01b81529096506001600160a01b038e169063fe9d9303906120669089908d9060040161410e565b600060405180830381600087803b15801561208057600080fd5b505af1158015612094573d6000803e3d6000fd5b5050505050505b886001600160a01b03168a6001600160a01b0316826001600160a01b03167f1e90de9ae4d02420648a650f45f089a1be18fbca324092544ea626f9833212b0878b6040516120ea92919061410e565b60405180910390a4841561211457612114612103611867565b6001600160a01b038d1690876128bb565b50505050506035548114610fe25760405162461bcd60e51b815260040161034190613784565b600060128260ff1611156121605760405162461bcd60e51b815260040161034190613ce7565b5060120360ff16600a0a90565b60006001600160a01b0382166121955760405162461bcd60e51b815260040161034190613dc0565b506001600160a01b03166000908152602091909152604090205460ff1690565b603954845160208087015160608801516001600160a01b038416600090815260458452604080822080546001810190915590519196612241969095612226957ff18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd8043395929490938d928d928d910161369c565b604051602081830303815290604052805190602001206128df565b95945050505050565b603580546001019081905560608501356000908152604360205260408120549091906001600160a01b0316806122925760405162461bcd60e51b815260040161034190613f45565b60006122c36122a460208a018a612f3e565b60208a013560408b013560608c013561073a60a08e0160808f01613402565b606089013560009081526042602052604090205490915081146122f85760405162461bcd60e51b8152600401610341906140cd565b6000818152603e602052604090205460ff16156123275760405162461bcd60e51b815260040161034190613e02565b6000818152603e60209081526040808320805460ff191660011790556001600160a01b0385168352603d90915290205460ff16156123775761237082888a6020013589896128fe565b935061238b565b61238882888a602001358989612a74565b93505b6123986020890189612f3e565b6001600160a01b0316826001600160a01b031689606001357f42b1cb6263e8da47edf0583516eda1de16f729d26282f5791dc5b7af1010e925604460008d60600135815260200190815260200160002060009054906101000a90046001600160a01b03168c602001358d604001358e60800160208101906124199190613402565b8e8e8e60405161242f9796959493929190613640565b60405180910390a45050603554811461245a5760405162461bcd60e51b815260040161034190613784565b50949350505050565b61246e603382612c0b565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b611725846323b872dd60e01b8585856040516024016124c693929190613603565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612c53565b612508603382612d37565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b6001600160a01b0381166125bc5760405162461bcd60e51b815260040161034190613fa3565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600082612632575060006111f2565b8282028284828161263f57fe5b041461265d5760405162461bcd60e51b815260040161034190613d1e565b9392505050565b600061265d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612d83565b600061265d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612dba565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b0386169161272e919061348a565b600060405180830381855afa9150503d8060008114612769576040519150601f19603f3d011682016040523d82523d6000602084013e61276e565b606091505b5091509150816127905760405162461bcd60e51b81526004016103419061382e565b808060200190518101906127a49190613350565b949350505050565b60408051600481526024810182526020810180516001600160e01b031663556f0dc760e01b1790529051600091829182916001600160a01b038616916127f2919061348a565b600060405180830381855afa9150503d806000811461282d576040519150601f19603f3d011682016040523d82523d6000602084013e612832565b606091505b5091509150816127905760405162461bcd60e51b815260040161034190613bbc565b600061265d83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250612de6565b60008282018381101561265d5760405162461bcd60e51b815260040161034190613894565b6128da8363a9059cbb60e01b84846040516024016124c6929190613627565b505050565b60405161190160f01b8152600281019290925260228201526042902090565b60008061290a876126e8565b60ff1690506000612922866012849003600a0a612664565b9050808411156129445760405162461bcd60e51b815260040161034190613f75565b60415484820393506001600160a01b0389811691161415612a3b57604154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d9061298f908490600401613693565b600060405180830381600087803b1580156129a957600080fd5b505af11580156129bd573d6000803e3d6000fd5b50506040516001600160a01b038a16925085156108fc02915085906000818181858888f193505050501580156129f7573d6000803e3d6000fd5b508315612a36576040516001600160a01b0386169085156108fc029086906000818181858888f19350505050158015612a34573d6000803e3d6000fd5b505b612a69565b612a4f6001600160a01b03891688856128bb565b8315612a6957612a696001600160a01b03891686866128bb565b505095945050505050565b6001600160a01b038086166000908152603b6020908152604080832054815163556f0dc760e01b81529151939416928492849263556f0dc79260048083019392829003018186803b158015612ac857600080fd5b505afa158015612adc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b009190613350565b90506000612b0e8783612623565b905080851115612b305760405162461bcd60e51b815260040161034190613f75565b604051630dcdc7dd60e41b815285820394506001600160a01b0384169063dcdc7dd090612b63908b9088906004016135cd565b600060405180830381600087803b158015612b7d57600080fd5b505af1158015612b91573d6000803e3d6000fd5b505050506000851115612bff57604051630dcdc7dd60e41b81526001600160a01b0384169063dcdc7dd090612bcc9089908990600401613582565b600060405180830381600087803b158015612be657600080fd5b505af1158015612bfa573d6000803e3d6000fd5b505050505b50505095945050505050565b612c15828261216d565b612c315760405162461bcd60e51b815260040161034190613953565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b612c65826001600160a01b0316611e7a565b612c815760405162461bcd60e51b815260040161034190614096565b600080836001600160a01b031683604051612c9c919061348a565b6000604051808303816000865af19150503d8060008114612cd9576040519150601f19603f3d011682016040523d82523d6000602084013e612cde565b606091505b509150915081612d005760405162461bcd60e51b815260040161034190613988565b8051156117255780806020019051810190612d1b919061321b565b6117255760405162461bcd60e51b815260040161034190613fe5565b612d41828261216d565b15612d5e5760405162461bcd60e51b8152600401610341906137f7565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60008183612da45760405162461bcd60e51b8152600401610341919061374f565b506000838581612db057fe5b0495945050505050565b60008184841115612dde5760405162461bcd60e51b8152600401610341919061374f565b505050900390565b60008183612e075760405162461bcd60e51b8152600401610341919061374f565b50828481612e1157fe5b06949350505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282612e505760008555612e96565b82601f10612e6957805160ff1916838001178555612e96565b82800160010185558215612e96579182015b82811115612e96578251825591602001919060010190612e7b565b50612ea2929150612ea6565b5090565b5b80821115612ea25760008155600101612ea7565b60008083601f840112612ecc578182fd5b50813567ffffffffffffffff811115612ee3578182fd5b602083019150836020828501011115612efb57600080fd5b9250929050565b600060a08284031215612f13578081fd5b50919050565b803563ffffffff8116811461109f57600080fd5b803560ff8116811461109f57600080fd5b600060208284031215612f4f578081fd5b813561265d81614177565b600060208284031215612f6b578081fd5b815161265d81614177565b600080600080600080600060e0888a031215612f90578283fd5b8735612f9b81614177565b96506020880135612fab81614177565b95506040880135612fbb81614177565b9450606088013593506080880135925060a08801359150612fde60c08901612f19565b905092959891949750929550565b600080600080600060a08688031215613003578081fd5b853561300e81614177565b945060208681013561301f81614177565b9450604087013561302f81614177565b9350606087013561303f81614177565b9250608087013567ffffffffffffffff8082111561305b578384fd5b818901915089601f83011261306e578384fd5b81358181111561307a57fe5b61308c601f8201601f19168501614127565b91508082528a848285010111156130a1578485fd5b8084840185840137810190920192909252949793965091945092919050565b60008060008060008060008060c0898b0312156130db578081fd5b88356130e681614177565b975060208901356130f681614177565b9650604089013561310681614177565b955060608901359450608089013567ffffffffffffffff80821115613129578283fd5b6131358c838d01612ebb565b909650945060a08b013591508082111561314d578283fd5b5061315a8b828c01612ebb565b999c989b5096995094979396929594505050565b600080600060608486031215613182578081fd5b833561318d81614177565b9250602084013561319d81614177565b929592945050506040919091013590565b600080600080600060a086880312156131c5578283fd5b85356131d081614177565b94506020860135935060408601359250606086013591506131f360808701612f19565b90509295509295909350565b600060208284031215613210578081fd5b813561265d8161418c565b60006020828403121561322c578081fd5b815161265d8161418c565b600060208284031215613248578081fd5b5035919050565b600060a08284031215613260578081fd5b61265d8383612f02565b6000806000806000806000610160888a031215613285578081fd5b61328f8989612f02565b965060a088013561329f81614177565b955060c0880135945060e088013593506132bc6101008901612f2d565b92506101208801359150610140880135905092959891949750929550565b600060a082840312156132eb578081fd5b60405160a0810181811067ffffffffffffffff8211171561330857fe5b604052823561331681614177565b8082525060208301356020820152604083013560408201526060830135606082015261334460808401612f19565b60808201529392505050565b600060208284031215613361578081fd5b5051919050565b600080600080600080600060a0888a031215613382578081fd5b87359650602088013561339481614177565b95506133a260408901612f2d565b9450606088013567ffffffffffffffff808211156133be578283fd5b6133ca8b838c01612ebb565b909650945060808a01359150808211156133e2578283fd5b506133ef8a828b01612ebb565b989b979a50959850939692959293505050565b600060208284031215613413578081fd5b61265d82612f19565b6000815180845261343481602086016020860161414b565b601f01601f19169290920160200192915050565b948552602085019390935260609190911b6bffffffffffffffffffffffff19166040840152605483015260e01b6001600160e01b031916607482015260780190565b6000825161349c81846020870161414b565b9190910192915050565b60008085546001808216600081146134c557600181146134dc5761350b565b60ff198316865260028304607f168601935061350b565b600283048986526020808720875b838110156135035781548a8201529085019082016134ea565b505050860193505b505050838582379092019182525092915050565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b6001600160a01b039490941684526020840192909252604083015263ffffffff16606082015260800190565b6001600160a01b03929092168252602082015260806040820181905260009082015260a060608201819052600b908201526a72656c617965722066656560a81b60c082015260e00190565b6001600160a01b039290921682526020820152608060408201819052600090820181905260a06060830181905282015260c00190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0397881681526020810196909652604086019490945263ffffffff9290921660608501528416608084015290921660a082015260c081019190915260e00190565b901515815260200190565b90815260200190565b9788526001600160a01b039687166020890152604088019590955260608701939093529316608085015260a084019290925260c083019190915260e08201526101000190565b93845260ff9290921660208401526040830152606082015260800190565b600060608252846060830152848660808401378060808684010152601f19601f8601168201608083820301602084015261373d608082018661341c565b91505082604083015295945050505050565b60006020825261265d602083018461341c565b600060408252613775604083018561341c565b90508260208301529392505050565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b6020808252601f908201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604082015260600190565b6020808252601590820152744c69625574696c733a204e6f20646563696d616c7360581b604082015260600190565b6020808252601b908201527f4272696467653a2046656465726174696f6e20697320656d7074790000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601190820152704272696467653a20557067726164696e6760781b604082015260600190565b602080825260169082015275213934b233b29d1034b73b30b634b21039b2b73232b960511b604082015260600190565b602080825260139082015272084e4d2c8ceca74409cead8d840a8f090c2e6d606b1b604082015260600190565b6020808252818101527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c65604082015260600190565b6020808252818101527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604082015260600190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b60208082526019908201527f4272696467653a20494e56414c49445f5349474e415455524500000000000000604082015260600190565b60208082526010908201526f04272696467653a20416d6f756e7420360841b604082015260600190565b6020808252601690820152754272696467653a20777261707020697320656d70747960501b604082015260600190565b602080825260159082015274213934b233b29d102ab735b737bbb7103a37b5b2b760591b604082015260600190565b6020808252601b908201527f4272696467653a204e6f7420746f207468697320616464726573730000000000604082015260600190565b602080825260169082015275213934b233b29d102737ba102332b232b930ba34b7b760511b604082015260600190565b60208082526028908201527f4272696467653a2053706563696679207265636569766572206164647265737360408201526720696e206461746160c01b606082015260800190565b60208082526018908201527f4c69625574696c733a204e6f206772616e756c61726974790000000000000000604082015260600190565b6020808252600f908201526e4272696467653a204e756c6c20546f60881b604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252601d908201527f4272696467653a207772617070656443757272656e637920656d707479000000604082015260600190565b6020808252600f908201526e109c9a5919d94e8811561412549151608a1b604082015260600190565b60208082526021908201527f4272696467653a2053696465546f6b656e466163746f727920697320656d70746040820152607960f81b606082015260800190565b6020808252601c908201527f4c69625574696c733a20446563696d616c73206e6f74203c3d20313800000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260129082015271213934b233b29d10273ab636103a37b5b2b760711b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526022908201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526017908201527f4272696467653a20416c726561647920636c61696d6564000000000000000000604082015260600190565b6020808252601b908201527f4272696467653a206e6f74207772617070656443757272656e63790000000000604082015260600190565b60208082526018908201527f4272696467653a20416c72656164792061636365707465640000000000000000604082015260600190565b602080825260169082015275084e4d2c8ceca74409cead8d84084d8dec6d690c2e6d60531b604082015260600190565b6020808252601c908201527f4272696467653a20416c6c6f77546f6b656e7320697320656d70747900000000604082015260600190565b60208082526018908201527f4272696467653a204e6f742045524337373720746f6b656e0000000000000000604082015260600190565b602080825260169082015275109c9a5919d94e88151e081b9bdd0818dc9bdcdcd95960521b604082015260600190565b602080825260149082015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b604082015260600190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601690820152754272696467653a20416c72656164792065786973747360501b604082015260600190565b60208082526017908201527f4272696467653a20626967676572207468616e20313025000000000000000000604082015260600190565b6020808252601f908201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604082015260600190565b60208082526021908201527f4272696467653a2057726f6e67207472616e73616374696f6e446174614861736040820152600d60fb1b606082015260800190565b6000838252604060208301526127a4604083018461341c565b60405181810167ffffffffffffffff8111828210171561414357fe5b604052919050565b60005b8381101561416657818101518382015260200161414e565b838111156117255750506000910152565b6001600160a01b03811681146117b457600080fd5b80151581146117b457600080fdfea26469706673582212209f3d6b55444296ed94eaacc847d94aabd3d0ccef57edd6d16aca1a9136ef6cc264736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106103025760003560e01c80638456cb5911610190578063c4d66de8116100dc578063e6fc774411610095578063f2fde38b1161006f578063f2fde38b146108b0578063f698da25146108d0578063f74032f0146108e5578063fa0caa16146109055761034c565b8063e6fc774414610866578063ea2170911461087b578063eb16136f146108905761034c565b8063c4d66de8146107b1578063ca07140c146107d1578063cc3c0f06146107f1578063d12e825d14610811578063da67703714610826578063e6ede14d146108465761034c565b8063ae06c1b711610149578063b50277bb11610123578063b50277bb14610754578063b760faf914610774578063b794726214610787578063b86f60d21461079c5761034c565b8063ae06c1b7146106ff578063afad80ac1461071f578063b0e1268e1461073f5761034c565b80638456cb591461066b5780638da5cb5b146106805780638f32d59b14610695578063916dc59d146106aa578063a53d6e6e146106ca578063adc5fb64146106df5761034c565b80634beea5061161024f5780636b0509b1116102085780637813bea2116101e25780637813bea2146105f65780637ecebe00146106165780638129fc1c1461063657806382dc1ec41461064b5761034c565b80636b0509b1146105b75780636ef8d66d146105cc578063715018a6146105e15761034c565b80634beea5061461050b57806354fd4d501461052b57806359a8a8671461054d5780635c975abb146105625780635d447129146105775780636a863191146105975761034c565b80632fb3b361116102bc5780633cf3058b116102965780633cf3058b146104895780633f4ba83a146104b657806342cdb2c6146104cb57806346fbf68e146104eb5761034c565b80632fb3b3611461041c5780633500c1dc1461043c57806337e761091461045c5761034c565b806223de2914610351578063026976191461037157806307c8f7b0146103a757806311efbf61146103c757806320e3bb00146103dc5780632f3cca4e146103fc5761034c565b3661034c576041546001600160a01b031661031b610925565b6001600160a01b03161461034a5760405162461bcd60e51b815260040161034190613e39565b60405180910390fd5b005b600080fd5b34801561035d57600080fd5b5061034a61036c3660046130c0565b610929565b34801561037d57600080fd5b5061039161038c366004613237565b610b20565b60405161039e9190613693565b60405180910390f35b3480156103b357600080fd5b5061034a6103c23660046131ff565b610b32565b3480156103d357600080fd5b50610391610bb0565b3480156103e857600080fd5b5061034a6103f7366004613368565b610bb6565b34801561040857600080fd5b5061034a610417366004612f3e565b610df1565b34801561042857600080fd5b5061034a610437366004612fec565b610e7a565b34801561044857600080fd5b5061034a610457366004612f3e565b610fea565b34801561046857600080fd5b5061047c610477366004613237565b61107f565b60405161039e9190613688565b34801561049557600080fd5b506104a96104a4366004613237565b6110a4565b60405161039e919061351f565b3480156104c257600080fd5b5061034a6110bf565b3480156104d757600080fd5b5061034a6104e6366004612f3e565b611152565b3480156104f757600080fd5b5061047c610506366004612f3e565b6111e5565b34801561051757600080fd5b5061039161052636600461326a565b6111f8565b34801561053757600080fd5b50610540611312565b60405161039e919061374f565b34801561055957600080fd5b5061054061132e565b34801561056e57600080fd5b5061047c6113bc565b34801561058357600080fd5b5061047c610592366004612f3e565b6113c5565b3480156105a357600080fd5b5061034a6105b2366004612f76565b6113da565b3480156105c357600080fd5b5061039161163e565b3480156105d857600080fd5b5061034a611662565b3480156105ed57600080fd5b5061034a611674565b34801561060257600080fd5b5061034a61061136600461316e565b6116e8565b34801561062257600080fd5b50610391610631366004612f3e565b61172b565b34801561064257600080fd5b5061034a61173d565b34801561065757600080fd5b5061034a610666366004612f3e565b6117b7565b34801561067757600080fd5b5061034a6117e7565b34801561068c57600080fd5b506104a9611867565b3480156106a157600080fd5b5061047c61187b565b3480156106b657600080fd5b5061034a6106c5366004612f3e565b6118a6565b3480156106d657600080fd5b506104a961193b565b3480156106eb57600080fd5b506103916106fa36600461324f565b61194a565b34801561070b57600080fd5b5061034a61071a366004613237565b6119a9565b34801561072b57600080fd5b5061039161073a3660046131ae565b611a23565b34801561074b57600080fd5b506104a9611a5f565b34801561076057600080fd5b5061039161076f36600461324f565b611a6e565b61034a610782366004612f3e565b611a81565b34801561079357600080fd5b5061047c611b50565b3480156107a857600080fd5b506104a9611b60565b3480156107bd57600080fd5b5061034a6107cc366004612f3e565b611b6f565b3480156107dd57600080fd5b506104a96107ec366004613237565b611c3a565b3480156107fd57600080fd5b5061047c61080c366004613237565b611c55565b34801561081d57600080fd5b5061034a611c6a565b34801561083257600080fd5b5061047c610841366004613237565b611cc2565b34801561085257600080fd5b506104a9610861366004612f3e565b611cd6565b34801561087257600080fd5b50610391611cf1565b34801561088757600080fd5b506104a9611cf7565b34801561089c57600080fd5b5061034a6108ab366004612f3e565b611d06565b3480156108bc57600080fd5b5061034a6108cb366004612f3e565b611d91565b3480156108dc57600080fd5b50610391611dbe565b3480156108f157600080fd5b506104a9610900366004612f3e565b611dc4565b34801561091157600080fd5b5061034a610920366004612f3e565b611ddf565b3390565b6001600160a01b03881630141561093f57610b16565b6001600160a01b03861630146109675760405162461bcd60e51b815260040161034190613b0d565b6000610971610925565b60405163555ddc6560e11b8152909150600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906109d09085907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce217705490600401613627565b60206040518083038186803b1580156109e857600080fd5b505afa1580156109fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a209190612f5a565b6001600160a01b03161415610a475760405162461bcd60e51b815260040161034190613f0e565b83151580610a645750610a62886001600160a01b0316611e7a565b155b610a805760405162461bcd60e51b815260040161034190613b74565b60008415610acc57610ac786868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e8092505050565b610ace565b885b9050610b13828a838a8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e8792505050565b50505b5050505050505050565b60426020526000908152604090205481565b610b3a61187b565b610b565760405162461bcd60e51b815260040161034190613d8b565b6040805460ff60a01b1916600160a01b83151581029190911780835591517f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad992610ba59260ff91041690613688565b60405180910390a150565b60375490565b610bbe61187b565b610bda5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b038616610c005760405162461bcd60e51b815260040161034190613d5f565b6001600160a01b038087166000908152603b6020526040902054168015610c395760405162461bcd60e51b81526004016103419061402f565b6000610c448761213a565b9050600060388787604051602001610c5e939291906134a6565b60408051601f1981840301815282825290546326d9e96360e01b83529092506001600160a01b0316906326d9e96390610ca1908890889086908890600401613700565b602060405180830381600087803b158015610cbb57600080fd5b505af1158015610ccf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf39190612f5a565b6001600160a01b03808b166000818152603b6020908152604080832080548688166001600160a01b03199182168117909255908452603c909252918290208054909116909217909155603f5490516378bf2b5360e01b815292955016906378bf2b5390610d669086908e90600401613627565b600060405180830381600087803b158015610d8057600080fd5b505af1158015610d94573d6000803e3d6000fd5b50505050886001600160a01b0316836001600160a01b03167f2ef93c4e96a4ef0b19497ff60c9e7360a8734f3d2cd27ae5318e43851734d17f8385604051610ddd929190613762565b60405180910390a350505050505050505050565b600054610100900460ff1680610e0a575060005460ff16155b610e265760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015610e51576000805460ff1961ff0019909116610100171660011790555b610e5a82611d06565b6034805460ff191690558015610e76576000805461ff00191690555b5050565b600054610100900460ff1680610e93575060005460ff16155b610eaf5760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015610eda576000805460ff1961ff0019909116610100171660011790555b610ee386611b6f565b610eec86610df1565b8151610eff906038906020850190612e1a565b50603f80546001600160a01b038087166001600160a01b031992831617909255604080548684169083161781556036805493891693909216929092179055516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90610f969030907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b908290600401613533565b600060405180830381600087803b158015610fb057600080fd5b505af1158015610fc4573d6000803e3d6000fd5b50505050610fd0611c6a565b8015610fe2576000805461ff00191690555b505050505050565b610ff261187b565b61100e5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b0381166110345760405162461bcd60e51b815260040161034190613aae565b604180546001600160a01b0319166001600160a01b0383161790556040517f0966c958966f6fac9ff807af074f8117eb2e9ce2b76390db7a158e9bdeb2485c90610ba590839061351f565b6000818152604260209081526040808320548352603e90915290205460ff165b919050565b6044602052600090815260409020546001600160a01b031681565b6110ca610506610925565b6110e65760405162461bcd60e51b815260040161034190613a05565b60345460ff166111085760405162461bcd60e51b8152600401610341906137c9565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61113b610925565b604051611148919061351f565b60405180910390a1565b61115a61187b565b6111765760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b03811661119c5760405162461bcd60e51b815260040161034190613ca6565b604080546001600160a01b0319166001600160a01b038316178155517f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e318369252162590610ba590839061351f565b60006111f260338361216d565b92915050565b60004285101561121a5760405162461bcd60e51b815260040161034190613c7d565b600061123661122e368b90038b018b6132da565b8989896121b5565b905060006001828787876040516000815260200160405260405161125d94939291906136e2565b6020604051602081039080840390855afa15801561127f573d6000803e3d6000fd5b5050604051601f19015191506000905061129c60208c018c612f3e565b6001600160a01b0316141580156112d057506112bb60208b018b612f3e565b6001600160a01b0316816001600160a01b0316145b6112ec5760405162461bcd60e51b815260040161034190613a4d565b6113048a6112fd6020820182612f3e565b8b8b61224a565b9a9950505050505050505050565b604080518082019091526002815261763360f01b602082015290565b6038805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156113b45780601f10611389576101008083540402835291602001916113b4565b820191906000526020600020905b81548152906001019060200180831161139757829003601f168201915b505050505081565b60345460ff1690565b603d6020526000908152604090205460ff1681565b60345460ff16156113fd5760405162461bcd60e51b815260040161034190613c1c565b60358054600101908190556036546001600160a01b031661141c610925565b6001600160a01b0316146114425760405162461bcd60e51b815260040161034190613b44565b6001600160a01b0388166000908152603d602052604090205460ff168061148257506001600160a01b038881166000908152603b60205260409020541615155b61149e5760405162461bcd60e51b815260040161034190613ade565b6001600160a01b0386166114c45760405162461bcd60e51b815260040161034190613bf3565b600085116114e45760405162461bcd60e51b815260040161034190613a84565b836115015760405162461bcd60e51b815260040161034190613ea7565b8261151e5760405162461bcd60e51b815260040161034190613926565b6000838152604260205260409020541561154a5760405162461bcd60e51b815260040161034190613e70565b60006115598787878787611a23565b6000818152603e602052604090205490915060ff161561158b5760405162461bcd60e51b815260040161034190613e02565b60008481526042602090815260408083208490556043825280832080546001600160a01b03199081166001600160a01b038f811691821790935560449094529382902080549094168c821617909355519189169186907f2858b8803acb87882fd2de49ce7572ae3e741fb8073cbe772fa50ce00bdfba2290611614908d908c908c908b90613556565b60405180910390a4506035548114610b165760405162461bcd60e51b815260040161034190613784565b7ff18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd8043381565b61167261166d610925565b612463565b565b61167c61187b565b6116985760405162461bcd60e51b815260040161034190613d8b565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b60006116f2610925565b90506117096001600160a01b0385168230856124a5565b6117258482858560405180602001604052806000815250611e87565b50505050565b60456020526000908152604090205481565b600054610100900460ff1680611756575060005460ff16155b6117725760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff1615801561179d576000805460ff1961ff0019909116610100171660011790555b600160355580156117b4576000805461ff00191690555b50565b6117c2610506610925565b6117de5760405162461bcd60e51b815260040161034190613a05565b6117b4816124fd565b6117f2610506610925565b61180e5760405162461bcd60e51b815260040161034190613a05565b60345460ff16156118315760405162461bcd60e51b815260040161034190613c1c565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861113b610925565b60345461010090046001600160a01b031690565b60345460009061010090046001600160a01b0316611897610925565b6001600160a01b031614905090565b6118ae61187b565b6118ca5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b0381166118f05760405162461bcd60e51b815260040161034190613ed7565b603f80546001600160a01b0319166001600160a01b0383161790556040517f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e390610ba590839061351f565b603f546001600160a01b031681565b60608101356000908152604460205260408120546001600160a01b031661196f610925565b6001600160a01b0316146119955760405162461bcd60e51b8152600401610341906138f6565b6111f2826119a1610925565b60008061224a565b6119b161187b565b6119cd5760405162461bcd60e51b815260040161034190613d8b565b6103e881106119ee5760405162461bcd60e51b81526004016103419061405f565b60378190556040517f97e97c577f03bda90e2c9739011ec065ed5fbfb36ae217d20bb0d9be95e160cd90610ba5908390613693565b60008383878785604051602001611a3e959493929190613448565b60405160208183030381529060405280519060200120905095945050505050565b6041546001600160a01b031681565b60006111f2826119a16020820182612f3e565b6000611a8b610925565b6041549091506001600160a01b0316611ab65760405162461bcd60e51b815260040161034190613c46565b604160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611b0657600080fd5b505af1158015611b1a573d6000803e3d6000fd5b5050505050610e76604160009054906101000a90046001600160a01b031682843460405180602001604052806000815250611e87565b604054600160a01b900460ff1681565b6040546001600160a01b031681565b600054610100900460ff1680611b88575060005460ff16155b611ba45760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015611bcf576000805460ff1961ff0019909116610100171660011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e76576000805461ff00191690555050565b6043602052600090815260409020546001600160a01b031681565b603e6020526000908152604090205460ff1681565b6000469050611cbc6040518060400160405280601081526020016f52534b20546f6b656e2042726964676560801b815250604051806040016040528060018152602001603160f81b815250833061253f565b60395550565b600090815260426020526040902054151590565b603b602052600090815260409020546001600160a01b031681565b61271081565b6036546001600160a01b031690565b600054610100900460ff1680611d1f575060005460ff16155b611d3b5760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015611d66576000805460ff1961ff0019909116610100171660011790555b611d6f826111e5565b611d7c57611d7c826124fd565b8015610e76576000805461ff00191690555050565b611d9961187b565b611db55760405162461bcd60e51b815260040161034190613d8b565b6117b481612596565b60395481565b603c602052600090815260409020546001600160a01b031681565b611de761187b565b611e035760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b038116611e295760405162461bcd60e51b81526004016103419061385d565b603680546001600160a01b0319166001600160a01b0383811691909117918290556040517f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb92610ba592169061351f565b3b151590565b6014015190565b604054600160a01b900460ff1615611eb15760405162461bcd60e51b8152600401610341906138cb565b60345460ff1615611ed45760405162461bcd60e51b815260040161034190613c1c565b603580546001908101918290556001600160a01b0387166000908152603d60205260408120805460ff1916909217909155603754611f219061271090611f1b908790612623565b90612664565b90506000611f2f85836126a6565b90506000611f3c896126e8565b905085601260ff831614611f6157611f5e8760ff601285900316600a0a612623565b90505b603f54604051638c34bc5560e01b81526001600160a01b0390911690638c34bc5590611f93908d908590600401613627565b600060405180830381600087803b158015611fad57600080fd5b505af1158015611fc1573d6000803e3d6000fd5b5050506001600160a01b03808c166000908152603c60205260409020548c9250161561209b57506001600160a01b03808b166000908152603c60205260408120549091169061200f8c6127ac565b9050600061201d8683612854565b90506120298782612896565b965061203586826126a6565b60405163fe9d930360e01b81529096506001600160a01b038e169063fe9d9303906120669089908d9060040161410e565b600060405180830381600087803b15801561208057600080fd5b505af1158015612094573d6000803e3d6000fd5b5050505050505b886001600160a01b03168a6001600160a01b0316826001600160a01b03167f1e90de9ae4d02420648a650f45f089a1be18fbca324092544ea626f9833212b0878b6040516120ea92919061410e565b60405180910390a4841561211457612114612103611867565b6001600160a01b038d1690876128bb565b50505050506035548114610fe25760405162461bcd60e51b815260040161034190613784565b600060128260ff1611156121605760405162461bcd60e51b815260040161034190613ce7565b5060120360ff16600a0a90565b60006001600160a01b0382166121955760405162461bcd60e51b815260040161034190613dc0565b506001600160a01b03166000908152602091909152604090205460ff1690565b603954845160208087015160608801516001600160a01b038416600090815260458452604080822080546001810190915590519196612241969095612226957ff18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd8043395929490938d928d928d910161369c565b604051602081830303815290604052805190602001206128df565b95945050505050565b603580546001019081905560608501356000908152604360205260408120549091906001600160a01b0316806122925760405162461bcd60e51b815260040161034190613f45565b60006122c36122a460208a018a612f3e565b60208a013560408b013560608c013561073a60a08e0160808f01613402565b606089013560009081526042602052604090205490915081146122f85760405162461bcd60e51b8152600401610341906140cd565b6000818152603e602052604090205460ff16156123275760405162461bcd60e51b815260040161034190613e02565b6000818152603e60209081526040808320805460ff191660011790556001600160a01b0385168352603d90915290205460ff16156123775761237082888a6020013589896128fe565b935061238b565b61238882888a602001358989612a74565b93505b6123986020890189612f3e565b6001600160a01b0316826001600160a01b031689606001357f42b1cb6263e8da47edf0583516eda1de16f729d26282f5791dc5b7af1010e925604460008d60600135815260200190815260200160002060009054906101000a90046001600160a01b03168c602001358d604001358e60800160208101906124199190613402565b8e8e8e60405161242f9796959493929190613640565b60405180910390a45050603554811461245a5760405162461bcd60e51b815260040161034190613784565b50949350505050565b61246e603382612c0b565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b611725846323b872dd60e01b8585856040516024016124c693929190613603565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612c53565b612508603382612d37565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b6001600160a01b0381166125bc5760405162461bcd60e51b815260040161034190613fa3565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600082612632575060006111f2565b8282028284828161263f57fe5b041461265d5760405162461bcd60e51b815260040161034190613d1e565b9392505050565b600061265d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612d83565b600061265d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612dba565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b0386169161272e919061348a565b600060405180830381855afa9150503d8060008114612769576040519150601f19603f3d011682016040523d82523d6000602084013e61276e565b606091505b5091509150816127905760405162461bcd60e51b81526004016103419061382e565b808060200190518101906127a49190613350565b949350505050565b60408051600481526024810182526020810180516001600160e01b031663556f0dc760e01b1790529051600091829182916001600160a01b038616916127f2919061348a565b600060405180830381855afa9150503d806000811461282d576040519150601f19603f3d011682016040523d82523d6000602084013e612832565b606091505b5091509150816127905760405162461bcd60e51b815260040161034190613bbc565b600061265d83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250612de6565b60008282018381101561265d5760405162461bcd60e51b815260040161034190613894565b6128da8363a9059cbb60e01b84846040516024016124c6929190613627565b505050565b60405161190160f01b8152600281019290925260228201526042902090565b60008061290a876126e8565b60ff1690506000612922866012849003600a0a612664565b9050808411156129445760405162461bcd60e51b815260040161034190613f75565b60415484820393506001600160a01b0389811691161415612a3b57604154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d9061298f908490600401613693565b600060405180830381600087803b1580156129a957600080fd5b505af11580156129bd573d6000803e3d6000fd5b50506040516001600160a01b038a16925085156108fc02915085906000818181858888f193505050501580156129f7573d6000803e3d6000fd5b508315612a36576040516001600160a01b0386169085156108fc029086906000818181858888f19350505050158015612a34573d6000803e3d6000fd5b505b612a69565b612a4f6001600160a01b03891688856128bb565b8315612a6957612a696001600160a01b03891686866128bb565b505095945050505050565b6001600160a01b038086166000908152603b6020908152604080832054815163556f0dc760e01b81529151939416928492849263556f0dc79260048083019392829003018186803b158015612ac857600080fd5b505afa158015612adc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b009190613350565b90506000612b0e8783612623565b905080851115612b305760405162461bcd60e51b815260040161034190613f75565b604051630dcdc7dd60e41b815285820394506001600160a01b0384169063dcdc7dd090612b63908b9088906004016135cd565b600060405180830381600087803b158015612b7d57600080fd5b505af1158015612b91573d6000803e3d6000fd5b505050506000851115612bff57604051630dcdc7dd60e41b81526001600160a01b0384169063dcdc7dd090612bcc9089908990600401613582565b600060405180830381600087803b158015612be657600080fd5b505af1158015612bfa573d6000803e3d6000fd5b505050505b50505095945050505050565b612c15828261216d565b612c315760405162461bcd60e51b815260040161034190613953565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b612c65826001600160a01b0316611e7a565b612c815760405162461bcd60e51b815260040161034190614096565b600080836001600160a01b031683604051612c9c919061348a565b6000604051808303816000865af19150503d8060008114612cd9576040519150601f19603f3d011682016040523d82523d6000602084013e612cde565b606091505b509150915081612d005760405162461bcd60e51b815260040161034190613988565b8051156117255780806020019051810190612d1b919061321b565b6117255760405162461bcd60e51b815260040161034190613fe5565b612d41828261216d565b15612d5e5760405162461bcd60e51b8152600401610341906137f7565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60008183612da45760405162461bcd60e51b8152600401610341919061374f565b506000838581612db057fe5b0495945050505050565b60008184841115612dde5760405162461bcd60e51b8152600401610341919061374f565b505050900390565b60008183612e075760405162461bcd60e51b8152600401610341919061374f565b50828481612e1157fe5b06949350505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282612e505760008555612e96565b82601f10612e6957805160ff1916838001178555612e96565b82800160010185558215612e96579182015b82811115612e96578251825591602001919060010190612e7b565b50612ea2929150612ea6565b5090565b5b80821115612ea25760008155600101612ea7565b60008083601f840112612ecc578182fd5b50813567ffffffffffffffff811115612ee3578182fd5b602083019150836020828501011115612efb57600080fd5b9250929050565b600060a08284031215612f13578081fd5b50919050565b803563ffffffff8116811461109f57600080fd5b803560ff8116811461109f57600080fd5b600060208284031215612f4f578081fd5b813561265d81614177565b600060208284031215612f6b578081fd5b815161265d81614177565b600080600080600080600060e0888a031215612f90578283fd5b8735612f9b81614177565b96506020880135612fab81614177565b95506040880135612fbb81614177565b9450606088013593506080880135925060a08801359150612fde60c08901612f19565b905092959891949750929550565b600080600080600060a08688031215613003578081fd5b853561300e81614177565b945060208681013561301f81614177565b9450604087013561302f81614177565b9350606087013561303f81614177565b9250608087013567ffffffffffffffff8082111561305b578384fd5b818901915089601f83011261306e578384fd5b81358181111561307a57fe5b61308c601f8201601f19168501614127565b91508082528a848285010111156130a1578485fd5b8084840185840137810190920192909252949793965091945092919050565b60008060008060008060008060c0898b0312156130db578081fd5b88356130e681614177565b975060208901356130f681614177565b9650604089013561310681614177565b955060608901359450608089013567ffffffffffffffff80821115613129578283fd5b6131358c838d01612ebb565b909650945060a08b013591508082111561314d578283fd5b5061315a8b828c01612ebb565b999c989b5096995094979396929594505050565b600080600060608486031215613182578081fd5b833561318d81614177565b9250602084013561319d81614177565b929592945050506040919091013590565b600080600080600060a086880312156131c5578283fd5b85356131d081614177565b94506020860135935060408601359250606086013591506131f360808701612f19565b90509295509295909350565b600060208284031215613210578081fd5b813561265d8161418c565b60006020828403121561322c578081fd5b815161265d8161418c565b600060208284031215613248578081fd5b5035919050565b600060a08284031215613260578081fd5b61265d8383612f02565b6000806000806000806000610160888a031215613285578081fd5b61328f8989612f02565b965060a088013561329f81614177565b955060c0880135945060e088013593506132bc6101008901612f2d565b92506101208801359150610140880135905092959891949750929550565b600060a082840312156132eb578081fd5b60405160a0810181811067ffffffffffffffff8211171561330857fe5b604052823561331681614177565b8082525060208301356020820152604083013560408201526060830135606082015261334460808401612f19565b60808201529392505050565b600060208284031215613361578081fd5b5051919050565b600080600080600080600060a0888a031215613382578081fd5b87359650602088013561339481614177565b95506133a260408901612f2d565b9450606088013567ffffffffffffffff808211156133be578283fd5b6133ca8b838c01612ebb565b909650945060808a01359150808211156133e2578283fd5b506133ef8a828b01612ebb565b989b979a50959850939692959293505050565b600060208284031215613413578081fd5b61265d82612f19565b6000815180845261343481602086016020860161414b565b601f01601f19169290920160200192915050565b948552602085019390935260609190911b6bffffffffffffffffffffffff19166040840152605483015260e01b6001600160e01b031916607482015260780190565b6000825161349c81846020870161414b565b9190910192915050565b60008085546001808216600081146134c557600181146134dc5761350b565b60ff198316865260028304607f168601935061350b565b600283048986526020808720875b838110156135035781548a8201529085019082016134ea565b505050860193505b505050838582379092019182525092915050565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b6001600160a01b039490941684526020840192909252604083015263ffffffff16606082015260800190565b6001600160a01b03929092168252602082015260806040820181905260009082015260a060608201819052600b908201526a72656c617965722066656560a81b60c082015260e00190565b6001600160a01b039290921682526020820152608060408201819052600090820181905260a06060830181905282015260c00190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0397881681526020810196909652604086019490945263ffffffff9290921660608501528416608084015290921660a082015260c081019190915260e00190565b901515815260200190565b90815260200190565b9788526001600160a01b039687166020890152604088019590955260608701939093529316608085015260a084019290925260c083019190915260e08201526101000190565b93845260ff9290921660208401526040830152606082015260800190565b600060608252846060830152848660808401378060808684010152601f19601f8601168201608083820301602084015261373d608082018661341c565b91505082604083015295945050505050565b60006020825261265d602083018461341c565b600060408252613775604083018561341c565b90508260208301529392505050565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b6020808252601f908201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604082015260600190565b6020808252601590820152744c69625574696c733a204e6f20646563696d616c7360581b604082015260600190565b6020808252601b908201527f4272696467653a2046656465726174696f6e20697320656d7074790000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601190820152704272696467653a20557067726164696e6760781b604082015260600190565b602080825260169082015275213934b233b29d1034b73b30b634b21039b2b73232b960511b604082015260600190565b602080825260139082015272084e4d2c8ceca74409cead8d840a8f090c2e6d606b1b604082015260600190565b6020808252818101527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c65604082015260600190565b6020808252818101527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604082015260600190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b60208082526019908201527f4272696467653a20494e56414c49445f5349474e415455524500000000000000604082015260600190565b60208082526010908201526f04272696467653a20416d6f756e7420360841b604082015260600190565b6020808252601690820152754272696467653a20777261707020697320656d70747960501b604082015260600190565b602080825260159082015274213934b233b29d102ab735b737bbb7103a37b5b2b760591b604082015260600190565b6020808252601b908201527f4272696467653a204e6f7420746f207468697320616464726573730000000000604082015260600190565b602080825260169082015275213934b233b29d102737ba102332b232b930ba34b7b760511b604082015260600190565b60208082526028908201527f4272696467653a2053706563696679207265636569766572206164647265737360408201526720696e206461746160c01b606082015260800190565b60208082526018908201527f4c69625574696c733a204e6f206772616e756c61726974790000000000000000604082015260600190565b6020808252600f908201526e4272696467653a204e756c6c20546f60881b604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252601d908201527f4272696467653a207772617070656443757272656e637920656d707479000000604082015260600190565b6020808252600f908201526e109c9a5919d94e8811561412549151608a1b604082015260600190565b60208082526021908201527f4272696467653a2053696465546f6b656e466163746f727920697320656d70746040820152607960f81b606082015260800190565b6020808252601c908201527f4c69625574696c733a20446563696d616c73206e6f74203c3d20313800000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260129082015271213934b233b29d10273ab636103a37b5b2b760711b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526022908201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526017908201527f4272696467653a20416c726561647920636c61696d6564000000000000000000604082015260600190565b6020808252601b908201527f4272696467653a206e6f74207772617070656443757272656e63790000000000604082015260600190565b60208082526018908201527f4272696467653a20416c72656164792061636365707465640000000000000000604082015260600190565b602080825260169082015275084e4d2c8ceca74409cead8d84084d8dec6d690c2e6d60531b604082015260600190565b6020808252601c908201527f4272696467653a20416c6c6f77546f6b656e7320697320656d70747900000000604082015260600190565b60208082526018908201527f4272696467653a204e6f742045524337373720746f6b656e0000000000000000604082015260600190565b602080825260169082015275109c9a5919d94e88151e081b9bdd0818dc9bdcdcd95960521b604082015260600190565b602080825260149082015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b604082015260600190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601690820152754272696467653a20416c72656164792065786973747360501b604082015260600190565b60208082526017908201527f4272696467653a20626967676572207468616e20313025000000000000000000604082015260600190565b6020808252601f908201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604082015260600190565b60208082526021908201527f4272696467653a2057726f6e67207472616e73616374696f6e446174614861736040820152600d60fb1b606082015260800190565b6000838252604060208301526127a4604083018461341c565b60405181810167ffffffffffffffff8111828210171561414357fe5b604052919050565b60005b8381101561416657818101518382015260200161414e565b838111156117255750506000910152565b6001600160a01b03811681146117b457600080fd5b80151581146117b457600080fdfea26469706673582212209f3d6b55444296ed94eaacc847d94aabd3d0ccef57edd6d16aca1a9136ef6cc264736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "__Pausable_init(address)": {
+ "details": "Initializes the contract in unpaused state. Assigns the Pauser role to the deployer."
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "pause()": {
+ "details": "Called by a pauser to pause, triggers stopped state."
+ },
+ "paused()": {
+ "details": "Returns true if the contract is paused, and false otherwise."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "unpause()": {
+ "details": "Called by a pauser to unpause, returns to normal state."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "acceptTransfer(address,address,address,uint256,bytes32,bytes32,uint32)": {
+ "notice": "Accepts the transaction from the other chain that was voted and sent by the Federation contract"
+ },
+ "claim((address,uint256,bytes32,bytes32,uint32))": {
+ "notice": "Claims the crossed transaction using the hash, this sends the funds to the address indicated in"
+ },
+ "depositTo(address)": {
+ "notice": "Use network currency and cross it."
+ },
+ "receiveTokensTo(address,address,uint256)": {
+ "notice": "ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom"
+ },
+ "tokensReceived(address,address,address,uint256,bytes,bytes)": {
+ "notice": "ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction See https://eips.ethereum.org/EIPS/eip-777#motivation for details"
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15785,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15788,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15828,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 15852,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_pausers",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_struct(Role)10129_storage"
+ },
+ {
+ "astId": 15974,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_paused",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16072,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_owner",
+ "offset": 1,
+ "slot": "52",
+ "type": "t_address"
+ },
+ {
+ "astId": 16786,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_guardCounter",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1282,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "federation",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_address"
+ },
+ {
+ "astId": 1284,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "feePercentage",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1286,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "symbolPrefix",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 1288,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "domainSeparator",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_bytes32"
+ },
+ {
+ "astId": 1290,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_deprecatedSpentToday",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1294,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "mappedTokens",
+ "offset": 0,
+ "slot": "59",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 1298,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originalTokens",
+ "offset": 0,
+ "slot": "60",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 1302,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "knownTokens",
+ "offset": 0,
+ "slot": "61",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 1306,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "claimed",
+ "offset": 0,
+ "slot": "62",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ },
+ {
+ "astId": 1308,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "allowTokens",
+ "offset": 0,
+ "slot": "63",
+ "type": "t_contract(IAllowTokens)7210"
+ },
+ {
+ "astId": 1310,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "sideTokenFactory",
+ "offset": 0,
+ "slot": "64",
+ "type": "t_contract(ISideTokenFactory)7607"
+ },
+ {
+ "astId": 1312,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "isUpgrading",
+ "offset": 20,
+ "slot": "64",
+ "type": "t_bool"
+ },
+ {
+ "astId": 1322,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "wrappedCurrency",
+ "offset": 0,
+ "slot": "65",
+ "type": "t_contract(IWrapped)7660"
+ },
+ {
+ "astId": 1326,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "transactionsDataHashes",
+ "offset": 0,
+ "slot": "66",
+ "type": "t_mapping(t_bytes32,t_bytes32)"
+ },
+ {
+ "astId": 1330,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originalTokenAddresses",
+ "offset": 0,
+ "slot": "67",
+ "type": "t_mapping(t_bytes32,t_address)"
+ },
+ {
+ "astId": 1334,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "senderAddresses",
+ "offset": 0,
+ "slot": "68",
+ "type": "t_mapping(t_bytes32,t_address)"
+ },
+ {
+ "astId": 1341,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "nonces",
+ "offset": 0,
+ "slot": "69",
+ "type": "t_mapping(t_address,t_uint256)"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IAllowTokens)7210": {
+ "encoding": "inplace",
+ "label": "contract IAllowTokens",
+ "numberOfBytes": "20"
+ },
+ "t_contract(ISideTokenFactory)7607": {
+ "encoding": "inplace",
+ "label": "contract ISideTokenFactory",
+ "numberOfBytes": "20"
+ },
+ "t_contract(IWrapped)7660": {
+ "encoding": "inplace",
+ "label": "contract IWrapped",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_address)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_mapping(t_bytes32,t_address)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bytes32)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bytes32)",
+ "numberOfBytes": "32",
+ "value": "t_bytes32"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)10129_storage": {
+ "encoding": "inplace",
+ "label": "struct Roles.Role",
+ "members": [
+ {
+ "astId": 10128,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "bearer",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_address,t_bool)"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/BridgeProxy.json b/bridge/deployments/rsktestnetbsc/BridgeProxy.json
new file mode 100644
index 000000000..022e3562f
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/BridgeProxy.json
@@ -0,0 +1,234 @@
+{
+ "address": "0x4ec10A50801f89266F0F1FA7fd3fa320106bBF63",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_admin",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x4ec10A50801f89266F0F1FA7fd3fa320106bBF63",
+ "transactionIndex": 0,
+ "gasUsed": "947465",
+ "logsBloom": "0x00000000020000000000000000008000000000000000004000800000000000001000000000000000000000000020002000000000000000000000000000000000000000000080000000000000000000000081000000000000000000000000000000000000020008000000000000040800000010004020000000000000000000400000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000240801000000000000000000000000000000000000000100000000000000000000000000000020000000000000000000000000000000000000000000000000008000000000000000",
+ "blockHash": "0x36083a7b34699ea6db1b1a64eeba40a5a29fa7d8c9c873e7e1361e02bb124f42",
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152250,
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "address": "0x4ec10A50801f89266F0F1FA7fd3fa320106bBF63",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x00000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x36083a7b34699ea6db1b1a64eeba40a5a29fa7d8c9c873e7e1361e02bb124f42"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152250,
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "address": "0x4ec10A50801f89266F0F1FA7fd3fa320106bBF63",
+ "topics": [
+ "0x6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f8",
+ "0x00000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a"
+ ],
+ "data": "0x",
+ "logIndex": 1,
+ "blockHash": "0x36083a7b34699ea6db1b1a64eeba40a5a29fa7d8c9c873e7e1361e02bb124f42"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152250,
+ "transactionHash": "0x575296331dbe2a8796e7f6edaf69431b63c77b63362fd9729ab796f7a52b15fb",
+ "address": "0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24",
+ "topics": [
+ "0x93baa6efbd2244243bfee6ce4cfdd1d04fc4c0e9a786abd3a41313bd352db153",
+ "0x0000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf63",
+ "0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b",
+ "0x0000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf63"
+ ],
+ "data": "0x",
+ "logIndex": 2,
+ "blockHash": "0x36083a7b34699ea6db1b1a64eeba40a5a29fa7d8c9c873e7e1361e02bb124f42"
+ }
+ ],
+ "blockNumber": 2152250,
+ "cumulativeGasUsed": "947465",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0xCEA4F7E9a2080D206be1fa7E4245BDecff7102dF",
+ "0x8c35e166d2dea7a8a28aaea11ad7933cdae4b0ab",
+ "0x2fb3b36100000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8000000000000000000000000bb74098e1f6f95198209ba30ba92725a6ccd5eab00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000016200000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Proxies.sol\":\"BridgeProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Proxies.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\\\";\\n\\ncontract BridgeProxy is TransparentUpgradeableProxy {\\n // solhint-disable-next-line no-empty-blocks\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\n}\\n\\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\\n // solhint-disable-next-line no-empty-blocks\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\n}\\n\\ncontract FederationProxy is TransparentUpgradeableProxy {\\n // solhint-disable-next-line no-empty-blocks\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\n}\",\"keccak256\":\"0x58e34ea4864c39b1d234084bc49b12bd7835c0a23f2604e450526eaa7581a554\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0x590a4d952d39a99972cbcb691b472c5d58af9ae8fd142355ad26200affdd2a51\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x0d5202a38732881d576fe3831605fe2633e1bc9f981ebea9c3a368af027e0b71\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x53b00bc48bd4eac1e100195c494267c0ca082bd91ac3018e2ee6155fbcbbb14f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000ca538038062000ca5833981016040819052620000269162000234565b8282828281620000368262000077565b8051156200005757620000558282620000d960201b620002ca1760201c565b505b50620000609050565b6200006b8262000108565b50505050505062000423565b6200008d816200012c60201b620002f61760201c565b620000b55760405162461bcd60e51b8152600401620000ac906200034d565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606062000101838360405180606001604052806027815260200162000c7e6027913962000136565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b606062000143846200012c565b620001625760405162461bcd60e51b8152600401620000ac90620003aa565b600080856001600160a01b0316856040516200017f9190620002fa565b600060405180830381855af49150503d8060008114620001bc576040519150601f19603f3d011682016040523d82523d6000602084013e620001c1565b606091505b509092509050620001d4828286620001de565b9695505050505050565b60608315620001ef57508162000101565b825115620002005782518084602001fd5b8160405162461bcd60e51b8152600401620000ac919062000318565b80516001600160a01b03811681146200013157600080fd5b60008060006060848603121562000249578283fd5b62000254846200021c565b925062000264602085016200021c565b60408501519092506001600160401b038082111562000281578283fd5b818601915086601f83011262000295578283fd5b815181811115620002a257fe5b604051601f8201601f191681016020018381118282101715620002c157fe5b604052818152838201602001891015620002d9578485fd5b620002ec826020830160208701620003f0565b809450505050509250925092565b600082516200030e818460208701620003f0565b9190910192915050565b600060208252825180602084015262000339816040850160208701620003f0565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b838110156200040d578181015183820152602001620003f3565b838111156200041d576000848401525b50505050565b61084b80620004336000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e3ec70ca139aef33041f9d7a058cc6501b5f73e931f4077b7f513ef7e0b3bf5c64736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e3ec70ca139aef33041f9d7a058cc6501b5f73e931f4077b7f513ef7e0b3bf5c64736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/FederationProxy.json b/bridge/deployments/rsktestnetbsc/FederationProxy.json
new file mode 100644
index 000000000..629b9b9cf
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/FederationProxy.json
@@ -0,0 +1,257 @@
+{
+ "address": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "transactionIndex": 0,
+ "gasUsed": "895606",
+ "logsBloom": "0x00000000000000000001000000008000000100000000000000800000000000000000000000000000000000000000000000000000000000000080000000000000000000800000000000000000000000100001000000000000000000000000000000000000020000000000000000040800000000000000000000000000000000400000000000000000000020008000000000000000000000000000000000000000000000000000000000000000000000000000008000008000000010800000000000000040000000000000000000000100000000000000000000000000000020000010000000000000000000000000000100000000000000000800000000000000",
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4",
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152252,
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "address": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x00000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152252,
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "address": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "topics": [
+ "0x72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c7",
+ "0x0000000000000000000000008f397ff074ff190fc650e5cab4da039a8163e12a"
+ ],
+ "data": "0x",
+ "logIndex": 1,
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152252,
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "address": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "topics": [
+ "0xa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "logIndex": 2,
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152252,
+ "transactionHash": "0xa5ec6f287deaf42186d58fd325de9f99ae454b2e871afa71641d6d65b22a719a",
+ "address": "0xe450bBE6C28cCd253a56ac24c55E44015e576783",
+ "topics": [
+ "0x9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b92551782794497"
+ ],
+ "data": "0x0000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf63",
+ "logIndex": 3,
+ "blockHash": "0x7f91a995e8df86e4e0a309522d3bf2e51e9d6ed9de79d0a1d40cf331d3fdd4a4"
+ }
+ ],
+ "blockNumber": 2152252,
+ "cumulativeGasUsed": "895606",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0x9c36A1E78D68417396FE6c715A5515d659973cF6",
+ "0x8c35e166d2dea7a8a28aaea11ad7933cdae4b0ab",
+ "0xc1b4a1e3000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000004ec10a50801f89266f0f1fa7fd3fa320106bbf6300000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000008f397ff074ff190fc650e5cab4da039a8163e12a"
+ ],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"stateVariables\":{\"_ADMIN_SLOT\":{\"details\":\"Storage slot with the admin of the contract. This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0x590a4d952d39a99972cbcb691b472c5d58af9ae8fd142355ad26200affdd2a51\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x0d5202a38732881d576fe3831605fe2633e1bc9f981ebea9c3a368af027e0b71\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x53b00bc48bd4eac1e100195c494267c0ca082bd91ac3018e2ee6155fbcbbb14f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000c9f38038062000c9f83398101604081905262000026916200022e565b8281620000338262000071565b8051156200005457620000528282620000d360201b620002ca1760201c565b505b506200005d9050565b620000688262000102565b5050506200041d565b62000087816200012660201b620002f61760201c565b620000af5760405162461bcd60e51b8152600401620000a69062000347565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6060620000fb838360405180606001604052806027815260200162000c786027913962000130565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b60606200013d8462000126565b6200015c5760405162461bcd60e51b8152600401620000a690620003a4565b600080856001600160a01b031685604051620001799190620002f4565b600060405180830381855af49150503d8060008114620001b6576040519150601f19603f3d011682016040523d82523d6000602084013e620001bb565b606091505b509092509050620001ce828286620001d8565b9695505050505050565b60608315620001e9575081620000fb565b825115620001fa5782518084602001fd5b8160405162461bcd60e51b8152600401620000a6919062000312565b80516001600160a01b03811681146200012b57600080fd5b60008060006060848603121562000243578283fd5b6200024e8462000216565b92506200025e6020850162000216565b60408501519092506001600160401b03808211156200027b578283fd5b818601915086601f8301126200028f578283fd5b8151818111156200029c57fe5b604051601f8201601f191681016020018381118282101715620002bb57fe5b604052818152838201602001891015620002d3578485fd5b620002e6826020830160208701620003ea565b809450505050509250925092565b6000825162000308818460208701620003ea565b9190910192915050565b600060208252825180602084015262000333816040850160208701620003ea565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b8381101562000407578181015183820152602001620003ed565b8381111562000417576000848401525b50505050565b61084b806200042d6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fabbc30a04f636413f38ca4eda3e460473659576ddb6aaf9066d31235c793fc064736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fabbc30a04f636413f38ca4eda3e460473659576ddb6aaf9066d31235c793fc064736f6c63430007060033",
+ "devdoc": {
+ "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.",
+ "events": {
+ "AdminChanged(address,address)": {
+ "details": "Emitted when the admin account has changed."
+ }
+ },
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "constructor": {
+ "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "stateVariables": {
+ "_ADMIN_SLOT": {
+ "details": "Storage slot with the admin of the contract. This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/FederationV2.json b/bridge/deployments/rsktestnetbsc/FederationV2.json
new file mode 100644
index 000000000..b32b06ef6
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/FederationV2.json
@@ -0,0 +1,905 @@
+{
+ "address": "0x9c36A1E78D68417396FE6c715A5515d659973cF6",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridge",
+ "type": "address"
+ }
+ ],
+ "name": "BridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Executed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "HeartBeat",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Voted",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_MEMBER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_newMember",
+ "type": "address"
+ }
+ ],
+ "name": "addMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridge",
+ "outputs": [
+ {
+ "internalType": "contract IBridge",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "emitHeartbeat",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getMembers",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "getTransactionId",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_members",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isMember",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "members",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "processed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_oldMember",
+ "type": "address"
+ }
+ ],
+ "name": "removeMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ }
+ ],
+ "name": "setBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionWasProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "voteTransaction",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "votes",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x19d064fe48152b878f3d9335a6bce717230a681f843f53eb17cbea04811f51cd",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x9c36A1E78D68417396FE6c715A5515d659973cF6",
+ "transactionIndex": 0,
+ "gasUsed": "1897118",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x8342e7f56adeebb21f7cf5af57f5fc1054b18f7c52c89d995cab2c19280d17e0",
+ "transactionHash": "0x19d064fe48152b878f3d9335a6bce717230a681f843f53eb17cbea04811f51cd",
+ "logs": [],
+ "blockNumber": 2152180,
+ "cumulativeGasUsed": "1897118",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"bridge\",\"type\":\"address\"}],\"name\":\"BridgeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"Executed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fedRskBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fedEthBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"federatorVersion\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"nodeRskInfo\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"nodeEthInfo\",\"type\":\"string\"}],\"name\":\"HeartBeat\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"Voted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MEMBER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newMember\",\"type\":\"address\"}],\"name\":\"addMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contract IBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fedRskBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fedEthBlock\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"federatorVersion\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nodeRskInfo\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nodeEthInfo\",\"type\":\"string\"}],\"name\":\"emitHeartbeat\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMembers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"getTransactionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"hasVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_members\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMember\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"members\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"processed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_oldMember\",\"type\":\"address\"}],\"name\":\"removeMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"name\":\"setBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"transactionWasProcessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"voteTransaction\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"votes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Federation/FederationV2.sol\":\"FederationV2\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Federation/FederationV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n// Upgradables\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\n\\nimport \\\"../interface/IBridge.sol\\\";\\n\\ncontract FederationV2 is Initializable, UpgradableOwnable {\\n uint constant public MAX_MEMBER_COUNT = 50;\\n address constant private NULL_ADDRESS = address(0);\\n\\n IBridge public bridge;\\n address[] public members;\\n uint public required;\\n\\n mapping (address => bool) public isMember;\\n mapping (bytes32 => mapping (address => bool)) public votes;\\n mapping(bytes32 => bool) public processed;\\n\\n event Executed(\\n address indexed federator,\\n bytes32 indexed transactionHash,\\n bytes32 indexed transactionId,\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n uint32 logIndex\\n );\\n event MemberAddition(address indexed member);\\n event MemberRemoval(address indexed member);\\n event RequirementChange(uint required);\\n event BridgeChanged(address bridge);\\n event Voted(\\n address indexed federator,\\n bytes32 indexed transactionHash,\\n bytes32 indexed transactionId,\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n uint32 logIndex\\n );\\n event HeartBeat(\\n address indexed sender,\\n uint256 fedRskBlock,\\n uint256 fedEthBlock,\\n string federatorVersion,\\n string nodeRskInfo,\\n string nodeEthInfo\\n );\\n\\n modifier onlyMember() {\\n require(isMember[_msgSender()], \\\"Federation: Not Federator\\\");\\n _;\\n }\\n\\n modifier validRequirement(uint membersCount, uint _required) {\\n // solium-disable-next-line max-len\\n require(_required <= membersCount && _required != 0 && membersCount != 0, \\\"Federation: Invalid requirements\\\");\\n _;\\n }\\n\\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\\n public validRequirement(_members.length, _required) initializer {\\n UpgradableOwnable.initialize(owner);\\n require(_members.length <= MAX_MEMBER_COUNT, \\\"Federation: Too many members\\\");\\n members = _members;\\n for (uint i = 0; i < _members.length; i++) {\\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \\\"Federation: Invalid members\\\");\\n isMember[_members[i]] = true;\\n emit MemberAddition(_members[i]);\\n }\\n required = _required;\\n emit RequirementChange(required);\\n _setBridge(_bridge);\\n }\\n\\n function version() external pure returns (string memory) {\\n return \\\"v2\\\";\\n }\\n\\n function setBridge(address _bridge) external onlyOwner {\\n _setBridge(_bridge);\\n }\\n\\n function _setBridge(address _bridge) internal {\\n require(_bridge != NULL_ADDRESS, \\\"Federation: Empty bridge\\\");\\n bridge = IBridge(_bridge);\\n emit BridgeChanged(_bridge);\\n }\\n\\n function voteTransaction(\\n address originalTokenAddress,\\n address payable sender,\\n address payable receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n bytes32 transactionHash,\\n uint32 logIndex\\n )\\n public onlyMember returns(bool)\\n {\\n bytes32 transactionId = getTransactionId(\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n transactionHash,\\n logIndex\\n );\\n if (processed[transactionId])\\n return true;\\n\\n if (votes[transactionId][_msgSender()])\\n return true;\\n\\n votes[transactionId][_msgSender()] = true;\\n emit Voted(\\n _msgSender(),\\n transactionHash,\\n transactionId,\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n logIndex\\n );\\n\\n uint transactionCount = getTransactionCount(transactionId);\\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\\n processed[transactionId] = true;\\n bridge.acceptTransfer(\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n transactionHash,\\n logIndex\\n );\\n emit Executed(\\n _msgSender(),\\n transactionHash,\\n transactionId,\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n logIndex\\n );\\n return true;\\n }\\n\\n return true;\\n }\\n\\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\\n uint count = 0;\\n for (uint i = 0; i < members.length; i++) {\\n if (votes[transactionId][members[i]])\\n count += 1;\\n }\\n return count;\\n }\\n\\n function hasVoted(bytes32 transactionId) external view returns(bool)\\n {\\n return votes[transactionId][_msgSender()];\\n }\\n\\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\\n {\\n return processed[transactionId];\\n }\\n\\n function getTransactionId(\\n address originalTokenAddress,\\n address sender,\\n address receiver,\\n uint256 amount,\\n bytes32 blockHash,\\n bytes32 transactionHash,\\n uint32 logIndex\\n ) public pure returns(bytes32)\\n {\\n return keccak256(\\n abi.encodePacked(\\n originalTokenAddress,\\n sender,\\n receiver,\\n amount,\\n blockHash,\\n transactionHash,\\n logIndex\\n )\\n );\\n }\\n\\n function addMember(address _newMember) external onlyOwner\\n {\\n require(_newMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\n require(!isMember[_newMember], \\\"Federation: Member already exists\\\");\\n require(members.length < MAX_MEMBER_COUNT, \\\"Federation: Max members reached\\\");\\n\\n isMember[_newMember] = true;\\n members.push(_newMember);\\n emit MemberAddition(_newMember);\\n }\\n\\n function removeMember(address _oldMember) external onlyOwner\\n {\\n require(_oldMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\n require(isMember[_oldMember], \\\"Federation: Member doesn't exists\\\");\\n require(members.length > 1, \\\"Federation: Can't remove all the members\\\");\\n require(members.length - 1 >= required, \\\"Federation: Can't have less than required members\\\");\\n\\n isMember[_oldMember] = false;\\n for (uint i = 0; i < members.length - 1; i++) {\\n if (members[i] == _oldMember) {\\n members[i] = members[members.length - 1];\\n break;\\n }\\n }\\n members.pop(); // remove an element from the end of the array.\\n emit MemberRemoval(_oldMember);\\n }\\n\\n function getMembers() external view returns (address[] memory)\\n {\\n return members;\\n }\\n\\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\\n {\\n require(_required >= 2, \\\"Federation: Requires at least 2\\\");\\n required = _required;\\n emit RequirementChange(_required);\\n }\\n\\n function emitHeartbeat(\\n uint256 fedRskBlock,\\n uint256 fedEthBlock,\\n string calldata federatorVersion,\\n string calldata nodeRskInfo,\\n string calldata nodeEthInfo\\n ) external onlyMember {\\n emit HeartBeat(\\n _msgSender(),\\n fedRskBlock,\\n fedEthBlock,\\n federatorVersion,\\n nodeRskInfo,\\n nodeEthInfo\\n );\\n }\\n}\",\"keccak256\":\"0x6f9f6a650c694e2a400fa8ea64871fb3aa19eb5610d6a3ea726318c3491c866b\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\ninterface IBridge {\\n\\n struct ClaimData {\\n address payable to;\\n uint256 amount;\\n bytes32 blockHash;\\n bytes32 transactionHash;\\n uint32 logIndex;\\n }\\n\\n function version() external pure returns (string memory);\\n\\n function getFeePercentage() external view returns(uint);\\n\\n /**\\n * ERC-20 tokens approve and transferFrom pattern\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\n */\\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\\n\\n /**\\n * Use network currency and cross it.\\n */\\n function depositTo(address to) external payable;\\n\\n /**\\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\n */\\n function tokensReceived (\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n\\n /**\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\n */\\n function acceptTransfer(\\n address _originalTokenAddress,\\n address payable _from,\\n address payable _to,\\n uint256 _amount,\\n bytes32 _blockHash,\\n bytes32 _transactionHash,\\n uint32 _logIndex\\n ) external;\\n\\n /**\\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\n */\\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\n\\n function claimGasless(\\n ClaimData calldata _claimData,\\n address payable _relayer,\\n uint256 _fee,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external returns (uint256 receivedAmount);\\n\\n function getTransactionDataHash(\\n address _to,\\n uint256 _amount,\\n bytes32 _blockHash,\\n bytes32 _transactionHash,\\n uint32 _logIndex\\n ) external returns(bytes32);\\n\\n event Cross(\\n address indexed _tokenAddress,\\n address indexed _from,\\n address indexed _to,\\n uint256 _amount,\\n bytes _userData\\n );\\n event NewSideToken(\\n address indexed _newSideTokenAddress,\\n address indexed _originalTokenAddress,\\n string _newSymbol,\\n uint256 _granularity\\n );\\n event AcceptedCrossTransfer(\\n bytes32 indexed _transactionHash,\\n address indexed _originalTokenAddress,\\n address indexed _to,\\n address _from,\\n uint256 _amount,\\n bytes32 _blockHash,\\n uint256 _logIndex\\n );\\n event FeePercentageChanged(uint256 _amount);\\n event Claimed(\\n bytes32 indexed _transactionHash,\\n address indexed _originalTokenAddress,\\n address indexed _to,\\n address _sender,\\n uint256 _amount,\\n bytes32 _blockHash,\\n uint256 _logIndex,\\n address _reciever,\\n address _relayer,\\n uint256 _fee\\n );\\n}\",\"keccak256\":\"0x188bdd14d3e1d1eaddd5d86a4d957a8c6a7e6c4571058b6db13a974db3ab5f39\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\",\"keccak256\":\"0x3eeeb5ea6bf7d3458bb36acebd4268b406e6a1525e009d4d8a90626c277a37d1\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../Initializable.sol\\\";\\n\\nimport \\\"../../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract UpgradableOwnable is Initializable, Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function initialize(address sender) public initializer {\\n _owner = sender;\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * > Note: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n\\n}\\n\",\"keccak256\":\"0x2e0e58f4a3991801550e6a52512a3c1bbcaa5cb824120c177cb6ec1b4fa0ce97\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50611afa806100206000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063a1fb4acb116100de578063c1f0808a11610097578063dc8452cd11610071578063dc8452cd14610311578063e78cea9214610319578063f2fde38b14610321578063fa6297ba1461033457610173565b8063c1f0808a146102d8578063c4d66de8146102eb578063ca6d56dc146102fe57610173565b8063a1fb4acb14610266578063a230c52414610279578063a93585f01461028c578063b9a3b9dc1461029f578063ba51a6df146102b2578063c1b4a1e3146102c557610173565b8063715018a611610130578063715018a6146102135780638da5cb5b1461021b5780638dd14802146102235780638f32d59b146102365780639386775a1461023e5780639eab52531461025157610173565b80630b1ca49a146101785780631b4613cb1461018d57806335d4aa9e146101b657806354fd4d50146101c95780635daf08ca146101de578063681fc921146101fe575b600080fd5b61018b61018636600461128b565b610347565b005b6101a061019b366004611404565b610555565b6040516101ad9190611661565b60405180910390f35b6101a06101c43660046112ae565b610591565b6101d161080b565b6040516101ad9190611675565b6101f16101ec366004611404565b610827565b6040516101ad919061157c565b610206610851565b6040516101ad919061166c565b61018b610856565b6101f16108c4565b61018b61023136600461128b565b6108d3565b6101a0610903565b6101a061024c36600461141c565b610929565b610259610949565b6040516101ad9190611614565b610206610274366004611404565b6109ab565b6101a061028736600461128b565b610a1c565b6101a061029a366004611404565b610a31565b61018b6102ad36600461144b565b610a46565b61018b6102c0366004611404565b610aeb565b61018b6102d3366004611324565b610bac565b6101a06102e6366004611404565b610e1a565b61018b6102f936600461128b565b610e2f565b61018b61030c36600461128b565b610ef4565b610206611025565b6101f161102b565b61018b61032f36600461128b565b61103a565b6102066103423660046112ae565b611067565b61034f610903565b6103745760405162461bcd60e51b815260040161036b906118f4565b60405180910390fd5b6001600160a01b03811661039a5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff166103d25760405162461bcd60e51b815260040161036b9061176b565b6035546001106103f45760405162461bcd60e51b815260040161036b90611997565b60365460355460001901101561041c5760405162461bcd60e51b815260040161036b906118a3565b6001600160a01b0381166000908152603760205260408120805460ff191690555b603554600019018110156104f057816001600160a01b03166035828154811061046257fe5b6000918252602090912001546001600160a01b031614156104e85760358054600019810190811061048f57fe5b600091825260209091200154603580546001600160a01b0390921691839081106104b557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506104f0565b60010161043d565b5060358054806104fc57fe5b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b60008181526038602052604081208161056c6110a9565b6001600160a01b0316815260208101919091526040016000205460ff1690505b919050565b60006037600061059f6110a9565b6001600160a01b0316815260208101919091526040016000205460ff166105d85760405162461bcd60e51b815260040161036b90611a21565b60006105e989898989898989611067565b60008181526039602052604090205490915060ff161561060d576001915050610800565b6000818152603860205260408120906106246110a9565b6001600160a01b0316815260208101919091526040016000205460ff1615610650576001915050610800565b60008181526038602052604081206001916106696110a9565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055808461069b6110a9565b6001600160a01b03167fd22894491aaa5bb67855bcff4b9730bdf7768be1e25f66ced9a7d7ad623bf2918c8c8c8c8c8b6040516106dd969594939291906115d6565b60405180910390a460006106f0826109ab565b9050603654811015801561070d5750603554600290046001018110155b156107f95760008281526039602052604090819020805460ff191660011790556034549051636a86319160e01b81526001600160a01b0390911690636a86319190610768908d908d908d908d908d908d908d90600401611590565b600060405180830381600087803b15801561078257600080fd5b505af1158015610796573d6000803e3d6000fd5b5050505081856107a46110a9565b6001600160a01b03167fe21e4d3d66ef78424137270e65cfafe938736bb770702ab4fd630383e7820b738d8d8d8d8d8c6040516107e6969594939291906115d6565b60405180910390a4600192505050610800565b6001925050505b979650505050505050565b6040805180820190915260028152613b1960f11b602082015290565b6035818154811061083757600080fd5b6000918252602090912001546001600160a01b0316905081565b603281565b61085e610903565b61087a5760405162461bcd60e51b815260040161036b906118f4565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6108db610903565b6108f75760405162461bcd60e51b815260040161036b906118f4565b610900816110ad565b50565b6033546000906001600160a01b031661091a6110a9565b6001600160a01b031614905090565b603860209081526000928352604080842090915290825290205460ff1681565b606060358054806020026020016040519081016040528092919081815260200182805480156109a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610983575b5050505050905090565b600080805b603554811015610a1557600084815260386020526040812060358054919291849081106109d957fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0d576001820191505b6001016109b0565b5092915050565b60376020526000908152604090205460ff1681565b60009081526039602052604090205460ff1690565b60376000610a526110a9565b6001600160a01b0316815260208101919091526040016000205460ff16610a8b5760405162461bcd60e51b815260040161036b90611a21565b610a936110a9565b6001600160a01b03167fbb00e6cbdccbb5b7549e189335249187223d88583604555326aa1d7ccbcad4428989898989898989604051610ad9989796959493929190611a58565b60405180910390a25050505050505050565b610af3610903565b610b0f5760405162461bcd60e51b815260040161036b906118f4565b60355481818111801590610b2257508015155b8015610b2d57508115155b610b495760405162461bcd60e51b815260040161036b906116c8565b6002831015610b6a5760405162461bcd60e51b815260040161036b90611929565b60368390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610b9f90859061166c565b60405180910390a1505050565b835183818111158015610bbe57508015155b8015610bc957508115155b610be55760405162461bcd60e51b815260040161036b906116c8565b600054610100900460ff1680610bfe575060005460ff16155b610c1a5760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610c45576000805460ff1961ff0019909116610100171660011790555b610c4e84610e2f565b603287511115610c705760405162461bcd60e51b815260040161036b90611734565b8651610c839060359060208a01906111ab565b5060005b8751811015610db85760376000898381518110610ca057fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015610cfa575060006001600160a01b0316888281518110610ce657fe5b60200260200101516001600160a01b031614155b610d165760405162461bcd60e51b815260040161036b906117f4565b6001603760008a8481518110610d2857fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550878181518110610d7357fe5b60200260200101516001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a2600101610c87565b5060368690556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610dee90889061166c565b60405180910390a1610dff856110ad565b8015610e11576000805461ff00191690555b50505050505050565b60396020526000908152604090205460ff1681565b600054610100900460ff1680610e48575060005460ff16155b610e645760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610e8f576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610ef0576000805461ff00191690555b5050565b610efc610903565b610f185760405162461bcd60e51b815260040161036b906118f4565b6001600160a01b038116610f3e5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff1615610f775760405162461bcd60e51b815260040161036b9061182b565b603554603211610f995760405162461bcd60e51b815260040161036b906116fd565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b60365481565b6034546001600160a01b031681565b611042610903565b61105e5760405162461bcd60e51b815260040161036b906118f4565b61090081611129565b600087878787878787604051602001611086979695949392919061151e565b604051602081830303815290604052805190602001209050979650505050505050565b3390565b6001600160a01b0381166110d35760405162461bcd60e51b815260040161036b9061186c565b603480546001600160a01b0319166001600160a01b0383161790556040517f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b925517827944979061111e90839061157c565b60405180910390a150565b6001600160a01b03811661114f5760405162461bcd60e51b815260040161036b906119df565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b828054828255906000526020600020908101928215611200579160200282015b8281111561120057825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906111cb565b5061120c929150611210565b5090565b5b8082111561120c5760008155600101611211565b803561058c81611aaf565b60008083601f840112611241578182fd5b50813567ffffffffffffffff811115611258578182fd5b60208301915083602082850101111561127057600080fd5b9250929050565b803563ffffffff8116811461058c57600080fd5b60006020828403121561129c578081fd5b81356112a781611aaf565b9392505050565b600080600080600080600060e0888a0312156112c8578283fd5b87356112d381611aaf565b965060208801356112e381611aaf565b955060408801356112f381611aaf565b9450606088013593506080880135925060a0880135915061131660c08901611277565b905092959891949750929550565b60008060008060808587031215611339578384fd5b843567ffffffffffffffff80821115611350578586fd5b818701915087601f830112611363578586fd5b813560208282111561137157fe5b8082026040518282820101818110868211171561138a57fe5b604052838152828101945085830182870184018d10156113a8578a8bfd5b8a96505b848710156113d1576113bd81611225565b8652600196909601959483019483016113ac565b5098505088013595506113eb925050604087019050611225565b91506113f960608601611225565b905092959194509250565b600060208284031215611415578081fd5b5035919050565b6000806040838503121561142e578182fd5b82359150602083013561144081611aaf565b809150509250929050565b60008060008060008060008060a0898b031215611466578081fd5b8835975060208901359650604089013567ffffffffffffffff8082111561148b578283fd5b6114978c838d01611230565b909850965060608b01359150808211156114af578283fd5b6114bb8c838d01611230565b909650945060808b01359150808211156114d3578283fd5b506114e08b828c01611230565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b606097881b6bffffffffffffffffffffffff19908116825296881b871660148201529490961b9094166028840152603c830191909152605c820152607c81019190915260e09190911b6001600160e01b031916609c82015260a00190565b6001600160a01b0391909116815260200190565b6001600160a01b03978816815295871660208701529390951660408501526060840191909152608083015260a082019290925263ffffffff90911660c082015260e00190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925263ffffffff90911660a082015260c00190565b6020808252825182820181905260009190848201906040850190845b818110156116555783516001600160a01b031683529284019291840191600101611630565b50909695505050505050565b901515815260200190565b90815260200190565b6000602080835283518082850152825b818110156116a157858101830151858201604001528201611685565b818111156116b25783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f46656465726174696f6e3a20496e76616c696420726571756972656d656e7473604082015260600190565b6020808252601f908201527f46656465726174696f6e3a204d6178206d656d62657273207265616368656400604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20546f6f206d616e79206d656d6265727300000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746040820152607360f81b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252601b908201527f46656465726174696f6e3a20496e76616c6964206d656d626572730000000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746040820152607360f81b606082015260800190565b60208082526018908201527f46656465726174696f6e3a20456d707479206272696467650000000000000000604082015260600190565b60208082526031908201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604082015270207265717569726564206d656d6265727360781b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f46656465726174696f6e3a205265717569726573206174206c65617374203200604082015260600190565b60208082526018908201527f46656465726174696f6e3a20456d707479206d656d6265720000000000000000604082015260600190565b60208082526028908201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604082015267206d656d6265727360c01b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526019908201527f46656465726174696f6e3a204e6f7420466564657261746f7200000000000000604082015260600190565b600089825288602083015260a06040830152611a7860a08301888a6114f4565b8281036060840152611a8b8187896114f4565b90508281036080840152611aa08185876114f4565b9b9a5050505050505050505050565b6001600160a01b038116811461090057600080fdfea2646970667358221220128a4b4f51a83044e466d0c301c3119ae839536443710de99b33113388de820464736f6c63430007060033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101735760003560e01c8063a1fb4acb116100de578063c1f0808a11610097578063dc8452cd11610071578063dc8452cd14610311578063e78cea9214610319578063f2fde38b14610321578063fa6297ba1461033457610173565b8063c1f0808a146102d8578063c4d66de8146102eb578063ca6d56dc146102fe57610173565b8063a1fb4acb14610266578063a230c52414610279578063a93585f01461028c578063b9a3b9dc1461029f578063ba51a6df146102b2578063c1b4a1e3146102c557610173565b8063715018a611610130578063715018a6146102135780638da5cb5b1461021b5780638dd14802146102235780638f32d59b146102365780639386775a1461023e5780639eab52531461025157610173565b80630b1ca49a146101785780631b4613cb1461018d57806335d4aa9e146101b657806354fd4d50146101c95780635daf08ca146101de578063681fc921146101fe575b600080fd5b61018b61018636600461128b565b610347565b005b6101a061019b366004611404565b610555565b6040516101ad9190611661565b60405180910390f35b6101a06101c43660046112ae565b610591565b6101d161080b565b6040516101ad9190611675565b6101f16101ec366004611404565b610827565b6040516101ad919061157c565b610206610851565b6040516101ad919061166c565b61018b610856565b6101f16108c4565b61018b61023136600461128b565b6108d3565b6101a0610903565b6101a061024c36600461141c565b610929565b610259610949565b6040516101ad9190611614565b610206610274366004611404565b6109ab565b6101a061028736600461128b565b610a1c565b6101a061029a366004611404565b610a31565b61018b6102ad36600461144b565b610a46565b61018b6102c0366004611404565b610aeb565b61018b6102d3366004611324565b610bac565b6101a06102e6366004611404565b610e1a565b61018b6102f936600461128b565b610e2f565b61018b61030c36600461128b565b610ef4565b610206611025565b6101f161102b565b61018b61032f36600461128b565b61103a565b6102066103423660046112ae565b611067565b61034f610903565b6103745760405162461bcd60e51b815260040161036b906118f4565b60405180910390fd5b6001600160a01b03811661039a5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff166103d25760405162461bcd60e51b815260040161036b9061176b565b6035546001106103f45760405162461bcd60e51b815260040161036b90611997565b60365460355460001901101561041c5760405162461bcd60e51b815260040161036b906118a3565b6001600160a01b0381166000908152603760205260408120805460ff191690555b603554600019018110156104f057816001600160a01b03166035828154811061046257fe5b6000918252602090912001546001600160a01b031614156104e85760358054600019810190811061048f57fe5b600091825260209091200154603580546001600160a01b0390921691839081106104b557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506104f0565b60010161043d565b5060358054806104fc57fe5b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b60008181526038602052604081208161056c6110a9565b6001600160a01b0316815260208101919091526040016000205460ff1690505b919050565b60006037600061059f6110a9565b6001600160a01b0316815260208101919091526040016000205460ff166105d85760405162461bcd60e51b815260040161036b90611a21565b60006105e989898989898989611067565b60008181526039602052604090205490915060ff161561060d576001915050610800565b6000818152603860205260408120906106246110a9565b6001600160a01b0316815260208101919091526040016000205460ff1615610650576001915050610800565b60008181526038602052604081206001916106696110a9565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055808461069b6110a9565b6001600160a01b03167fd22894491aaa5bb67855bcff4b9730bdf7768be1e25f66ced9a7d7ad623bf2918c8c8c8c8c8b6040516106dd969594939291906115d6565b60405180910390a460006106f0826109ab565b9050603654811015801561070d5750603554600290046001018110155b156107f95760008281526039602052604090819020805460ff191660011790556034549051636a86319160e01b81526001600160a01b0390911690636a86319190610768908d908d908d908d908d908d908d90600401611590565b600060405180830381600087803b15801561078257600080fd5b505af1158015610796573d6000803e3d6000fd5b5050505081856107a46110a9565b6001600160a01b03167fe21e4d3d66ef78424137270e65cfafe938736bb770702ab4fd630383e7820b738d8d8d8d8d8c6040516107e6969594939291906115d6565b60405180910390a4600192505050610800565b6001925050505b979650505050505050565b6040805180820190915260028152613b1960f11b602082015290565b6035818154811061083757600080fd5b6000918252602090912001546001600160a01b0316905081565b603281565b61085e610903565b61087a5760405162461bcd60e51b815260040161036b906118f4565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6108db610903565b6108f75760405162461bcd60e51b815260040161036b906118f4565b610900816110ad565b50565b6033546000906001600160a01b031661091a6110a9565b6001600160a01b031614905090565b603860209081526000928352604080842090915290825290205460ff1681565b606060358054806020026020016040519081016040528092919081815260200182805480156109a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610983575b5050505050905090565b600080805b603554811015610a1557600084815260386020526040812060358054919291849081106109d957fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0d576001820191505b6001016109b0565b5092915050565b60376020526000908152604090205460ff1681565b60009081526039602052604090205460ff1690565b60376000610a526110a9565b6001600160a01b0316815260208101919091526040016000205460ff16610a8b5760405162461bcd60e51b815260040161036b90611a21565b610a936110a9565b6001600160a01b03167fbb00e6cbdccbb5b7549e189335249187223d88583604555326aa1d7ccbcad4428989898989898989604051610ad9989796959493929190611a58565b60405180910390a25050505050505050565b610af3610903565b610b0f5760405162461bcd60e51b815260040161036b906118f4565b60355481818111801590610b2257508015155b8015610b2d57508115155b610b495760405162461bcd60e51b815260040161036b906116c8565b6002831015610b6a5760405162461bcd60e51b815260040161036b90611929565b60368390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610b9f90859061166c565b60405180910390a1505050565b835183818111158015610bbe57508015155b8015610bc957508115155b610be55760405162461bcd60e51b815260040161036b906116c8565b600054610100900460ff1680610bfe575060005460ff16155b610c1a5760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610c45576000805460ff1961ff0019909116610100171660011790555b610c4e84610e2f565b603287511115610c705760405162461bcd60e51b815260040161036b90611734565b8651610c839060359060208a01906111ab565b5060005b8751811015610db85760376000898381518110610ca057fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015610cfa575060006001600160a01b0316888281518110610ce657fe5b60200260200101516001600160a01b031614155b610d165760405162461bcd60e51b815260040161036b906117f4565b6001603760008a8481518110610d2857fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550878181518110610d7357fe5b60200260200101516001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a2600101610c87565b5060368690556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610dee90889061166c565b60405180910390a1610dff856110ad565b8015610e11576000805461ff00191690555b50505050505050565b60396020526000908152604090205460ff1681565b600054610100900460ff1680610e48575060005460ff16155b610e645760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610e8f576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610ef0576000805461ff00191690555b5050565b610efc610903565b610f185760405162461bcd60e51b815260040161036b906118f4565b6001600160a01b038116610f3e5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff1615610f775760405162461bcd60e51b815260040161036b9061182b565b603554603211610f995760405162461bcd60e51b815260040161036b906116fd565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b60365481565b6034546001600160a01b031681565b611042610903565b61105e5760405162461bcd60e51b815260040161036b906118f4565b61090081611129565b600087878787878787604051602001611086979695949392919061151e565b604051602081830303815290604052805190602001209050979650505050505050565b3390565b6001600160a01b0381166110d35760405162461bcd60e51b815260040161036b9061186c565b603480546001600160a01b0319166001600160a01b0383161790556040517f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b925517827944979061111e90839061157c565b60405180910390a150565b6001600160a01b03811661114f5760405162461bcd60e51b815260040161036b906119df565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b828054828255906000526020600020908101928215611200579160200282015b8281111561120057825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906111cb565b5061120c929150611210565b5090565b5b8082111561120c5760008155600101611211565b803561058c81611aaf565b60008083601f840112611241578182fd5b50813567ffffffffffffffff811115611258578182fd5b60208301915083602082850101111561127057600080fd5b9250929050565b803563ffffffff8116811461058c57600080fd5b60006020828403121561129c578081fd5b81356112a781611aaf565b9392505050565b600080600080600080600060e0888a0312156112c8578283fd5b87356112d381611aaf565b965060208801356112e381611aaf565b955060408801356112f381611aaf565b9450606088013593506080880135925060a0880135915061131660c08901611277565b905092959891949750929550565b60008060008060808587031215611339578384fd5b843567ffffffffffffffff80821115611350578586fd5b818701915087601f830112611363578586fd5b813560208282111561137157fe5b8082026040518282820101818110868211171561138a57fe5b604052838152828101945085830182870184018d10156113a8578a8bfd5b8a96505b848710156113d1576113bd81611225565b8652600196909601959483019483016113ac565b5098505088013595506113eb925050604087019050611225565b91506113f960608601611225565b905092959194509250565b600060208284031215611415578081fd5b5035919050565b6000806040838503121561142e578182fd5b82359150602083013561144081611aaf565b809150509250929050565b60008060008060008060008060a0898b031215611466578081fd5b8835975060208901359650604089013567ffffffffffffffff8082111561148b578283fd5b6114978c838d01611230565b909850965060608b01359150808211156114af578283fd5b6114bb8c838d01611230565b909650945060808b01359150808211156114d3578283fd5b506114e08b828c01611230565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b606097881b6bffffffffffffffffffffffff19908116825296881b871660148201529490961b9094166028840152603c830191909152605c820152607c81019190915260e09190911b6001600160e01b031916609c82015260a00190565b6001600160a01b0391909116815260200190565b6001600160a01b03978816815295871660208701529390951660408501526060840191909152608083015260a082019290925263ffffffff90911660c082015260e00190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925263ffffffff90911660a082015260c00190565b6020808252825182820181905260009190848201906040850190845b818110156116555783516001600160a01b031683529284019291840191600101611630565b50909695505050505050565b901515815260200190565b90815260200190565b6000602080835283518082850152825b818110156116a157858101830151858201604001528201611685565b818111156116b25783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f46656465726174696f6e3a20496e76616c696420726571756972656d656e7473604082015260600190565b6020808252601f908201527f46656465726174696f6e3a204d6178206d656d62657273207265616368656400604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20546f6f206d616e79206d656d6265727300000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746040820152607360f81b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252601b908201527f46656465726174696f6e3a20496e76616c6964206d656d626572730000000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746040820152607360f81b606082015260800190565b60208082526018908201527f46656465726174696f6e3a20456d707479206272696467650000000000000000604082015260600190565b60208082526031908201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604082015270207265717569726564206d656d6265727360781b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f46656465726174696f6e3a205265717569726573206174206c65617374203200604082015260600190565b60208082526018908201527f46656465726174696f6e3a20456d707479206d656d6265720000000000000000604082015260600190565b60208082526028908201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604082015267206d656d6265727360c01b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526019908201527f46656465726174696f6e3a204e6f7420466564657261746f7200000000000000604082015260600190565b600089825288602083015260a06040830152611a7860a08301888a6114f4565b8281036060840152611a8b8187896114f4565b90508281036080840152611aa08185876114f4565b9b9a5050505050505050505050565b6001600160a01b038116811461090057600080fdfea2646970667358221220128a4b4f51a83044e466d0c301c3119ae839536443710de99b33113388de820464736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15785,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15788,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15828,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16072,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 5414,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "bridge",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_contract(IBridge)7398"
+ },
+ {
+ "astId": 5417,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "members",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 5419,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "required",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 5423,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "isMember",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 5429,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "votes",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_mapping(t_bytes32,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 5433,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "processed",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IBridge)7398": {
+ "encoding": "inplace",
+ "label": "contract IBridge",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/MultiSigWallet.json b/bridge/deployments/rsktestnetbsc/MultiSigWallet.json
new file mode 100644
index 000000000..0cba5232a
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/MultiSigWallet.json
@@ -0,0 +1,843 @@
+{
+ "address": "0x88f6b2bc66f4c31a3669b9b1359524abf79cfc4a",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_owners",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Confirmation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposit",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Execution",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "ExecutionFailure",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnerAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnerRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Revocation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Submission",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_OWNER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "addOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "confirmTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "confirmations",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "executeTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getConfirmationCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "count",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getConfirmations",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "_confirmations",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getOwners",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "pending",
+ "type": "bool"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "count",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "from",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "to",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "pending",
+ "type": "bool"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "name": "getTransactionIds",
+ "outputs": [
+ {
+ "internalType": "uint256[]",
+ "name": "_transactionIds",
+ "type": "uint256[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "isConfirmed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "owners",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "removeOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "replaceOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "revokeConfirmation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "destination",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "submitTransaction",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "transactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "transactions",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "destination",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x3220b2ff54a523efde76537b235936e6dd8382bf5482db2c8433f6bdd558e172",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x6fd64b716Ef38Cbcdc966bfF1517F5B34CaA43F1",
+ "transactionIndex": 0,
+ "gasUsed": "2019878",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x879ccf214b2f36d116c885abe787bd0b2590a85bb773539465443a9750bf9284",
+ "transactionHash": "0x3220b2ff54a523efde76537b235936e6dd8382bf5482db2c8433f6bdd558e172",
+ "logs": [],
+ "blockNumber": 2152170,
+ "cumulativeGasUsed": "2019878",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ [
+ "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8"
+ ],
+ 1
+ ],
+ "solcInputHash": "3b83f9cb61a99eec06a616e65f41d75c",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_owners\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Confirmation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Execution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"ExecutionFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnerAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnerRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Revocation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Submission\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_OWNER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"addOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"confirmTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"confirmations\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"executeTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"getConfirmationCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"getConfirmations\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_confirmations\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pending\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"from\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"to\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"pending\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"name\":\"getTransactionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_transactionIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"isConfirmed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"owners\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"removeOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"replaceOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"revokeConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"submitTransaction\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"transactions\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"author\":\"Stefan George - \",\"kind\":\"dev\",\"methods\":{\"addOwner(address)\":{\"details\":\"Allows to add a new owner. Transaction has to be sent by wallet.\",\"params\":{\"owner\":\"Address of new owner.\"}},\"changeRequirement(uint256)\":{\"details\":\"Allows to change the number of required confirmations. Transaction has to be sent by wallet.\",\"params\":{\"_required\":\"Number of required confirmations.\"}},\"confirmTransaction(uint256)\":{\"details\":\"Allows an owner to confirm a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"constructor\":{\"details\":\"Contract constructor sets initial owners and required number of confirmations.\",\"params\":{\"_owners\":\"List of initial owners.\",\"_required\":\"Number of required confirmations.\"}},\"executeTransaction(uint256)\":{\"details\":\"Allows anyone to execute a confirmed transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"getConfirmationCount(uint256)\":{\"details\":\"Returns number of confirmations of a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"count\":\"Number of confirmations.\"}},\"getConfirmations(uint256)\":{\"details\":\"Returns array with owner addresses, which confirmed transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"_confirmations\":\"Returns array of owner addresses.\"}},\"getOwners()\":{\"details\":\"Returns list of owners.\",\"returns\":{\"_0\":\"List of owner addresses.\"}},\"getTransactionCount(bool,bool)\":{\"details\":\"Returns total number of transactions after filers are applied.\",\"params\":{\"executed\":\"Include executed transactions.\",\"pending\":\"Include pending transactions.\"},\"returns\":{\"count\":\"Total number of transactions after filters are applied.\"}},\"getTransactionIds(uint256,uint256,bool,bool)\":{\"details\":\"Returns list of transaction IDs in defined range.\",\"params\":{\"executed\":\"Include executed transactions.\",\"from\":\"Index start position of transaction array.\",\"pending\":\"Include pending transactions.\",\"to\":\"Index end position of transaction array.\"},\"returns\":{\"_transactionIds\":\"Returns array of transaction IDs.\"}},\"isConfirmed(uint256)\":{\"details\":\"Returns the confirmation status of a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"_0\":\"Confirmation status.\"}},\"removeOwner(address)\":{\"details\":\"Allows to remove an owner. Transaction has to be sent by wallet.\",\"params\":{\"owner\":\"Address of owner.\"}},\"replaceOwner(address,address)\":{\"details\":\"Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\",\"params\":{\"newOwner\":\"Address of new owner.\",\"owner\":\"Address of owner to be replaced.\"}},\"revokeConfirmation(uint256)\":{\"details\":\"Allows an owner to revoke a confirmation for a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"submitTransaction(address,uint256,bytes)\":{\"details\":\"Allows an owner to submit and confirm a transaction.\",\"params\":{\"data\":\"Transaction data payload.\",\"destination\":\"Transaction target address.\",\"value\":\"Transaction ether value.\"},\"returns\":{\"transactionId\":\"Returns transaction ID.\"}}},\"title\":\"Multisignature wallet - Allows multiple parties to agree on transactions before execution.\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/MultiSigWallet.sol\":\"MultiSigWallet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/MultiSigWallet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.\\n/// @author Stefan George - \\ncontract MultiSigWallet {\\n\\n /*\\n * Events\\n */\\n event Confirmation(address indexed sender, uint indexed transactionId);\\n event Revocation(address indexed sender, uint indexed transactionId);\\n event Submission(uint indexed transactionId);\\n event Execution(uint indexed transactionId);\\n event ExecutionFailure(uint indexed transactionId);\\n event Deposit(address indexed sender, uint value);\\n event OwnerAddition(address indexed owner);\\n event OwnerRemoval(address indexed owner);\\n event RequirementChange(uint required);\\n\\n /*\\n * views\\n */\\n uint constant public MAX_OWNER_COUNT = 50;\\n\\n /*\\n * Storage\\n */\\n mapping (uint => Transaction) public transactions;\\n mapping (uint => mapping (address => bool)) public confirmations;\\n mapping (address => bool) public isOwner;\\n address[] public owners;\\n uint public required;\\n uint public transactionCount;\\n\\n struct Transaction {\\n address destination;\\n uint value;\\n bytes data;\\n bool executed;\\n }\\n\\n /*\\n * Modifiers\\n */\\n modifier onlyWallet() {\\n require(msg.sender == address(this), \\\"Only wallet allowed\\\");\\n _;\\n }\\n\\n modifier ownerDoesNotExist(address owner) {\\n require(!isOwner[owner], \\\"The owner already exists\\\");\\n _;\\n }\\n\\n modifier ownerExists(address owner) {\\n require(isOwner[owner], \\\"The owner does not exist\\\");\\n _;\\n }\\n\\n modifier transactionExists(uint transactionId) {\\n require(transactions[transactionId].destination != address(0), \\\"Transaction does not exist\\\");\\n _;\\n }\\n\\n modifier confirmed(uint transactionId, address owner) {\\n require(confirmations[transactionId][owner], \\\"Transaction is not confirmed by owner\\\");\\n _;\\n }\\n\\n modifier notConfirmed(uint transactionId, address owner) {\\n require(!confirmations[transactionId][owner], \\\"Transaction is already confirmed by owner\\\");\\n _;\\n }\\n\\n modifier notExecuted(uint transactionId) {\\n require(!transactions[transactionId].executed, \\\"Transaction was already executed\\\");\\n _;\\n }\\n\\n modifier notNull(address _address) {\\n require(_address != address(0), \\\"Address cannot be empty\\\");\\n _;\\n }\\n\\n modifier validRequirement(uint ownerCount, uint _required) {\\n // solium-disable-next-line max-len\\n require(ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && _required != 0 && ownerCount != 0, \\\"Required value is invalid for the current owners count\\\");\\n _;\\n }\\n\\n /// @dev Fallback function allows to deposit ether.\\n receive ()\\n external\\n payable\\n {\\n if (msg.value > 0)\\n emit Deposit(msg.sender, msg.value);\\n }\\n\\n /*\\n * Public functions\\n */\\n /// @dev Contract constructor sets initial owners and required number of confirmations.\\n /// @param _owners List of initial owners.\\n /// @param _required Number of required confirmations.\\n constructor(address[] memory _owners, uint _required)\\n validRequirement(_owners.length, _required)\\n {\\n for (uint i = 0; i < _owners.length; i++) {\\n require(!isOwner[_owners[i]] && _owners[i] != address(0), \\\"Owners addresses are invalid\\\");\\n isOwner[_owners[i]] = true;\\n }\\n owners = _owners;\\n required = _required;\\n }\\n\\n /// @dev Allows to add a new owner. Transaction has to be sent by wallet.\\n /// @param owner Address of new owner.\\n function addOwner(address owner)\\n public\\n onlyWallet\\n ownerDoesNotExist(owner)\\n notNull(owner)\\n validRequirement(owners.length + 1, required)\\n {\\n isOwner[owner] = true;\\n owners.push(owner);\\n emit OwnerAddition(owner);\\n }\\n\\n /// @dev Allows to remove an owner. Transaction has to be sent by wallet.\\n /// @param owner Address of owner.\\n function removeOwner(address owner)\\n public\\n onlyWallet\\n ownerExists(owner)\\n {\\n isOwner[owner] = false;\\n for (uint i = 0; i < owners.length - 1; i++)\\n if (owners[i] == owner) {\\n owners[i] = owners[owners.length - 1];\\n break;\\n }\\n owners.pop(); // remove an element from the end of the array.\\n if (required > owners.length)\\n changeRequirement(owners.length);\\n emit OwnerRemoval(owner);\\n }\\n\\n /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\\n /// @param owner Address of owner to be replaced.\\n /// @param newOwner Address of new owner.\\n function replaceOwner(address owner, address newOwner)\\n public\\n onlyWallet\\n ownerExists(owner)\\n ownerDoesNotExist(newOwner)\\n {\\n for (uint i = 0; i < owners.length; i++)\\n if (owners[i] == owner) {\\n owners[i] = newOwner;\\n break;\\n }\\n isOwner[owner] = false;\\n isOwner[newOwner] = true;\\n emit OwnerRemoval(owner);\\n emit OwnerAddition(newOwner);\\n }\\n\\n /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.\\n /// @param _required Number of required confirmations.\\n function changeRequirement(uint _required)\\n public\\n onlyWallet\\n validRequirement(owners.length, _required)\\n {\\n required = _required;\\n emit RequirementChange(_required);\\n }\\n\\n /// @dev Allows an owner to submit and confirm a transaction.\\n /// @param destination Transaction target address.\\n /// @param value Transaction ether value.\\n /// @param data Transaction data payload.\\n /// @return transactionId Returns transaction ID.\\n function submitTransaction(address destination, uint value, bytes memory data)\\n public\\n returns (uint transactionId)\\n {\\n transactionId = addTransaction(destination, value, data);\\n confirmTransaction(transactionId);\\n }\\n\\n /// @dev Allows an owner to confirm a transaction.\\n /// @param transactionId Transaction ID.\\n function confirmTransaction(uint transactionId)\\n public\\n ownerExists(msg.sender)\\n transactionExists(transactionId)\\n notConfirmed(transactionId, msg.sender)\\n {\\n confirmations[transactionId][msg.sender] = true;\\n emit Confirmation(msg.sender, transactionId);\\n executeTransaction(transactionId);\\n }\\n\\n /// @dev Allows an owner to revoke a confirmation for a transaction.\\n /// @param transactionId Transaction ID.\\n function revokeConfirmation(uint transactionId)\\n public\\n ownerExists(msg.sender)\\n confirmed(transactionId, msg.sender)\\n notExecuted(transactionId)\\n {\\n confirmations[transactionId][msg.sender] = false;\\n emit Revocation(msg.sender, transactionId);\\n }\\n\\n /// @dev Allows anyone to execute a confirmed transaction.\\n /// @param transactionId Transaction ID.\\n function executeTransaction(uint transactionId)\\n public\\n ownerExists(msg.sender)\\n confirmed(transactionId, msg.sender)\\n notExecuted(transactionId)\\n {\\n if (isConfirmed(transactionId)) {\\n Transaction storage txn = transactions[transactionId];\\n txn.executed = true;\\n if (external_call(txn.destination, txn.value, txn.data.length, txn.data))\\n emit Execution(transactionId);\\n else {\\n emit ExecutionFailure(transactionId);\\n txn.executed = false;\\n }\\n }\\n }\\n\\n // call has been separated into its own function in order to take advantage\\n // of the Solidity's code generator to produce a loop that copies tx.data into memory.\\n function external_call(address destination, uint value, uint dataLength, bytes memory data) internal returns (bool) {\\n bool result;\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n let x := mload(0x40) // \\\"Allocate\\\" memory for output (0x40 is where \\\"free memory\\\" pointer is stored by convention)\\n let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that\\n result := call(\\n sub(gas(), 34710), // 34710 is the value that solidity is currently emitting\\n // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +\\n // callNewAccountGas (25000, in case the destination address does not exist and needs creating)\\n destination,\\n value,\\n d,\\n dataLength, // Size of the input (in bytes) - this is what fixes the padding problem\\n x,\\n 0 // Output is ignored, therefore the output size is zero\\n )\\n }\\n return result;\\n }\\n\\n /// @dev Returns the confirmation status of a transaction.\\n /// @param transactionId Transaction ID.\\n /// @return Confirmation status.\\n function isConfirmed(uint transactionId)\\n public\\n view\\n returns (bool)\\n {\\n uint count = 0;\\n for (uint i = 0; i < owners.length; i++) {\\n if (confirmations[transactionId][owners[i]])\\n count += 1;\\n if (count == required)\\n return true;\\n }\\n return false;\\n }\\n\\n /*\\n * Internal functions\\n */\\n /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.\\n /// @param destination Transaction target address.\\n /// @param value Transaction ether value.\\n /// @param data Transaction data payload.\\n /// @return transactionId Returns transaction ID.\\n function addTransaction(address destination, uint value, bytes memory data)\\n internal\\n notNull(destination)\\n returns (uint transactionId)\\n {\\n transactionId = transactionCount;\\n transactions[transactionId] = Transaction({\\n destination: destination,\\n value: value,\\n data: data,\\n executed: false\\n });\\n transactionCount += 1;\\n emit Submission(transactionId);\\n }\\n\\n /*\\n * Web3 call functions\\n */\\n /// @dev Returns number of confirmations of a transaction.\\n /// @param transactionId Transaction ID.\\n /// @return count Number of confirmations.\\n function getConfirmationCount(uint transactionId)\\n public\\n view\\n returns (uint count)\\n {\\n for (uint i = 0; i < owners.length; i++) {\\n if (confirmations[transactionId][owners[i]]) {\\n count += 1;\\n }\\n }\\n }\\n\\n /// @dev Returns total number of transactions after filers are applied.\\n /// @param pending Include pending transactions.\\n /// @param executed Include executed transactions.\\n /// @return count Total number of transactions after filters are applied.\\n function getTransactionCount(bool pending, bool executed)\\n public\\n view\\n returns (uint count)\\n {\\n for (uint i = 0; i < transactionCount; i++) {\\n if ( pending && !transactions[i].executed || executed && transactions[i].executed) {\\n count += 1;\\n }\\n }\\n }\\n\\n /// @dev Returns list of owners.\\n /// @return List of owner addresses.\\n function getOwners()\\n public\\n view\\n returns (address[] memory)\\n {\\n return owners;\\n }\\n\\n /// @dev Returns array with owner addresses, which confirmed transaction.\\n /// @param transactionId Transaction ID.\\n /// @return _confirmations Returns array of owner addresses.\\n function getConfirmations(uint transactionId)\\n public\\n view\\n returns (address[] memory _confirmations)\\n {\\n address[] memory confirmationsTemp = new address[](owners.length);\\n uint count = 0;\\n uint i;\\n for (i = 0; i < owners.length; i++)\\n if (confirmations[transactionId][owners[i]]) {\\n confirmationsTemp[count] = owners[i];\\n count += 1;\\n }\\n _confirmations = new address[](count);\\n for (i = 0; i < count; i++)\\n _confirmations[i] = confirmationsTemp[i];\\n }\\n\\n /// @dev Returns list of transaction IDs in defined range.\\n /// @param from Index start position of transaction array.\\n /// @param to Index end position of transaction array.\\n /// @param pending Include pending transactions.\\n /// @param executed Include executed transactions.\\n /// @return _transactionIds Returns array of transaction IDs.\\n function getTransactionIds(uint from, uint to, bool pending, bool executed)\\n public\\n view\\n returns (uint[] memory _transactionIds)\\n {\\n uint[] memory transactionIdsTemp = new uint[](transactionCount);\\n uint count = 0;\\n uint i;\\n for (i = 0; i < transactionCount; i++)\\n if ( pending && !transactions[i].executed || executed && transactions[i].executed)\\n {\\n transactionIdsTemp[count] = i;\\n count += 1;\\n }\\n _transactionIds = new uint[](to - from);\\n for (i = from; i < to; i++)\\n _transactionIds[i - from] = transactionIdsTemp[i];\\n }\\n}\",\"keccak256\":\"0x48128d95302f2405b2ca70996b8f12f7d9c52224aadf3b381139246bf2baa31b\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x60806040523480156200001157600080fd5b5060405162001e5838038062001e58833981016040819052620000349162000231565b81518160328211158015620000495750818111155b80156200005557508015155b80156200006157508115155b620000895760405162461bcd60e51b81526004016200008090620002f7565b60405180910390fd5b60005b8451811015620001705760026000868381518110620000a757fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1615801562000103575060006001600160a01b0316858281518110620000ef57fe5b60200260200101516001600160a01b031614155b620001225760405162461bcd60e51b8152600401620000809062000354565b6001600260008784815181106200013557fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff19169115159190911790556001016200008c565b5083516200018690600390602087019062000193565b505050600455506200038b565b828054828255906000526020600020908101928215620001eb579160200282015b82811115620001eb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620001b4565b50620001f9929150620001fd565b5090565b5b80821115620001f95760008155600101620001fe565b80516001600160a01b03811681146200022c57600080fd5b919050565b6000806040838503121562000244578182fd5b82516001600160401b03808211156200025b578384fd5b818501915085601f8301126200026f578384fd5b81516020828211156200027e57fe5b808202604051828282010181811086821117156200029857fe5b604052838152828101945085830182870184018b1015620002b7578889fd5b8896505b84871015620002e457620002cf8162000214565b865260019690960195948301948301620002bb565b5097909101519698969750505050505050565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f7220746860408201527f652063757272656e74206f776e65727320636f756e7400000000000000000000606082015260800190565b6020808252601c908201527f4f776e657273206164647265737365732061726520696e76616c696400000000604082015260600190565b611abd806200039b6000396000f3fe60806040526004361061012e5760003560e01c8063a0e67e2b116100ab578063c01a8c841161006f578063c01a8c84146103a6578063c6427474146103c6578063d74f8edd146103e6578063dc8452cd146103fb578063e20056e614610410578063ee22610b146104305761017d565b8063a0e67e2b14610302578063a8abe69a14610324578063b5dc40c314610351578063b77bf60014610371578063ba51a6df146103865761017d565b806354741525116100f257806354741525146102455780637065cb4814610272578063784547a7146102925780638b51d13f146102b25780639ace38c2146102d25761017d565b8063025e7c2714610182578063173825d9146101b857806320ea8d86146101d85780632f54bf6e146101f85780633411c81c146102255761017d565b3661017d57341561017b57336001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040516101729190611a7e565b60405180910390a25b005b600080fd5b34801561018e57600080fd5b506101a261019d3660046116ba565b610450565b6040516101af919061173f565b60405180910390f35b3480156101c457600080fd5b5061017b6101d3366004611594565b61047a565b3480156101e457600080fd5b5061017b6101f33660046116ba565b61062e565b34801561020457600080fd5b50610218610213366004611594565b61071d565b6040516101af9190611851565b34801561023157600080fd5b506102186102403660046116d2565b610732565b34801561025157600080fd5b50610265610260366004611691565b610752565b6040516101af9190611a7e565b34801561027e57600080fd5b5061017b61028d366004611594565b6107be565b34801561029e57600080fd5b506102186102ad3660046116ba565b61091e565b3480156102be57600080fd5b506102656102cd3660046116ba565b6109a9565b3480156102de57600080fd5b506102f26102ed3660046116ba565b610a18565b6040516101af9493929190611753565b34801561030e57600080fd5b50610317610ad6565b6040516101af91906117cc565b34801561033057600080fd5b5061034461033f3660046116f4565b610b38565b6040516101af9190611819565b34801561035d57600080fd5b5061031761036c3660046116ba565b610c92565b34801561037d57600080fd5b50610265610e37565b34801561039257600080fd5b5061017b6103a13660046116ba565b610e3d565b3480156103b257600080fd5b5061017b6103c13660046116ba565b610ee5565b3480156103d257600080fd5b506102656103e13660046115e0565b610fe5565b3480156103f257600080fd5b50610265611004565b34801561040757600080fd5b50610265611009565b34801561041c57600080fd5b5061017b61042b3660046115ae565b61100f565b34801561043c57600080fd5b5061017b61044b3660046116ba565b6111c5565b6003818154811061046057600080fd5b6000918252602090912001546001600160a01b0316905081565b3330146104a25760405162461bcd60e51b815260040161049990611977565b60405180910390fd5b6001600160a01b038116600090815260026020526040902054819060ff166104dc5760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b0382166000908152600260205260408120805460ff191690555b600354600019018110156105b057826001600160a01b03166003828154811061052257fe5b6000918252602090912001546001600160a01b031614156105a85760038054600019810190811061054f57fe5b600091825260209091200154600380546001600160a01b03909216918390811061057557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506105b0565b6001016104fd565b5060038054806105bc57fe5b600082815260209020810160001990810180546001600160a01b031916905501905560035460045411156105f6576003546105f690610e3d565b6040516001600160a01b038316907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a25050565b3360008181526002602052604090205460ff1661065d5760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff1661069a5760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156106ce5760405162461bcd60e51b815260040161049990611a49565b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b6005548110156107b75783801561077f575060008181526020819052604090206003015460ff16155b806107a357508280156107a3575060008181526020819052604090206003015460ff165b156107af576001820191505b600101610756565b5092915050565b3330146107dd5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038116600090815260026020526040902054819060ff16156108185760405162461bcd60e51b815260040161049990611a12565b816001600160a01b03811661083f5760405162461bcd60e51b815260040161049990611940565b6003805490506001016004546032821115801561085c5750818111155b801561086757508015155b801561087257508115155b61088e5760405162461bcd60e51b8152600401610499906118a5565b6001600160a01b038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b60035481101561099d576000848152600160205260408120600380549192918490811061094c57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610980576001820191505b600454821415610995576001925050506109a4565b600101610923565b5060009150505b919050565b6000805b600354811015610a1257600083815260016020526040812060038054919291849081106109d657fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0a576001820191505b6001016109ad565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f81018890048802840188019096528583526001600160a01b0390931695909491929190830182828015610ac35780601f10610a9857610100808354040283529160200191610ac3565b820191906000526020600020905b815481529060010190602001808311610aa657829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610b2e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b10575b5050505050905090565b6060600060055467ffffffffffffffff81118015610b5557600080fd5b50604051908082528060200260200182016040528015610b7f578160200160208202803683370190505b5090506000805b600554811015610c0057858015610baf575060008181526020819052604090206003015460ff16155b80610bd35750848015610bd3575060008181526020819052604090206003015460ff165b15610bf85780838381518110610be557fe5b6020026020010181815250506001820191505b600101610b86565b87870367ffffffffffffffff81118015610c1957600080fd5b50604051908082528060200260200182016040528015610c43578160200160208202803683370190505b5093508790505b86811015610c8757828181518110610c5e57fe5b60200260200101518489830381518110610c7457fe5b6020908102919091010152600101610c4a565b505050949350505050565b60035460609060009067ffffffffffffffff81118015610cb157600080fd5b50604051908082528060200260200182016040528015610cdb578160200160208202803683370190505b5090506000805b600354811015610d9e5760008581526001602052604081206003805491929184908110610d0b57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610d965760038181548110610d4557fe5b9060005260206000200160009054906101000a90046001600160a01b0316838381518110610d6f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001820191505b600101610ce2565b8167ffffffffffffffff81118015610db557600080fd5b50604051908082528060200260200182016040528015610ddf578160200160208202803683370190505b509350600090505b81811015610e2f57828181518110610dfb57fe5b6020026020010151848281518110610e0f57fe5b6001600160a01b0390921660209283029190910190910152600101610de7565b505050919050565b60055481565b333014610e5c5760405162461bcd60e51b815260040161049990611977565b6003548160328211801590610e715750818111155b8015610e7c57508015155b8015610e8757508115155b610ea35760405162461bcd60e51b8152600401610499906118a5565b60048390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610ed8908590611a7e565b60405180910390a1505050565b3360008181526002602052604090205460ff16610f145760405162461bcd60e51b8152600401610499906119a4565b60008281526020819052604090205482906001600160a01b0316610f4a5760405162461bcd60e51b8152600401610499906119db565b60008381526001602090815260408083203380855292529091205484919060ff1615610f885760405162461bcd60e51b81526004016104999061185c565b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3610fde856111c5565b5050505050565b6000610ff28484846113b5565b9050610ffd81610ee5565b9392505050565b603281565b60045481565b33301461102e5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038216600090815260026020526040902054829060ff166110685760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b038216600090815260026020526040902054829060ff16156110a35760405162461bcd60e51b815260040161049990611a12565b60005b60035481101561112b57846001600160a01b0316600382815481106110c757fe5b6000918252602090912001546001600160a01b031614156111235783600382815481106110f057fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061112b565b6001016110a6565b506001600160a01b03808516600081815260026020526040808220805460ff1990811690915593871682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a26040516001600160a01b038416907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a250505050565b3360008181526002602052604090205460ff166111f45760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff166112315760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156112655760405162461bcd60e51b815260040161049990611a49565b61126e8561091e565b15610fde576000858152602081815260409182902060038101805460ff19166001908117909155815481830154600280850180548851601f600019978316156101000297909701909116929092049485018790048702820187019097528381529395611340956001600160a01b039093169491939283908301828280156113365780601f1061130b57610100808354040283529160200191611336565b820191906000526020600020905b81548152906001019060200180831161131957829003601f168201915b50505050506114a9565b156113755760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26113ad565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038101805460ff191690555b505050505050565b6000836001600160a01b0381166113de5760405162461bcd60e51b815260040161049990611940565b600554604080516080810182526001600160a01b038881168252602080830189815283850189815260006060860181905287815280845295909520845181546001600160a01b031916941693909317835551600183015592518051949650919390926114519260028501929101906114cc565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b6000806040516020840160008287838a8c6187965a03f198975050505050505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826115025760008555611548565b82601f1061151b57805160ff1916838001178555611548565b82800160010185558215611548579182015b8281111561154857825182559160200191906001019061152d565b50611554929150611558565b5090565b5b808211156115545760008155600101611559565b80356001600160a01b03811681146109a457600080fd5b803580151581146109a457600080fd5b6000602082840312156115a5578081fd5b610ffd8261156d565b600080604083850312156115c0578081fd5b6115c98361156d565b91506115d76020840161156d565b90509250929050565b6000806000606084860312156115f4578081fd5b6115fd8461156d565b92506020808501359250604085013567ffffffffffffffff80821115611621578384fd5b818701915087601f830112611634578384fd5b81358181111561164057fe5b604051601f8201601f191681018501838111828210171561165d57fe5b60405281815283820185018a1015611673578586fd5b81858501868301378585838301015280955050505050509250925092565b600080604083850312156116a3578182fd5b6116ac83611584565b91506115d760208401611584565b6000602082840312156116cb578081fd5b5035919050565b600080604083850312156116e4578182fd5b823591506115d76020840161156d565b60008060008060808587031215611709578081fd5b843593506020850135925061172060408601611584565b915061172e60608601611584565b905092959194509250565b15159052565b6001600160a01b0391909116815260200190565b600060018060a01b038616825260208581840152608060408401528451806080850152825b818110156117945786810183015185820160a001528201611778565b818111156117a5578360a083870101525b50601f01601f1916830160a00191506117c390506060830184611739565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d5783516001600160a01b0316835292840192918401916001016117e8565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d57835183529284019291840191600101611835565b901515815260200190565b60208082526029908201527f5472616e73616374696f6e20697320616c726561647920636f6e6669726d656460408201526810313c9037bbb732b960b91b606082015260800190565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f72207468604082015275194818dd5c9c995b9d081bdddb995c9cc818dbdd5b9d60521b606082015260800190565b60208082526025908201527f5472616e73616374696f6e206973206e6f7420636f6e6669726d65642062792060408201526437bbb732b960d91b606082015260800190565b60208082526017908201527f416464726573732063616e6e6f7420626520656d707479000000000000000000604082015260600190565b60208082526013908201527213db9b1e481dd85b1b195d08185b1b1bddd959606a1b604082015260600190565b60208082526018908201527f546865206f776e657220646f6573206e6f742065786973740000000000000000604082015260600190565b6020808252601a908201527f5472616e73616374696f6e20646f6573206e6f74206578697374000000000000604082015260600190565b60208082526018908201527f546865206f776e657220616c7265616479206578697374730000000000000000604082015260600190565b6020808252818101527f5472616e73616374696f6e2077617320616c7265616479206578656375746564604082015260600190565b9081526020019056fea264697066735822122062c2739111652d12775c1bfdbf576765e75e1ef9880050cc336a31164f199d6c64736f6c63430007060033",
+ "deployedBytecode": "0x60806040526004361061012e5760003560e01c8063a0e67e2b116100ab578063c01a8c841161006f578063c01a8c84146103a6578063c6427474146103c6578063d74f8edd146103e6578063dc8452cd146103fb578063e20056e614610410578063ee22610b146104305761017d565b8063a0e67e2b14610302578063a8abe69a14610324578063b5dc40c314610351578063b77bf60014610371578063ba51a6df146103865761017d565b806354741525116100f257806354741525146102455780637065cb4814610272578063784547a7146102925780638b51d13f146102b25780639ace38c2146102d25761017d565b8063025e7c2714610182578063173825d9146101b857806320ea8d86146101d85780632f54bf6e146101f85780633411c81c146102255761017d565b3661017d57341561017b57336001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040516101729190611a7e565b60405180910390a25b005b600080fd5b34801561018e57600080fd5b506101a261019d3660046116ba565b610450565b6040516101af919061173f565b60405180910390f35b3480156101c457600080fd5b5061017b6101d3366004611594565b61047a565b3480156101e457600080fd5b5061017b6101f33660046116ba565b61062e565b34801561020457600080fd5b50610218610213366004611594565b61071d565b6040516101af9190611851565b34801561023157600080fd5b506102186102403660046116d2565b610732565b34801561025157600080fd5b50610265610260366004611691565b610752565b6040516101af9190611a7e565b34801561027e57600080fd5b5061017b61028d366004611594565b6107be565b34801561029e57600080fd5b506102186102ad3660046116ba565b61091e565b3480156102be57600080fd5b506102656102cd3660046116ba565b6109a9565b3480156102de57600080fd5b506102f26102ed3660046116ba565b610a18565b6040516101af9493929190611753565b34801561030e57600080fd5b50610317610ad6565b6040516101af91906117cc565b34801561033057600080fd5b5061034461033f3660046116f4565b610b38565b6040516101af9190611819565b34801561035d57600080fd5b5061031761036c3660046116ba565b610c92565b34801561037d57600080fd5b50610265610e37565b34801561039257600080fd5b5061017b6103a13660046116ba565b610e3d565b3480156103b257600080fd5b5061017b6103c13660046116ba565b610ee5565b3480156103d257600080fd5b506102656103e13660046115e0565b610fe5565b3480156103f257600080fd5b50610265611004565b34801561040757600080fd5b50610265611009565b34801561041c57600080fd5b5061017b61042b3660046115ae565b61100f565b34801561043c57600080fd5b5061017b61044b3660046116ba565b6111c5565b6003818154811061046057600080fd5b6000918252602090912001546001600160a01b0316905081565b3330146104a25760405162461bcd60e51b815260040161049990611977565b60405180910390fd5b6001600160a01b038116600090815260026020526040902054819060ff166104dc5760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b0382166000908152600260205260408120805460ff191690555b600354600019018110156105b057826001600160a01b03166003828154811061052257fe5b6000918252602090912001546001600160a01b031614156105a85760038054600019810190811061054f57fe5b600091825260209091200154600380546001600160a01b03909216918390811061057557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506105b0565b6001016104fd565b5060038054806105bc57fe5b600082815260209020810160001990810180546001600160a01b031916905501905560035460045411156105f6576003546105f690610e3d565b6040516001600160a01b038316907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a25050565b3360008181526002602052604090205460ff1661065d5760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff1661069a5760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156106ce5760405162461bcd60e51b815260040161049990611a49565b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b6005548110156107b75783801561077f575060008181526020819052604090206003015460ff16155b806107a357508280156107a3575060008181526020819052604090206003015460ff165b156107af576001820191505b600101610756565b5092915050565b3330146107dd5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038116600090815260026020526040902054819060ff16156108185760405162461bcd60e51b815260040161049990611a12565b816001600160a01b03811661083f5760405162461bcd60e51b815260040161049990611940565b6003805490506001016004546032821115801561085c5750818111155b801561086757508015155b801561087257508115155b61088e5760405162461bcd60e51b8152600401610499906118a5565b6001600160a01b038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b60035481101561099d576000848152600160205260408120600380549192918490811061094c57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610980576001820191505b600454821415610995576001925050506109a4565b600101610923565b5060009150505b919050565b6000805b600354811015610a1257600083815260016020526040812060038054919291849081106109d657fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0a576001820191505b6001016109ad565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f81018890048802840188019096528583526001600160a01b0390931695909491929190830182828015610ac35780601f10610a9857610100808354040283529160200191610ac3565b820191906000526020600020905b815481529060010190602001808311610aa657829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610b2e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b10575b5050505050905090565b6060600060055467ffffffffffffffff81118015610b5557600080fd5b50604051908082528060200260200182016040528015610b7f578160200160208202803683370190505b5090506000805b600554811015610c0057858015610baf575060008181526020819052604090206003015460ff16155b80610bd35750848015610bd3575060008181526020819052604090206003015460ff165b15610bf85780838381518110610be557fe5b6020026020010181815250506001820191505b600101610b86565b87870367ffffffffffffffff81118015610c1957600080fd5b50604051908082528060200260200182016040528015610c43578160200160208202803683370190505b5093508790505b86811015610c8757828181518110610c5e57fe5b60200260200101518489830381518110610c7457fe5b6020908102919091010152600101610c4a565b505050949350505050565b60035460609060009067ffffffffffffffff81118015610cb157600080fd5b50604051908082528060200260200182016040528015610cdb578160200160208202803683370190505b5090506000805b600354811015610d9e5760008581526001602052604081206003805491929184908110610d0b57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610d965760038181548110610d4557fe5b9060005260206000200160009054906101000a90046001600160a01b0316838381518110610d6f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001820191505b600101610ce2565b8167ffffffffffffffff81118015610db557600080fd5b50604051908082528060200260200182016040528015610ddf578160200160208202803683370190505b509350600090505b81811015610e2f57828181518110610dfb57fe5b6020026020010151848281518110610e0f57fe5b6001600160a01b0390921660209283029190910190910152600101610de7565b505050919050565b60055481565b333014610e5c5760405162461bcd60e51b815260040161049990611977565b6003548160328211801590610e715750818111155b8015610e7c57508015155b8015610e8757508115155b610ea35760405162461bcd60e51b8152600401610499906118a5565b60048390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610ed8908590611a7e565b60405180910390a1505050565b3360008181526002602052604090205460ff16610f145760405162461bcd60e51b8152600401610499906119a4565b60008281526020819052604090205482906001600160a01b0316610f4a5760405162461bcd60e51b8152600401610499906119db565b60008381526001602090815260408083203380855292529091205484919060ff1615610f885760405162461bcd60e51b81526004016104999061185c565b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3610fde856111c5565b5050505050565b6000610ff28484846113b5565b9050610ffd81610ee5565b9392505050565b603281565b60045481565b33301461102e5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038216600090815260026020526040902054829060ff166110685760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b038216600090815260026020526040902054829060ff16156110a35760405162461bcd60e51b815260040161049990611a12565b60005b60035481101561112b57846001600160a01b0316600382815481106110c757fe5b6000918252602090912001546001600160a01b031614156111235783600382815481106110f057fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061112b565b6001016110a6565b506001600160a01b03808516600081815260026020526040808220805460ff1990811690915593871682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a26040516001600160a01b038416907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a250505050565b3360008181526002602052604090205460ff166111f45760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff166112315760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156112655760405162461bcd60e51b815260040161049990611a49565b61126e8561091e565b15610fde576000858152602081815260409182902060038101805460ff19166001908117909155815481830154600280850180548851601f600019978316156101000297909701909116929092049485018790048702820187019097528381529395611340956001600160a01b039093169491939283908301828280156113365780601f1061130b57610100808354040283529160200191611336565b820191906000526020600020905b81548152906001019060200180831161131957829003601f168201915b50505050506114a9565b156113755760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26113ad565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038101805460ff191690555b505050505050565b6000836001600160a01b0381166113de5760405162461bcd60e51b815260040161049990611940565b600554604080516080810182526001600160a01b038881168252602080830189815283850189815260006060860181905287815280845295909520845181546001600160a01b031916941693909317835551600183015592518051949650919390926114519260028501929101906114cc565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b6000806040516020840160008287838a8c6187965a03f198975050505050505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826115025760008555611548565b82601f1061151b57805160ff1916838001178555611548565b82800160010185558215611548579182015b8281111561154857825182559160200191906001019061152d565b50611554929150611558565b5090565b5b808211156115545760008155600101611559565b80356001600160a01b03811681146109a457600080fd5b803580151581146109a457600080fd5b6000602082840312156115a5578081fd5b610ffd8261156d565b600080604083850312156115c0578081fd5b6115c98361156d565b91506115d76020840161156d565b90509250929050565b6000806000606084860312156115f4578081fd5b6115fd8461156d565b92506020808501359250604085013567ffffffffffffffff80821115611621578384fd5b818701915087601f830112611634578384fd5b81358181111561164057fe5b604051601f8201601f191681018501838111828210171561165d57fe5b60405281815283820185018a1015611673578586fd5b81858501868301378585838301015280955050505050509250925092565b600080604083850312156116a3578182fd5b6116ac83611584565b91506115d760208401611584565b6000602082840312156116cb578081fd5b5035919050565b600080604083850312156116e4578182fd5b823591506115d76020840161156d565b60008060008060808587031215611709578081fd5b843593506020850135925061172060408601611584565b915061172e60608601611584565b905092959194509250565b15159052565b6001600160a01b0391909116815260200190565b600060018060a01b038616825260208581840152608060408401528451806080850152825b818110156117945786810183015185820160a001528201611778565b818111156117a5578360a083870101525b50601f01601f1916830160a00191506117c390506060830184611739565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d5783516001600160a01b0316835292840192918401916001016117e8565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d57835183529284019291840191600101611835565b901515815260200190565b60208082526029908201527f5472616e73616374696f6e20697320616c726561647920636f6e6669726d656460408201526810313c9037bbb732b960b91b606082015260800190565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f72207468604082015275194818dd5c9c995b9d081bdddb995c9cc818dbdd5b9d60521b606082015260800190565b60208082526025908201527f5472616e73616374696f6e206973206e6f7420636f6e6669726d65642062792060408201526437bbb732b960d91b606082015260800190565b60208082526017908201527f416464726573732063616e6e6f7420626520656d707479000000000000000000604082015260600190565b60208082526013908201527213db9b1e481dd85b1b195d08185b1b1bddd959606a1b604082015260600190565b60208082526018908201527f546865206f776e657220646f6573206e6f742065786973740000000000000000604082015260600190565b6020808252601a908201527f5472616e73616374696f6e20646f6573206e6f74206578697374000000000000604082015260600190565b60208082526018908201527f546865206f776e657220616c7265616479206578697374730000000000000000604082015260600190565b6020808252818101527f5472616e73616374696f6e2077617320616c7265616479206578656375746564604082015260600190565b9081526020019056fea264697066735822122062c2739111652d12775c1bfdbf576765e75e1ef9880050cc336a31164f199d6c64736f6c63430007060033",
+ "devdoc": {
+ "author": "Stefan George - ",
+ "kind": "dev",
+ "methods": {
+ "addOwner(address)": {
+ "details": "Allows to add a new owner. Transaction has to be sent by wallet.",
+ "params": {
+ "owner": "Address of new owner."
+ }
+ },
+ "changeRequirement(uint256)": {
+ "details": "Allows to change the number of required confirmations. Transaction has to be sent by wallet.",
+ "params": {
+ "_required": "Number of required confirmations."
+ }
+ },
+ "confirmTransaction(uint256)": {
+ "details": "Allows an owner to confirm a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "constructor": {
+ "details": "Contract constructor sets initial owners and required number of confirmations.",
+ "params": {
+ "_owners": "List of initial owners.",
+ "_required": "Number of required confirmations."
+ }
+ },
+ "executeTransaction(uint256)": {
+ "details": "Allows anyone to execute a confirmed transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "getConfirmationCount(uint256)": {
+ "details": "Returns number of confirmations of a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "count": "Number of confirmations."
+ }
+ },
+ "getConfirmations(uint256)": {
+ "details": "Returns array with owner addresses, which confirmed transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "_confirmations": "Returns array of owner addresses."
+ }
+ },
+ "getOwners()": {
+ "details": "Returns list of owners.",
+ "returns": {
+ "_0": "List of owner addresses."
+ }
+ },
+ "getTransactionCount(bool,bool)": {
+ "details": "Returns total number of transactions after filers are applied.",
+ "params": {
+ "executed": "Include executed transactions.",
+ "pending": "Include pending transactions."
+ },
+ "returns": {
+ "count": "Total number of transactions after filters are applied."
+ }
+ },
+ "getTransactionIds(uint256,uint256,bool,bool)": {
+ "details": "Returns list of transaction IDs in defined range.",
+ "params": {
+ "executed": "Include executed transactions.",
+ "from": "Index start position of transaction array.",
+ "pending": "Include pending transactions.",
+ "to": "Index end position of transaction array."
+ },
+ "returns": {
+ "_transactionIds": "Returns array of transaction IDs."
+ }
+ },
+ "isConfirmed(uint256)": {
+ "details": "Returns the confirmation status of a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "_0": "Confirmation status."
+ }
+ },
+ "removeOwner(address)": {
+ "details": "Allows to remove an owner. Transaction has to be sent by wallet.",
+ "params": {
+ "owner": "Address of owner."
+ }
+ },
+ "replaceOwner(address,address)": {
+ "details": "Allows to replace an owner with a new owner. Transaction has to be sent by wallet.",
+ "params": {
+ "newOwner": "Address of new owner.",
+ "owner": "Address of owner to be replaced."
+ }
+ },
+ "revokeConfirmation(uint256)": {
+ "details": "Allows an owner to revoke a confirmation for a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "submitTransaction(address,uint256,bytes)": {
+ "details": "Allows an owner to submit and confirm a transaction.",
+ "params": {
+ "data": "Transaction data payload.",
+ "destination": "Transaction target address.",
+ "value": "Transaction ether value."
+ },
+ "returns": {
+ "transactionId": "Returns transaction ID."
+ }
+ }
+ },
+ "title": "Multisignature wallet - Allows multiple parties to agree on transactions before execution.",
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 52,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "transactions",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_uint256,t_struct(Transaction)78_storage)"
+ },
+ {
+ "astId": 58,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "confirmations",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_mapping(t_uint256,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 62,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "isOwner",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 65,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "owners",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 67,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "required",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 69,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "transactionCount",
+ "offset": 0,
+ "slot": "5",
+ "type": "t_uint256"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes_storage": {
+ "encoding": "bytes",
+ "label": "bytes",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_uint256,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_mapping(t_uint256,t_struct(Transaction)78_storage)": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => struct MultiSigWallet.Transaction)",
+ "numberOfBytes": "32",
+ "value": "t_struct(Transaction)78_storage"
+ },
+ "t_struct(Transaction)78_storage": {
+ "encoding": "inplace",
+ "label": "struct MultiSigWallet.Transaction",
+ "members": [
+ {
+ "astId": 71,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "destination",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ },
+ {
+ "astId": 73,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "value",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 75,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "data",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_bytes_storage"
+ },
+ {
+ "astId": 77,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "executed",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_bool"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/ProxyAdmin.json b/bridge/deployments/rsktestnetbsc/ProxyAdmin.json
new file mode 100644
index 000000000..fe5dd077d
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/ProxyAdmin.json
@@ -0,0 +1,261 @@
+{
+ "address": "0x8c35e166d2dea7a8a28aaea11ad7933cdae4b0ab",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeProxyAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ }
+ ],
+ "name": "getProxyAdmin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ }
+ ],
+ "name": "getProxyImplementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgrade",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xccb5efec2a755bdacf9df4f51f512e23701a31e89a59c11fc6bb0f6134c34a2d",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x826e131ADF0fFc77308540966d757B466fa72FFd",
+ "transactionIndex": 0,
+ "gasUsed": "601344",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000100000000000000020000020000000000000800000000000000000000000000000000400000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000020000000000000200000000000000000000000000000000000040000000000000000",
+ "blockHash": "0x23d2689ca13007d1c676dd0836055c3198c867cd10fc217c7808e956e6004304",
+ "transactionHash": "0xccb5efec2a755bdacf9df4f51f512e23701a31e89a59c11fc6bb0f6134c34a2d",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152171,
+ "transactionHash": "0xccb5efec2a755bdacf9df4f51f512e23701a31e89a59c11fc6bb0f6134c34a2d",
+ "address": "0x826e131ADF0fFc77308540966d757B466fa72FFd",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x23d2689ca13007d1c676dd0836055c3198c867cd10fc217c7808e956e6004304"
+ }
+ ],
+ "blockNumber": 2152171,
+ "cumulativeGasUsed": "601344",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\",\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"details\":\"Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`.\"},\"getProxyAdmin(address)\":{\"details\":\"Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"getProxyImplementation(address)\":{\"details\":\"Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"details\":\"Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`.\"},\"upgradeAndCall(address,address,bytes)\":{\"details\":\"Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol\":\"ProxyAdmin\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../GSN/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () {\\n _owner = _msgSender();\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x82fe89d36187df48c5e24e6ca1cf0566f4b0c0a3bd8da835ab64100e28d21b62\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0x590a4d952d39a99972cbcb691b472c5d58af9ae8fd142355ad26200affdd2a51\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../../ownership/Ownable.sol\\\";\\nimport \\\"./TransparentUpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\\n */\\ncontract ProxyAdmin is Ownable {\\n\\n /**\\n * @dev Returns the current implementation of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"implementation()\\\")) == 0x5c60da1b\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"5c60da1b\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Returns the current admin of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"admin()\\\")) == 0xf851a440\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"f851a440\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Changes the admin of `proxy` to `newAdmin`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the current admin of `proxy`.\\n */\\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\\n proxy.changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\\n proxy.upgradeTo(implementation);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\\n }\\n}\\n\",\"keccak256\":\"0x808ad1c30093ccfc011509c642615a9bad84d0e1eced5327fe50d3ec145a9899\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x0d5202a38732881d576fe3831605fe2633e1bc9f981ebea9c3a368af027e0b71\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x53b00bc48bd4eac1e100195c494267c0ca082bd91ac3018e2ee6155fbcbbb14f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50610019610066565b600080546001600160a01b0319166001600160a01b03928316178082556040519216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a361006a565b3390565b61079e806100796000396000f3fe6080604052600436106100865760003560e01c80638f32d59b116100595780638f32d59b1461010d5780639623609d1461012f57806399a88ec414610142578063f2fde38b14610162578063f3b7dead1461018257610086565b8063204e1c7a1461008b578063715018a6146100c15780637eff275e146100d85780638da5cb5b146100f8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610503565b6101a2565b6040516100b89190610656565b60405180910390f35b3480156100cd57600080fd5b506100d6610228565b005b3480156100e457600080fd5b506100d66100f3366004610542565b61029f565b34801561010457600080fd5b506100ab610325565b34801561011957600080fd5b50610122610334565b6040516100b891906106cd565b6100d661013d36600461057a565b610358565b34801561014e57600080fd5b506100d661015d366004610542565b6103e3565b34801561016e57600080fd5b506100d661017d366004610503565b610433565b34801561018e57600080fd5b506100ab61019d366004610503565b610463565b6000806000836001600160a01b03166040516101bd90610636565b600060405180830381855afa9150503d80600081146101f8576040519150601f19603f3d011682016040523d82523d6000602084013e6101fd565b606091505b50915091508161020c57600080fd5b808060200190518101906102209190610526565b949350505050565b610230610334565b6102555760405162461bcd60e51b815260040161024c9061071e565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6102a7610334565b6102c35760405162461bcd60e51b815260040161024c9061071e565b6040516308f2839760e41b81526001600160a01b03831690638f283970906102ef908490600401610656565b600060405180830381600087803b15801561030957600080fd5b505af115801561031d573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031690565b600080546001600160a01b031661034961047e565b6001600160a01b031614905090565b610360610334565b61037c5760405162461bcd60e51b815260040161024c9061071e565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906103ac908690869060040161066a565b6000604051808303818588803b1580156103c557600080fd5b505af11580156103d9573d6000803e3d6000fd5b5050505050505050565b6103eb610334565b6104075760405162461bcd60e51b815260040161024c9061071e565b604051631b2ce7f360e11b81526001600160a01b03831690633659cfe6906102ef908490600401610656565b61043b610334565b6104575760405162461bcd60e51b815260040161024c9061071e565b61046081610482565b50565b6000806000836001600160a01b03166040516101bd90610646565b3390565b6001600160a01b0381166104a85760405162461bcd60e51b815260040161024c906106d8565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600060208284031215610514578081fd5b813561051f81610753565b9392505050565b600060208284031215610537578081fd5b815161051f81610753565b60008060408385031215610554578081fd5b823561055f81610753565b9150602083013561056f81610753565b809150509250929050565b60008060006060848603121561058e578081fd5b833561059981610753565b92506020848101356105aa81610753565b9250604085013567ffffffffffffffff808211156105c6578384fd5b818701915087601f8301126105d9578384fd5b8135818111156105e557fe5b604051601f8201601f191681018501838111828210171561060257fe5b60405281815283820185018a1015610618578586fd5b81858501868301378585838301015280955050505050509250925092565b635c60da1b60e01b815260040190565b6303e1469160e61b815260040190565b6001600160a01b0391909116815260200190565b600060018060a01b038416825260206040818401528351806040850152825b818110156106a557858101830151858201606001528201610689565b818111156106b65783606083870101525b50601f01601f191692909201606001949350505050565b901515815260200190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6001600160a01b038116811461046057600080fdfea2646970667358221220142b10fc4fdd881bdff70408546e1b1005f22944adc6b0a0da6becaf7c2b47a164736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106100865760003560e01c80638f32d59b116100595780638f32d59b1461010d5780639623609d1461012f57806399a88ec414610142578063f2fde38b14610162578063f3b7dead1461018257610086565b8063204e1c7a1461008b578063715018a6146100c15780637eff275e146100d85780638da5cb5b146100f8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610503565b6101a2565b6040516100b89190610656565b60405180910390f35b3480156100cd57600080fd5b506100d6610228565b005b3480156100e457600080fd5b506100d66100f3366004610542565b61029f565b34801561010457600080fd5b506100ab610325565b34801561011957600080fd5b50610122610334565b6040516100b891906106cd565b6100d661013d36600461057a565b610358565b34801561014e57600080fd5b506100d661015d366004610542565b6103e3565b34801561016e57600080fd5b506100d661017d366004610503565b610433565b34801561018e57600080fd5b506100ab61019d366004610503565b610463565b6000806000836001600160a01b03166040516101bd90610636565b600060405180830381855afa9150503d80600081146101f8576040519150601f19603f3d011682016040523d82523d6000602084013e6101fd565b606091505b50915091508161020c57600080fd5b808060200190518101906102209190610526565b949350505050565b610230610334565b6102555760405162461bcd60e51b815260040161024c9061071e565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6102a7610334565b6102c35760405162461bcd60e51b815260040161024c9061071e565b6040516308f2839760e41b81526001600160a01b03831690638f283970906102ef908490600401610656565b600060405180830381600087803b15801561030957600080fd5b505af115801561031d573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031690565b600080546001600160a01b031661034961047e565b6001600160a01b031614905090565b610360610334565b61037c5760405162461bcd60e51b815260040161024c9061071e565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906103ac908690869060040161066a565b6000604051808303818588803b1580156103c557600080fd5b505af11580156103d9573d6000803e3d6000fd5b5050505050505050565b6103eb610334565b6104075760405162461bcd60e51b815260040161024c9061071e565b604051631b2ce7f360e11b81526001600160a01b03831690633659cfe6906102ef908490600401610656565b61043b610334565b6104575760405162461bcd60e51b815260040161024c9061071e565b61046081610482565b50565b6000806000836001600160a01b03166040516101bd90610646565b3390565b6001600160a01b0381166104a85760405162461bcd60e51b815260040161024c906106d8565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600060208284031215610514578081fd5b813561051f81610753565b9392505050565b600060208284031215610537578081fd5b815161051f81610753565b60008060408385031215610554578081fd5b823561055f81610753565b9150602083013561056f81610753565b809150509250929050565b60008060006060848603121561058e578081fd5b833561059981610753565b92506020848101356105aa81610753565b9250604085013567ffffffffffffffff808211156105c6578384fd5b818701915087601f8301126105d9578384fd5b8135818111156105e557fe5b604051601f8201601f191681018501838111828210171561060257fe5b60405281815283820185018a1015610618578586fd5b81858501868301378585838301015280955050505050509250925092565b635c60da1b60e01b815260040190565b6303e1469160e61b815260040190565b6001600160a01b0391909116815260200190565b600060018060a01b038416825260206040818401528351806040850152825b818110156106a557858101830151858201606001528201610689565b818111156106b65783606083870101525b50601f01601f191692909201606001949350505050565b901515815260200190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6001600160a01b038116811461046057600080fdfea2646970667358221220142b10fc4fdd881bdff70408546e1b1005f22944adc6b0a0da6becaf7c2b47a164736f6c63430007060033",
+ "devdoc": {
+ "details": "This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.",
+ "kind": "dev",
+ "methods": {
+ "changeProxyAdmin(address,address)": {
+ "details": "Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`."
+ },
+ "getProxyAdmin(address)": {
+ "details": "Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "getProxyImplementation(address)": {
+ "details": "Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "upgrade(address,address)": {
+ "details": "Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "upgradeAndCall(address,address,bytes)": {
+ "details": "Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 10887,
+ "contract": "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol:ProxyAdmin",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/SideNFTTokenFactory.json b/bridge/deployments/rsktestnetbsc/SideNFTTokenFactory.json
new file mode 100644
index 000000000..c476c0670
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/SideNFTTokenFactory.json
@@ -0,0 +1,184 @@
+{
+ "address": "0x94E8f377a6c58C7bEC87DC4EDe1537afEa8A7102",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sideTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "baseURI",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "contractURI",
+ "type": "string"
+ }
+ ],
+ "name": "SideNFTTokenCreated",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "baseURI",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "contractURI",
+ "type": "string"
+ }
+ ],
+ "name": "createSideNFTToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x322c23b758527212845afeb6c31813c7b3b362fbfbfbf58e945738e74b1642b3",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x94E8f377a6c58C7bEC87DC4EDe1537afEa8A7102",
+ "transactionIndex": 0,
+ "gasUsed": "2834639",
+ "logsBloom": "0x00000000000000000000000000000000000000000000200000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000",
+ "blockHash": "0x8c1647b243c763b7149b24296f0c569382fea8f2f70259d37d5b462982b991d7",
+ "transactionHash": "0x322c23b758527212845afeb6c31813c7b3b362fbfbfbf58e945738e74b1642b3",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2155390,
+ "transactionHash": "0x322c23b758527212845afeb6c31813c7b3b362fbfbfbf58e945738e74b1642b3",
+ "address": "0x94E8f377a6c58C7bEC87DC4EDe1537afEa8A7102",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ],
+ "data": "0x000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8",
+ "logIndex": 0,
+ "blockHash": "0x8c1647b243c763b7149b24296f0c569382fea8f2f70259d37d5b462982b991d7"
+ }
+ ],
+ "blockNumber": 2155390,
+ "cumulativeGasUsed": "2834639",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "bd60cbce915f67c6e3ddca09e6c29f99",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sideTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"baseURI\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"contractURI\",\"type\":\"string\"}],\"name\":\"SideNFTTokenCreated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"baseURI\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"contractURI\",\"type\":\"string\"}],\"name\":\"createSideNFTToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/nftbridge/SideNFTTokenFactory.sol\":\"SideNFTTokenFactory\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/nftbridge/ISideNFTToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\ninterface ISideNFTToken {\\n function mint(address account, uint256 tokenId) external;\\n}\",\"keccak256\":\"0x3ce1dc4d6b81fc6aaef960aa3cce9cbebcc7ab7b395829df06aa25cd2a51d889\",\"license\":\"MIT\"},\"contracts/nftbridge/ISideNFTTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\ninterface ISideNFTTokenFactory {\\n\\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\\n string calldata contractURI) external returns(address);\\n\\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\\n}\",\"keccak256\":\"0x13024ccfd1adaba749b05cbd58494909580893ccdc605b8b7aaba9a7692d490a\",\"license\":\"MIT\"},\"contracts/nftbridge/SideNFTToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./ISideNFTToken.sol\\\";\\nimport \\\"../zeppelin/token/ERC721/ERC721.sol\\\";\\nimport \\\"../zeppelin/token/ERC721/ERC721Burnable.sol\\\";\\n\\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\\n address public minter;\\n string private _contractURI;\\n\\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\\n require(_minter != address(0), \\\"SideToken: Empty Minter\\\");\\n minter = _minter;\\n _setBaseURI(_baseURI);\\n _setContractURI(contractURI_);\\n }\\n\\n function _setContractURI(string memory contractURI_) internal {\\n _contractURI = contractURI_;\\n }\\n\\n function contractURI() public view returns (string memory) {\\n return _contractURI;\\n }\\n\\n modifier onlyMinter() {\\n require(_msgSender() == minter, \\\"SideToken: Caller is not the minter\\\");\\n _;\\n }\\n\\n function mint(address account, uint256 tokenId) external onlyMinter override {\\n _mint(account, tokenId);\\n }\\n}\",\"keccak256\":\"0xe2408318ef5c83857f9839bf522b238a22f56a8db8800c5f210b7314f62f5c97\",\"license\":\"MIT\"},\"contracts/nftbridge/SideNFTTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../zeppelin/ownership/Secondary.sol\\\";\\nimport \\\"./ISideNFTTokenFactory.sol\\\";\\nimport \\\"./SideNFTToken.sol\\\";\\n\\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\\n\\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\\n string calldata contractURI) external onlyPrimary override returns(address) {\\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\\n return sideTokenAddress;\\n }\\n}\",\"keccak256\":\"0x6b1ec284a8696ecdf4312352e820202c32a4f1b3fa6e64636bf1fb0b8703ef89\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts may inherit from this and call {_registerInterface} to declare\\n * their support of an interface.\\n */\\nabstract contract ERC165 is IERC165 {\\n /*\\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\\n */\\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\\n\\n /**\\n * @dev Mapping of interface ids to whether or not it's supported.\\n */\\n mapping(bytes4 => bool) private _supportedInterfaces;\\n\\n constructor () {\\n // Derived contracts need only register support for their own interfaces,\\n // we register support for ERC165 itself here\\n _registerInterface(_INTERFACE_ID_ERC165);\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n *\\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return _supportedInterfaces[interfaceId];\\n }\\n\\n /**\\n * @dev Registers the contract as an implementer of the interface defined by\\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\\n * registering its interface id is not required.\\n *\\n * See {IERC165-supportsInterface}.\\n *\\n * Requirements:\\n *\\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\\n */\\n function _registerInterface(bytes4 interfaceId) internal virtual {\\n require(interfaceId != 0xffffffff, \\\"ERC165: invalid interface id\\\");\\n _supportedInterfaces[interfaceId] = true;\\n }\\n}\\n\",\"keccak256\":\"0x234cdf2c3efd5f0dc17d32fe65d33c21674ca17de1e945eb60ac1076d7152d96\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xd2f30fad5b24c4120f96dbac83aacdb7993ee610a9092bc23c44463da292bf8d\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x09ca2716452528a6e69ac9f83f874292a1e547630473f3133038314a2f16029e\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Secondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../GSN/Context.sol\\\";\\n/**\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\n */\\nabstract contract Secondary is Context {\\n address private _primary;\\n\\n /**\\n * @dev Emitted when the primary contract changes.\\n */\\n event PrimaryTransferred(\\n address recipient\\n );\\n\\n /**\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\n */\\n constructor () {\\n _primary = _msgSender();\\n emit PrimaryTransferred(_primary);\\n }\\n\\n /**\\n * @dev Reverts if called from any account other than the primary.\\n */\\n modifier onlyPrimary() {\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\n _;\\n }\\n\\n /**\\n * @return the address of the primary.\\n */\\n function primary() public view returns (address) {\\n return _primary;\\n }\\n\\n /**\\n * @dev Transfers contract to a new primary.\\n * @param recipient The address of new primary.\\n */\\n function transferPrimary(address recipient) public onlyPrimary {\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\n _primary = recipient;\\n emit PrimaryTransferred(_primary);\\n }\\n}\\n\",\"keccak256\":\"0x79b3afb98ca1e12e33c63da57ca460fc217f2110a4fa1c18c67a7d84e048d285\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Metadata.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"../../introspection/ERC165.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/EnumerableSet.sol\\\";\\nimport \\\"../../utils/EnumerableMap.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\n\\n/**\\n * @title ERC721 Non-Fungible Token Standard basic implementation\\n * @dev see https://eips.ethereum.org/EIPS/eip-721\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\\n using SafeMath for uint256;\\n using Address for address;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using EnumerableMap for EnumerableMap.UintToAddressMap;\\n using Strings for uint256;\\n\\n // Equals to `bytes4(keccak256(\\\"onERC721Received(address,address,uint256,bytes)\\\"))`\\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\\n\\n // Mapping from holder address to their (enumerable) set of owned tokens\\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\\n\\n // Enumerable mapping from token ids to their owners\\n EnumerableMap.UintToAddressMap private _tokenOwners;\\n\\n // Mapping from token ID to approved address\\n mapping (uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping (address => mapping (address => bool)) private _operatorApprovals;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Optional mapping for token URIs\\n mapping (uint256 => string) private _tokenURIs;\\n\\n // Base URI\\n string private _baseURI;\\n\\n /*\\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\\n *\\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\\n */\\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\\n\\n /*\\n * bytes4(keccak256('name()')) == 0x06fdde03\\n * bytes4(keccak256('symbol()')) == 0x95d89b41\\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\\n *\\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\\n */\\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\\n\\n /*\\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\\n *\\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\\n */\\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n\\n // register the supported interfaces to conform to ERC721 via ERC165\\n _registerInterface(_INTERFACE_ID_ERC721);\\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: balance query for the zero address\\\");\\n return _holderTokens[owner].length();\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n return _tokenOwners.get(tokenId, \\\"ERC721: owner query for nonexistent token\\\");\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n require(_exists(tokenId), \\\"ERC721Metadata: URI query for nonexistent token\\\");\\n\\n string memory _tokenURI = _tokenURIs[tokenId];\\n string memory base = baseURI();\\n\\n // If there is no base URI, return the token URI.\\n if (bytes(base).length == 0) {\\n return _tokenURI;\\n }\\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\\n if (bytes(_tokenURI).length > 0) {\\n return string(abi.encodePacked(base, _tokenURI));\\n }\\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\\n return string(abi.encodePacked(base, tokenId.toString()));\\n }\\n\\n /**\\n * @dev Returns the base URI set via {_setBaseURI}. This will be\\n * automatically added as a prefix in {tokenURI} to each token's URI, or\\n * to the token ID if no specific URI is set for that token ID.\\n */\\n function baseURI() public view virtual returns (string memory) {\\n return _baseURI;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n return _holderTokens[owner].at(index);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\\n return _tokenOwners.length();\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n (uint256 tokenId, ) = _tokenOwners.at(index);\\n return tokenId;\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not owner nor approved for all\\\"\\n );\\n\\n _approve(to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\n require(_exists(tokenId), \\\"ERC721: approved query for nonexistent token\\\");\\n\\n return _tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n require(operator != _msgSender(), \\\"ERC721: approve to caller\\\");\\n\\n _operatorApprovals[_msgSender()][operator] = approved;\\n emit ApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\n return _operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\n _safeTransfer(from, to, tokenId, _data);\\n }\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\\n *\\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\\n _transfer(from, to, tokenId);\\n require(_checkOnERC721Received(from, to, tokenId, _data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n }\\n\\n /**\\n * @dev Returns whether `tokenId` exists.\\n *\\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\n *\\n * Tokens start existing when they are minted (`_mint`),\\n * and stop existing when they are burned (`_burn`).\\n */\\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\\n return _tokenOwners.contains(tokenId);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n require(_exists(tokenId), \\\"ERC721: operator query for nonexistent token\\\");\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n d*\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\\n _mint(to, tokenId);\\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n }\\n\\n /**\\n * @dev Mints `tokenId` and transfers it to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - `to` cannot be the zero address.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _mint(address to, uint256 tokenId) internal virtual {\\n require(to != address(0), \\\"ERC721: mint to the zero address\\\");\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\n\\n _beforeTokenTransfer(address(0), to, tokenId);\\n\\n _holderTokens[to].add(tokenId);\\n\\n _tokenOwners.set(tokenId, to);\\n\\n emit Transfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId); // internal owner\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n // Clear metadata (if any)\\n if (bytes(_tokenURIs[tokenId]).length != 0) {\\n delete _tokenURIs[tokenId];\\n }\\n\\n _holderTokens[owner].remove(tokenId);\\n\\n _tokenOwners.remove(tokenId);\\n\\n emit Transfer(owner, address(0), tokenId);\\n }\\n\\n /**\\n * @dev Transfers `tokenId` from `from` to `to`.\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer of token that is not own\\\"); // internal owner\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _holderTokens[from].remove(tokenId);\\n _holderTokens[to].add(tokenId);\\n\\n _tokenOwners.set(tokenId, to);\\n\\n emit Transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\\n require(_exists(tokenId), \\\"ERC721Metadata: URI set of nonexistent token\\\");\\n _tokenURIs[tokenId] = _tokenURI;\\n }\\n\\n /**\\n * @dev Internal function to set the base URI for all token IDs. It is\\n * automatically added as a prefix to the value returned in {tokenURI},\\n * or to the token ID if {tokenURI} is empty.\\n */\\n function _setBaseURI(string memory baseURI_) internal virtual {\\n _baseURI = baseURI_;\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param _data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\\n private returns (bool)\\n {\\n if (!to.isContract()) {\\n return true;\\n }\\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\\n IERC721Receiver(to).onERC721Received.selector,\\n _msgSender(),\\n from,\\n tokenId,\\n _data\\n ), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n bytes4 retval = abi.decode(returndata, (bytes4));\\n return (retval == _ERC721_RECEIVED);\\n }\\n\\n function _approve(address to, uint256 tokenId) private {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\\n}\\n\",\"keccak256\":\"0xc097fe06cc7bbb7554dd9742e31354af83dad44e6371f40c3f0c0cd5ffd5078d\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"./ERC721.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721Burnable: caller is not owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"keccak256\":\"0x770787ba19afb0cabcd6787bebba006165509fa6a1b6f4342be5b334e60ed79a\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xb11597841d47f7a773bca63ca323c76f804cb5d944788de0327db5526319dc82\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"./IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x2789dfea2d73182683d637db5729201f6730dae6113030a94c828f8688f38f2f\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"./IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0xc82c7d1d732081d9bd23f1555ebdf8f3bc1738bc42c2bfc4b9aa7564d9fa3573\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\\n */\\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x05604ffcf69e416b8a42728bb0e4fd75170d8fac70bf1a284afeb4752a9bc52f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/EnumerableMap.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Library for managing an enumerable variant of Solidity's\\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\\n * type.\\n *\\n * Maps have the following properties:\\n *\\n * - Entries are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\\n *\\n * // Declare a set state variable\\n * EnumerableMap.UintToAddressMap private myMap;\\n * }\\n * ```\\n *\\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\\n * supported.\\n */\\nlibrary EnumerableMap {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Map type with\\n // bytes32 keys and values.\\n // The Map implementation uses private functions, and user-facing\\n // implementations (such as Uint256ToAddressMap) are just wrappers around\\n // the underlying Map.\\n // This means that we can only create new EnumerableMaps for types that fit\\n // in bytes32.\\n\\n struct MapEntry {\\n bytes32 _key;\\n bytes32 _value;\\n }\\n\\n struct Map {\\n // Storage of map keys and values\\n MapEntry[] _entries;\\n\\n // Position of the entry defined by a key in the `entries` array, plus 1\\n // because index 0 means a key is not in the map.\\n mapping (bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Adds a key-value pair to a map, or updates the value for an existing\\n * key. O(1).\\n *\\n * Returns true if the key was added to the map, that is if it was not\\n * already present.\\n */\\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\\n // We read and store the key's index to prevent multiple reads from the same storage slot\\n uint256 keyIndex = map._indexes[key];\\n\\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\\n map._entries.push(MapEntry({ _key: key, _value: value }));\\n // The entry is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n map._indexes[key] = map._entries.length;\\n return true;\\n } else {\\n map._entries[keyIndex - 1]._value = value;\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a key-value pair from a map. O(1).\\n *\\n * Returns true if the key was removed from the map, that is if it was present.\\n */\\n function _remove(Map storage map, bytes32 key) private returns (bool) {\\n // We read and store the key's index to prevent multiple reads from the same storage slot\\n uint256 keyIndex = map._indexes[key];\\n\\n if (keyIndex != 0) { // Equivalent to contains(map, key)\\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = keyIndex - 1;\\n uint256 lastIndex = map._entries.length - 1;\\n\\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\n MapEntry storage lastEntry = map._entries[lastIndex];\\n\\n // Move the last entry to the index where the entry to delete is\\n map._entries[toDeleteIndex] = lastEntry;\\n // Update the index for the moved entry\\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\\n\\n // Delete the slot where the moved entry was stored\\n map._entries.pop();\\n\\n // Delete the index for the deleted slot\\n delete map._indexes[key];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the key is in the map. O(1).\\n */\\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\\n return map._indexes[key] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of key-value pairs in the map. O(1).\\n */\\n function _length(Map storage map) private view returns (uint256) {\\n return map._entries.length;\\n }\\n\\n /**\\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\\n *\\n * Note that there are no guarantees on the ordering of entries inside the\\n * array, and it may change when more entries are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\\n require(map._entries.length > index, \\\"EnumerableMap: index out of bounds\\\");\\n\\n MapEntry storage entry = map._entries[index];\\n return (entry._key, entry._value);\\n }\\n\\n /**\\n * @dev Tries to returns the value associated with `key`. O(1).\\n * Does not revert if `key` is not in the map.\\n */\\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\\n uint256 keyIndex = map._indexes[key];\\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\\n }\\n\\n /**\\n * @dev Returns the value associated with `key`. O(1).\\n *\\n * Requirements:\\n *\\n * - `key` must be in the map.\\n */\\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\\n uint256 keyIndex = map._indexes[key];\\n require(keyIndex != 0, \\\"EnumerableMap: nonexistent key\\\"); // Equivalent to contains(map, key)\\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\\n }\\n\\n /**\\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {_tryGet}.\\n */\\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\\n uint256 keyIndex = map._indexes[key];\\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\\n }\\n\\n // UintToAddressMap\\n\\n struct UintToAddressMap {\\n Map _inner;\\n }\\n\\n /**\\n * @dev Adds a key-value pair to a map, or updates the value for an existing\\n * key. O(1).\\n *\\n * Returns true if the key was added to the map, that is if it was not\\n * already present.\\n */\\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the key was removed from the map, that is if it was present.\\n */\\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\\n return _remove(map._inner, bytes32(key));\\n }\\n\\n /**\\n * @dev Returns true if the key is in the map. O(1).\\n */\\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\\n return _contains(map._inner, bytes32(key));\\n }\\n\\n /**\\n * @dev Returns the number of elements in the map. O(1).\\n */\\n function length(UintToAddressMap storage map) internal view returns (uint256) {\\n return _length(map._inner);\\n }\\n\\n /**\\n * @dev Returns the element stored at position `index` in the set. O(1).\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\\n (bytes32 key, bytes32 value) = _at(map._inner, index);\\n return (uint256(key), address(uint160(uint256(value))));\\n }\\n\\n /**\\n * @dev Tries to returns the value associated with `key`. O(1).\\n * Does not revert if `key` is not in the map.\\n *\\n * _Available since v3.4._\\n */\\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\\n return (success, address(uint160(uint256(value))));\\n }\\n\\n /**\\n * @dev Returns the value associated with `key`. O(1).\\n *\\n * Requirements:\\n *\\n * - `key` must be in the map.\\n */\\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\\n }\\n\\n /**\\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryGet}.\\n */\\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\\n }\\n}\\n\",\"keccak256\":\"0x2114555153edb5f273008b3d34205f511db9af06b88f752e4c280dd612c4c549\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping (bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x9a2c1eebb65250f0e11882237038600f22a62376f0547db4acc0dfe0a3d8d34f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n uint256 index = digits - 1;\\n temp = value;\\n while (temp != 0) {\\n buffer[index--] = bytes1(uint8(48 + temp % 10));\\n temp /= 10;\\n }\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x08e38e034333372aea8cb1b8846085b7fbab42c6b77a0af464d2c6827827c4f0\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50610019610074565b600080546001600160a01b0319166001600160a01b0392831617908190556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610067921690610078565b60405180910390a161008c565b3390565b6001600160a01b0391909116815260200190565b61286d8061009b6000396000f3fe60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b578063884758661462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002c7565b6200009d565b005b6200007b62000075366004620002f7565b6200016c565b6040516200008a9190620003ed565b60405180910390f35b6200007b6200025c565b6000546001600160a01b0316620000b36200026b565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000512565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc90620004c8565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d99262000161921690620003ed565b60405180910390a150565b600080546001600160a01b0316620001836200026b565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000512565b600089898989620001bc6200025c565b8a8a8a8a604051620001ce906200026f565b620001e29998979695949392919062000401565b604051809103906000f080158015620001ff573d6000803e3d6000fd5b509050806001600160a01b03167f3d0677e9be6c322795ce7407a961a98bb2822f9ed8a66c3c11d2ac9bab6d401a898989898989604051620002479695949392919062000479565b60405180910390a29998505050505050505050565b6000546001600160a01b031690565b3390565b6122d9806200055f83390190565b60008083601f8401126200028f578182fd5b50813567ffffffffffffffff811115620002a7578182fd5b602083019150836020828501011115620002c057600080fd5b9250929050565b600060208284031215620002d9578081fd5b81356001600160a01b0381168114620002f0578182fd5b9392505050565b6000806000806000806000806080898b03121562000313578384fd5b883567ffffffffffffffff808211156200032b578586fd5b620003398c838d016200027d565b909a50985060208b013591508082111562000352578586fd5b620003608c838d016200027d565b909850965060408b013591508082111562000379578586fd5b620003878c838d016200027d565b909650945060608b0135915080821115620003a0578384fd5b50620003af8b828c016200027d565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060a082526200041760a083018b8d620003c3565b82810360208401526200042c818a8c620003c3565b6001600160a01b03891660408501528381036060850152905062000452818789620003c3565b9050828103608084015262000469818587620003c3565b9c9b505050505050505050505050565b6000606082526200048f60608301888a620003c3565b8281036020840152620004a4818789620003c3565b90508281036040840152620004bb818587620003c3565b9998505050505050505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b50604051620022d9380380620022d983398101604081905262000034916200030f565b8484620000486301ffc9a760e01b6200011a565b81516200005d906006906020850190620001c8565b50805162000073906007906020840190620001c8565b50620000866380ac58cd60e01b6200011a565b62000098635b5e139f60e01b6200011a565b620000aa63780e9d6360e01b6200011a565b50506001600160a01b038316620000de5760405162461bcd60e51b8152600401620000d590620003e4565b60405180910390fd5b600a80546001600160a01b0319166001600160a01b03851617905562000104826200019f565b6200010f81620001b8565b50505050506200041b565b6001600160e01b031980821614156200017a576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b8051620001b4906009906020840190620001c8565b5050565b8051620001b490600b9060208401905b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200020057600085556200024b565b82601f106200021b57805160ff19168380011785556200024b565b828001600101855582156200024b579182015b828111156200024b5782518255916020019190600101906200022e565b50620002599291506200025d565b5090565b5b808211156200025957600081556001016200025e565b600082601f83011262000285578081fd5b81516001600160401b03808211156200029a57fe5b6040516020601f8401601f1916820181018381118382101715620002ba57fe5b6040528382528584018101871015620002d1578485fd5b8492505b83831015620002f45785830181015182840182015291820191620002d5565b838311156200030557848185840101525b5095945050505050565b600080600080600060a0868803121562000327578081fd5b85516001600160401b03808211156200033e578283fd5b6200034c89838a0162000274565b9650602088015191508082111562000362578283fd5b6200037089838a0162000274565b604089015190965091506001600160a01b03821682146200038f578283fd5b606088015191945080821115620003a4578283fd5b620003b289838a0162000274565b93506080880151915080821115620003c8578283fd5b50620003d78882890162000274565b9150509295509295909350565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b611eae806200042b6000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806342966c68116100b857806395d89b411161007c57806395d89b411461026c578063a22cb46514610274578063b88d4fde14610287578063c87b56dd1461029a578063e8a3d485146102ad578063e985e9c5146102b557610137565b806342966c68146102185780634f6ccce71461022b5780636352211e1461023e5780636c0360eb1461025157806370a082311461025957610137565b806318160ddd116100ff57806318160ddd146101b757806323b872dd146101cc5780632f745c59146101df57806340c10f19146101f257806342842e0e1461020557610137565b806301ffc9a71461013c57806306fdde0314610165578063075461721461017a578063081812fc1461018f578063095ea7b3146101a2575b600080fd5b61014f61014a366004611ac4565b6102c8565b60405161015c9190611b34565b60405180910390f35b61016d6102eb565b60405161015c9190611b3f565b610182610381565b60405161015c9190611b20565b61018261019d366004611aec565b610390565b6101b56101b0366004611a9b565b6103f2565b005b6101bf6104c8565b60405161015c9190611bec565b6101b56101da366004611966565b6104d9565b6101bf6101ed366004611a9b565b610530565b6101b5610200366004611a9b565b61055b565b6101b5610213366004611966565b6105ac565b6101b5610226366004611aec565b6105c7565b6101bf610239366004611aec565b610619565b61018261024c366004611aec565b61062f565b61016d610657565b6101bf61026736600461191a565b6106b8565b61016d610720565b6101b5610282366004611a61565b610781565b6101b56102953660046119a1565b610886565b61016d6102a8366004611aec565b6108e4565b61016d610b65565b61014f6102c3366004611934565b610bc6565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b820191906000526020600020905b81548152906001019060200180831161035a57829003601f168201915b5050505050905090565b600a546001600160a01b031681565b600061039b82610bf4565b6103d65760405162461bcd60e51b815260040180806020018281038252602c815260200180611d73602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006103fd8261062f565b9050806001600160a01b0316836001600160a01b031614156104505760405162461bcd60e51b8152600401808060200182810382526021815260200180611df76021913960400191505060405180910390fd5b806001600160a01b0316610462610c01565b6001600160a01b0316148061047e575061047e816102c3610c01565b6104b95760405162461bcd60e51b8152600401808060200182810382526038815260200180611cc66038913960400191505060405180910390fd5b6104c38383610c05565b505050565b60006104d46002610c73565b905090565b6104ea6104e4610c01565b82610c7e565b6105255760405162461bcd60e51b8152600401808060200182810382526031815260200180611e186031913960400191505060405180910390fd5b6104c3838383610d22565b6001600160a01b03821660009081526001602052604081206105529083610e6e565b90505b92915050565b600a546001600160a01b031661056f610c01565b6001600160a01b03161461059e5760405162461bcd60e51b815260040161059590611b72565b60405180910390fd5b6105a88282610e7a565b5050565b6104c383838360405180602001604052806000815250610886565b6105d26104e4610c01565b61060d5760405162461bcd60e51b8152600401808060200182810382526030815260200180611e496030913960400191505060405180910390fd5b61061681610fa8565b50565b600080610627600284611075565b509392505050565b600061055582604051806060016040528060298152602001611d286029913960029190611091565b60098054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b60006001600160a01b0382166106ff5760405162461bcd60e51b815260040180806020018281038252602a815260200180611cfe602a913960400191505060405180910390fd5b6001600160a01b038216600090815260016020526040902061055590610c73565b60078054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b610789610c01565b6001600160a01b0316826001600160a01b031614156107ef576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b80600560006107fc610c01565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610840610c01565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b610897610891610c01565b83610c7e565b6108d25760405162461bcd60e51b8152600401808060200182810382526031815260200180611e186031913960400191505060405180910390fd5b6108de848484846110a8565b50505050565b60606108ef82610bf4565b61092a5760405162461bcd60e51b815260040180806020018281038252602f815260200180611dc8602f913960400191505060405180910390fd5b60008281526008602090815260408083208054825160026001831615610100026000190190921691909104601f8101859004850282018501909352828152929091908301828280156109bd5780601f10610992576101008083540402835291602001916109bd565b820191906000526020600020905b8154815290600101906020018083116109a057829003601f168201915b5050505050905060006109ce610657565b90508051600014156109e2575090506102e6565b815115610aa35780826040516020018083805190602001908083835b60208310610a1d5780518252601f1990920191602091820191016109fe565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610a655780518252601f199092019160209182019101610a46565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052925050506102e6565b80610aad856110fa565b6040516020018083805190602001908083835b60208310610adf5780518252601f199092019160209182019101610ac0565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610b275780518252601f199092019160209182019101610b08565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b600b8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006105556002836111d5565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610c3a8261062f565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610555826111e1565b6000610c8982610bf4565b610cc45760405162461bcd60e51b815260040180806020018281038252602c815260200180611c9a602c913960400191505060405180910390fd5b6000610ccf8361062f565b9050806001600160a01b0316846001600160a01b03161480610d0a5750836001600160a01b0316610cff84610390565b6001600160a01b0316145b80610d1a5750610d1a8185610bc6565b949350505050565b826001600160a01b0316610d358261062f565b6001600160a01b031614610d7a5760405162461bcd60e51b8152600401808060200182810382526029815260200180611d9f6029913960400191505060405180910390fd5b6001600160a01b038216610dbf5760405162461bcd60e51b8152600401808060200182810382526024815260200180611c766024913960400191505060405180910390fd5b610dca8383836104c3565b610dd5600082610c05565b6001600160a01b0383166000908152600160205260409020610df790826111e5565b506001600160a01b0382166000908152600160205260409020610e1a90826111f1565b50610e27600282846111fd565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006105528383611213565b6001600160a01b038216610ed5576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b610ede81610bf4565b15610f30576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b610f3c600083836104c3565b6001600160a01b0382166000908152600160205260409020610f5e90826111f1565b50610f6b600282846111fd565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000610fb38261062f565b9050610fc1816000846104c3565b610fcc600083610c05565b600082815260086020526040902054600260001961010060018416150201909116041561100a57600082815260086020526040812061100a916118ab565b6001600160a01b038116600090815260016020526040902061102c90836111e5565b50611038600283611277565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60008080806110848686611283565b9097909650945050505050565b600061109e8484846112fe565b90505b9392505050565b6110b3848484610d22565b6110bf848484846113c8565b6108de5760405162461bcd60e51b8152600401808060200182810382526032815260200180611c446032913960400191505060405180910390fd5b60608161111f57506040805180820190915260018152600360fc1b60208201526102e6565b8160005b811561113757600101600a82049150611123565b60008167ffffffffffffffff8111801561115057600080fd5b506040519080825280601f01601f19166020018201604052801561117b576020820181803683370190505b50859350905060001982015b83156111cc57600a840660300160f81b828280600190039350815181106111aa57fe5b60200101906001600160f81b031916908160001a905350600a84049350611187565b50949350505050565b60006105528383611530565b5490565b60006105528383611548565b6000610552838361160e565b600061109e84846001600160a01b038516611658565b815460009082106112555760405162461bcd60e51b8152600401808060200182810382526022815260200180611c226022913960400191505060405180910390fd5b82600001828154811061126457fe5b9060005260206000200154905092915050565b600061055283836116ef565b8154600090819083106112c75760405162461bcd60e51b8152600401808060200182810382526022815260200180611d516022913960400191505060405180910390fd5b60008460000184815481106112d857fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816113995760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561135e578181015183820152602001611346565b50505050905090810190601f16801561138b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508460000160018203815481106113ac57fe5b9060005260206000209060020201600101549150509392505050565b60006113dc846001600160a01b03166117c3565b6113e857506001610d1a565b60006114f6630a85bd0160e11b6113fd610c01565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561146457818101518382015260200161144c565b50505050905090810190601f1680156114915780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001611c44603291396001600160a01b03881691906117c9565b9050600081806020019051602081101561150f57600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60009081526001919091016020526040902054151590565b60008181526001830160205260408120548015611604578354600019808301919081019060009087908390811061157b57fe5b906000526020600020015490508087600001848154811061159857fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806115c857fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610555565b6000915050610555565b600061161a8383611530565b61165057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610555565b506000610555565b6000828152600184016020526040812054806116bd5750506040805180820182528381526020808201848152865460018181018955600089815284812095516002909302909501918255915190820155865486845281880190925292909120556110a1565b828560000160018303815481106116d057fe5b90600052602060002090600202016001018190555060009150506110a1565b60008181526001830160205260408120548015611604578354600019808301919081019060009087908390811061172257fe5b906000526020600020906002020190508087600001848154811061174257fe5b60009182526020808320845460029093020191825560019384015491840191909155835482528983019052604090209084019055865487908061178157fe5b60008281526020808220600260001990940193840201828155600190810183905592909355888152898201909252604082209190915594506105559350505050565b3b151590565b606061109e8484600085856117dd856117c3565b6117f95760405162461bcd60e51b815260040161059590611bb5565b600080866001600160a01b031685876040516118159190611b04565b60006040518083038185875af1925050503d8060008114611852576040519150601f19603f3d011682016040523d82523d6000602084013e611857565b606091505b5091509150611867828286611872565b979650505050505050565b606083156118815750816110a1565b8251156118915782518084602001fd5b8160405162461bcd60e51b81526004016105959190611b3f565b50805460018160011615610100020316600290046000825580601f106118d15750610616565b601f01602090049060005260206000209081019061061691905b808211156118ff57600081556001016118eb565b5090565b80356001600160a01b03811681146102e657600080fd5b60006020828403121561192b578081fd5b61055282611903565b60008060408385031215611946578081fd5b61194f83611903565b915061195d60208401611903565b90509250929050565b60008060006060848603121561197a578081fd5b61198384611903565b925061199160208501611903565b9150604084013590509250925092565b600080600080608085870312156119b6578081fd5b6119bf85611903565b935060206119ce818701611903565b935060408601359250606086013567ffffffffffffffff808211156119f1578384fd5b818801915088601f830112611a04578384fd5b813581811115611a1057fe5b604051601f8201601f1916810185018381118282101715611a2d57fe5b60405281815283820185018b1015611a43578586fd5b81858501868301379081019093019390935250939692955090935050565b60008060408385031215611a73578182fd5b611a7c83611903565b915060208301358015158114611a90578182fd5b809150509250929050565b60008060408385031215611aad578182fd5b611ab683611903565b946020939093013593505050565b600060208284031215611ad5578081fd5b81356001600160e01b0319811681146110a1578182fd5b600060208284031215611afd578081fd5b5035919050565b60008251611b16818460208701611bf5565b9190910192915050565b6001600160a01b0391909116815260200190565b901515815260200190565b6000602082528251806020840152611b5e816040850160208701611bf5565b601f01601f19169190910160400192915050565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b90815260200190565b60005b83811015611c10578181015183820152602001611bf8565b838111156108de575050600091015256fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665644552433732314275726e61626c653a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a26469706673582212205cc2e184e746a3c403edffc7d30edfdb1e10a35427c4ced316319c724b1e56d364736f6c63430007060033a26469706673582212209153560207e02b3e709b81167ca88928d8f5e9b907d5b5330b41e800df19bd7064736f6c63430007060033",
+ "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b578063884758661462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002c7565b6200009d565b005b6200007b62000075366004620002f7565b6200016c565b6040516200008a9190620003ed565b60405180910390f35b6200007b6200025c565b6000546001600160a01b0316620000b36200026b565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000512565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc90620004c8565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d99262000161921690620003ed565b60405180910390a150565b600080546001600160a01b0316620001836200026b565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000512565b600089898989620001bc6200025c565b8a8a8a8a604051620001ce906200026f565b620001e29998979695949392919062000401565b604051809103906000f080158015620001ff573d6000803e3d6000fd5b509050806001600160a01b03167f3d0677e9be6c322795ce7407a961a98bb2822f9ed8a66c3c11d2ac9bab6d401a898989898989604051620002479695949392919062000479565b60405180910390a29998505050505050505050565b6000546001600160a01b031690565b3390565b6122d9806200055f83390190565b60008083601f8401126200028f578182fd5b50813567ffffffffffffffff811115620002a7578182fd5b602083019150836020828501011115620002c057600080fd5b9250929050565b600060208284031215620002d9578081fd5b81356001600160a01b0381168114620002f0578182fd5b9392505050565b6000806000806000806000806080898b03121562000313578384fd5b883567ffffffffffffffff808211156200032b578586fd5b620003398c838d016200027d565b909a50985060208b013591508082111562000352578586fd5b620003608c838d016200027d565b909850965060408b013591508082111562000379578586fd5b620003878c838d016200027d565b909650945060608b0135915080821115620003a0578384fd5b50620003af8b828c016200027d565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060a082526200041760a083018b8d620003c3565b82810360208401526200042c818a8c620003c3565b6001600160a01b03891660408501528381036060850152905062000452818789620003c3565b9050828103608084015262000469818587620003c3565b9c9b505050505050505050505050565b6000606082526200048f60608301888a620003c3565b8281036020840152620004a4818789620003c3565b90508281036040840152620004bb818587620003c3565b9998505050505050505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b50604051620022d9380380620022d983398101604081905262000034916200030f565b8484620000486301ffc9a760e01b6200011a565b81516200005d906006906020850190620001c8565b50805162000073906007906020840190620001c8565b50620000866380ac58cd60e01b6200011a565b62000098635b5e139f60e01b6200011a565b620000aa63780e9d6360e01b6200011a565b50506001600160a01b038316620000de5760405162461bcd60e51b8152600401620000d590620003e4565b60405180910390fd5b600a80546001600160a01b0319166001600160a01b03851617905562000104826200019f565b6200010f81620001b8565b50505050506200041b565b6001600160e01b031980821614156200017a576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b8051620001b4906009906020840190620001c8565b5050565b8051620001b490600b9060208401905b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200020057600085556200024b565b82601f106200021b57805160ff19168380011785556200024b565b828001600101855582156200024b579182015b828111156200024b5782518255916020019190600101906200022e565b50620002599291506200025d565b5090565b5b808211156200025957600081556001016200025e565b600082601f83011262000285578081fd5b81516001600160401b03808211156200029a57fe5b6040516020601f8401601f1916820181018381118382101715620002ba57fe5b6040528382528584018101871015620002d1578485fd5b8492505b83831015620002f45785830181015182840182015291820191620002d5565b838311156200030557848185840101525b5095945050505050565b600080600080600060a0868803121562000327578081fd5b85516001600160401b03808211156200033e578283fd5b6200034c89838a0162000274565b9650602088015191508082111562000362578283fd5b6200037089838a0162000274565b604089015190965091506001600160a01b03821682146200038f578283fd5b606088015191945080821115620003a4578283fd5b620003b289838a0162000274565b93506080880151915080821115620003c8578283fd5b50620003d78882890162000274565b9150509295509295909350565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b611eae806200042b6000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806342966c68116100b857806395d89b411161007c57806395d89b411461026c578063a22cb46514610274578063b88d4fde14610287578063c87b56dd1461029a578063e8a3d485146102ad578063e985e9c5146102b557610137565b806342966c68146102185780634f6ccce71461022b5780636352211e1461023e5780636c0360eb1461025157806370a082311461025957610137565b806318160ddd116100ff57806318160ddd146101b757806323b872dd146101cc5780632f745c59146101df57806340c10f19146101f257806342842e0e1461020557610137565b806301ffc9a71461013c57806306fdde0314610165578063075461721461017a578063081812fc1461018f578063095ea7b3146101a2575b600080fd5b61014f61014a366004611ac4565b6102c8565b60405161015c9190611b34565b60405180910390f35b61016d6102eb565b60405161015c9190611b3f565b610182610381565b60405161015c9190611b20565b61018261019d366004611aec565b610390565b6101b56101b0366004611a9b565b6103f2565b005b6101bf6104c8565b60405161015c9190611bec565b6101b56101da366004611966565b6104d9565b6101bf6101ed366004611a9b565b610530565b6101b5610200366004611a9b565b61055b565b6101b5610213366004611966565b6105ac565b6101b5610226366004611aec565b6105c7565b6101bf610239366004611aec565b610619565b61018261024c366004611aec565b61062f565b61016d610657565b6101bf61026736600461191a565b6106b8565b61016d610720565b6101b5610282366004611a61565b610781565b6101b56102953660046119a1565b610886565b61016d6102a8366004611aec565b6108e4565b61016d610b65565b61014f6102c3366004611934565b610bc6565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b820191906000526020600020905b81548152906001019060200180831161035a57829003601f168201915b5050505050905090565b600a546001600160a01b031681565b600061039b82610bf4565b6103d65760405162461bcd60e51b815260040180806020018281038252602c815260200180611d73602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006103fd8261062f565b9050806001600160a01b0316836001600160a01b031614156104505760405162461bcd60e51b8152600401808060200182810382526021815260200180611df76021913960400191505060405180910390fd5b806001600160a01b0316610462610c01565b6001600160a01b0316148061047e575061047e816102c3610c01565b6104b95760405162461bcd60e51b8152600401808060200182810382526038815260200180611cc66038913960400191505060405180910390fd5b6104c38383610c05565b505050565b60006104d46002610c73565b905090565b6104ea6104e4610c01565b82610c7e565b6105255760405162461bcd60e51b8152600401808060200182810382526031815260200180611e186031913960400191505060405180910390fd5b6104c3838383610d22565b6001600160a01b03821660009081526001602052604081206105529083610e6e565b90505b92915050565b600a546001600160a01b031661056f610c01565b6001600160a01b03161461059e5760405162461bcd60e51b815260040161059590611b72565b60405180910390fd5b6105a88282610e7a565b5050565b6104c383838360405180602001604052806000815250610886565b6105d26104e4610c01565b61060d5760405162461bcd60e51b8152600401808060200182810382526030815260200180611e496030913960400191505060405180910390fd5b61061681610fa8565b50565b600080610627600284611075565b509392505050565b600061055582604051806060016040528060298152602001611d286029913960029190611091565b60098054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b60006001600160a01b0382166106ff5760405162461bcd60e51b815260040180806020018281038252602a815260200180611cfe602a913960400191505060405180910390fd5b6001600160a01b038216600090815260016020526040902061055590610c73565b60078054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b610789610c01565b6001600160a01b0316826001600160a01b031614156107ef576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b80600560006107fc610c01565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610840610c01565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b610897610891610c01565b83610c7e565b6108d25760405162461bcd60e51b8152600401808060200182810382526031815260200180611e186031913960400191505060405180910390fd5b6108de848484846110a8565b50505050565b60606108ef82610bf4565b61092a5760405162461bcd60e51b815260040180806020018281038252602f815260200180611dc8602f913960400191505060405180910390fd5b60008281526008602090815260408083208054825160026001831615610100026000190190921691909104601f8101859004850282018501909352828152929091908301828280156109bd5780601f10610992576101008083540402835291602001916109bd565b820191906000526020600020905b8154815290600101906020018083116109a057829003601f168201915b5050505050905060006109ce610657565b90508051600014156109e2575090506102e6565b815115610aa35780826040516020018083805190602001908083835b60208310610a1d5780518252601f1990920191602091820191016109fe565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610a655780518252601f199092019160209182019101610a46565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052925050506102e6565b80610aad856110fa565b6040516020018083805190602001908083835b60208310610adf5780518252601f199092019160209182019101610ac0565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610b275780518252601f199092019160209182019101610b08565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b600b8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006105556002836111d5565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610c3a8261062f565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610555826111e1565b6000610c8982610bf4565b610cc45760405162461bcd60e51b815260040180806020018281038252602c815260200180611c9a602c913960400191505060405180910390fd5b6000610ccf8361062f565b9050806001600160a01b0316846001600160a01b03161480610d0a5750836001600160a01b0316610cff84610390565b6001600160a01b0316145b80610d1a5750610d1a8185610bc6565b949350505050565b826001600160a01b0316610d358261062f565b6001600160a01b031614610d7a5760405162461bcd60e51b8152600401808060200182810382526029815260200180611d9f6029913960400191505060405180910390fd5b6001600160a01b038216610dbf5760405162461bcd60e51b8152600401808060200182810382526024815260200180611c766024913960400191505060405180910390fd5b610dca8383836104c3565b610dd5600082610c05565b6001600160a01b0383166000908152600160205260409020610df790826111e5565b506001600160a01b0382166000908152600160205260409020610e1a90826111f1565b50610e27600282846111fd565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006105528383611213565b6001600160a01b038216610ed5576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b610ede81610bf4565b15610f30576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b610f3c600083836104c3565b6001600160a01b0382166000908152600160205260409020610f5e90826111f1565b50610f6b600282846111fd565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000610fb38261062f565b9050610fc1816000846104c3565b610fcc600083610c05565b600082815260086020526040902054600260001961010060018416150201909116041561100a57600082815260086020526040812061100a916118ab565b6001600160a01b038116600090815260016020526040902061102c90836111e5565b50611038600283611277565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60008080806110848686611283565b9097909650945050505050565b600061109e8484846112fe565b90505b9392505050565b6110b3848484610d22565b6110bf848484846113c8565b6108de5760405162461bcd60e51b8152600401808060200182810382526032815260200180611c446032913960400191505060405180910390fd5b60608161111f57506040805180820190915260018152600360fc1b60208201526102e6565b8160005b811561113757600101600a82049150611123565b60008167ffffffffffffffff8111801561115057600080fd5b506040519080825280601f01601f19166020018201604052801561117b576020820181803683370190505b50859350905060001982015b83156111cc57600a840660300160f81b828280600190039350815181106111aa57fe5b60200101906001600160f81b031916908160001a905350600a84049350611187565b50949350505050565b60006105528383611530565b5490565b60006105528383611548565b6000610552838361160e565b600061109e84846001600160a01b038516611658565b815460009082106112555760405162461bcd60e51b8152600401808060200182810382526022815260200180611c226022913960400191505060405180910390fd5b82600001828154811061126457fe5b9060005260206000200154905092915050565b600061055283836116ef565b8154600090819083106112c75760405162461bcd60e51b8152600401808060200182810382526022815260200180611d516022913960400191505060405180910390fd5b60008460000184815481106112d857fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816113995760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561135e578181015183820152602001611346565b50505050905090810190601f16801561138b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508460000160018203815481106113ac57fe5b9060005260206000209060020201600101549150509392505050565b60006113dc846001600160a01b03166117c3565b6113e857506001610d1a565b60006114f6630a85bd0160e11b6113fd610c01565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561146457818101518382015260200161144c565b50505050905090810190601f1680156114915780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001611c44603291396001600160a01b03881691906117c9565b9050600081806020019051602081101561150f57600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60009081526001919091016020526040902054151590565b60008181526001830160205260408120548015611604578354600019808301919081019060009087908390811061157b57fe5b906000526020600020015490508087600001848154811061159857fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806115c857fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610555565b6000915050610555565b600061161a8383611530565b61165057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610555565b506000610555565b6000828152600184016020526040812054806116bd5750506040805180820182528381526020808201848152865460018181018955600089815284812095516002909302909501918255915190820155865486845281880190925292909120556110a1565b828560000160018303815481106116d057fe5b90600052602060002090600202016001018190555060009150506110a1565b60008181526001830160205260408120548015611604578354600019808301919081019060009087908390811061172257fe5b906000526020600020906002020190508087600001848154811061174257fe5b60009182526020808320845460029093020191825560019384015491840191909155835482528983019052604090209084019055865487908061178157fe5b60008281526020808220600260001990940193840201828155600190810183905592909355888152898201909252604082209190915594506105559350505050565b3b151590565b606061109e8484600085856117dd856117c3565b6117f95760405162461bcd60e51b815260040161059590611bb5565b600080866001600160a01b031685876040516118159190611b04565b60006040518083038185875af1925050503d8060008114611852576040519150601f19603f3d011682016040523d82523d6000602084013e611857565b606091505b5091509150611867828286611872565b979650505050505050565b606083156118815750816110a1565b8251156118915782518084602001fd5b8160405162461bcd60e51b81526004016105959190611b3f565b50805460018160011615610100020316600290046000825580601f106118d15750610616565b601f01602090049060005260206000209081019061061691905b808211156118ff57600081556001016118eb565b5090565b80356001600160a01b03811681146102e657600080fd5b60006020828403121561192b578081fd5b61055282611903565b60008060408385031215611946578081fd5b61194f83611903565b915061195d60208401611903565b90509250929050565b60008060006060848603121561197a578081fd5b61198384611903565b925061199160208501611903565b9150604084013590509250925092565b600080600080608085870312156119b6578081fd5b6119bf85611903565b935060206119ce818701611903565b935060408601359250606086013567ffffffffffffffff808211156119f1578384fd5b818801915088601f830112611a04578384fd5b813581811115611a1057fe5b604051601f8201601f1916810185018381118282101715611a2d57fe5b60405281815283820185018b1015611a43578586fd5b81858501868301379081019093019390935250939692955090935050565b60008060408385031215611a73578182fd5b611a7c83611903565b915060208301358015158114611a90578182fd5b809150509250929050565b60008060408385031215611aad578182fd5b611ab683611903565b946020939093013593505050565b600060208284031215611ad5578081fd5b81356001600160e01b0319811681146110a1578182fd5b600060208284031215611afd578081fd5b5035919050565b60008251611b16818460208701611bf5565b9190910192915050565b6001600160a01b0391909116815260200190565b901515815260200190565b6000602082528251806020840152611b5e816040850160208701611bf5565b601f01601f19169190910160400192915050565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b90815260200190565b60005b83811015611c10578181015183820152602001611bf8565b838111156108de575050600091015256fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665644552433732314275726e61626c653a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a26469706673582212205cc2e184e746a3c403edffc7d30edfdb1e10a35427c4ced316319c724b1e56d364736f6c63430007060033a26469706673582212209153560207e02b3e709b81167ca88928d8f5e9b907d5b5330b41e800df19bd7064736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 11018,
+ "contract": "contracts/nftbridge/SideNFTTokenFactory.sol:SideNFTTokenFactory",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/SideTokenFactory.json b/bridge/deployments/rsktestnetbsc/SideTokenFactory.json
new file mode 100644
index 000000000..b6f7c8871
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/SideTokenFactory.json
@@ -0,0 +1,173 @@
+{
+ "address": "0xbB74098e1F6F95198209bA30BA92725a6CCd5eab",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "SideTokenCreated",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xf071cbcee4df45bf0ae491286231caef0506950be07a1abcbc958b9fd4f2a393",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0xbB74098e1F6F95198209bA30BA92725a6CCd5eab",
+ "transactionIndex": 0,
+ "gasUsed": "3175216",
+ "logsBloom": "0x08000400000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000100000",
+ "blockHash": "0x79b80ecb04e871e6dfecafd5fe3a5df3b027a87a2268ac97a843fcdea8e78280",
+ "transactionHash": "0xf071cbcee4df45bf0ae491286231caef0506950be07a1abcbc958b9fd4f2a393",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152177,
+ "transactionHash": "0xf071cbcee4df45bf0ae491286231caef0506950be07a1abcbc958b9fd4f2a393",
+ "address": "0xbB74098e1F6F95198209bA30BA92725a6CCd5eab",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ],
+ "data": "0x000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8",
+ "logIndex": 0,
+ "blockHash": "0x79b80ecb04e871e6dfecafd5fe3a5df3b027a87a2268ac97a843fcdea8e78280"
+ }
+ ],
+ "blockNumber": 2152177,
+ "cumulativeGasUsed": "3175216",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"granularity\",\"type\":\"uint256\"}],\"name\":\"SideTokenCreated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"granularity\",\"type\":\"uint256\"}],\"name\":\"createSideToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/SideTokenFactory/SideTokenFactory.sol\":\"SideTokenFactory\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/SideToken/SideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../zeppelin/token/ERC777/ERC777.sol\\\";\\nimport \\\"../interface/IERC677Receiver.sol\\\";\\nimport \\\"../interface/ISideToken.sol\\\";\\nimport \\\"../lib/LibEIP712.sol\\\";\\n\\ncontract SideToken is ISideToken, ERC777 {\\n using Address for address;\\n using SafeMath for uint256;\\n\\n address public minter;\\n uint256 private _granularity;\\n\\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\\n bytes32 public domainSeparator;\\n // keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\\n mapping(address => uint) public nonces;\\n\\n // ERC677 Transfer Event\\n event Transfer(address,address,uint256,bytes);\\n\\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\\n require(_minterAddr != address(0), \\\"SideToken: Empty Minter\\\");\\n require(_newGranularity >= 1, \\\"SideToken: Granularity < 1\\\");\\n minter = _minterAddr;\\n _granularity = _newGranularity;\\n\\n uint chainId;\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n chainId := chainid()\\n }\\n domainSeparator = LibEIP712.hashEIP712Domain(\\n name(),\\n \\\"1\\\",\\n chainId,\\n address(this)\\n );\\n }\\n\\n modifier onlyMinter() {\\n require(_msgSender() == minter, \\\"SideToken: Caller is not the minter\\\");\\n _;\\n }\\n\\n function mint(\\n address account,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n )\\n external onlyMinter override\\n {\\n _mint(_msgSender(), account, amount, userData, operatorData);\\n }\\n\\n /**\\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\\n * @param recipient The address to transfer to.\\n * @param amount The amount to be transferred.\\n * @param data The extra data to be passed to the receiving contract.\\n */\\n function transferAndCall(address recipient, uint amount, bytes calldata data)\\n external returns (bool success)\\n {\\n address from = _msgSender();\\n\\n _send(from, from, recipient, amount, data, \\\"\\\", false);\\n emit Transfer(from, recipient, amount, data);\\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\\n return true;\\n }\\n\\n function granularity() public view override returns (uint256) {\\n return _granularity;\\n }\\n\\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\\n require(deadline >= block.timestamp, \\\"SideToken: EXPIRED\\\"); // solhint-disable-line not-rely-on-time\\n bytes32 digest = LibEIP712.hashEIP712Message(\\n domainSeparator,\\n keccak256(\\n abi.encode(\\n PERMIT_TYPEHASH,\\n owner,\\n spender,\\n value,\\n nonces[owner]++,\\n deadline\\n )\\n )\\n );\\n address recoveredAddress = ecrecover(digest, v, r, s);\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"SideToken: INVALID_SIGNATURE\\\");\\n _approve(owner, spender, value);\\n }\\n\\n}\",\"keccak256\":\"0x4f6915fef50725cfde92986c2e2c83c80758b7de6d863d125974c1e1b5c47c82\",\"license\":\"MIT\"},\"contracts/SideTokenFactory/SideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../zeppelin/ownership/Secondary.sol\\\";\\nimport \\\"../interface/ISideTokenFactory.sol\\\";\\nimport \\\"../SideToken/SideToken.sol\\\";\\n\\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\\n\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\\n external onlyPrimary override returns(address) {\\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\\n emit SideTokenCreated(sideToken, symbol, granularity);\\n return sideToken;\\n }\\n}\",\"keccak256\":\"0xd777e928d953e0bc0f31cbcaa50b9e10eb501fd580fe7b32da279833824def44\",\"license\":\"MIT\"},\"contracts/interface/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\\n}\",\"keccak256\":\"0xea0204863235cba5119f6c54b594ea1eefa84e4741ee607ed7ee05f62cb2d9e0\",\"license\":\"MIT\"},\"contracts/interface/ISideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\ninterface ISideToken {\\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\\n}\",\"keccak256\":\"0xf01477bc820f57970d7d8384417ac0aead22bd336077e371c48da917270013b4\",\"license\":\"MIT\"},\"contracts/interface/ISideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\ninterface ISideTokenFactory {\\n\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\\n\\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\\n}\",\"keccak256\":\"0x550c1af5fa52739ac28f58c36f04ba634213c5307ae95b412e41f3ee1d2e7217\",\"license\":\"MIT\"},\"contracts/lib/LibEIP712.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\\nlibrary LibEIP712 {\\n\\n // Hash of the EIP712 Domain Separator Schema\\n // keccak256(abi.encodePacked(\\n // \\\"EIP712Domain(\\\",\\n // \\\"string name,\\\",\\n // \\\"string version,\\\",\\n // \\\"uint256 chainId,\\\",\\n // \\\"address verifyingContract\\\",\\n // \\\")\\\"\\n // ))\\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\\n\\n /// @dev Calculates a EIP712 domain separator.\\n /// @param name The EIP712 domain name.\\n /// @param version The EIP712 domain version.\\n /// @param verifyingContract The EIP712 verifying contract.\\n /// @return result EIP712 domain separator.\\n function hashEIP712Domain(\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract\\n )\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\\n\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\\n // keccak256(bytes(name)),\\n // keccak256(bytes(version)),\\n // chainId,\\n // uint256(verifyingContract)\\n // ))\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Calculate hashes of dynamic data\\n let nameHash := keccak256(add(name, 32), mload(name))\\n let versionHash := keccak256(add(version, 32), mload(version))\\n\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n // Store params in memory\\n mstore(memPtr, schemaHash)\\n mstore(add(memPtr, 32), nameHash)\\n mstore(add(memPtr, 64), versionHash)\\n mstore(add(memPtr, 96), chainId)\\n mstore(add(memPtr, 128), verifyingContract)\\n\\n // Compute hash\\n result := keccak256(memPtr, 160)\\n }\\n return result;\\n }\\n\\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\\n /// with getDomainHash().\\n /// @param hashStruct The EIP712 hash struct.\\n /// @return result EIP712 hash applied to the given EIP712 Domain.\\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n // Assembly for more efficient computing:\\n // keccak256(abi.encodePacked(\\n // EIP191_HEADER,\\n // EIP712_DOMAIN_HASH,\\n // hashStruct\\n // ));\\n\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n // Load free memory pointer\\n let memPtr := mload(64)\\n\\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\\n\\n // Compute hash\\n result := keccak256(memPtr, 66)\\n }\\n return result;\\n }\\n}\",\"keccak256\":\"0x6116e22c413fc65e87bf7db958d5c1f301b493494813f76dce512f8254c3b012\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC1820Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\n * implementers for interfaces in this registry, as well as query support.\\n *\\n * Implementers may be shared by multiple accounts, and can also implement more\\n * than a single interface for each account. Contracts can implement interfaces\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\n * contract.\\n *\\n * {IERC165} interfaces can also be queried via the registry.\\n *\\n * For an in-depth explanation and source code analysis, see the EIP text.\\n */\\ninterface IERC1820Registry {\\n /**\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\n * account is able to set interface implementers for it.\\n *\\n * By default, each account is its own manager. Passing a value of `0x0` in\\n * `newManager` will reset the manager to this initial state.\\n *\\n * Emits a {ManagerChanged} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `account`.\\n */\\n function setManager(address account, address newManager) external;\\n\\n /**\\n * @dev Returns the manager for `account`.\\n *\\n * See {setManager}.\\n */\\n function getManager(address account) external view returns (address);\\n\\n /**\\n * @dev Sets the `implementer` contract as `account`'s implementer for\\n * `interfaceHash`.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n * The zero address can also be used in `implementer` to remove an old one.\\n *\\n * See {interfaceHash} to learn how these are created.\\n *\\n * Emits an {InterfaceImplementerSet} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `_account`.\\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\n * end in 28 zeroes).\\n * - `_implementer` must implement {IERC1820Implementer} and return true when\\n * queried for support, unless `implementer` is the caller. See\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\n */\\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\\n\\n /**\\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\\n * implementer is registered, returns the zero address.\\n *\\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\n * zeroes), `_account` will be queried for support of it.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n */\\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\\n\\n /**\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\n * corresponding\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\n */\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\n\\n /**\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\n * @param account Address of the contract for which to update the cache.\\n * @param interfaceId ERC165 interface for which to update the cache.\\n */\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\n * If the result is not cached a direct lookup on the contract address is performed.\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\n * {updateERC165Cache} with the contract address.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\n\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\n\\n event ManagerChanged(address indexed account, address indexed newManager);\\n}\\n\",\"keccak256\":\"0x1b44f619ae588fd201e93b126b80576e1244ef468e8b4e54e62fbad6a805cc87\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x09ca2716452528a6e69ac9f83f874292a1e547630473f3133038314a2f16029e\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Secondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../GSN/Context.sol\\\";\\n/**\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\n */\\nabstract contract Secondary is Context {\\n address private _primary;\\n\\n /**\\n * @dev Emitted when the primary contract changes.\\n */\\n event PrimaryTransferred(\\n address recipient\\n );\\n\\n /**\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\n */\\n constructor () {\\n _primary = _msgSender();\\n emit PrimaryTransferred(_primary);\\n }\\n\\n /**\\n * @dev Reverts if called from any account other than the primary.\\n */\\n modifier onlyPrimary() {\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\n _;\\n }\\n\\n /**\\n * @return the address of the primary.\\n */\\n function primary() public view returns (address) {\\n return _primary;\\n }\\n\\n /**\\n * @dev Transfers contract to a new primary.\\n * @param recipient The address of new primary.\\n */\\n function transferPrimary(address recipient) public onlyPrimary {\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\n _primary = recipient;\\n emit PrimaryTransferred(_primary);\\n }\\n}\\n\",\"keccak256\":\"0x79b3afb98ca1e12e33c63da57ca460fc217f2110a4fa1c18c67a7d84e048d285\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {ERC20Detailed}.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x1bc9527655c4be58541c2fb90c0a05952938961c289f505c70160f87e08aef33\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/ERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"./IERC777.sol\\\";\\nimport \\\"./IERC777Recipient.sol\\\";\\nimport \\\"./IERC777Sender.sol\\\";\\nimport \\\"../../token/ERC20/IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../introspection/IERC1820Registry.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC777} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n *\\n * Support for ERC20 is included in this contract, as specified by the EIP: both\\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\\n * movements.\\n *\\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\\n * are no special restrictions in the amount of tokens that created, moved, or\\n * destroyed. This makes integration with ERC20 applications seamless.\\n */\\ncontract ERC777 is Context, IERC777, IERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\n\\n mapping(address => uint256) private _balances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\\n // See https://github.com/ethereum/solidity/issues/4024.\\n\\n // keccak256(\\\"ERC777TokensSender\\\")\\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\\n\\n // keccak256(\\\"ERC777TokensRecipient\\\")\\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\\n\\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\\n address[] private _defaultOperatorsArray;\\n\\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\\n mapping(address => bool) private _defaultOperators;\\n\\n // For each account, a mapping of its operators and revoked default operators.\\n mapping(address => mapping(address => bool)) private _operators;\\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\\n\\n // ERC20-allowances\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n /**\\n * @dev `defaultOperators` may be an empty array.\\n */\\n constructor(\\n string memory aName,\\n string memory aSymbol,\\n address[] memory theDefaultOperators\\n ) {\\n _name = aName;\\n _symbol = aSymbol;\\n\\n _defaultOperatorsArray = theDefaultOperators;\\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\\n _defaultOperators[_defaultOperatorsArray[i]] = true;\\n }\\n\\n // register interfaces\\n _erc1820.setInterfaceImplementer(address(this), keccak256(\\\"ERC777Token\\\"), address(this));\\n _erc1820.setInterfaceImplementer(address(this), keccak256(\\\"ERC20Token\\\"), address(this));\\n }\\n\\n /**\\n * @dev See {IERC777-name}.\\n */\\n function name() public view override(IERC777) returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC777-symbol}.\\n */\\n function symbol() public view override(IERC777) returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {ERC20Detailed-decimals}.\\n *\\n * Always returns 18, as per the\\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\\n */\\n function decimals() public pure override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC777-granularity}.\\n *\\n * This implementation always returns `1`.\\n */\\n function granularity() public view virtual override(IERC777) returns (uint256) {\\n return 1;\\n }\\n\\n /**\\n * @dev See {IERC777-totalSupply}.\\n */\\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\\n */\\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\\n return _balances[tokenHolder];\\n }\\n\\n /**\\n * @dev See {IERC777-send}.\\n *\\n * Also emits a {Transfer} event for ERC20 compatibility.\\n */\\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\\n _send(_msgSender(), _msgSender(), recipient, amount, data, \\\"\\\", true);\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\\n * interface if it is a contract.\\n *\\n * Also emits a {Sent} event.\\n */\\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\\n require(recipient != address(0), \\\"ERC777: transfer to zero address\\\");\\n\\n address from = _msgSender();\\n\\n _callTokensToSend(from, from, recipient, amount, \\\"\\\", \\\"\\\");\\n\\n _move(from, from, recipient, amount, \\\"\\\", \\\"\\\");\\n\\n _callTokensReceived(from, from, recipient, amount, \\\"\\\", \\\"\\\", false);\\n\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC777-burn}.\\n *\\n * Also emits a {Transfer} event for ERC20 compatibility.\\n */\\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\\n _burn(_msgSender(), _msgSender(), amount, data, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC777-isOperatorFor}.\\n */\\n function isOperatorFor(\\n address operator,\\n address tokenHolder\\n ) public view override(IERC777) returns (bool) {\\n return operator == tokenHolder ||\\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\\n _operators[tokenHolder][operator];\\n }\\n\\n /**\\n * @dev See {IERC777-authorizeOperator}.\\n */\\n function authorizeOperator(address operator) external override(IERC777) {\\n require(_msgSender() != operator, \\\"ERC777: authorizing self as operator\\\");\\n\\n if (_defaultOperators[operator]) {\\n delete _revokedDefaultOperators[_msgSender()][operator];\\n } else {\\n _operators[_msgSender()][operator] = true;\\n }\\n\\n emit AuthorizedOperator(operator, _msgSender());\\n }\\n\\n /**\\n * @dev See {IERC777-revokeOperator}.\\n */\\n function revokeOperator(address operator) external override(IERC777) {\\n require(operator != _msgSender(), \\\"ERC777: revoking self as operator\\\");\\n\\n if (_defaultOperators[operator]) {\\n _revokedDefaultOperators[_msgSender()][operator] = true;\\n } else {\\n delete _operators[_msgSender()][operator];\\n }\\n\\n emit RevokedOperator(operator, _msgSender());\\n }\\n\\n /**\\n * @dev See {IERC777-defaultOperators}.\\n */\\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\\n return _defaultOperatorsArray;\\n }\\n\\n /**\\n * @dev See {IERC777-operatorSend}.\\n *\\n * Emits {Sent} and {Transfer} events.\\n */\\n function operatorSend(\\n address sender,\\n address recipient,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n )\\n external override(IERC777)\\n {\\n require(isOperatorFor(_msgSender(), sender), \\\"ERC777: caller is not an operator\\\");\\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\\n }\\n\\n /**\\n * @dev See {IERC777-operatorBurn}.\\n *\\n * Emits {Burned} and {Transfer} events.\\n */\\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\\n external override(IERC777) {\\n require(isOperatorFor(_msgSender(), account), \\\"ERC777: caller is not an operator\\\");\\n _burn(_msgSender(), account, amount, data, operatorData);\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n *\\n * Note that operator and allowance concepts are orthogonal: operators may\\n * not have allowance, and accounts with allowance may not be operators\\n * themselves.\\n */\\n function allowance(address holder, address spender)\\n public view override(IERC20) returns (uint256) {\\n return _allowances[holder][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Note that accounts cannot have allowance issued by their operators.\\n */\\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\\n address holder = _msgSender();\\n _approve(holder, spender, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Note that operator and allowance concepts are orthogonal: operators cannot\\n * call `transferFrom` (unless they have allowance), and accounts with\\n * allowance cannot call `operatorSend` (unless they are operators).\\n *\\n * Emits {Sent}, {Transfer} and {Approval} events.\\n */\\n function transferFrom(address holder, address recipient, uint256 amount)\\n external override(IERC20) returns (bool) {\\n require(recipient != address(0), \\\"ERC777: transfer to zero address\\\");\\n require(holder != address(0), \\\"ERC777: transfer from zero address\\\");\\n\\n address spender = _msgSender();\\n\\n _callTokensToSend(spender, holder, recipient, amount, \\\"\\\", \\\"\\\");\\n\\n _move(spender, holder, recipient, amount, \\\"\\\", \\\"\\\");\\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \\\"ERC777: transfer amount exceeds allowance\\\"));\\n\\n _callTokensReceived(spender, holder, recipient, amount, \\\"\\\", \\\"\\\", false);\\n\\n return true;\\n }\\n\\n /**\\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * If a send hook is registered for `account`, the corresponding function\\n * will be called with `operator`, `data` and `operatorData`.\\n *\\n * See {IERC777Sender} and {IERC777Recipient}.\\n *\\n * Emits {Minted} and {Transfer} events.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - if `account` is a contract, it must implement the {IERC777Recipient}\\n * interface.\\n */\\n function _mint(\\n address operator,\\n address account,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData\\n )\\n internal\\n {\\n require(account != address(0), \\\"ERC777: mint to zero address\\\");\\n\\n // Update state variables\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n\\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\\n\\n emit Minted(operator, account, amount, userData, operatorData);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Send tokens\\n * @param operator address operator requesting the transfer\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\\n */\\n function _send(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData,\\n bool requireReceptionAck\\n )\\n internal\\n {\\n require(from != address(0), \\\"ERC777: send from zero address\\\");\\n require(to != address(0), \\\"ERC777: send to zero address\\\");\\n\\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\\n\\n _move(operator, from, to, amount, userData, operatorData);\\n\\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\\n }\\n\\n /**\\n * @dev Burn tokens\\n * @param operator address operator requesting the operation\\n * @param from address token holder address\\n * @param amount uint256 amount of tokens to burn\\n * @param data bytes extra information provided by the token holder\\n * @param operatorData bytes extra information provided by the operator (if any)\\n */\\n function _burn(\\n address operator,\\n address from,\\n uint256 amount,\\n bytes memory data,\\n bytes memory operatorData\\n )\\n internal\\n {\\n require(from != address(0), \\\"ERC777: burn from zero address\\\");\\n\\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\\n\\n // Update state variables\\n _balances[from] = _balances[from].sub(amount, \\\"ERC777: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n\\n emit Burned(operator, from, amount, data, operatorData);\\n emit Transfer(from, address(0), amount);\\n }\\n\\n function _move(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData\\n )\\n internal\\n {\\n _balances[from] = _balances[from].sub(amount, \\\"ERC777: transfer amount exceeds balance\\\");\\n _balances[to] = _balances[to].add(amount);\\n\\n emit Sent(operator, from, to, amount, userData, operatorData);\\n emit Transfer(from, to, amount);\\n }\\n\\n function _approve(address holder, address spender, uint256 value) internal {\\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\\n // currently unnecessary.\\n //require(holder != address(0), \\\"ERC777: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC777: approve to zero address\\\");\\n\\n _allowances[holder][spender] = value;\\n emit Approval(holder, spender, value);\\n }\\n\\n /**\\n * @dev Call from.tokensToSend() if the interface is registered\\n * @param operator address operator requesting the transfer\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n */\\n function _callTokensToSend(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData\\n )\\n internal\\n {\\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\\n if (implementer != address(0)) {\\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\\n }\\n }\\n\\n /**\\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\\n * tokensReceived() was not registered for the recipient\\n * @param operator address operator requesting the transfer\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\\n */\\n function _callTokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData,\\n bool requireReceptionAck\\n )\\n private\\n {\\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\\n if (implementer != address(0)) {\\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\\n } else if (requireReceptionAck) {\\n require(!to.isContract(), \\\"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xcde4544ee18969a20b184e0acccecfa116a5abbfd9c2a1ebd4dcafc7b65cfc86\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777Token standard as defined in the EIP.\\n *\\n * This contract uses the\\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\\n * token holders and recipients react to token movements by using setting implementers\\n * for the associated interfaces in said registry. See `IERC1820Registry` and\\n * `ERC1820Implementer`.\\n */\\ninterface IERC777 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the smallest part of the token that is not divisible. This\\n * means all token operations (creation, movement and destruction) must have\\n * amounts that are a multiple of this number.\\n *\\n * For most token contracts, this value will equal 1.\\n */\\n function granularity() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by an account (`owner`).\\n */\\n function balanceOf(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * If send or receive hooks are registered for the caller and `recipient`,\\n * the corresponding functions will be called with `data` and empty\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function send(address recipient, uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Destroys `amount` tokens from the caller's account, reducing the\\n * total supply.\\n *\\n * If a send hook is registered for the caller, the corresponding function\\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n */\\n function burn(uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Returns true if an account is an operator of `tokenHolder`.\\n * Operators can send and burn tokens on behalf of their owners. All\\n * accounts are their own operator.\\n *\\n * See `operatorSend` and `operatorBurn`.\\n */\\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor`.\\n *\\n * Emits an `AuthorizedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function authorizeOperator(address operator) external;\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See `isOperatorFor` and `defaultOperators`.\\n *\\n * Emits a `RevokedOperator` event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function revokeOperator(address operator) external;\\n\\n /**\\n * @dev Returns the list of default operators. These accounts are operators\\n * for all token holders, even if `authorizeOperator` was never called on\\n * them.\\n *\\n * This list is immutable, but individual holders may revoke these via\\n * `revokeOperator`, in which case `isOperatorFor` will return false.\\n */\\n function defaultOperators() external view returns (address[] memory);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\\n * be an operator of `sender`.\\n *\\n * If send or receive hooks are registered for `sender` and `recipient`,\\n * the corresponding functions will be called with `data` and\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\n *\\n * Emits a `Sent` event.\\n *\\n * Requirements\\n *\\n * - `sender` cannot be the zero address.\\n * - `sender` must have at least `amount` tokens.\\n * - the caller must be an operator for `sender`.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\n * interface.\\n */\\n function operatorSend(\\n address sender,\\n address recipient,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n /**\\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\\n * The caller must be an operator of `account`.\\n *\\n * If a send hook is registered for `account`, the corresponding function\\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\\n *\\n * Emits a `Burned` event.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n * - the caller must be an operator for `account`.\\n */\\n function operatorBurn(\\n address account,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n event Sent(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256 amount,\\n bytes data,\\n bytes operatorData\\n );\\n\\n function decimals() external returns (uint8);\\n\\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\\n\\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\\n\\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\\n\\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\\n}\\n\",\"keccak256\":\"0x9ace3cf83443ae90a995a8e33652238fa2b5afb258897757f85467d5fb437c1a\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\n *\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an `IERC777` token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0xc8dae3544a459d13f23ba0c7737f6e279e06d83ef86b8f7a0318d83bcf4147e3\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Sender.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\\n *\\n * `IERC777` Token holders can be notified of operations performed on their\\n * tokens by having a contract implement this interface (contract holders can be\\n * their own implementer) and registering it on the\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\n *\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\n */\\ninterface IERC777Sender {\\n /**\\n * @dev Called by an `IERC777` token contract whenever a registered holder's\\n * (`from`) tokens are about to be moved or destroyed. The type of operation\\n * is conveyed by `to` being the zero address or not.\\n *\\n * This call occurs _before_ the token contract's state is updated, so\\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensToSend(\\n address operator,\\n address from,\\n address to,\\n uint amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x222036566a212defc97ef08e8f41f08dbc4880c69839f0e8d76f4d4d2406c862\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50610019610074565b600080546001600160a01b0319166001600160a01b0392831617908190556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610067921690610078565b60405180910390a161008c565b3390565b6001600160a01b0391909116815260200190565b612d628061009b6000396000f3fe60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b57806326d9e9631462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002b8565b6200009d565b005b6200007b62000075366004620002e8565b6200016c565b6040516200008a91906200038a565b60405180910390f35b6200007b6200024d565b6000546001600160a01b0316620000b36200025c565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000458565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc906200040e565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992620001619216906200038a565b60405180910390a150565b600080546001600160a01b0316620001836200025c565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000458565b600086868686620001bc6200024d565b87604051620001cb9062000260565b620001dc969594939291906200039e565b604051809103906000f080158015620001f9573d6000803e3d6000fd5b509050806001600160a01b03167ff57d2ded8330a4affd2fa52378069be534fe22288536537d1a1cfc06151845078686866040516200023b93929190620003e8565b60405180910390a29695505050505050565b6000546001600160a01b031690565b3390565b61288880620004a583390190565b60008083601f84011262000280578182fd5b50813567ffffffffffffffff81111562000298578182fd5b602083019150836020828501011115620002b157600080fd5b9250929050565b600060208284031215620002ca578081fd5b81356001600160a01b0381168114620002e1578182fd5b9392505050565b60008060008060006060868803121562000300578081fd5b853567ffffffffffffffff8082111562000318578283fd5b6200032689838a016200026e565b909750955060208801359150808211156200033f578283fd5b506200034e888289016200026e565b96999598509660400135949350505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060808252620003b460808301888a62000360565b8281036020840152620003c981878962000360565b6001600160a01b03959095166040840152505060600152949350505050565b600060408252620003fe60408301858762000360565b9050826020830152949350505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b506040516200288838038062002888833981016040819052620000349162000561565b60408051600081526020808201909252855186928692916200005d9160029190860190620003c2565b50815162000073906003906020850190620003c2565b5080516200008990600490602084019062000457565b5060005b600454811015620000e95760016005600060048481548110620000ac57fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff19169115159190911790556001016200008d565b506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90620001479030907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054908290600401620005f0565b600060405180830381600087803b1580156200016257600080fd5b505af115801562000177573d6000803e3d6000fd5b50506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad2492506329965a1d9150620001d89030907faea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a908290600401620005f0565b600060405180830381600087803b158015620001f357600080fd5b505af115801562000208573d6000803e3d6000fd5b50505050506001600160a01b038416151591506200024590505760405162461bcd60e51b81526004016200023c9062000613565b60405180910390fd5b6001811015620002695760405162461bcd60e51b81526004016200023c906200064a565b600980546001600160a01b0319166001600160a01b038416179055600a81905546620002c562000298620002d4565b604051806040016040528060018152602001603160f81b81525083306200036b60201b62000fa41760201c565b600b5550620006819350505050565b60028054604080516020601f6000196101006001871615020190941685900493840181900481028201810190925282815260609390929091830182828015620003615780601f10620003355761010080835404028352916020019162000361565b820191906000526020600020905b8154815290600101906020018083116200034357829003601f168201915b5050505050905090565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620003fa576000855562000445565b82601f106200041557805160ff191683800117855562000445565b8280016001018555821562000445579182015b828111156200044557825182559160200191906001019062000428565b5062000453929150620004af565b5090565b82805482825590600052602060002090810192821562000445579160200282015b828111156200044557825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000478565b5b80821115620004535760008155600101620004b0565b600082601f830112620004d7578081fd5b81516001600160401b0380821115620004ec57fe5b6040516020601f8401601f19168201810183811183821017156200050c57fe5b604052838252858401810187101562000523578485fd5b8492505b8383101562000546578583018101518284018201529182019162000527565b838311156200055757848185840101525b5095945050505050565b6000806000806080858703121562000577578384fd5b84516001600160401b03808211156200058e578586fd5b6200059c88838901620004c6565b95506020870151915080821115620005b2578485fd5b50620005c187828801620004c6565b604087015190945090506001600160a01b0381168114620005e0578283fd5b6060959095015193969295505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b6020808252601a908201527f53696465546f6b656e3a204772616e756c6172697479203c2031000000000000604082015260600190565b6121f780620006916000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80637ecebe00116100de578063d95b637111610097578063f698da2511610071578063f698da2514610308578063fad8b32a14610310578063fc673c4f14610323578063fe9d93031461033657610173565b8063d95b6371146102cf578063dcdc7dd0146102e2578063dd62ed3e146102f557610173565b80637ecebe0014610268578063959b8c3f1461027b57806395d89b411461028e5780639bd9bbc614610296578063a9059cbb146102a9578063d505accf146102bc57610173565b806330adf81f1161013057806330adf81f14610208578063313ce567146102105780634000aea014610225578063556f0dc71461023857806362ad1b831461024057806370a082311461025557610173565b806306e485381461017857806306fdde031461019657806307546172146101ab578063095ea7b3146101c057806318160ddd146101e057806323b872dd146101f5575b600080fd5b610180610349565b60405161018d9190611c97565b60405180910390f35b61019e6103ab565b60405161018d9190611d4a565b6101b3610435565b60405161018d9190611b9f565b6101d36101ce3660046119d2565b610444565b60405161018d9190611ce4565b6101e8610466565b60405161018d9190611cef565b6101d3610203366004611881565b61046c565b6101e86105b4565b6102186105d8565b60405161018d9190612128565b6101d36102333660046119fd565b6105dd565b6101e86106eb565b61025361024e3660046118c1565b6106f1565b005b6101e8610263366004611811565b6107a8565b6101e8610276366004611811565b6107c3565b610253610289366004611811565b6107d5565b61019e610902565b6102536102a43660046119fd565b610963565b6101d36102b73660046119d2565b6109cb565b6102536102ca36600461195d565b610a85565b6101d36102dd366004611849565b610bd8565b6102536102f0366004611a57565b610c7a565b6101e8610303366004611849565b610d39565b6101e8610d64565b61025361031e366004611811565b610d6a565b610253610331366004611a57565b610e97565b610253610344366004611ae0565b610f41565b606060048054806020026020016040519081016040528092919081815260200182805480156103a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610383575b5050505050905090565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b820191906000526020600020905b81548152906001019060200180831161041757509395945050505050565b6009546001600160a01b031681565b60008061044f610ffb565b905061045c818585610fff565b5060019392505050565b60015490565b60006001600160a01b03831661049d5760405162461bcd60e51b815260040161049490611e50565b60405180910390fd5b6001600160a01b0384166104c35760405162461bcd60e51b815260040161049490612043565b60006104cd610ffb565b90506104fb81868686604051806020016040528060008152506040518060200160405280600081525061108d565b6105278186868660405180602001604052806000815250604051806020016040528060008152506111bb565b61057b858261057686604051806060016040528060298152602001612176602991396001600160a01b03808c166000908152600860209081526040808320938b168352929052205491906112db565b610fff565b6105a98186868660405180602001604052806000815250604051806020016040528060008152506000611307565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601290565b6000806105e8610ffb565b905061063c8182888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060408051602081019091528181529350915061146e9050565b7fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c168187878787604051610673959493929190611c0d565b60405180910390a1604051635260769b60e11b81526001600160a01b0387169063a4c0ed36906106ad908490899089908990600401611c65565b600060405180830381600087803b1580156106c757600080fd5b505af11580156106db573d6000803e3d6000fd5b5060019998505050505050505050565b600a5490565b6107026106fc610ffb565b88610bd8565b61071e5760405162461bcd60e51b815260040161049490612085565b61079f610729610ffb565b88888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a91508990819084018382808284376000920191909152506001925061146e915050565b50505050505050565b6001600160a01b031660009081526020819052604090205490565b600c6020526000908152604090205481565b806001600160a01b03166107e7610ffb565b6001600160a01b0316141561080e5760405162461bcd60e51b815260040161049490611dcb565b6001600160a01b03811660009081526005602052604090205460ff1615610871576007600061083b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690556108b8565b60016006600061087f610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b6108c0610ffb565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b6109c561096e610ffb565b610976610ffb565b868686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604080516020810190915290815292506001915061146e9050565b50505050565b60006001600160a01b0383166109f35760405162461bcd60e51b815260040161049490611e50565b60006109fd610ffb565b9050610a2b81828686604051806020016040528060008152506040518060200160405280600081525061108d565b610a578182868660405180602001604052806000815250604051806020016040528060008152506111bb565b61045c8182868660405180602001604052806000815250604051806020016040528060008152506000611307565b42841015610aa55760405162461bcd60e51b815260040161049490611fa9565b600b546001600160a01b0388166000908152600c6020908152604080832080546001810190915590519293610b27939092610b0c927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928e928e928e9290918e9101611cf8565b604051602081830303815290604052805190602001206114e5565b9050600060018286868660405160008152602001604052604051610b4e9493929190611d2c565b6020604051602081039080840390855afa158015610b70573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610ba65750886001600160a01b0316816001600160a01b0316145b610bc25760405162461bcd60e51b815260040161049490611f2f565b610bcd898989610fff565b505050505050505050565b6000816001600160a01b0316836001600160a01b03161480610c4357506001600160a01b03831660009081526005602052604090205460ff168015610c4357506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b80610c7357506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b6009546001600160a01b0316610c8e610ffb565b6001600160a01b031614610cb45760405162461bcd60e51b815260040161049490611f66565b610d31610cbf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061150492505050565b505050505050565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b600b5481565b610d72610ffb565b6001600160a01b0316816001600160a01b03161415610da35760405162461bcd60e51b815260040161049490611e0f565b6001600160a01b03811660009081526005602052604090205460ff1615610e0f57600160076000610dd2610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055610e4d565b60066000610e1b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b610e55610ffb565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b610ea8610ea2610ffb565b87610bd8565b610ec45760405162461bcd60e51b815260040161049490612085565b610d31610ecf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061162c92505050565b610f9f610f4c610ffb565b610f54610ffb565b8585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805160208101909152908152925061162c915050565b505050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b3390565b6001600160a01b0382166110255760405162461bcd60e51b8152600401610494906120c6565b6001600160a01b0380841660008181526008602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611080908590611cef565b60405180910390a3505050565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906110e99089907f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89590600401611c4c565b60206040518083038186803b15801561110157600080fd5b505afa158015611115573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611139919061182d565b90506001600160a01b0381161561079f57604051633ad5cbc160e11b81526001600160a01b038216906375ab978290611180908a908a908a908a908a908a90600401611bb3565b600060405180830381600087803b15801561119a57600080fd5b505af11580156111ae573d6000803e3d6000fd5b5050505050505050505050565b6111f88360405180606001604052806027815260200161214f602791396001600160a01b03881660009081526020819052604090205491906112db565b6001600160a01b038087166000908152602081905260408082209390935590861681522054611227908461175d565b6001600160a01b0380861660008181526020819052604090819020939093559151878216918916907f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc8261467798790611280908890889088906120fd565b60405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516112cb9190611cef565b60405180910390a3505050505050565b600081848411156112ff5760405162461bcd60e51b81526004016104949190611d4a565b505050900390565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906113639089907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b90600401611c4c565b60206040518083038186803b15801561137b57600080fd5b505afa15801561138f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b3919061182d565b90506001600160a01b0381161561142f576040516223de2960e01b81526001600160a01b038216906223de29906113f8908b908b908b908b908b908b90600401611bb3565b600060405180830381600087803b15801561141257600080fd5b505af1158015611426573d6000803e3d6000fd5b50505050611464565b811561146457611447866001600160a01b0316611782565b156114645760405162461bcd60e51b815260040161049490611ebc565b5050505050505050565b6001600160a01b0386166114945760405162461bcd60e51b815260040161049490611fd5565b6001600160a01b0385166114ba5760405162461bcd60e51b81526004016104949061200c565b6114c887878787878761108d565b6114d68787878787876111bb565b61079f87878787878787611307565b60405161190160f01b8152600281019290925260228201526042902090565b6001600160a01b03841661152a5760405162461bcd60e51b815260040161049490611e85565b600154611537908461175d565b6001556001600160a01b03841660009081526020819052604090205461155d908461175d565b6001600160a01b03851660009081526020819052604081209190915561158a908690868686866001611307565b836001600160a01b0316856001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d8585856040516115d1939291906120fd565b60405180910390a3836001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b60405180910390a35050505050565b6001600160a01b0384166116525760405162461bcd60e51b815260040161049490611d94565b6116618585600086868661108d565b61169e8360405180606001604052806023815260200161219f602391396001600160a01b03871660009081526020819052604090205491906112db565b6001600160a01b0385166000908152602081905260409020556001546116c49084611788565b600181905550836001600160a01b0316856001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098858585604051611711939291906120fd565b60405180910390a360006001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b600082820183811015610c735760405162461bcd60e51b815260040161049490611d5d565b3b151590565b6000610c7383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506112db565b60008083601f8401126117db578182fd5b50813567ffffffffffffffff8111156117f2578182fd5b60208301915083602082850101111561180a57600080fd5b9250929050565b600060208284031215611822578081fd5b8135610c7381612136565b60006020828403121561183e578081fd5b8151610c7381612136565b6000806040838503121561185b578081fd5b823561186681612136565b9150602083013561187681612136565b809150509250929050565b600080600060608486031215611895578081fd5b83356118a081612136565b925060208401356118b081612136565b929592945050506040919091013590565b600080600080600080600060a0888a0312156118db578283fd5b87356118e681612136565b965060208801356118f681612136565b955060408801359450606088013567ffffffffffffffff80821115611919578485fd5b6119258b838c016117ca565b909650945060808a013591508082111561193d578384fd5b5061194a8a828b016117ca565b989b979a50959850939692959293505050565b600080600080600080600060e0888a031215611977578283fd5b873561198281612136565b9650602088013561199281612136565b95506040880135945060608801359350608088013560ff811681146119b5578384fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156119e4578182fd5b82356119ef81612136565b946020939093013593505050565b60008060008060608587031215611a12578384fd5b8435611a1d81612136565b935060208501359250604085013567ffffffffffffffff811115611a3f578283fd5b611a4b878288016117ca565b95989497509550505050565b60008060008060008060808789031215611a6f578182fd5b8635611a7a81612136565b955060208701359450604087013567ffffffffffffffff80821115611a9d578384fd5b611aa98a838b016117ca565b90965094506060890135915080821115611ac1578384fd5b50611ace89828a016117ca565b979a9699509497509295939492505050565b600080600060408486031215611af4578283fd5b83359250602084013567ffffffffffffffff811115611b11578283fd5b611b1d868287016117ca565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b81811015611b7957602081850181015186830182015201611b5d565b81811115611b8a5782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0387811682528681166020830152851660408201526060810184905260c060808201819052600090611bee90830185611b54565b82810360a0840152611c008185611b54565b9998505050505050505050565b6001600160a01b0386811682528516602082015260408101849052608060608201819052600090611c419083018486611b2a565b979650505050505050565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038616825284602083015260606040830152611c8d606083018486611b2a565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611cd85783516001600160a01b031683529284019291840191600101611cb3565b50909695505050505050565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610c736020830184611b54565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f4552433737373a206275726e2066726f6d207a65726f20616464726573730000604082015260600190565b60208082526024908201527f4552433737373a20617574686f72697a696e672073656c66206173206f70657260408201526330ba37b960e11b606082015260800190565b60208082526021908201527f4552433737373a207265766f6b696e672073656c66206173206f70657261746f6040820152603960f91b606082015260800190565b6020808252818101527f4552433737373a207472616e7366657220746f207a65726f2061646472657373604082015260600190565b6020808252601c908201527f4552433737373a206d696e7420746f207a65726f206164647265737300000000604082015260600190565b6020808252604d908201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460408201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60608201526c1ad95b9cd49958da5c1a595b9d609a1b608082015260a00190565b6020808252601c908201527f53696465546f6b656e3a20494e56414c49445f5349474e415455524500000000604082015260600190565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b60208082526012908201527114da5919551bdad95b8e881156141254915160721b604082015260600190565b6020808252601e908201527f4552433737373a2073656e642066726f6d207a65726f20616464726573730000604082015260600190565b6020808252601c908201527f4552433737373a2073656e6420746f207a65726f206164647265737300000000604082015260600190565b60208082526022908201527f4552433737373a207472616e736665722066726f6d207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526021908201527f4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f6040820152603960f91b606082015260800190565b6020808252601f908201527f4552433737373a20617070726f766520746f207a65726f206164647265737300604082015260600190565b6000848252606060208301526121166060830185611b54565b8281036040840152611c8d8185611b54565b60ff91909116815260200190565b6001600160a01b038116811461214b57600080fd5b5056fe4552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a206275726e20616d6f756e7420657863656564732062616c616e6365a2646970667358221220e96305596548c1ccf5a73d7bede36fbfaeee3f672cbf14157179325f27c57bf764736f6c63430007060033a26469706673582212204cc330cf5079dbaee9f34fb1607540a3d5891d5eeb955ff8beaa47811a8c189964736f6c63430007060033",
+ "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b57806326d9e9631462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002b8565b6200009d565b005b6200007b62000075366004620002e8565b6200016c565b6040516200008a91906200038a565b60405180910390f35b6200007b6200024d565b6000546001600160a01b0316620000b36200025c565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000458565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc906200040e565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992620001619216906200038a565b60405180910390a150565b600080546001600160a01b0316620001836200025c565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000458565b600086868686620001bc6200024d565b87604051620001cb9062000260565b620001dc969594939291906200039e565b604051809103906000f080158015620001f9573d6000803e3d6000fd5b509050806001600160a01b03167ff57d2ded8330a4affd2fa52378069be534fe22288536537d1a1cfc06151845078686866040516200023b93929190620003e8565b60405180910390a29695505050505050565b6000546001600160a01b031690565b3390565b61288880620004a583390190565b60008083601f84011262000280578182fd5b50813567ffffffffffffffff81111562000298578182fd5b602083019150836020828501011115620002b157600080fd5b9250929050565b600060208284031215620002ca578081fd5b81356001600160a01b0381168114620002e1578182fd5b9392505050565b60008060008060006060868803121562000300578081fd5b853567ffffffffffffffff8082111562000318578283fd5b6200032689838a016200026e565b909750955060208801359150808211156200033f578283fd5b506200034e888289016200026e565b96999598509660400135949350505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060808252620003b460808301888a62000360565b8281036020840152620003c981878962000360565b6001600160a01b03959095166040840152505060600152949350505050565b600060408252620003fe60408301858762000360565b9050826020830152949350505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b506040516200288838038062002888833981016040819052620000349162000561565b60408051600081526020808201909252855186928692916200005d9160029190860190620003c2565b50815162000073906003906020850190620003c2565b5080516200008990600490602084019062000457565b5060005b600454811015620000e95760016005600060048481548110620000ac57fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff19169115159190911790556001016200008d565b506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90620001479030907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054908290600401620005f0565b600060405180830381600087803b1580156200016257600080fd5b505af115801562000177573d6000803e3d6000fd5b50506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad2492506329965a1d9150620001d89030907faea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a908290600401620005f0565b600060405180830381600087803b158015620001f357600080fd5b505af115801562000208573d6000803e3d6000fd5b50505050506001600160a01b038416151591506200024590505760405162461bcd60e51b81526004016200023c9062000613565b60405180910390fd5b6001811015620002695760405162461bcd60e51b81526004016200023c906200064a565b600980546001600160a01b0319166001600160a01b038416179055600a81905546620002c562000298620002d4565b604051806040016040528060018152602001603160f81b81525083306200036b60201b62000fa41760201c565b600b5550620006819350505050565b60028054604080516020601f6000196101006001871615020190941685900493840181900481028201810190925282815260609390929091830182828015620003615780601f10620003355761010080835404028352916020019162000361565b820191906000526020600020905b8154815290600101906020018083116200034357829003601f168201915b5050505050905090565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620003fa576000855562000445565b82601f106200041557805160ff191683800117855562000445565b8280016001018555821562000445579182015b828111156200044557825182559160200191906001019062000428565b5062000453929150620004af565b5090565b82805482825590600052602060002090810192821562000445579160200282015b828111156200044557825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000478565b5b80821115620004535760008155600101620004b0565b600082601f830112620004d7578081fd5b81516001600160401b0380821115620004ec57fe5b6040516020601f8401601f19168201810183811183821017156200050c57fe5b604052838252858401810187101562000523578485fd5b8492505b8383101562000546578583018101518284018201529182019162000527565b838311156200055757848185840101525b5095945050505050565b6000806000806080858703121562000577578384fd5b84516001600160401b03808211156200058e578586fd5b6200059c88838901620004c6565b95506020870151915080821115620005b2578485fd5b50620005c187828801620004c6565b604087015190945090506001600160a01b0381168114620005e0578283fd5b6060959095015193969295505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b6020808252601a908201527f53696465546f6b656e3a204772616e756c6172697479203c2031000000000000604082015260600190565b6121f780620006916000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80637ecebe00116100de578063d95b637111610097578063f698da2511610071578063f698da2514610308578063fad8b32a14610310578063fc673c4f14610323578063fe9d93031461033657610173565b8063d95b6371146102cf578063dcdc7dd0146102e2578063dd62ed3e146102f557610173565b80637ecebe0014610268578063959b8c3f1461027b57806395d89b411461028e5780639bd9bbc614610296578063a9059cbb146102a9578063d505accf146102bc57610173565b806330adf81f1161013057806330adf81f14610208578063313ce567146102105780634000aea014610225578063556f0dc71461023857806362ad1b831461024057806370a082311461025557610173565b806306e485381461017857806306fdde031461019657806307546172146101ab578063095ea7b3146101c057806318160ddd146101e057806323b872dd146101f5575b600080fd5b610180610349565b60405161018d9190611c97565b60405180910390f35b61019e6103ab565b60405161018d9190611d4a565b6101b3610435565b60405161018d9190611b9f565b6101d36101ce3660046119d2565b610444565b60405161018d9190611ce4565b6101e8610466565b60405161018d9190611cef565b6101d3610203366004611881565b61046c565b6101e86105b4565b6102186105d8565b60405161018d9190612128565b6101d36102333660046119fd565b6105dd565b6101e86106eb565b61025361024e3660046118c1565b6106f1565b005b6101e8610263366004611811565b6107a8565b6101e8610276366004611811565b6107c3565b610253610289366004611811565b6107d5565b61019e610902565b6102536102a43660046119fd565b610963565b6101d36102b73660046119d2565b6109cb565b6102536102ca36600461195d565b610a85565b6101d36102dd366004611849565b610bd8565b6102536102f0366004611a57565b610c7a565b6101e8610303366004611849565b610d39565b6101e8610d64565b61025361031e366004611811565b610d6a565b610253610331366004611a57565b610e97565b610253610344366004611ae0565b610f41565b606060048054806020026020016040519081016040528092919081815260200182805480156103a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610383575b5050505050905090565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b820191906000526020600020905b81548152906001019060200180831161041757509395945050505050565b6009546001600160a01b031681565b60008061044f610ffb565b905061045c818585610fff565b5060019392505050565b60015490565b60006001600160a01b03831661049d5760405162461bcd60e51b815260040161049490611e50565b60405180910390fd5b6001600160a01b0384166104c35760405162461bcd60e51b815260040161049490612043565b60006104cd610ffb565b90506104fb81868686604051806020016040528060008152506040518060200160405280600081525061108d565b6105278186868660405180602001604052806000815250604051806020016040528060008152506111bb565b61057b858261057686604051806060016040528060298152602001612176602991396001600160a01b03808c166000908152600860209081526040808320938b168352929052205491906112db565b610fff565b6105a98186868660405180602001604052806000815250604051806020016040528060008152506000611307565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601290565b6000806105e8610ffb565b905061063c8182888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060408051602081019091528181529350915061146e9050565b7fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c168187878787604051610673959493929190611c0d565b60405180910390a1604051635260769b60e11b81526001600160a01b0387169063a4c0ed36906106ad908490899089908990600401611c65565b600060405180830381600087803b1580156106c757600080fd5b505af11580156106db573d6000803e3d6000fd5b5060019998505050505050505050565b600a5490565b6107026106fc610ffb565b88610bd8565b61071e5760405162461bcd60e51b815260040161049490612085565b61079f610729610ffb565b88888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a91508990819084018382808284376000920191909152506001925061146e915050565b50505050505050565b6001600160a01b031660009081526020819052604090205490565b600c6020526000908152604090205481565b806001600160a01b03166107e7610ffb565b6001600160a01b0316141561080e5760405162461bcd60e51b815260040161049490611dcb565b6001600160a01b03811660009081526005602052604090205460ff1615610871576007600061083b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690556108b8565b60016006600061087f610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b6108c0610ffb565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b6109c561096e610ffb565b610976610ffb565b868686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604080516020810190915290815292506001915061146e9050565b50505050565b60006001600160a01b0383166109f35760405162461bcd60e51b815260040161049490611e50565b60006109fd610ffb565b9050610a2b81828686604051806020016040528060008152506040518060200160405280600081525061108d565b610a578182868660405180602001604052806000815250604051806020016040528060008152506111bb565b61045c8182868660405180602001604052806000815250604051806020016040528060008152506000611307565b42841015610aa55760405162461bcd60e51b815260040161049490611fa9565b600b546001600160a01b0388166000908152600c6020908152604080832080546001810190915590519293610b27939092610b0c927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928e928e928e9290918e9101611cf8565b604051602081830303815290604052805190602001206114e5565b9050600060018286868660405160008152602001604052604051610b4e9493929190611d2c565b6020604051602081039080840390855afa158015610b70573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610ba65750886001600160a01b0316816001600160a01b0316145b610bc25760405162461bcd60e51b815260040161049490611f2f565b610bcd898989610fff565b505050505050505050565b6000816001600160a01b0316836001600160a01b03161480610c4357506001600160a01b03831660009081526005602052604090205460ff168015610c4357506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b80610c7357506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b6009546001600160a01b0316610c8e610ffb565b6001600160a01b031614610cb45760405162461bcd60e51b815260040161049490611f66565b610d31610cbf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061150492505050565b505050505050565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b600b5481565b610d72610ffb565b6001600160a01b0316816001600160a01b03161415610da35760405162461bcd60e51b815260040161049490611e0f565b6001600160a01b03811660009081526005602052604090205460ff1615610e0f57600160076000610dd2610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055610e4d565b60066000610e1b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b610e55610ffb565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b610ea8610ea2610ffb565b87610bd8565b610ec45760405162461bcd60e51b815260040161049490612085565b610d31610ecf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061162c92505050565b610f9f610f4c610ffb565b610f54610ffb565b8585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805160208101909152908152925061162c915050565b505050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b3390565b6001600160a01b0382166110255760405162461bcd60e51b8152600401610494906120c6565b6001600160a01b0380841660008181526008602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611080908590611cef565b60405180910390a3505050565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906110e99089907f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89590600401611c4c565b60206040518083038186803b15801561110157600080fd5b505afa158015611115573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611139919061182d565b90506001600160a01b0381161561079f57604051633ad5cbc160e11b81526001600160a01b038216906375ab978290611180908a908a908a908a908a908a90600401611bb3565b600060405180830381600087803b15801561119a57600080fd5b505af11580156111ae573d6000803e3d6000fd5b5050505050505050505050565b6111f88360405180606001604052806027815260200161214f602791396001600160a01b03881660009081526020819052604090205491906112db565b6001600160a01b038087166000908152602081905260408082209390935590861681522054611227908461175d565b6001600160a01b0380861660008181526020819052604090819020939093559151878216918916907f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc8261467798790611280908890889088906120fd565b60405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516112cb9190611cef565b60405180910390a3505050505050565b600081848411156112ff5760405162461bcd60e51b81526004016104949190611d4a565b505050900390565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906113639089907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b90600401611c4c565b60206040518083038186803b15801561137b57600080fd5b505afa15801561138f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b3919061182d565b90506001600160a01b0381161561142f576040516223de2960e01b81526001600160a01b038216906223de29906113f8908b908b908b908b908b908b90600401611bb3565b600060405180830381600087803b15801561141257600080fd5b505af1158015611426573d6000803e3d6000fd5b50505050611464565b811561146457611447866001600160a01b0316611782565b156114645760405162461bcd60e51b815260040161049490611ebc565b5050505050505050565b6001600160a01b0386166114945760405162461bcd60e51b815260040161049490611fd5565b6001600160a01b0385166114ba5760405162461bcd60e51b81526004016104949061200c565b6114c887878787878761108d565b6114d68787878787876111bb565b61079f87878787878787611307565b60405161190160f01b8152600281019290925260228201526042902090565b6001600160a01b03841661152a5760405162461bcd60e51b815260040161049490611e85565b600154611537908461175d565b6001556001600160a01b03841660009081526020819052604090205461155d908461175d565b6001600160a01b03851660009081526020819052604081209190915561158a908690868686866001611307565b836001600160a01b0316856001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d8585856040516115d1939291906120fd565b60405180910390a3836001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b60405180910390a35050505050565b6001600160a01b0384166116525760405162461bcd60e51b815260040161049490611d94565b6116618585600086868661108d565b61169e8360405180606001604052806023815260200161219f602391396001600160a01b03871660009081526020819052604090205491906112db565b6001600160a01b0385166000908152602081905260409020556001546116c49084611788565b600181905550836001600160a01b0316856001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098858585604051611711939291906120fd565b60405180910390a360006001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b600082820183811015610c735760405162461bcd60e51b815260040161049490611d5d565b3b151590565b6000610c7383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506112db565b60008083601f8401126117db578182fd5b50813567ffffffffffffffff8111156117f2578182fd5b60208301915083602082850101111561180a57600080fd5b9250929050565b600060208284031215611822578081fd5b8135610c7381612136565b60006020828403121561183e578081fd5b8151610c7381612136565b6000806040838503121561185b578081fd5b823561186681612136565b9150602083013561187681612136565b809150509250929050565b600080600060608486031215611895578081fd5b83356118a081612136565b925060208401356118b081612136565b929592945050506040919091013590565b600080600080600080600060a0888a0312156118db578283fd5b87356118e681612136565b965060208801356118f681612136565b955060408801359450606088013567ffffffffffffffff80821115611919578485fd5b6119258b838c016117ca565b909650945060808a013591508082111561193d578384fd5b5061194a8a828b016117ca565b989b979a50959850939692959293505050565b600080600080600080600060e0888a031215611977578283fd5b873561198281612136565b9650602088013561199281612136565b95506040880135945060608801359350608088013560ff811681146119b5578384fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156119e4578182fd5b82356119ef81612136565b946020939093013593505050565b60008060008060608587031215611a12578384fd5b8435611a1d81612136565b935060208501359250604085013567ffffffffffffffff811115611a3f578283fd5b611a4b878288016117ca565b95989497509550505050565b60008060008060008060808789031215611a6f578182fd5b8635611a7a81612136565b955060208701359450604087013567ffffffffffffffff80821115611a9d578384fd5b611aa98a838b016117ca565b90965094506060890135915080821115611ac1578384fd5b50611ace89828a016117ca565b979a9699509497509295939492505050565b600080600060408486031215611af4578283fd5b83359250602084013567ffffffffffffffff811115611b11578283fd5b611b1d868287016117ca565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b81811015611b7957602081850181015186830182015201611b5d565b81811115611b8a5782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0387811682528681166020830152851660408201526060810184905260c060808201819052600090611bee90830185611b54565b82810360a0840152611c008185611b54565b9998505050505050505050565b6001600160a01b0386811682528516602082015260408101849052608060608201819052600090611c419083018486611b2a565b979650505050505050565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038616825284602083015260606040830152611c8d606083018486611b2a565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611cd85783516001600160a01b031683529284019291840191600101611cb3565b50909695505050505050565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610c736020830184611b54565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f4552433737373a206275726e2066726f6d207a65726f20616464726573730000604082015260600190565b60208082526024908201527f4552433737373a20617574686f72697a696e672073656c66206173206f70657260408201526330ba37b960e11b606082015260800190565b60208082526021908201527f4552433737373a207265766f6b696e672073656c66206173206f70657261746f6040820152603960f91b606082015260800190565b6020808252818101527f4552433737373a207472616e7366657220746f207a65726f2061646472657373604082015260600190565b6020808252601c908201527f4552433737373a206d696e7420746f207a65726f206164647265737300000000604082015260600190565b6020808252604d908201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460408201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60608201526c1ad95b9cd49958da5c1a595b9d609a1b608082015260a00190565b6020808252601c908201527f53696465546f6b656e3a20494e56414c49445f5349474e415455524500000000604082015260600190565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b60208082526012908201527114da5919551bdad95b8e881156141254915160721b604082015260600190565b6020808252601e908201527f4552433737373a2073656e642066726f6d207a65726f20616464726573730000604082015260600190565b6020808252601c908201527f4552433737373a2073656e6420746f207a65726f206164647265737300000000604082015260600190565b60208082526022908201527f4552433737373a207472616e736665722066726f6d207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526021908201527f4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f6040820152603960f91b606082015260800190565b6020808252601f908201527f4552433737373a20617070726f766520746f207a65726f206164647265737300604082015260600190565b6000848252606060208301526121166060830185611b54565b8281036040840152611c8d8185611b54565b60ff91909116815260200190565b6001600160a01b038116811461214b57600080fd5b5056fe4552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a206275726e20616d6f756e7420657863656564732062616c616e6365a2646970667358221220e96305596548c1ccf5a73d7bede36fbfaeee3f672cbf14157179325f27c57bf764736f6c63430007060033a26469706673582212204cc330cf5079dbaee9f34fb1607540a3d5891d5eeb955ff8beaa47811a8c189964736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 11014,
+ "contract": "contracts/SideTokenFactory/SideTokenFactory.sol:SideTokenFactory",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/WRBTC.json b/bridge/deployments/rsktestnetbsc/WRBTC.json
new file mode 100644
index 000000000..f78571e12
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/WRBTC.json
@@ -0,0 +1,400 @@
+{
+ "address": "0x09b6ca5e4496238a1f176aea6bb607db96c2286e",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "guy",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposit",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Withdrawal",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "guy",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "deposit",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdraw",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xa55afc0a86fae3e78c22da4d796f54929788ac921ad83ef5ebf35902982c73ca",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0xcAB50DA63928519b4dD58e3766D90B8E860982D9",
+ "transactionIndex": 0,
+ "gasUsed": "665718",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xdb8404801fc937df8ffbc62579c7ec91193ef9ac5d47401cb5a264ab3ce8090c",
+ "transactionHash": "0xa55afc0a86fae3e78c22da4d796f54929788ac921ad83ef5ebf35902982c73ca",
+ "logs": [],
+ "blockNumber": 2152326,
+ "cumulativeGasUsed": "665718",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/test/WRBTC.sol\":\"WRBTC\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interface/IWrapped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\ninterface IWrapped {\\n function balanceOf(address) external returns(uint);\\n\\n function deposit() external payable;\\n\\n function withdraw(uint wad) external;\\n\\n function totalSupply() external view returns (uint);\\n\\n function approve(address guy, uint wad) external returns (bool);\\n\\n function transfer(address dst, uint wad) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint wad)\\n external\\n returns (bool);\\n}\",\"keccak256\":\"0x2d8a99b6a030e37f01dba86db80e3bd29d1d01e592e399c8635df3fb636ec0d1\",\"license\":\"MIT\"},\"contracts/test/WRBTC.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../interface/IWrapped.sol\\\";\\n\\ncontract WRBTC is IWrapped {\\n string public name = \\\"Wrapped RBTC\\\";\\n string public symbol = \\\"WRBTC\\\";\\n uint8 public decimals = 18;\\n\\n event Approval(address indexed src, address indexed guy, uint wad);\\n event Transfer(address indexed src, address indexed dst, uint wad);\\n event Deposit(address indexed dst, uint wad);\\n event Withdrawal(address indexed src, uint wad);\\n\\n mapping (address => uint) override public balanceOf;\\n mapping (address => mapping (address => uint)) public allowance;\\n\\n receive () external payable {\\n deposit();\\n }\\n function deposit() override public payable {\\n balanceOf[msg.sender] += msg.value;\\n emit Deposit(msg.sender, msg.value);\\n }\\n function withdraw(uint wad) override public {\\n require(balanceOf[msg.sender] >= wad, \\\"WRBTC: Balance less than wad\\\");\\n balanceOf[msg.sender] -= wad;\\n msg.sender.transfer(wad);\\n emit Withdrawal(msg.sender, wad);\\n }\\n\\n function totalSupply() override public view returns (uint) {\\n return address(this).balance;\\n }\\n\\n function approve(address guy, uint wad) override public returns (bool) {\\n allowance[msg.sender][guy] = wad;\\n emit Approval(msg.sender, guy, wad);\\n return true;\\n }\\n\\n function transfer(address dst, uint wad) override public returns (bool) {\\n return transferFrom(msg.sender, dst, wad);\\n }\\n\\n function transferFrom(address src, address dst, uint wad)\\n override public\\n returns (bool)\\n {\\n require(balanceOf[src] >= wad, \\\"WRBTC: Balance less than wad\\\");\\n\\n if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\\n require(allowance[src][msg.sender] >= wad, \\\"WRBTC: Allowance less than wad\\\");\\n allowance[src][msg.sender] -= wad;\\n }\\n\\n balanceOf[src] -= wad;\\n balanceOf[dst] += wad;\\n\\n emit Transfer(src, dst, wad);\\n\\n return true;\\n }\\n}\",\"keccak256\":\"0xf664c159f6302a78c9e6393c00de0c2630dc3e830215dc467a03f17a533b6807\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x60c0604052600c60808190526b57726170706564205242544360a01b60a090815261002d916000919061007a565b5060408051808201909152600580825264575242544360d81b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b5061011b565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826100b057600085556100f6565b82601f106100c957805160ff19168380011785556100f6565b828001600101855582156100f6579182015b828111156100f65782518255916020019190600101906100db565b50610102929150610106565b5090565b5b808211156101025760008155600101610107565b6107d28061012a6000396000f3fe6080604052600436106100a05760003560e01c8063313ce56711610064578063313ce5671461021f57806370a082311461024a57806395d89b411461027d578063a9059cbb14610292578063d0e30db0146102cb578063dd62ed3e146102d3576100af565b806306fdde03146100b4578063095ea7b31461013e57806318160ddd1461018b57806323b872dd146101b25780632e1a7d4d146101f5576100af565b366100af576100ad61030e565b005b600080fd5b3480156100c057600080fd5b506100c961035d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101035781810151838201526020016100eb565b50505050905090810190601f1680156101305780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014a57600080fd5b506101776004803603604081101561016157600080fd5b506001600160a01b0381351690602001356103eb565b604080519115158252519081900360200190f35b34801561019757600080fd5b506101a0610451565b60408051918252519081900360200190f35b3480156101be57600080fd5b50610177600480360360608110156101d557600080fd5b506001600160a01b03813581169160208101359091169060400135610455565b34801561020157600080fd5b506100ad6004803603602081101561021857600080fd5b5035610619565b34801561022b57600080fd5b506102346106f6565b6040805160ff9092168252519081900360200190f35b34801561025657600080fd5b506101a06004803603602081101561026d57600080fd5b50356001600160a01b03166106ff565b34801561028957600080fd5b506100c9610711565b34801561029e57600080fd5b50610177600480360360408110156102b557600080fd5b506001600160a01b03813516906020013561076b565b6100ad61030e565b3480156102df57600080fd5b506101a0600480360360408110156102f657600080fd5b506001600160a01b038135811691602001351661077f565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b820191906000526020600020905b8154815290600101906020018083116103c657829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b6001600160a01b0383166000908152600360205260408120548211156104c2576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b6001600160a01b038416331480159061050057506001600160a01b038416600090815260046020908152604080832033845290915290205460001914155b156105a8576001600160a01b038416600090815260046020908152604080832033845290915290205482111561057d576040805162461bcd60e51b815260206004820152601e60248201527f57524254433a20416c6c6f77616e6365206c657373207468616e207761640000604482015290519081900360640190fd5b6001600160a01b03841660009081526004602090815260408083203384529091529020805483900390555b6001600160a01b03808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561067d576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106bc573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b6000610778338484610455565b9392505050565b60046020908152600092835260408084209091529082529020548156fea26469706673582212202d01111733e2aa80d67d08b8b3a53d89aabe0e468d80eba287b4a34d46db4ab564736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106100a05760003560e01c8063313ce56711610064578063313ce5671461021f57806370a082311461024a57806395d89b411461027d578063a9059cbb14610292578063d0e30db0146102cb578063dd62ed3e146102d3576100af565b806306fdde03146100b4578063095ea7b31461013e57806318160ddd1461018b57806323b872dd146101b25780632e1a7d4d146101f5576100af565b366100af576100ad61030e565b005b600080fd5b3480156100c057600080fd5b506100c961035d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101035781810151838201526020016100eb565b50505050905090810190601f1680156101305780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014a57600080fd5b506101776004803603604081101561016157600080fd5b506001600160a01b0381351690602001356103eb565b604080519115158252519081900360200190f35b34801561019757600080fd5b506101a0610451565b60408051918252519081900360200190f35b3480156101be57600080fd5b50610177600480360360608110156101d557600080fd5b506001600160a01b03813581169160208101359091169060400135610455565b34801561020157600080fd5b506100ad6004803603602081101561021857600080fd5b5035610619565b34801561022b57600080fd5b506102346106f6565b6040805160ff9092168252519081900360200190f35b34801561025657600080fd5b506101a06004803603602081101561026d57600080fd5b50356001600160a01b03166106ff565b34801561028957600080fd5b506100c9610711565b34801561029e57600080fd5b50610177600480360360408110156102b557600080fd5b506001600160a01b03813516906020013561076b565b6100ad61030e565b3480156102df57600080fd5b506101a0600480360360408110156102f657600080fd5b506001600160a01b038135811691602001351661077f565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b820191906000526020600020905b8154815290600101906020018083116103c657829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b6001600160a01b0383166000908152600360205260408120548211156104c2576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b6001600160a01b038416331480159061050057506001600160a01b038416600090815260046020908152604080832033845290915290205460001914155b156105a8576001600160a01b038416600090815260046020908152604080832033845290915290205482111561057d576040805162461bcd60e51b815260206004820152601e60248201527f57524254433a20416c6c6f77616e6365206c657373207468616e207761640000604482015290519081900360640190fd5b6001600160a01b03841660009081526004602090815260408083203384529091529020805483900390555b6001600160a01b03808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561067d576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106bc573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b6000610778338484610455565b9392505050565b60046020908152600092835260408084209091529082529020548156fea26469706673582212202d01111733e2aa80d67d08b8b3a53d89aabe0e468d80eba287b4a34d46db4ab564736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {},
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 9308,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "name",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 9311,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "symbol",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 9314,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "decimals",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint8"
+ },
+ {
+ "astId": 9347,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "balanceOf",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_mapping(t_address,t_uint256)"
+ },
+ {
+ "astId": 9353,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "allowance",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_uint256))": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_uint256)"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "encoding": "inplace",
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/solcInputs/3b83f9cb61a99eec06a616e65f41d75c.json b/bridge/deployments/rsktestnetbsc/solcInputs/3b83f9cb61a99eec06a616e65f41d75c.json
new file mode 100644
index 000000000..e68d5ccb0
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/solcInputs/3b83f9cb61a99eec06a616e65f41d75c.json
@@ -0,0 +1,36 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/MultiSigWallet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.\n/// @author Stefan George - \ncontract MultiSigWallet {\n\n /*\n * Events\n */\n event Confirmation(address indexed sender, uint indexed transactionId);\n event Revocation(address indexed sender, uint indexed transactionId);\n event Submission(uint indexed transactionId);\n event Execution(uint indexed transactionId);\n event ExecutionFailure(uint indexed transactionId);\n event Deposit(address indexed sender, uint value);\n event OwnerAddition(address indexed owner);\n event OwnerRemoval(address indexed owner);\n event RequirementChange(uint required);\n\n /*\n * views\n */\n uint constant public MAX_OWNER_COUNT = 50;\n\n /*\n * Storage\n */\n mapping (uint => Transaction) public transactions;\n mapping (uint => mapping (address => bool)) public confirmations;\n mapping (address => bool) public isOwner;\n address[] public owners;\n uint public required;\n uint public transactionCount;\n\n struct Transaction {\n address destination;\n uint value;\n bytes data;\n bool executed;\n }\n\n /*\n * Modifiers\n */\n modifier onlyWallet() {\n require(msg.sender == address(this), \"Only wallet allowed\");\n _;\n }\n\n modifier ownerDoesNotExist(address owner) {\n require(!isOwner[owner], \"The owner already exists\");\n _;\n }\n\n modifier ownerExists(address owner) {\n require(isOwner[owner], \"The owner does not exist\");\n _;\n }\n\n modifier transactionExists(uint transactionId) {\n require(transactions[transactionId].destination != address(0), \"Transaction does not exist\");\n _;\n }\n\n modifier confirmed(uint transactionId, address owner) {\n require(confirmations[transactionId][owner], \"Transaction is not confirmed by owner\");\n _;\n }\n\n modifier notConfirmed(uint transactionId, address owner) {\n require(!confirmations[transactionId][owner], \"Transaction is already confirmed by owner\");\n _;\n }\n\n modifier notExecuted(uint transactionId) {\n require(!transactions[transactionId].executed, \"Transaction was already executed\");\n _;\n }\n\n modifier notNull(address _address) {\n require(_address != address(0), \"Address cannot be empty\");\n _;\n }\n\n modifier validRequirement(uint ownerCount, uint _required) {\n // solium-disable-next-line max-len\n require(ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && _required != 0 && ownerCount != 0, \"Required value is invalid for the current owners count\");\n _;\n }\n\n /// @dev Fallback function allows to deposit ether.\n receive ()\n external\n payable\n {\n if (msg.value > 0)\n emit Deposit(msg.sender, msg.value);\n }\n\n /*\n * Public functions\n */\n /// @dev Contract constructor sets initial owners and required number of confirmations.\n /// @param _owners List of initial owners.\n /// @param _required Number of required confirmations.\n constructor(address[] memory _owners, uint _required)\n validRequirement(_owners.length, _required)\n {\n for (uint i = 0; i < _owners.length; i++) {\n require(!isOwner[_owners[i]] && _owners[i] != address(0), \"Owners addresses are invalid\");\n isOwner[_owners[i]] = true;\n }\n owners = _owners;\n required = _required;\n }\n\n /// @dev Allows to add a new owner. Transaction has to be sent by wallet.\n /// @param owner Address of new owner.\n function addOwner(address owner)\n public\n onlyWallet\n ownerDoesNotExist(owner)\n notNull(owner)\n validRequirement(owners.length + 1, required)\n {\n isOwner[owner] = true;\n owners.push(owner);\n emit OwnerAddition(owner);\n }\n\n /// @dev Allows to remove an owner. Transaction has to be sent by wallet.\n /// @param owner Address of owner.\n function removeOwner(address owner)\n public\n onlyWallet\n ownerExists(owner)\n {\n isOwner[owner] = false;\n for (uint i = 0; i < owners.length - 1; i++)\n if (owners[i] == owner) {\n owners[i] = owners[owners.length - 1];\n break;\n }\n owners.pop(); // remove an element from the end of the array.\n if (required > owners.length)\n changeRequirement(owners.length);\n emit OwnerRemoval(owner);\n }\n\n /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\n /// @param owner Address of owner to be replaced.\n /// @param newOwner Address of new owner.\n function replaceOwner(address owner, address newOwner)\n public\n onlyWallet\n ownerExists(owner)\n ownerDoesNotExist(newOwner)\n {\n for (uint i = 0; i < owners.length; i++)\n if (owners[i] == owner) {\n owners[i] = newOwner;\n break;\n }\n isOwner[owner] = false;\n isOwner[newOwner] = true;\n emit OwnerRemoval(owner);\n emit OwnerAddition(newOwner);\n }\n\n /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.\n /// @param _required Number of required confirmations.\n function changeRequirement(uint _required)\n public\n onlyWallet\n validRequirement(owners.length, _required)\n {\n required = _required;\n emit RequirementChange(_required);\n }\n\n /// @dev Allows an owner to submit and confirm a transaction.\n /// @param destination Transaction target address.\n /// @param value Transaction ether value.\n /// @param data Transaction data payload.\n /// @return transactionId Returns transaction ID.\n function submitTransaction(address destination, uint value, bytes memory data)\n public\n returns (uint transactionId)\n {\n transactionId = addTransaction(destination, value, data);\n confirmTransaction(transactionId);\n }\n\n /// @dev Allows an owner to confirm a transaction.\n /// @param transactionId Transaction ID.\n function confirmTransaction(uint transactionId)\n public\n ownerExists(msg.sender)\n transactionExists(transactionId)\n notConfirmed(transactionId, msg.sender)\n {\n confirmations[transactionId][msg.sender] = true;\n emit Confirmation(msg.sender, transactionId);\n executeTransaction(transactionId);\n }\n\n /// @dev Allows an owner to revoke a confirmation for a transaction.\n /// @param transactionId Transaction ID.\n function revokeConfirmation(uint transactionId)\n public\n ownerExists(msg.sender)\n confirmed(transactionId, msg.sender)\n notExecuted(transactionId)\n {\n confirmations[transactionId][msg.sender] = false;\n emit Revocation(msg.sender, transactionId);\n }\n\n /// @dev Allows anyone to execute a confirmed transaction.\n /// @param transactionId Transaction ID.\n function executeTransaction(uint transactionId)\n public\n ownerExists(msg.sender)\n confirmed(transactionId, msg.sender)\n notExecuted(transactionId)\n {\n if (isConfirmed(transactionId)) {\n Transaction storage txn = transactions[transactionId];\n txn.executed = true;\n if (external_call(txn.destination, txn.value, txn.data.length, txn.data))\n emit Execution(transactionId);\n else {\n emit ExecutionFailure(transactionId);\n txn.executed = false;\n }\n }\n }\n\n // call has been separated into its own function in order to take advantage\n // of the Solidity's code generator to produce a loop that copies tx.data into memory.\n function external_call(address destination, uint value, uint dataLength, bytes memory data) internal returns (bool) {\n bool result;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let x := mload(0x40) // \"Allocate\" memory for output (0x40 is where \"free memory\" pointer is stored by convention)\n let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that\n result := call(\n sub(gas(), 34710), // 34710 is the value that solidity is currently emitting\n // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +\n // callNewAccountGas (25000, in case the destination address does not exist and needs creating)\n destination,\n value,\n d,\n dataLength, // Size of the input (in bytes) - this is what fixes the padding problem\n x,\n 0 // Output is ignored, therefore the output size is zero\n )\n }\n return result;\n }\n\n /// @dev Returns the confirmation status of a transaction.\n /// @param transactionId Transaction ID.\n /// @return Confirmation status.\n function isConfirmed(uint transactionId)\n public\n view\n returns (bool)\n {\n uint count = 0;\n for (uint i = 0; i < owners.length; i++) {\n if (confirmations[transactionId][owners[i]])\n count += 1;\n if (count == required)\n return true;\n }\n return false;\n }\n\n /*\n * Internal functions\n */\n /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.\n /// @param destination Transaction target address.\n /// @param value Transaction ether value.\n /// @param data Transaction data payload.\n /// @return transactionId Returns transaction ID.\n function addTransaction(address destination, uint value, bytes memory data)\n internal\n notNull(destination)\n returns (uint transactionId)\n {\n transactionId = transactionCount;\n transactions[transactionId] = Transaction({\n destination: destination,\n value: value,\n data: data,\n executed: false\n });\n transactionCount += 1;\n emit Submission(transactionId);\n }\n\n /*\n * Web3 call functions\n */\n /// @dev Returns number of confirmations of a transaction.\n /// @param transactionId Transaction ID.\n /// @return count Number of confirmations.\n function getConfirmationCount(uint transactionId)\n public\n view\n returns (uint count)\n {\n for (uint i = 0; i < owners.length; i++) {\n if (confirmations[transactionId][owners[i]]) {\n count += 1;\n }\n }\n }\n\n /// @dev Returns total number of transactions after filers are applied.\n /// @param pending Include pending transactions.\n /// @param executed Include executed transactions.\n /// @return count Total number of transactions after filters are applied.\n function getTransactionCount(bool pending, bool executed)\n public\n view\n returns (uint count)\n {\n for (uint i = 0; i < transactionCount; i++) {\n if ( pending && !transactions[i].executed || executed && transactions[i].executed) {\n count += 1;\n }\n }\n }\n\n /// @dev Returns list of owners.\n /// @return List of owner addresses.\n function getOwners()\n public\n view\n returns (address[] memory)\n {\n return owners;\n }\n\n /// @dev Returns array with owner addresses, which confirmed transaction.\n /// @param transactionId Transaction ID.\n /// @return _confirmations Returns array of owner addresses.\n function getConfirmations(uint transactionId)\n public\n view\n returns (address[] memory _confirmations)\n {\n address[] memory confirmationsTemp = new address[](owners.length);\n uint count = 0;\n uint i;\n for (i = 0; i < owners.length; i++)\n if (confirmations[transactionId][owners[i]]) {\n confirmationsTemp[count] = owners[i];\n count += 1;\n }\n _confirmations = new address[](count);\n for (i = 0; i < count; i++)\n _confirmations[i] = confirmationsTemp[i];\n }\n\n /// @dev Returns list of transaction IDs in defined range.\n /// @param from Index start position of transaction array.\n /// @param to Index end position of transaction array.\n /// @param pending Include pending transactions.\n /// @param executed Include executed transactions.\n /// @return _transactionIds Returns array of transaction IDs.\n function getTransactionIds(uint from, uint to, bool pending, bool executed)\n public\n view\n returns (uint[] memory _transactionIds)\n {\n uint[] memory transactionIdsTemp = new uint[](transactionCount);\n uint count = 0;\n uint i;\n for (i = 0; i < transactionCount; i++)\n if ( pending && !transactions[i].executed || executed && transactions[i].executed)\n {\n transactionIdsTemp[count] = i;\n count += 1;\n }\n _transactionIds = new uint[](to - from);\n for (i = from; i < to; i++)\n _transactionIds[i - from] = transactionIdsTemp[i];\n }\n}"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/solcInputs/bd60cbce915f67c6e3ddca09e6c29f99.json b/bridge/deployments/rsktestnetbsc/solcInputs/bd60cbce915f67c6e3ddca09e6c29f99.json
new file mode 100644
index 000000000..75948d241
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/solcInputs/bd60cbce915f67c6e3ddca09e6c29f99.json
@@ -0,0 +1,297 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/math/SafeMath.sol\";\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\n\nimport \"../interface/IAllowTokens.sol\";\n\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n uint256 constant public MAX_TYPES = 250;\n mapping (address => TokenInfo) public allowedTokens;\n mapping (uint256 => Limits) public typeLimits;\n uint256 public smallAmountConfirmations;\n uint256 public mediumAmountConfirmations;\n uint256 public largeAmountConfirmations;\n string[] public typeDescriptions;\n\n event SetToken(address indexed _tokenAddress, uint256 _typeId);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\n event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\n event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\n event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\n\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\n _;\n }\n\n function initialize(\n address _manager,\n address _primary,\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations,\n TypeInfo[] memory typesInfo) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradableSecondary.__Secondary_init(_primary);\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n for(uint i = 0; i < typesInfo.length; i = i + 1) {\n _addTokenType(typesInfo[i].description, typesInfo[i].limits);\n }\n }\n\n function version() override external pure returns (string memory) {\n return \"v1\";\n }\n\n function getInfoAndLimits(address token) override public view\n returns (TokenInfo memory info, Limits memory limit) {\n info = allowedTokens[token];\n limit = typeLimits[info.typeId];\n return (info, limit);\n }\n function calcMaxWithdraw(address token) override public view returns (uint256 maxWithdraw) {\n (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\n return _calcMaxWithdraw(info, limits);\n }\n\n function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n info.spentToday = 0;\n }\n if (limits.daily <= info.spentToday)\n return 0;\n maxWithdraw = limits.daily - info.spentToday;\n if(maxWithdraw > limits.max)\n maxWithdraw = limits.max;\n return maxWithdraw;\n }\n\n // solium-disable-next-line max-len\n function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\n (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\n require(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\n require(amount >= limit.min, \"AllowTokens: Lower than limit\");\n\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n // solium-disable-next-line security/no-block-members\n info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n info.spentToday = 0;\n }\n uint maxWithdraw = _calcMaxWithdraw(info, limit);\n require(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\n info.spentToday = info.spentToday.add(amount);\n allowedTokens[token] = info;\n\n emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\n }\n\n function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\n require(bytes(description).length > 0, \"AllowTokens: Empty description\");\n len = typeDescriptions.length;\n require(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\n typeDescriptions.push(description);\n _setTypeLimits(len, limits);\n emit TokenTypeAdded(len, description);\n return len;\n }\n\n function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\n return _addTokenType(description, limits);\n }\n\n function _setTypeLimits(uint256 typeId, Limits memory limits) private {\n require(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\n require(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\n require(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\n require(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\n require(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\n typeLimits[typeId] = limits;\n emit TypeLimitsChanged(typeId, limits);\n }\n\n function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\n _setTypeLimits(typeId, limits);\n }\n\n function getTypesLimits() external view override returns(Limits[] memory limits) {\n limits = new Limits[](typeDescriptions.length);\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\n limits[i] = typeLimits[i];\n }\n return limits;\n }\n\n function getTypeDescriptionsLength() external view override returns(uint256) {\n return typeDescriptions.length;\n }\n\n function getTypeDescriptions() external view override returns(string[] memory descriptions) {\n descriptions = new string[](typeDescriptions.length);\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\n descriptions[i] = typeDescriptions[i];\n }\n return descriptions;\n }\n\n function isTokenAllowed(address token) public view notNull(token) override returns (bool) {\n return allowedTokens[token].allowed;\n }\n\n function setToken(address token, uint256 typeId) override public notNull(token) {\n require(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n require(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\n TokenInfo memory info = allowedTokens[token];\n info.allowed = true;\n info.typeId = typeId;\n allowedTokens[token] = info;\n emit SetToken(token, typeId);\n }\n\n function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\n require(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\n for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\n setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\n }\n }\n\n function removeAllowedToken(address token) external notNull(token) onlyOwner {\n TokenInfo memory info = allowedTokens[token];\n require(info.allowed, \"AllowTokens: Not Allowed\");\n info.allowed = false;\n allowedTokens[token] = info;\n emit AllowedTokenRemoved(token);\n }\n\n function setConfirmations(\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations) external onlyOwner {\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n }\n\n function _setConfirmations(\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations) private {\n require(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\n require(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\n smallAmountConfirmations = _smallAmountConfirmations;\n mediumAmountConfirmations = _mediumAmountConfirmations;\n largeAmountConfirmations = _largeAmountConfirmations;\n emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n }\n\n function getConfirmations() external view override\n returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount) {\n return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\n }\n\n}\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @title Initializable\n *\n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(initializing || !initialized, \"Contract instance is already initialized\");\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\n * the owner.\n */\ncontract UpgradableOwnable is Initializable, Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function initialize(address sender) public initializer {\n _owner = sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * > Note: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\ncontract UpgradableSecondary is Initializable, Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n function __Secondary_init(address sender) public initializer {\n _primary = sender;\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(recipient);\n }\n\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IAllowTokens {\n\n struct Limits {\n uint256 min;\n uint256 max;\n uint256 daily;\n uint256 mediumAmount;\n uint256 largeAmount;\n }\n\n struct TokenInfo {\n bool allowed;\n uint256 typeId;\n uint256 spentToday;\n uint256 lastDay;\n }\n\n struct TypeInfo {\n string description;\n Limits limits;\n }\n\n struct TokensAndType {\n address token;\n uint256 typeId;\n }\n\n function version() external pure returns (string memory);\n\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\n\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\n\n function getTypesLimits() external view returns(Limits[] memory limits);\n\n function getTypeDescriptionsLength() external view returns(uint256);\n\n function getTypeDescriptions() external view returns(string[] memory descriptions);\n\n function setToken(address token, uint256 typeId) external;\n\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\n\n function isTokenAllowed(address token) external view returns (bool);\n\n function updateTokenTransfer(address token, uint256 amount) external;\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n\n function _msgSender() internal view returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
+ },
+ "contracts/nftbridge/NFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC721/IERC721.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Metadata.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Enumerable.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Receiver.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./INFTBridge.sol\";\nimport \"./ISideNFTToken.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract NFTBridge is\n Initializable,\n INFTBridge,\n UpgradablePausable,\n UpgradableOwnable,\n ReentrancyGuard,\n IERC721Receiver {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address internal constant NULL_ADDRESS = address(0);\n bytes32 internal constant NULL_HASH = bytes32(0);\n IERC1820Registry internal constant ERC1820 =\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address payable internal federation;\n uint256 internal fixedFee;\n string public symbolPrefix;\n\n mapping(address => address) public sideTokenAddressByOriginalTokenAddress;\n mapping(address => address) public originalTokenAddressBySideTokenAddress;\n mapping(address => bool) public isAddressFromCrossedOriginalToken; // address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideNFTTokenFactory public sideTokenFactory;\n bool public isUpgrading;\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\n event Upgrading(bool _isUpgrading);\n\n function initialize(\n address _manager,\n address payable _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\n federation = _federation;\n ERC1820.setInterfaceImplementer(\n address(this),\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\n address(this)\n );\n }\n\n function version() external pure override returns (string memory) {\n return \"v1\";\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _tokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external override whenNotPaused nonReentrant {\n require(_msgSender() == federation, \"NFTBridge: Not Federation\");\n require(\n isAddressFromCrossedOriginalToken[_tokenAddress] ||\n sideTokenAddressByOriginalTokenAddress[_tokenAddress] != NULL_ADDRESS,\n \"NFTBridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"NFTBridge: Null To\");\n require(_from != NULL_ADDRESS, \"NFTBridge: Null From\");\n require(_blockHash != NULL_HASH, \"NFTBridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"NFTBridge: Null TxHash\");\n require(\n transactionDataHashes[_transactionHash] == bytes32(0),\n \"NFTBridge: Already accepted\"\n );\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\n require(!claimed[_transactionDataHash], \"NFTBridge: Already claimed\");\n\n transactionDataHashes[_transactionHash] = _transactionDataHash;\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\n// senderAddresses[_transactionHash] = _from;\n\n emit AcceptedNFTCrossTransfer(\n _transactionHash,\n _tokenAddress,\n _to,\n _from,\n _tokenId,\n _blockHash,\n _logIndex\n );\n }\n\n function createSideNFTToken(\n address _originalTokenAddress,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName,\n string calldata _baseURI,\n string calldata _contractURI\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"NFTBridge: Null original token address\");\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[_originalTokenAddress];\n require(sideTokenAddress == NULL_ADDRESS, \"NFTBridge: Side token already exists\");\n string memory sideTokenSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideTokenAddress = sideTokenFactory.createSideNFTToken(_originalTokenName, sideTokenSymbol, _baseURI, _contractURI);\n\n sideTokenAddressByOriginalTokenAddress[_originalTokenAddress] = sideTokenAddress;\n originalTokenAddressBySideTokenAddress[sideTokenAddress] = _originalTokenAddress;\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, sideTokenSymbol);\n }\n\n function claim(NFTClaimData calldata _claimData) external override {\n _claim(_claimData, _claimData.to);\n }\n\n function claimFallback(NFTClaimData calldata _claimData) external override {\n require(_msgSender() == _claimData.from, \"NFTBridge: invalid sender\");\n _claim(_claimData, _msgSender());\n }\n\n function _claim(\n NFTClaimData calldata _claimData,\n address payable _receiver\n ) internal {\n address tokenAddress = _claimData.tokenAddress;\n uint256 tokenId = _claimData.tokenId;\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.from,\n tokenId,\n tokenAddress,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\n \"NFTBridge: Wrong txDataHash\"\n );\n require(!claimed[transactionDataHash], \"NFTBridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n bool isClaimBeingRequestedInMainChain = isAddressFromCrossedOriginalToken[tokenAddress];\n if (isClaimBeingRequestedInMainChain) {\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\n } else {\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[tokenAddress];\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\n }\n\n emit ClaimedNFTToken(\n _claimData.transactionHash,\n tokenAddress,\n _claimData.to,\n _claimData.from,\n _claimData.tokenId,\n _claimData.blockHash,\n _claimData.logIndex,\n _receiver\n );\n }\n\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\"creator()\"));\n if (success) {\n return abi.decode(data, (address));\n }\n\n return IERC721(tokenAddress).ownerOf(tokenId);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId\n ) public payable override {\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\n\n address payable sender = _msgSender();\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\n\n crossTokens(tokenAddress, to, tokenCreator, \"\", tokenId);\n\n if (fixedFee > 0) {\n require(msg.value >= fixedFee, \"NFTBridge: value is smaller than fixed fee\");\n\n // Send the payment to the MultiSig of the Federation\n federation.transfer(fixedFee);\n if (msg.value > fixedFee) { // refund of unused value\n sender.transfer(msg.value.sub(fixedFee));\n }\n }\n }\n\n function crossTokens(\n address tokenAddress,\n address to,\n address tokenCreator,\n bytes memory userData,\n uint256 tokenId\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\n isAddressFromCrossedOriginalToken[tokenAddress] = true;\n\n IERC721Enumerable enumerable = IERC721Enumerable(tokenAddress);\n IERC721Metadata metadataIERC = IERC721Metadata(tokenAddress);\n string memory tokenURI = metadataIERC.tokenURI(tokenId);\n\n address originalTokenAddress = tokenAddress;\n if (originalTokenAddressBySideTokenAddress[tokenAddress] != NULL_ADDRESS) {\n originalTokenAddress = originalTokenAddressBySideTokenAddress[tokenAddress];\n ERC721Burnable(tokenAddress).burn(tokenId);\n }\n\n emit Cross(\n originalTokenAddress,\n _msgSender(),\n to,\n tokenCreator,\n userData,\n enumerable.totalSupply(),\n tokenId,\n tokenURI\n );\n }\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) public pure override returns (bytes32) {\n return keccak256(\n abi.encodePacked(\n _blockHash,\n _transactionHash,\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _logIndex\n )\n );\n }\n\n function setFixedFee(uint256 amount) external onlyOwner {\n fixedFee = amount;\n emit FixedFeeNFTChanged(fixedFee);\n }\n\n function getFixedFee() external view override returns (uint256) {\n return fixedFee;\n }\n\n function changeFederation(address payable newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"NFTBridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"NFTBridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns (address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\n require(\n newSideNFTTokenFactory != NULL_ADDRESS,\n \"NFTBridge: empty SideTokenFactory\"\n );\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionDataHashes[transactionHash]];\n }\n\n /**\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\n/**\n * @title Helps contracts guard against reentrancy attacks.\n * @author Remco Bloemen , Eenae \n * @dev If you mark a function `nonReentrant`, you should also\n * mark it `external`.\n */\ncontract ReentrancyGuard is Initializable {\n /// @dev counter to allow mutex lock with only one SSTORE operation\n uint256 private _guardCounter;\n\n function initialize() public initializer {\n // The counter starts at one to prevent changing it from zero to a non-zero\n // value, which is a more expensive operation.\n _guardCounter = 1;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _guardCounter += 1;\n uint256 localCounter = _guardCounter;\n _;\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\n }\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\nimport \"../access/roles/UpgradablePauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n function __Pausable_init(address sender) public initializer {\n UpgradablePauserRole.__PauserRol_init(sender);\n\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as `account`'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `_account`.\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `_implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\n\n /**\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `_account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {ERC20Detailed}.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeERC20: low-level call failed\");\n\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n */\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./ERC721.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721Burnable is Context, ERC721 {\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n _burn(tokenId);\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\nlibrary LibEIP712 {\n\n // Hash of the EIP712 Domain Separator Schema\n // keccak256(abi.encodePacked(\n // \"EIP712Domain(\",\n // \"string name,\",\n // \"string version,\",\n // \"uint256 chainId,\",\n // \"address verifyingContract\",\n // \")\"\n // ))\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n /// @dev Calculates a EIP712 domain separator.\n /// @param name The EIP712 domain name.\n /// @param version The EIP712 domain version.\n /// @param verifyingContract The EIP712 verifying contract.\n /// @return result EIP712 domain separator.\n function hashEIP712Domain(\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n // keccak256(bytes(name)),\n // keccak256(bytes(version)),\n // chainId,\n // uint256(verifyingContract)\n // ))\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Calculate hashes of dynamic data\n let nameHash := keccak256(add(name, 32), mload(name))\n let versionHash := keccak256(add(version, 32), mload(version))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n // Store params in memory\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), nameHash)\n mstore(add(memPtr, 64), versionHash)\n mstore(add(memPtr, 96), chainId)\n mstore(add(memPtr, 128), verifyingContract)\n\n // Compute hash\n result := keccak256(memPtr, 160)\n }\n return result;\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\n /// with getDomainHash().\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to the given EIP712 Domain.\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n internal\n pure\n returns (bytes32 result)\n {\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct\n // ));\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nlibrary LibUtils {\n\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\n return uint256(10)**(18-decimals);\n }\n\n function getDecimals(address tokenToUse) internal view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"LibUtils: No decimals\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n return uint8(abi.decode(data, (uint256)));\n }\n\n function getGranularity(address tokenToUse) internal view returns (uint256) {\n //support granularity if ERC777\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\n require(success, \"LibUtils: No granularity\");\n\n return abi.decode(data, (uint256));\n }\n\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n addr := mload(add(bys,20))\n }\n }\n\n}\n"
+ },
+ "contracts/nftbridge/INFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface INFTBridge {\n struct NFTClaimData {\n address payable to;\n address from;\n uint256 tokenId;\n address tokenAddress;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFixedFee() external view returns (uint256);\n\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId\n ) external payable;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\n */\n function claim(NFTClaimData calldata _claimData) external;\n\n function claimFallback(NFTClaimData calldata _claimData) external;\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns (bytes32);\n\n event Cross(\n address indexed _originalTokenAddress,\n address indexed _from,\n address indexed _to,\n address _tokenCreator,\n bytes _userData,\n uint256 _totalSupply,\n uint256 _tokenId,\n string _tokenURI\n );\n event NewSideNFTToken(\n address indexed _newSideNFTTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol\n );\n event AcceptedNFTCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FixedFeeNFTChanged(uint256 _amount);\n event ClaimedNFTToken(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _receiver\n );\n}\n"
+ },
+ "contracts/nftbridge/ISideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideNFTToken {\n function mint(address account, uint256 tokenId) external;\n}"
+ },
+ "contracts/nftbridge/ISideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideNFTTokenFactory {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external returns(address);\n\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IWrapped {\n function balanceOf(address) external returns(uint);\n\n function deposit() external payable;\n\n function withdraw(uint wad) external;\n\n function totalSupply() external view returns (uint);\n\n function approve(address guy, uint wad) external returns (bool);\n\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad)\n external\n returns (bool);\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../Initializable.sol\";\n\nimport \"../../../GSN/Context.sol\";\nimport \"../../../access/Roles.sol\";\n\ncontract UpgradablePauserRole is Initializable, Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n function __PauserRol_init(address sender) public initializer {\n if (!isPauser(sender)) {\n _addPauser(sender);\n }\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @title Roles\n * @dev Library for managing addresses assigned to a Role.\n */\nlibrary Roles {\n struct Role {\n mapping (address => bool) bearer;\n }\n\n /**\n * @dev Give an account access to this role.\n */\n function add(Role storage role, address account) internal {\n require(!has(role, account), \"Roles: account already has role\");\n role.bearer[account] = true;\n }\n\n /**\n * @dev Remove an account's access to this role.\n */\n function remove(Role storage role, address account) internal {\n require(has(role, account), \"Roles: account doesn't have role\");\n role.bearer[account] = false;\n }\n\n /**\n * @dev Check if an account has this role.\n * @return bool\n */\n function has(Role storage role, address account) internal view returns (bool) {\n require(account != address(0), \"Roles: account is the zero address\");\n return role.bearer[account];\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _tokenOwners.contains(tokenId);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(tokenId);\n\n emit Transfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n}\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract WRBTC is IWrapped {\n string public name = \"Wrapped RBTC\";\n string public symbol = \"WRBTC\";\n uint8 public decimals = 18;\n\n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n event Deposit(address indexed dst, uint wad);\n event Withdrawal(address indexed src, uint wad);\n\n mapping (address => uint) override public balanceOf;\n mapping (address => mapping (address => uint)) public allowance;\n\n receive () external payable {\n deposit();\n }\n function deposit() override public payable {\n balanceOf[msg.sender] += msg.value;\n emit Deposit(msg.sender, msg.value);\n }\n function withdraw(uint wad) override public {\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\n balanceOf[msg.sender] -= wad;\n msg.sender.transfer(wad);\n emit Withdrawal(msg.sender, wad);\n }\n\n function totalSupply() override public view returns (uint) {\n return address(this).balance;\n }\n\n function approve(address guy, uint wad) override public returns (bool) {\n allowance[msg.sender][guy] = wad;\n emit Approval(msg.sender, guy, wad);\n return true;\n }\n\n function transfer(address dst, uint wad) override public returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad)\n override public\n returns (bool)\n {\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\n\n if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\n allowance[src][msg.sender] -= wad;\n }\n\n balanceOf[src] -= wad;\n balanceOf[dst] += wad;\n\n emit Transfer(src, dst, wad);\n\n return true;\n }\n}"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant internal NULL_ADDRESS = address(0);\n bytes32 constant internal NULL_HASH = bytes32(0);\n IERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address internal federation;\n uint256 internal feePercentage;\n string public symbolPrefix;\n // replaces uint256 internal _depprecatedLastDay;\n bytes32 public domainSeparator;\n uint256 internal _deprecatedSpentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n // Percentage with up to 2 decimals\n uint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\n //Bridge_v3 variables\n bytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\n IWrapped public wrappedCurrency;\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n // keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\n mapping(address => uint) public nonces;\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool _isUpgrading);\n event WrappedCurrencyChanged(address _wrappedCurrency);\n\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n federation = _federation;\n //keccak256(\"ERC777TokensRecipient\")\n ERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n initDomainSeparator();\n }\n\n receive () external payable {\n // The fallback function is needed to use WRBTC\n require(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n }\n\n function version() override external pure returns (string memory) {\n return \"v3\";\n }\n\n function initDomainSeparator() public {\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n domainSeparator = LibEIP712.hashEIP712Domain(\n \"RSK Token Bridge\",\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"Bridge: Not Federation\");\n require(knownTokens[_originalTokenAddress] ||\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\n \"Bridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"Bridge: Null To\");\n require(_amount > 0, \"Bridge: Amount 0\");\n require(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _amount,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed also has the previously processed using the older bridge version\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n require(!claimed[_transactionDataHash], \"Bridge: Already claimed\");\n\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\n senderAddresses[_transactionHash] = _from;\n\n emit AcceptedCrossTransfer(\n _transactionHash,\n _originalTokenAddress,\n _to,\n _from,\n _amount,\n _blockHash,\n _logIndex\n );\n }\n\n\n function createSideToken(\n uint256 _typeId,\n address _originalTokenAddress,\n uint8 _originalTokenDecimals,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n address sideToken = mappedTokens[_originalTokenAddress];\n require(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\n\n mappedTokens[_originalTokenAddress] = sideToken;\n originalTokens[sideToken] = _originalTokenAddress;\n allowTokens.setToken(sideToken, _typeId);\n\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\n }\n\n function claim(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function claimFallback(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n receivedAmount = _claim(\n _claimData,\n _msgSender(),\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function getDigest(\n ClaimData memory _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline\n ) internal returns (bytes32) {\n return LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n CLAIM_TYPEHASH,\n _claimData.to,\n _claimData.amount,\n _claimData.transactionHash,\n _relayer,\n _fee,\n nonces[_claimData.to]++,\n _deadline\n )\n )\n );\n }\n\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external override returns (uint256 receivedAmount) {\n require(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\n\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claim(\n ClaimData calldata _claimData,\n address payable _reciever,\n address payable _relayer,\n uint256 _fee\n ) internal nonReentrant returns (uint256 receivedAmount) {\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n require(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.amount,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n require(!claimed[transactionDataHash], \"Bridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (knownTokens[originalTokenAddress]) {\n receivedAmount =_claimCrossBackToToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n } else {\n receivedAmount =_claimCrossToSideToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n }\n emit Claimed(\n _claimData.transactionHash,\n originalTokenAddress,\n _claimData.to,\n senderAddresses[_claimData.transactionHash],\n _claimData.amount,\n _claimData.blockHash,\n _claimData.logIndex,\n _reciever,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claimCrossToSideToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n address sideToken = mappedTokens[_originalTokenAddress];\n uint256 granularity = IERC777(sideToken).granularity();\n uint256 formattedAmount = _amount.mul(granularity);\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n ISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n if(_fee > 0) {\n ISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n }\n return receivedAmount;\n }\n\n function _claimCrossBackToToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n //As side tokens are ERC777 they will always have 18 decimals\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n if(address(wrappedCurrency) == _originalTokenAddress) {\n wrappedCurrency.withdraw(formattedAmount);\n _receiver.transfer(receivedAmount);\n if(_fee > 0) {\n _relayer.transfer(_fee);\n }\n } else {\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n if(_fee > 0) {\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n }\n }\n return receivedAmount;\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\n address sender = _msgSender();\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, to, amount, \"\");\n }\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) override external payable {\n address sender = _msgSender();\n require(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n wrappedCurrency.deposit{ value: msg.value }();\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \"\");\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external override(IBridge, IERC777Recipient){\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to this address\");\n address tokenToUse = _msgSender();\n require(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n require(userData.length != 0 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\n crossTokens(tokenToUse, from, receiver, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\n internal whenNotUpgrading whenNotPaused nonReentrant {\n knownTokens[tokenToUse] = true;\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n uint256 amountMinusFees = amount.sub(fee);\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n // We consider the amount before fees converted to 18 decimals to check the limits\n // updateTokenTransfer revert if token not allowed\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n address originalTokenAddress = tokenToUse;\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\n //Side Token Crossing\n originalTokenAddress = originalTokens[tokenToUse];\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\n uint256 modulo = amountMinusFees.mod(granularity);\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n }\n\n emit Cross(\n originalTokenAddress,\n from,\n to,\n amountMinusFees,\n userData\n );\n\n if (fee > 0) {\n //Send the payment to the MultiSig of the Federation\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n }\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n )\n public pure override returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n }\n\n function setFeePercentage(uint amount) external onlyOwner {\n require(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() external view override returns(uint) {\n return feePercentage;\n }\n\n function changeFederation(address newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n require(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n wrappedCurrency = IWrapped(_wrappedCurrency);\n emit WrappedCurrencyChanged(_wrappedCurrency);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionsDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionsDataHashes[transactionHash]];\n }\n\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an `IERC777` token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See `IERC1820Registry` and\n * `ERC1820Implementer`.\n */\ninterface IERC777 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See `operatorSend` and `operatorBurn`.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor`.\n *\n * Emits an `AuthorizedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor` and `defaultOperators`.\n *\n * Emits a `RevokedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if `authorizeOperator` was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * `revokeOperator`, in which case `isOperatorFor` will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n\n function decimals() external returns (uint8);\n\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n}\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IBridge {\n\n struct ClaimData {\n address payable to;\n uint256 amount;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) external payable;\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n */\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external returns (uint256 receivedAmount);\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns(bytes32);\n\n event Cross(\n address indexed _tokenAddress,\n address indexed _from,\n address indexed _to,\n uint256 _amount,\n bytes _userData\n );\n event NewSideToken(\n address indexed _newSideTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 _granularity\n );\n event AcceptedCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FeePercentageChanged(uint256 _amount);\n event Claimed(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _reciever,\n address _relayer,\n uint256 _fee\n );\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideToken {\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideTokenFactory {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\n\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../SideToken/SideToken.sol\";\n\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\n external onlyPrimary override returns(address) {\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\n emit SideTokenCreated(sideToken, symbol, granularity);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\nabstract contract Secondary is Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n constructor () {\n _primary = _msgSender();\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(_primary);\n }\n}\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\nimport \"../interface/IERC677Receiver.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../lib/LibEIP712.sol\";\n\ncontract SideToken is ISideToken, ERC777 {\n using Address for address;\n using SafeMath for uint256;\n\n address public minter;\n uint256 private _granularity;\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n bytes32 public domainSeparator;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n // ERC677 Transfer Event\n event Transfer(address,address,uint256,bytes);\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\n minter = _minterAddr;\n _granularity = _newGranularity;\n\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n domainSeparator = LibEIP712.hashEIP712Domain(\n name(),\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter override\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n /**\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\n * @param recipient The address to transfer to.\n * @param amount The amount to be transferred.\n * @param data The extra data to be passed to the receiving contract.\n */\n function transferAndCall(address recipient, uint amount, bytes calldata data)\n external returns (bool success)\n {\n address from = _msgSender();\n\n _send(from, from, recipient, amount, data, \"\", false);\n emit Transfer(from, recipient, amount, data);\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\n return true;\n }\n\n function granularity() public view override returns (uint256) {\n return _granularity;\n }\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\n bytes32 digest = LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../../token/ERC20/IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\n // See https://github.com/ethereum/solidity/issues/4024.\n\n // keccak256(\"ERC777TokensSender\")\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\n\n // keccak256(\"ERC777TokensRecipient\")\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping (address => mapping (address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(\n string memory aName,\n string memory aSymbol,\n address[] memory theDefaultOperators\n ) {\n _name = aName;\n _symbol = aSymbol;\n\n _defaultOperatorsArray = theDefaultOperators;\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\n _defaultOperators[_defaultOperatorsArray[i]] = true;\n }\n\n // register interfaces\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view override(IERC777) returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view override(IERC777) returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20Detailed-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override(IERC777) returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n\n address from = _msgSender();\n\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\n\n _move(from, from, recipient, amount, \"\", \"\");\n\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(\n address operator,\n address tokenHolder\n ) public view override(IERC777) returns (bool) {\n return operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) external override(IERC777) {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) external override(IERC777) {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n )\n external override(IERC777)\n {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {Transfer} events.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\n external override(IERC777) {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\n _burn(_msgSender(), account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender)\n public view override(IERC20) returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {Transfer} and {Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount)\n external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n require(holder != address(0), \"ERC777: transfer from zero address\");\n\n address spender = _msgSender();\n\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\n\n _move(spender, holder, recipient, amount, \"\", \"\");\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\n\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address operator,\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n require(account != address(0), \"ERC777: mint to zero address\");\n\n // Update state variables\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n internal\n {\n require(from != address(0), \"ERC777: send from zero address\");\n require(to != address(0), \"ERC777: send to zero address\");\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param operator address operator requesting the operation\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(\n address operator,\n address from,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n )\n internal\n {\n require(from != address(0), \"ERC777: burn from zero address\");\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n // Update state variables\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\n _balances[to] = _balances[to].add(amount);\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n function _approve(address holder, address spender, uint256 value) internal {\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\n // currently unnecessary.\n //require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n private\n {\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n}\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * `IERC777` Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an `IERC777` token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/Bridge/BridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"./IBridgeV2.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../AllowTokens/AllowTokensV0.sol\";\nimport \"../Utils/UtilsV1.sol\";\n\ncontract BridgeV2 is Initializable, IBridgeV2, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant private NULL_ADDRESS = address(0);\n bytes32 constant private NULL_HASH = bytes32(0);\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address private federation;\n uint256 private feePercentage;\n string public symbolPrefix;\n uint256 public lastDay;\n uint256 public spentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping(bytes32 => bool) public processed; // ProcessedHash => true\n AllowTokensV0 public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n uint256 constant public FEE_PERCENTAGE_DIVIDER = 10000; // Percentage with up to 2 decimals\n bool private alreadyRun;\n\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool isUpgrading);\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = AllowTokensV0(_allowTokens);\n _changeSideTokenFactory(_sideTokenFactory);\n _changeFederation(_federation);\n //keccak256(\"ERC777TokensRecipient\")\n ERC_1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function version() external pure override returns (string memory) {\n return \"v2\";\n }\n\n modifier onlyFederation() {\n require(msg.sender == federation, \"Bridge: Sender not Federation\");\n _;\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address tokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity\n ) external onlyFederation whenNotPaused nonReentrant override returns(bool) {\n require(tokenAddress != NULL_ADDRESS, \"Bridge: Token is null\");\n require(receiver != NULL_ADDRESS, \"Bridge: Receiver is null\");\n require(amount > 0, \"Bridge: Amount 0\");\n require(bytes(symbol).length > 0, \"Bridge: Empty symbol\");\n require(blockHash != NULL_HASH, \"Bridge: BlockHash is null\");\n require(transactionHash != NULL_HASH, \"Bridge: Transaction is null\");\n require(decimals <= 18, \"Bridge: Decimals bigger 18\");\n require(UtilsV1.granularityToDecimals(granularity) <= 18, \"Bridge: invalid granularity\");\n\n _processTransaction(blockHash, transactionHash, receiver, amount, logIndex);\n\n if (knownTokens[tokenAddress]) {\n _acceptCrossBackToToken(receiver, tokenAddress, decimals, granularity, amount);\n } else {\n _acceptCrossToSideToken(receiver, tokenAddress, decimals, granularity, amount, symbol);\n }\n return true;\n }\n\n function _acceptCrossToSideToken(\n address receiver,\n address tokenAddress,\n uint8 decimals,\n uint256 granularity,\n uint256 amount,\n string memory symbol\n ) private {\n\n (uint256 calculatedGranularity,uint256 formattedAmount) = UtilsV1.calculateGranularityAndAmount(decimals, granularity, amount);\n address sideToken = mappedTokens[tokenAddress];\n if (sideToken == NULL_ADDRESS) {\n sideToken = _createSideToken(tokenAddress, symbol, calculatedGranularity);\n } else {\n require(calculatedGranularity == IERC777(sideToken).granularity(), \"Bridge: Granularity differ from side token\");\n }\n ISideToken(sideToken).mint(receiver, formattedAmount, \"\", \"\");\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, 18, calculatedGranularity);\n }\n\n function _acceptCrossBackToToken(address receiver, address tokenAddress, uint8 decimals, uint256 granularity, uint256 amount) private {\n require(decimals == 18, \"Bridge: Invalid decimals cross back\");\n //As side tokens are ERC777 we need to convert granularity to decimals\n (uint8 calculatedDecimals, uint256 formattedAmount) = UtilsV1.calculateDecimalsAndAmount(tokenAddress, granularity, amount);\n IERC20(tokenAddress).safeTransfer(receiver, formattedAmount);\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, calculatedDecimals, 1);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokens(address tokenToUse, uint256 amount) override external whenNotUpgrading whenNotPaused nonReentrant returns(bool) {\n address sender = _msgSender();\n require(!sender.isContract(), \"Bridge: Sender can't be a contract\");\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, amount, \"\");\n return true;\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external whenNotPaused whenNotUpgrading override(IBridgeV2, IERC777Recipient) {\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to address\");\n address tokenToUse = _msgSender();\n //This can only be used with trusted contracts\n crossTokens(tokenToUse, from, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, uint256 amount, bytes memory userData) private {\n bool isASideToken = originalTokens[tokenToUse] != NULL_ADDRESS;\n //Send the payment to the MultiSig of the Federation\n uint256 fee = amount.mul(feePercentage).div(FEE_PERCENTAGE_DIVIDER);\n uint256 amountMinusFees = amount.sub(fee);\n if (isASideToken) {\n uint256 modulo = amountMinusFees.mod(IERC777(tokenToUse).granularity());\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n }\n if(fee > 0) {\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n if (isASideToken) {\n verifyWithAllowTokens(tokenToUse, amount, isASideToken);\n //Side Token Crossing\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n // solium-disable-next-line max-len\n emit Cross(originalTokens[tokenToUse], from, amountMinusFees, IERC777(tokenToUse).symbol(), userData, IERC777(tokenToUse).decimals(), IERC777(tokenToUse).granularity());\n } else {\n //Main Token Crossing\n knownTokens[tokenToUse] = true;\n (uint8 decimals, uint256 granularity, string memory symbol) = UtilsV1.getTokenInfo(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n //We consider the amount before fees converted to 18 decimals to check the limits\n verifyWithAllowTokens(tokenToUse, formattedAmount, isASideToken);\n emit Cross(tokenToUse, from, amountMinusFees, symbol, userData, decimals, granularity);\n }\n }\n\n function _createSideToken(address token, string memory symbol, uint256 granularity) private returns (address sideToken){\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, symbol));\n address sideTokenAddress = sideTokenFactory.createSideToken(newSymbol, newSymbol, granularity);\n sideToken = sideTokenAddress;\n mappedTokens[token] = sideToken;\n originalTokens[sideTokenAddress] = token;\n emit NewSideToken(sideTokenAddress, token, newSymbol, granularity);\n return sideToken;\n }\n\n function verifyWithAllowTokens(address tokenToUse, uint256 amount, bool isASideToken) private {\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n // solium-disable-next-line security/no-block-members\n lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n spentToday = 0;\n }\n require(allowTokens.isValidTokenTransfer(tokenToUse, amount, spentToday, isASideToken), \"Bridge: Bigger than limit\");\n spentToday = spentToday.add(amount);\n }\n\n function getTransactionId(\n bytes32 _blockHash,\n bytes32 _transactionHash,\n address _receiver,\n uint256 _amount,\n uint32 _logIndex\n )\n public pure returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _receiver, _amount, _logIndex));\n }\n\n function _processTransaction(\n bytes32 _blockHash,\n bytes32 _transactionHash,\n address _receiver,\n uint256 _amount,\n uint32 _logIndex\n )\n private\n {\n bytes32 compiledId = getTransactionId(_blockHash, _transactionHash, _receiver, _amount, _logIndex);\n require(!processed[compiledId], \"Bridge: Already processed\");\n processed[compiledId] = true;\n }\n\n function setFeePercentage(uint amount) external onlyOwner whenNotPaused {\n require(amount < (FEE_PERCENTAGE_DIVIDER/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() override external view returns(uint) {\n return feePercentage;\n }\n\n function calcMaxWithdraw() override external view returns (uint) {\n uint spent = spentToday;\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > lastDay + 24 hours) // solhint-disable-line not-rely-on-time\n spent = 0;\n return allowTokens.calcMaxWithdraw(spent);\n }\n\n function changeFederation(address newFederation) external onlyOwner returns(bool) {\n _changeFederation(newFederation);\n return true;\n }\n\n function _changeFederation(address newFederation) internal {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner returns(bool) {\n _changeSideTokenFactory(newSideTokenFactory);\n return true;\n }\n\n function _changeSideTokenFactory(address newSideTokenFactory) internal {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function startUpgrade() external onlyOwner {\n isUpgrading = true;\n emit Upgrading(isUpgrading);\n }\n\n function endUpgrade() external onlyOwner {\n isUpgrading = false;\n emit Upgrading(isUpgrading);\n }\n\n //This method is only to recreate the USDT and USDC tokens on rsk without granularity restrictions.\n function clearSideToken() external onlyOwner returns(bool) {\n require(!alreadyRun, \"already done\");\n alreadyRun = true;\n address payable[4] memory sideTokens = [\n 0xe506F698b31a66049BD4653ed934E7a07Cbc5549,\n 0x5a42221D7AaE8e185BC0054Bb036D9757eC18857,\n 0xcdc8ccBbFB6407c53118fE47259e8d00C81F42CD,\n 0x6117C9529F15c52e2d3188d5285C745B757b5825\n ];\n for (uint i = 0; i < sideTokens.length; i++) {\n address originalToken = address(originalTokens[sideTokens[i]]);\n originalTokens[sideTokens[i]] = NULL_ADDRESS;\n mappedTokens[originalToken] = address(NULL_ADDRESS);\n }\n return true;\n }\n\n}\n"
+ },
+ "contracts/Bridge/IBridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\ninterface IBridgeV2 {function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n function calcMaxWithdraw() external view returns (uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokens(address tokenToUse, uint256 amount) external returns(bool);\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the federation contract\n */\n function acceptTransfer(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity\n ) external returns(bool);\n\n event Cross(address indexed _tokenAddress, address indexed _to, uint256 _amount, string _symbol, bytes _userData,\n uint8 _decimals, uint256 _granularity);\n event NewSideToken(address indexed _newSideTokenAddress, address indexed _originalTokenAddress, string _newSymbol, uint256 _granularity);\n event AcceptedCrossTransfer(address indexed _tokenAddress, address indexed _to, uint256 _amount, uint8 _decimals, uint256 _granularity,\n uint256 _formattedAmount, uint8 _calculatedDecimals, uint256 _calculatedGranularity);\n event FeePercentageChanged(uint256 _amount);\n}"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract AllowTokensV0 is Ownable {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n\n mapping (address => bool) public allowedTokens;\n bool private validateAllowedTokens;\n uint256 private maxTokensAllowed;\n uint256 private minTokensAllowed;\n uint256 public dailyLimit;\n\n event AllowedTokenAdded(address indexed _tokenAddress);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event AllowedTokenValidation(bool _enabled);\n event MaxTokensAllowedChanged(uint256 _maxTokens);\n event MinTokensAllowedChanged(uint256 _minTokens);\n event DailyLimitChanged(uint256 dailyLimit);\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\n _;\n }\n\n constructor(address _manager) {\n transferOwnership(_manager);\n validateAllowedTokens = true;\n maxTokensAllowed = 10000 ether;\n minTokensAllowed = 1 ether;\n dailyLimit = 100000 ether;\n }\n\n function isValidatingAllowedTokens() external view returns(bool) {\n return validateAllowedTokens;\n }\n\n function getMaxTokensAllowed() external view returns(uint256) {\n return maxTokensAllowed;\n }\n\n function getMinTokensAllowed() external view returns(uint256) {\n return minTokensAllowed;\n }\n\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\n return allowedTokens[token];\n }\n\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\n if (validateAllowedTokens) {\n return allowedTokenExist(token);\n }\n return true;\n }\n\n function addAllowedToken(address token) external onlyOwner {\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\n allowedTokens[token] = true;\n emit AllowedTokenAdded(token);\n }\n\n function removeAllowedToken(address token) external onlyOwner {\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\n allowedTokens[token] = false;\n emit AllowedTokenRemoved(token);\n }\n\n function enableAllowedTokensValidation() external onlyOwner {\n validateAllowedTokens = true;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function disableAllowedTokensValidation() external onlyOwner {\n // Before disabling Allowed Tokens Validations some kind of contract validation system\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\n validateAllowedTokens = false;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\n maxTokensAllowed = maxTokens;\n emit MaxTokensAllowedChanged(maxTokensAllowed);\n }\n\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\n minTokensAllowed = minTokens;\n emit MinTokensAllowedChanged(minTokensAllowed);\n }\n\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\n dailyLimit = _dailyLimit;\n emit DailyLimitChanged(_dailyLimit);\n }\n\n // solium-disable-next-line max-len\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\n if(amount > maxTokensAllowed)\n return false;\n if(amount < minTokensAllowed)\n return false;\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\n return false;\n if(!isSideToken && !isTokenAllowed(tokenToUse))\n return false;\n return true;\n }\n\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\n uint maxWithrow = dailyLimit - spentToday;\n if (dailyLimit < spentToday)\n return 0;\n if(maxWithrow > maxTokensAllowed)\n maxWithrow = maxTokensAllowed;\n return maxWithrow;\n }\n\n}\n"
+ },
+ "contracts/Utils/UtilsV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nlibrary UtilsV1 {\n using SafeMath for uint256;\n\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n // keccak256(\"ERC777Token\")\n bytes32 constant private TOKENS_ERC777_HASH = 0xac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054;\n\n function getTokenInfo(address tokenToUse) external view returns (uint8 decimals, uint256 granularity, string memory symbol) {\n decimals = getDecimals(tokenToUse);\n granularity = getGranularity(tokenToUse);\n symbol = getSymbol(tokenToUse);\n }\n\n function getSymbol(address tokenToUse) public view returns (string memory symbol) {\n //support 32 bytes or string symbol\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"symbol()\"));\n require(success, \"Utils: Token hasn't symbol()\");\n if (data.length == 32) {\n symbol = bytes32ToString(abi.decode(data, (bytes32)));\n } else {\n symbol = abi.decode(data, (string));\n }\n require(bytes(symbol).length > 0, \"Utils: Token empty symbol\");\n return symbol;\n }\n\n function getDecimals(address tokenToUse) public view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"Utils: No decimals\");\n require(data.length == 32, \"Utils: Decimals not uint\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n uint256 decimalsDecoded = abi.decode(data, (uint256));\n require(decimalsDecoded <= 18, \"Utils: Decimals not in 0 to 18\");\n return uint8(decimalsDecoded);\n }\n\n function getGranularity(address tokenToUse) public view returns (uint256 granularity) {\n granularity = 1;\n //support granularity if ERC777\n address implementer = ERC_1820.getInterfaceImplementer(tokenToUse, TOKENS_ERC777_HASH);\n if (implementer != address(0)) {\n granularity = IERC777(implementer).granularity();\n //Verify granularity is power of 10 to keep it compatible with ERC20 decimals\n granularityToDecimals(granularity);\n }\n return granularity;\n }\n\n /* bytes32 (fixed-size array) to string (dynamically-sized array) */\n function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) {\n uint8 i = 0;\n while(i < 32 && _bytes32[i] != 0) {\n i++;\n }\n bytes memory bytesArray = new bytes(i);\n for (i = 0; i < 32 && _bytes32[i] != 0; i++) {\n bytesArray[i] = _bytes32[i];\n }\n return string(bytesArray);\n }\n\n function decimalsToGranularity(uint8 decimals) public pure returns (uint256) {\n require(decimals <= 18, \"Utils: Decimals not in 0 to 18\");\n return uint256(10)**(18-decimals);\n }\n\n function granularityToDecimals(uint256 granularity) public pure returns (uint8) {\n if(granularity == 1) return 18;\n if(granularity == 10) return 17;\n if(granularity == 100) return 16;\n if(granularity == 1000) return 15;\n if(granularity == 10000) return 14;\n if(granularity == 100000) return 13;\n if(granularity == 1000000) return 12;\n if(granularity == 10000000) return 11;\n if(granularity == 100000000) return 10;\n if(granularity == 1000000000) return 9;\n if(granularity == 10000000000) return 8;\n if(granularity == 100000000000) return 7;\n if(granularity == 1000000000000) return 6;\n if(granularity == 10000000000000) return 5;\n if(granularity == 100000000000000) return 4;\n if(granularity == 1000000000000000) return 3;\n if(granularity == 10000000000000000) return 2;\n if(granularity == 100000000000000000) return 1;\n if(granularity == 1000000000000000000) return 0;\n require(false, \"Utils: invalid granularity\");\n return 0;\n }\n\n function calculateGranularityAndAmount(uint8 decimals, uint256 granularity, uint256 amount) external pure\n returns(uint256 calculatedGranularity, uint256 formattedAmount) {\n\n if(decimals == 18) {\n //tokenAddress is a ERC20 with 18 decimals should have 1 granularity\n //tokenAddress is a ERC777 token we give the same granularity\n calculatedGranularity = granularity;\n formattedAmount = amount;\n } else {\n //tokenAddress is a ERC20 with other than 18 decimals\n calculatedGranularity = decimalsToGranularity(decimals);\n formattedAmount = amount.mul(calculatedGranularity);\n }\n }\n\n function calculateDecimalsAndAmount(address tokenAddress, uint256 granularity, uint256 amount)\n external view returns (uint8 calculatedDecimals, uint256 formattedAmount) {\n uint8 tokenDecimals = getDecimals(tokenAddress);\n //As side tokens are ERC777 we need to convert granularity to decimals\n calculatedDecimals = granularityToDecimals(granularity);\n require(tokenDecimals == calculatedDecimals, \"Utils: Token decimals differ from decimals - granularity\");\n formattedAmount = amount.div(granularity);\n }\n\n}\n"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () {\n _owner = _msgSender();\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../interface/IBridge.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockReceiveTokensCall is IERC777Recipient {\n address public bridge;\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor(address _bridge) {\n bridge = _bridge;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount) external {\n IERC20(tokenToUse).approve(bridge, amount);\n IBridge(bridge).receiveTokensTo(tokenToUse, receiver, amount);\n }\n\n function callDepositTo(address receiver) external payable {\n IBridge(bridge).depositTo{ value: msg.value }(receiver);\n }\n\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\n IERC777(tokenToUse).send(bridge, amount, data);\n }\n\n // Mandatory for IERC777Recipient\n function tokensReceived(\n address,\n address,\n address,\n uint,\n bytes calldata,\n bytes calldata\n ) override external view {\n this;\n }\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockERC777Recipient is IERC777Recipient {\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor() {\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\n }\n\n event Success(\n address operator,\n address from,\n address to,\n uint amount,\n bytes userData,\n bytes operatorData);\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) override external {\n emit Success(operator, from, to, amount, userData, operatorData);\n }\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\n\ncontract SideTokenV1 is ERC777 {\n address public minter;\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\n minter = _minterAddr;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../SideToken/SideTokenV1.sol\";\n\ncontract SideTokenFactoryV1 is Secondary {\n event CreatedSideToken(address sideToken, string symbol);\n\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\n emit CreatedSideToken(address(sideToken), symbol);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using SafeMath for uint256;\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping (uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /*\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri_) {\n _setURI(uri_);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) external view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: balance query for the zero address\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(amount);\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, address(0), id, amount);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\n /**\n @dev Handles the receipt of a single ERC1155 token type. This function is\n called at the end of a `safeTransferFrom` after the balance has been updated.\n To accept the transfer, this must return\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n (i.e. 0xf23a6e61, or its own function selector).\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n )\n external\n returns(bytes4);\n\n /**\n @dev Handles the receipt of a multiple ERC1155 token types. This function\n is called at the end of a `safeBatchTransferFrom` after the balances have\n been updated. To accept the transfer(s), this must return\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n (i.e. 0xbc197c81, or its own function selector).\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match values array)\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n )\n external\n returns(bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC1155 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Pausable is ERC1155, Pausable {\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\nimport \"../access/roles/PauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context, PauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n constructor () {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract PauserRole is Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n constructor () {\n _addPauser(_msgSender());\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC721.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC721 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC721Pausable is ERC721, Pausable {\n /**\n * @dev See {ERC721-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../../zeppelin/ownership/Ownable.sol\";\nimport \"../../zeppelin/math/SafeMath.sol\";\nimport \"../../zeppelin/utils/Strings.sol\";\nimport \"./OpenSeaEIP712Base.sol\";\n\n\n/**\n * @title OpenSea721\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\n */\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\n using SafeMath for uint256;\n\n uint256 private _currentTokenId = 0;\n\n constructor(\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n _initializeEIP712(_name);\n }\n\n function baseTokenURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/api/creature/\";\n }\n\n function contractURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\n }\n\n /**\n * @dev Mints a token to an address with a tokenURI.\n * @param _to address of the future owner of the token\n */\n function mintTo(address _to) public onlyOwner {\n uint256 newTokenId = _getNextTokenId();\n _mint(_to, newTokenId);\n _incrementTokenId();\n }\n\n /**\n * @dev calculates the next token ID based on value of _currentTokenId\n * @return uint256 for the next token ID\n */\n function _getNextTokenId() private view returns (uint256) {\n return _currentTokenId.add(1);\n }\n\n /**\n * @dev increments the value of _currentTokenId\n */\n function _incrementTokenId() private {\n _currentTokenId++;\n }\n\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\n }\n\n}"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../zeppelin/upgradable/Initializable.sol\";\n\ncontract OpenSeaEIP712Base is Initializable {\n struct EIP712Domain {\n string name;\n string version;\n address verifyingContract;\n bytes32 salt;\n }\n\n string constant public ERC712_VERSION = \"1\";\n\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\n bytes(\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\n )\n );\n bytes32 internal domainSeperator;\n\n // supposed to be called once while initializing.\n // one of the contracts that inherits this contract follows proxy pattern\n // so it is not possible to do this in a constructor\n function _initializeEIP712(\n string memory name\n )\n internal\n initializer\n {\n _setDomainSeperator(name);\n }\n\n function _setDomainSeperator(string memory name) internal {\n domainSeperator = keccak256(\n abi.encode(\n EIP712_DOMAIN_TYPEHASH,\n keccak256(bytes(name)),\n keccak256(bytes(ERC712_VERSION)),\n address(this),\n bytes32(getChainId())\n )\n );\n }\n\n function getDomainSeperator() public view returns (bytes32) {\n return domainSeperator;\n }\n\n function getChainId() public pure returns (uint256) {\n uint256 id;\n assembly {\n id := chainid()\n }\n return id;\n }\n\n /**\n * Accept message hash and returns hash message in EIP712 compatible form\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\n * https://eips.ethereum.org/EIPS/eip-712\n * \"\\\\x19\" makes the encoding deterministic\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\n */\n function toTypedMessageHash(bytes32 messageHash)\n internal\n view\n returns (bytes32)\n {\n return\n keccak256(\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\n );\n }\n}\n"
+ },
+ "contracts/Federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../interface/IBridge.sol\";\n\ncontract FederationV2 is Initializable, UpgradableOwnable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridge public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\n public validRequirement(_members.length, _required) initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n }\n\n function version() external pure returns (string memory) {\n return \"v2\";\n }\n\n function setBridge(address _bridge) external onlyOwner {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridge(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n )\n public onlyMember returns(bool)\n {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32)\n {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}"
+ },
+ "contracts/Federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../nftbridge/INFTBridge.sol\";\nimport \"../interface/IBridge.sol\";\nimport \"../interface/IFederation.sol\";\n\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridge public bridge;\n address[] public members;\n\n /**\n @notice The minimum amount of votes to approve a transaction\n @dev It should have more members than the required amount\n */\n uint public required;\n\n /**\n @notice All the addresses that are members of the federation\n @dev The address should be a member to vote in transactions\n */\n mapping (address => bool) public isMember;\n\n /**\n (bytes32) transactionId = keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n ) => (\n (address) members => (bool) voted\n )\n @notice Votes by members by the transaction ID\n @dev usually the members should approve the transaction by 50% + 1\n */\n mapping (bytes32 => mapping (address => bool)) public votes;\n\n /**\n (bytes32) transactionId => (bool) voted\n @notice Check if that transaction was already processed\n */\n mapping(bytes32 => bool) public processed;\n\n /** Federator v3 variables */\n INFTBridge public bridgeNFT;\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner, address _bridgeNFT) public\n validRequirement(_members.length, _required) initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n _setNFTBridge(_bridgeNFT);\n }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure override returns (string memory) {\n return \"v3\";\n }\n\n /**\n @notice Sets a new bridge contract\n @dev Emits BridgeChanged event\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external onlyOwner override {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridge(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n /**\n @notice Sets a new NFT bridge contract\n @dev Emits NFTBridgeChanged event\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external onlyOwner override {\n _setNFTBridge(_bridgeNFT);\n }\n\n function _setNFTBridge(address _bridgeNFT) internal {\n require(_bridgeNFT != NULL_ADDRESS, \"Federation: Empty NFT bridge\");\n bridgeNFT = INFTBridge(_bridgeNFT);\n emit NFTBridgeChanged(_bridgeNFT);\n }\n\n function validateTransaction(bytes32 transactionId) internal view returns(bool) {\n uint transactionCount = getTransactionCount(transactionId);\n return transactionCount >= required && transactionCount >= members.length / 2 + 1;\n }\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) external onlyMember override {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return;\n\n if (votes[transactionId][_msgSender()])\n return;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n logIndex\n );\n\n if (validateTransaction(transactionId)) {\n processed[transactionId] = true;\n acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex,\n tokenType\n );\n\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n logIndex\n );\n return;\n }\n }\n\n function acceptTransfer(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) internal {\n if (tokenType == TokenType.NFT) {\n require(address(bridgeNFT) != NULL_ADDRESS, \"Federation: Empty NFTBridge\");\n bridgeNFT.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n return;\n }\n\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n }\n\n /**\n @notice Get the amount of approved votes for that transactionId\n @param transactionId The transaction hashed from getTransactionId function\n */\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n /**\n @notice Gets the hash of transaction from the following parameters encoded and keccaked\n @dev It encodes and applies keccak256 to the parameters received in the same order\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param amount Could be the amount or the tokenId\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @return The hash generated by the parameters.\n */\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32) {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner override\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner override\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view override returns (address[] memory) {\n return members;\n }\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @dev Emits the RequirementChange event\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n /**\n @notice It emits an HeartBeat like an health check\n @dev Emits HeartBeat event\n */\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember override {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface IFederation {\n enum TokenType{ COIN, NFT }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure returns (string memory);\n\n /**\n @notice Sets a new bridge contract\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external;\n\n /**\n @notice Sets a new NFT bridge contract\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external;\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) external;\n\n /**\n @notice Add a new member to the federation\n @param _newMember address of the new member\n */\n function addMember(address _newMember) external;\n\n /**\n @notice Remove a member of the federation\n @param _oldMember address of the member to be removed from federation\n */\n function removeMember(address _oldMember) external;\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view returns (address[] memory);\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external;\n\n /**\n @notice It emmits an HeartBeat like an healthy check\n */\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event NFTBridgeChanged(address bridgeNFT);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n}\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract MinterRole is Context {\n using Roles for Roles.Role;\n\n event MinterAdded(address indexed account);\n event MinterRemoved(address indexed account);\n\n Roles.Role private _minters;\n\n constructor () {\n _addMinter(_msgSender());\n }\n\n modifier onlyMinter() {\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\n _;\n }\n\n function isMinter(address account) public view returns (bool) {\n return _minters.has(account);\n }\n\n function addMinter(address account) public onlyMinter {\n _addMinter(account);\n }\n\n function renounceMinter() public {\n _removeMinter(_msgSender());\n }\n\n function _addMinter(address account) internal {\n _minters.add(account);\n emit MinterAdded(account);\n }\n\n function _removeMinter(address account) internal {\n _minters.remove(account);\n emit MinterRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20Mintable}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() override public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) override public view returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) override public returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) override public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) override public returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal {\n require(sender != address(0), \"ERC20: transfer from zero address\");\n require(recipient != address(0), \"ERC20: transfer to zero address\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: mint to zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: burn from zero address\");\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n *\n * This is internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal {\n require(owner != address(0), \"ERC20: approve from zero address\");\n require(spender != address(0), \"ERC20: approve to zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\n * from the caller's allowance.\n *\n * See {_burn} and {_approve}.\n */\n function _burnFrom(address account, uint256 amount) internal {\n _burn(account, amount);\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\n }\n}\n"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\nimport \"../interface/IERC677Receiver.sol\";\n\ncontract mockERC677Receiver is IERC677Receiver {\n event Success(address _sender, uint _value, bytes _data);\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\n emit Success(_sender, _value, _data);\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Optional functions from the ERC20 standard.\n */\nabstract contract ERC20Detailed is IERC20 {\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\n * these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\n _name = aName;\n _symbol = aSymbol;\n _decimals = theDecimals;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./Proxy.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n *\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\n * {TransparentUpgradeableProxy}.\n */\ncontract UpgradeableProxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _setImplementation(_logic);\n if(_data.length > 0) {\n Address.functionDelegateCall(_logic, _data);\n }\n }\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n bytes32 slot = _IMPLEMENTATION_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n impl := sload(slot)\n }\n }\n\n /**\n * @dev Upgrades the proxy to a new implementation.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal virtual {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\n\n bytes32 slot = _IMPLEMENTATION_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newImplementation)\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./UpgradeableProxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _setAdmin(admin_);\n }\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _admin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _admin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\n emit AdminChanged(_admin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external virtual ifAdmin {\n _upgradeTo(newImplementation);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\n _upgradeTo(newImplementation);\n Address.functionDelegateCall(newImplementation, data);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address adm) {\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n adm := sload(slot)\n }\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n bytes32 slot = _ADMIN_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newAdmin)\n }\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../ownership/Ownable.sol\";\nimport \"./TransparentUpgradeableProxy.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
+ },
+ "contracts/Federation/FederationV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../Bridge/IBridgeV2.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract FederationV1 is Ownable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridgeV2 public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n // solium-disable-next-line max-len\n event Voted(address indexed sender, bytes32 indexed transactionId, address originalTokenAddress, address receiver, uint256 amount, string symbol, bytes32 blockHash, bytes32 indexed transactionHash, uint32 logIndex, uint8 decimals, uint256 granularity);\n event Executed(bytes32 indexed transactionId);\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Caller not a Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n constructor(address[] memory _members, uint _required) validRequirement(_members.length, _required) {\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Members larger than max allowed\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n }\n\n function setBridge(address _bridge) external onlyOwner {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridgeV2(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity)\n external onlyMember returns(bool)\n {\n // solium-disable-next-line max-len\n bytes32 transactionId = getTransactionId(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n // solium-disable-next-line max-len\n emit Voted(_msgSender(), transactionId, originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bool acceptTransfer = bridge.acceptTransfer(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n require(acceptTransfer, \"Federation: Bridge acceptTransfer error\");\n emit Executed(transactionId);\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string memory symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity)\n public pure returns(bytes32)\n {\n // solium-disable-next-line max-len\n return keccak256(abi.encodePacked(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity));\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove last element\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n}"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\n\ncontract BridgeProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract FederationProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract MainToken is ERC20Detailed, ERC20 {\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\n ERC20Detailed(name, symbol, decimals)\n {\n _mint(msg.sender, totalSupply);\n }\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\n bool result = transfer(_to, _value);\n if (!result) return false;\n\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\n receiver.tokenFallback(msg.sender, _value, _data);\n\n // IMPORTANT: the ERC-677 specification does not say\n // anything about the use of the receiver contract's\n // tokenFallback method return value. Given\n // its return type matches with this method's return\n // type, returning it could be a possibility.\n // We here take the more conservative approach and\n // ignore the return value, returning true\n // to signal a succesful transfer despite tokenFallback's\n // return value -- fact being tokens are transferred\n // in any case.\n return true;\n }\n}\n\ninterface ERC677TransferReceiver {\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\n}"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract AlternativeERC20Detailed is ERC20 {\n string private _name;\n bytes32 private _symbol;\n uint256 private _decimals;\n\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\n {\n _name = aName;\n _symbol = aSymbol;\n _decimals = someDecimals;\n _mint(msg.sender, aTotalSupply);\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (bytes32) {\n return _symbol;\n }\n\n function decimals() public view returns (uint256) {\n return _decimals;\n }\n}"
+ },
+ "contracts/test/nftbridge/NFTERC721TestToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.6;\n\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\n\ncontract NFTERC721TestToken is ERC721 {\n\n string private _contractURI;\n\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\n\n function safeMint(address to, uint256 tokenId) public {\n _safeMint(to, tokenId);\n }\n\n function setBaseURI(string memory baseURI) public {\n _setBaseURI(baseURI);\n }\n\n function setContractURI(string memory contractURI_) public {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n function setTokenURI(uint256 tokenId, string memory _tokenURI) public {\n _setTokenURI(tokenId, _tokenURI);\n }\n\n}\n"
+ },
+ "contracts/nftbridge/SideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./ISideNFTToken.sol\";\nimport \"../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\n\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\n address public minter;\n string private _contractURI;\n\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\n require(_minter != address(0), \"SideToken: Empty Minter\");\n minter = _minter;\n _setBaseURI(_baseURI);\n _setContractURI(contractURI_);\n }\n\n function _setContractURI(string memory contractURI_) internal {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(address account, uint256 tokenId) external onlyMinter override {\n _mint(account, tokenId);\n }\n}"
+ },
+ "contracts/nftbridge/SideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"./SideNFTToken.sol\";\n\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external onlyPrimary override returns(address) {\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\n return sideTokenAddress;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() {\n _registerInterface(\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\n );\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721Receiver.sol\";\n\n /**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers. \n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Burnable is ERC1155 {\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n}\n"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../lib/LibUtils.sol\";\n\ncontract LibUtilsHarness {\n\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\n return LibUtils.decimalsToGranularity(decimals);\n }\n\n function getDecimals(address tokenToUse) external view returns (uint8) {\n return LibUtils.getDecimals(tokenToUse);\n }\n\n function getGranularity(address tokenToUse) external view returns (uint256) {\n return LibUtils.getGranularity(tokenToUse);\n }\n\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\n return LibUtils.bytesToAddress(bys);\n }\n\n}\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetbsc/solcInputs/c9c50994c7f4ed6c6a7c2f652aca7adb.json b/bridge/deployments/rsktestnetbsc/solcInputs/c9c50994c7f4ed6c6a7c2f652aca7adb.json
new file mode 100644
index 000000000..c7008191d
--- /dev/null
+++ b/bridge/deployments/rsktestnetbsc/solcInputs/c9c50994c7f4ed6c6a7c2f652aca7adb.json
@@ -0,0 +1,297 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/math/SafeMath.sol\";\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\n\nimport \"../interface/IAllowTokens.sol\";\n\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n uint256 constant public MAX_TYPES = 250;\n mapping (address => TokenInfo) public allowedTokens;\n mapping (uint256 => Limits) public typeLimits;\n uint256 public smallAmountConfirmations;\n uint256 public mediumAmountConfirmations;\n uint256 public largeAmountConfirmations;\n string[] public typeDescriptions;\n\n event SetToken(address indexed _tokenAddress, uint256 _typeId);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\n event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\n event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\n event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\n\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\n _;\n }\n\n function initialize(\n address _manager,\n address _primary,\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations,\n TypeInfo[] memory typesInfo) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradableSecondary.__Secondary_init(_primary);\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n for(uint i = 0; i < typesInfo.length; i = i + 1) {\n _addTokenType(typesInfo[i].description, typesInfo[i].limits);\n }\n }\n\n function version() override external pure returns (string memory) {\n return \"v1\";\n }\n\n function getInfoAndLimits(address token) override public view\n returns (TokenInfo memory info, Limits memory limit) {\n info = allowedTokens[token];\n limit = typeLimits[info.typeId];\n return (info, limit);\n }\n function calcMaxWithdraw(address token) override public view returns (uint256 maxWithdraw) {\n (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\n return _calcMaxWithdraw(info, limits);\n }\n\n function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n info.spentToday = 0;\n }\n if (limits.daily <= info.spentToday)\n return 0;\n maxWithdraw = limits.daily - info.spentToday;\n if(maxWithdraw > limits.max)\n maxWithdraw = limits.max;\n return maxWithdraw;\n }\n\n // solium-disable-next-line max-len\n function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\n (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\n require(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\n require(amount >= limit.min, \"AllowTokens: Lower than limit\");\n\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n // solium-disable-next-line security/no-block-members\n info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n info.spentToday = 0;\n }\n uint maxWithdraw = _calcMaxWithdraw(info, limit);\n require(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\n info.spentToday = info.spentToday.add(amount);\n allowedTokens[token] = info;\n\n emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\n }\n\n function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\n require(bytes(description).length > 0, \"AllowTokens: Empty description\");\n len = typeDescriptions.length;\n require(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\n typeDescriptions.push(description);\n _setTypeLimits(len, limits);\n emit TokenTypeAdded(len, description);\n return len;\n }\n\n function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\n return _addTokenType(description, limits);\n }\n\n function _setTypeLimits(uint256 typeId, Limits memory limits) private {\n require(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\n require(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\n require(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\n require(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\n require(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\n typeLimits[typeId] = limits;\n emit TypeLimitsChanged(typeId, limits);\n }\n\n function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\n _setTypeLimits(typeId, limits);\n }\n\n function getTypesLimits() external view override returns(Limits[] memory limits) {\n limits = new Limits[](typeDescriptions.length);\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\n limits[i] = typeLimits[i];\n }\n return limits;\n }\n\n function getTypeDescriptionsLength() external view override returns(uint256) {\n return typeDescriptions.length;\n }\n\n function getTypeDescriptions() external view override returns(string[] memory descriptions) {\n descriptions = new string[](typeDescriptions.length);\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\n descriptions[i] = typeDescriptions[i];\n }\n return descriptions;\n }\n\n function isTokenAllowed(address token) public view notNull(token) override returns (bool) {\n return allowedTokens[token].allowed;\n }\n\n function setToken(address token, uint256 typeId) override public notNull(token) {\n require(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\n require(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\n TokenInfo memory info = allowedTokens[token];\n info.allowed = true;\n info.typeId = typeId;\n allowedTokens[token] = info;\n emit SetToken(token, typeId);\n }\n\n function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\n require(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\n for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\n setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\n }\n }\n\n function removeAllowedToken(address token) external notNull(token) onlyOwner {\n TokenInfo memory info = allowedTokens[token];\n require(info.allowed, \"AllowTokens: Not Allowed\");\n info.allowed = false;\n allowedTokens[token] = info;\n emit AllowedTokenRemoved(token);\n }\n\n function setConfirmations(\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations) external onlyOwner {\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n }\n\n function _setConfirmations(\n uint256 _smallAmountConfirmations,\n uint256 _mediumAmountConfirmations,\n uint256 _largeAmountConfirmations) private {\n require(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\n require(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\n smallAmountConfirmations = _smallAmountConfirmations;\n mediumAmountConfirmations = _mediumAmountConfirmations;\n largeAmountConfirmations = _largeAmountConfirmations;\n emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\n }\n\n function getConfirmations() external view override\n returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount) {\n return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\n }\n\n}\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @title Initializable\n *\n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(initializing || !initialized, \"Contract instance is already initialized\");\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\n * the owner.\n */\ncontract UpgradableOwnable is Initializable, Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function initialize(address sender) public initializer {\n _owner = sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * > Note: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\n\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\ncontract UpgradableSecondary is Initializable, Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n function __Secondary_init(address sender) public initializer {\n _primary = sender;\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(recipient);\n }\n\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IAllowTokens {\n\n struct Limits {\n uint256 min;\n uint256 max;\n uint256 daily;\n uint256 mediumAmount;\n uint256 largeAmount;\n }\n\n struct TokenInfo {\n bool allowed;\n uint256 typeId;\n uint256 spentToday;\n uint256 lastDay;\n }\n\n struct TypeInfo {\n string description;\n Limits limits;\n }\n\n struct TokensAndType {\n address token;\n uint256 typeId;\n }\n\n function version() external pure returns (string memory);\n\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\n\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\n\n function getTypesLimits() external view returns(Limits[] memory limits);\n\n function getTypeDescriptionsLength() external view returns(uint256);\n\n function getTypeDescriptions() external view returns(string[] memory descriptions);\n\n function setToken(address token, uint256 typeId) external;\n\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\n\n function isTokenAllowed(address token) external view returns (bool);\n\n function updateTokenTransfer(address token, uint256 amount) external;\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n\n function _msgSender() internal view returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
+ },
+ "contracts/nftbridge/NFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC721/IERC721.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Metadata.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Enumerable.sol\";\nimport \"../zeppelin/token/ERC721/IERC721Receiver.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"./INFTBridge.sol\";\nimport \"./ISideNFTToken.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract NFTBridge is\n Initializable,\n INFTBridge,\n UpgradablePausable,\n UpgradableOwnable,\n ReentrancyGuard,\n IERC721Receiver {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address internal constant NULL_ADDRESS = address(0);\n bytes32 internal constant NULL_HASH = bytes32(0);\n IERC1820Registry internal constant ERC1820 =\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address payable internal federation;\n uint256 internal fixedFee;\n string public symbolPrefix;\n\n mapping(address => address) public sideTokenAddressByOriginalTokenAddress;\n mapping(address => address) public originalTokenAddressBySideTokenAddress;\n mapping(address => bool) public isAddressFromCrossedOriginalToken; // address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideNFTTokenFactory public sideTokenFactory;\n bool public isUpgrading;\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\n event Upgrading(bool _isUpgrading);\n\n function initialize(\n address _manager,\n address payable _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\n federation = _federation;\n ERC1820.setInterfaceImplementer(\n address(this),\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\n address(this)\n );\n }\n\n function version() external pure override returns (string memory) {\n return \"v1\";\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _tokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external override whenNotPaused nonReentrant {\n require(_msgSender() == federation, \"NFTBridge: Not Federation\");\n require(\n isAddressFromCrossedOriginalToken[_tokenAddress] ||\n sideTokenAddressByOriginalTokenAddress[_tokenAddress] != NULL_ADDRESS,\n \"NFTBridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"NFTBridge: Null To\");\n require(_from != NULL_ADDRESS, \"NFTBridge: Null From\");\n require(_blockHash != NULL_HASH, \"NFTBridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"NFTBridge: Null TxHash\");\n require(\n transactionDataHashes[_transactionHash] == bytes32(0),\n \"NFTBridge: Already accepted\"\n );\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\n require(!claimed[_transactionDataHash], \"NFTBridge: Already claimed\");\n\n transactionDataHashes[_transactionHash] = _transactionDataHash;\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\n// senderAddresses[_transactionHash] = _from;\n\n emit AcceptedNFTCrossTransfer(\n _transactionHash,\n _tokenAddress,\n _to,\n _from,\n _tokenId,\n _blockHash,\n _logIndex\n );\n }\n\n function createSideNFTToken(\n address _originalTokenAddress,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName,\n string calldata _baseURI,\n string calldata _contractURI\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"NFTBridge: Null original token address\");\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[_originalTokenAddress];\n require(sideTokenAddress == NULL_ADDRESS, \"NFTBridge: Side token already exists\");\n string memory sideTokenSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideTokenAddress = sideTokenFactory.createSideNFTToken(_originalTokenName, sideTokenSymbol, _baseURI, _contractURI);\n\n sideTokenAddressByOriginalTokenAddress[_originalTokenAddress] = sideTokenAddress;\n originalTokenAddressBySideTokenAddress[sideTokenAddress] = _originalTokenAddress;\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, sideTokenSymbol);\n }\n\n function claim(NFTClaimData calldata _claimData) external override {\n _claim(_claimData, _claimData.to);\n }\n\n function claimFallback(NFTClaimData calldata _claimData) external override {\n require(_msgSender() == _claimData.from, \"NFTBridge: invalid sender\");\n _claim(_claimData, _msgSender());\n }\n\n function _claim(\n NFTClaimData calldata _claimData,\n address payable _receiver\n ) internal {\n address tokenAddress = _claimData.tokenAddress;\n uint256 tokenId = _claimData.tokenId;\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.from,\n tokenId,\n tokenAddress,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\n \"NFTBridge: Wrong txDataHash\"\n );\n require(!claimed[transactionDataHash], \"NFTBridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n bool isClaimBeingRequestedInMainChain = isAddressFromCrossedOriginalToken[tokenAddress];\n if (isClaimBeingRequestedInMainChain) {\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\n } else {\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[tokenAddress];\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\n }\n\n emit ClaimedNFTToken(\n _claimData.transactionHash,\n tokenAddress,\n _claimData.to,\n _claimData.from,\n _claimData.tokenId,\n _claimData.blockHash,\n _claimData.logIndex,\n _receiver\n );\n }\n\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\"creator()\"));\n if (success) {\n return abi.decode(data, (address));\n }\n\n return IERC721(tokenAddress).ownerOf(tokenId);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId\n ) public payable override {\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\n\n address payable sender = _msgSender();\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\n\n crossTokens(tokenAddress, to, tokenCreator, \"\", tokenId);\n\n if (fixedFee > 0) {\n require(msg.value >= fixedFee, \"NFTBridge: value is smaller than fixed fee\");\n\n // Send the payment to the MultiSig of the Federation\n federation.transfer(fixedFee);\n if (msg.value > fixedFee) { // refund of unused value\n sender.transfer(msg.value.sub(fixedFee));\n }\n }\n }\n\n function crossTokens(\n address tokenAddress,\n address to,\n address tokenCreator,\n bytes memory userData,\n uint256 tokenId\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\n isAddressFromCrossedOriginalToken[tokenAddress] = true;\n\n IERC721Enumerable enumerable = IERC721Enumerable(tokenAddress);\n IERC721Metadata metadataIERC = IERC721Metadata(tokenAddress);\n string memory tokenURI = metadataIERC.tokenURI(tokenId);\n\n address originalTokenAddress = tokenAddress;\n if (originalTokenAddressBySideTokenAddress[tokenAddress] != NULL_ADDRESS) {\n originalTokenAddress = originalTokenAddressBySideTokenAddress[tokenAddress];\n ERC721Burnable(tokenAddress).burn(tokenId);\n }\n\n emit Cross(\n originalTokenAddress,\n _msgSender(),\n to,\n tokenCreator,\n userData,\n enumerable.totalSupply(),\n tokenId,\n tokenURI\n );\n }\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) public pure override returns (bytes32) {\n return keccak256(\n abi.encodePacked(\n _blockHash,\n _transactionHash,\n _to,\n _from,\n _tokenId,\n _tokenAddress,\n _logIndex\n )\n );\n }\n\n function setFixedFee(uint256 amount) external onlyOwner {\n fixedFee = amount;\n emit FixedFeeNFTChanged(fixedFee);\n }\n\n function getFixedFee() external view override returns (uint256) {\n return fixedFee;\n }\n\n function changeFederation(address payable newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"NFTBridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"NFTBridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns (address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\n require(\n newSideNFTTokenFactory != NULL_ADDRESS,\n \"NFTBridge: empty SideTokenFactory\"\n );\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionDataHashes[transactionHash]];\n }\n\n /**\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n}\n"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\n/**\n * @title Helps contracts guard against reentrancy attacks.\n * @author Remco Bloemen , Eenae \n * @dev If you mark a function `nonReentrant`, you should also\n * mark it `external`.\n */\ncontract ReentrancyGuard is Initializable {\n /// @dev counter to allow mutex lock with only one SSTORE operation\n uint256 private _guardCounter;\n\n function initialize() public initializer {\n // The counter starts at one to prevent changing it from zero to a non-zero\n // value, which is a more expensive operation.\n _guardCounter = 1;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _guardCounter += 1;\n uint256 localCounter = _guardCounter;\n _;\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\n }\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../Initializable.sol\";\n\nimport \"../../GSN/Context.sol\";\nimport \"../access/roles/UpgradablePauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n function __Pausable_init(address sender) public initializer {\n UpgradablePauserRole.__PauserRol_init(sender);\n\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as `account`'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `_account`.\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `_implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\n\n /**\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `_account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {ERC20Detailed}.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeERC20: low-level call failed\");\n\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n */\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./ERC721.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721Burnable is Context, ERC721 {\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n _burn(tokenId);\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\nlibrary LibEIP712 {\n\n // Hash of the EIP712 Domain Separator Schema\n // keccak256(abi.encodePacked(\n // \"EIP712Domain(\",\n // \"string name,\",\n // \"string version,\",\n // \"uint256 chainId,\",\n // \"address verifyingContract\",\n // \")\"\n // ))\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n /// @dev Calculates a EIP712 domain separator.\n /// @param name The EIP712 domain name.\n /// @param version The EIP712 domain version.\n /// @param verifyingContract The EIP712 verifying contract.\n /// @return result EIP712 domain separator.\n function hashEIP712Domain(\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract\n )\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n // keccak256(bytes(name)),\n // keccak256(bytes(version)),\n // chainId,\n // uint256(verifyingContract)\n // ))\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Calculate hashes of dynamic data\n let nameHash := keccak256(add(name, 32), mload(name))\n let versionHash := keccak256(add(version, 32), mload(version))\n\n // Load free memory pointer\n let memPtr := mload(64)\n\n // Store params in memory\n mstore(memPtr, schemaHash)\n mstore(add(memPtr, 32), nameHash)\n mstore(add(memPtr, 64), versionHash)\n mstore(add(memPtr, 96), chainId)\n mstore(add(memPtr, 128), verifyingContract)\n\n // Compute hash\n result := keccak256(memPtr, 160)\n }\n return result;\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\n /// with getDomainHash().\n /// @param hashStruct The EIP712 hash struct.\n /// @return result EIP712 hash applied to the given EIP712 Domain.\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n internal\n pure\n returns (bytes32 result)\n {\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct\n // ));\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nlibrary LibUtils {\n\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\n return uint256(10)**(18-decimals);\n }\n\n function getDecimals(address tokenToUse) internal view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"LibUtils: No decimals\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n return uint8(abi.decode(data, (uint256)));\n }\n\n function getGranularity(address tokenToUse) internal view returns (uint256) {\n //support granularity if ERC777\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\n require(success, \"LibUtils: No granularity\");\n\n return abi.decode(data, (uint256));\n }\n\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n addr := mload(add(bys,20))\n }\n }\n\n}\n"
+ },
+ "contracts/nftbridge/INFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface INFTBridge {\n struct NFTClaimData {\n address payable to;\n address from;\n uint256 tokenId;\n address tokenAddress;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFixedFee() external view returns (uint256);\n\n function receiveTokensTo(\n address tokenAddress,\n address to,\n uint256 tokenId\n ) external payable;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _tokenId,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\n */\n function claim(NFTClaimData calldata _claimData) external;\n\n function claimFallback(NFTClaimData calldata _claimData) external;\n\n function getTransactionDataHash(\n address _to,\n address _from,\n uint256 _tokenId,\n address _tokenAddress,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns (bytes32);\n\n event Cross(\n address indexed _originalTokenAddress,\n address indexed _from,\n address indexed _to,\n address _tokenCreator,\n bytes _userData,\n uint256 _totalSupply,\n uint256 _tokenId,\n string _tokenURI\n );\n event NewSideNFTToken(\n address indexed _newSideNFTTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol\n );\n event AcceptedNFTCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FixedFeeNFTChanged(uint256 _amount);\n event ClaimedNFTToken(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _tokenId,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _receiver\n );\n}\n"
+ },
+ "contracts/nftbridge/ISideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\ninterface ISideNFTToken {\n function mint(address account, uint256 tokenId) external;\n}"
+ },
+ "contracts/nftbridge/ISideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\ninterface ISideNFTTokenFactory {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external returns(address);\n\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IWrapped {\n function balanceOf(address) external returns(uint);\n\n function deposit() external payable;\n\n function withdraw(uint wad) external;\n\n function totalSupply() external view returns (uint);\n\n function approve(address guy, uint wad) external returns (bool);\n\n function transfer(address dst, uint wad) external returns (bool);\n\n function transferFrom(address src, address dst, uint wad)\n external\n returns (bool);\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../Initializable.sol\";\n\nimport \"../../../GSN/Context.sol\";\nimport \"../../../access/Roles.sol\";\n\ncontract UpgradablePauserRole is Initializable, Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n function __PauserRol_init(address sender) public initializer {\n if (!isPauser(sender)) {\n _addPauser(sender);\n }\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @title Roles\n * @dev Library for managing addresses assigned to a Role.\n */\nlibrary Roles {\n struct Role {\n mapping (address => bool) bearer;\n }\n\n /**\n * @dev Give an account access to this role.\n */\n function add(Role storage role, address account) internal {\n require(!has(role, account), \"Roles: account already has role\");\n role.bearer[account] = true;\n }\n\n /**\n * @dev Remove an account's access to this role.\n */\n function remove(Role storage role, address account) internal {\n require(has(role, account), \"Roles: account doesn't have role\");\n role.bearer[account] = false;\n }\n\n /**\n * @dev Check if an account has this role.\n * @return bool\n */\n function has(Role storage role, address account) internal view returns (bool) {\n require(account != address(0), \"Roles: account is the zero address\");\n return role.bearer[account];\n }\n}\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _tokenOwners.contains(tokenId);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(tokenId);\n\n emit Transfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n}\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../interface/IWrapped.sol\";\n\ncontract WRBTC is IWrapped {\n string public name = \"Wrapped RBTC\";\n string public symbol = \"WRBTC\";\n uint8 public decimals = 18;\n\n event Approval(address indexed src, address indexed guy, uint wad);\n event Transfer(address indexed src, address indexed dst, uint wad);\n event Deposit(address indexed dst, uint wad);\n event Withdrawal(address indexed src, uint wad);\n\n mapping (address => uint) override public balanceOf;\n mapping (address => mapping (address => uint)) public allowance;\n\n receive () external payable {\n deposit();\n }\n function deposit() override public payable {\n balanceOf[msg.sender] += msg.value;\n emit Deposit(msg.sender, msg.value);\n }\n function withdraw(uint wad) override public {\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\n balanceOf[msg.sender] -= wad;\n msg.sender.transfer(wad);\n emit Withdrawal(msg.sender, wad);\n }\n\n function totalSupply() override public view returns (uint) {\n return address(this).balance;\n }\n\n function approve(address guy, uint wad) override public returns (bool) {\n allowance[msg.sender][guy] = wad;\n emit Approval(msg.sender, guy, wad);\n return true;\n }\n\n function transfer(address dst, uint wad) override public returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint wad)\n override public\n returns (bool)\n {\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\n\n if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\n allowance[src][msg.sender] -= wad;\n }\n\n balanceOf[src] -= wad;\n balanceOf[dst] += wad;\n\n emit Transfer(src, dst, wad);\n\n return true;\n }\n}"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nimport \"../lib/LibEIP712.sol\";\nimport \"../lib/LibUtils.sol\";\n\nimport \"../interface/IBridge.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../interface/IAllowTokens.sol\";\nimport \"../interface/IWrapped.sol\";\n\n// solhint-disable-next-line max-states-count\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant internal NULL_ADDRESS = address(0);\n bytes32 constant internal NULL_HASH = bytes32(0);\n IERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address internal federation;\n uint256 internal feePercentage;\n string public symbolPrefix;\n // replaces uint256 internal _depprecatedLastDay;\n bytes32 public domainSeparator;\n uint256 internal _deprecatedSpentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\n IAllowTokens public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n // Percentage with up to 2 decimals\n uint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\n //Bridge_v3 variables\n bytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\n IWrapped public wrappedCurrency;\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\n\n // keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\n mapping(address => uint) public nonces;\n\n event AllowTokensChanged(address _newAllowTokens);\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool _isUpgrading);\n event WrappedCurrencyChanged(address _wrappedCurrency);\n\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = IAllowTokens(_allowTokens);\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\n federation = _federation;\n //keccak256(\"ERC777TokensRecipient\")\n ERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n initDomainSeparator();\n }\n\n receive () external payable {\n // The fallback function is needed to use WRBTC\n require(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\n }\n\n function version() override external pure returns (string memory) {\n return \"v3\";\n }\n\n function initDomainSeparator() public {\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n domainSeparator = LibEIP712.hashEIP712Domain(\n \"RSK Token Bridge\",\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external whenNotPaused nonReentrant override {\n require(_msgSender() == federation, \"Bridge: Not Federation\");\n require(knownTokens[_originalTokenAddress] ||\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\n \"Bridge: Unknown token\"\n );\n require(_to != NULL_ADDRESS, \"Bridge: Null To\");\n require(_amount > 0, \"Bridge: Amount 0\");\n require(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\n require(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\n\n bytes32 _transactionDataHash = getTransactionDataHash(\n _to,\n _amount,\n _blockHash,\n _transactionHash,\n _logIndex\n );\n // Do not remove, claimed also has the previously processed using the older bridge version\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\n require(!claimed[_transactionDataHash], \"Bridge: Already claimed\");\n\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\n senderAddresses[_transactionHash] = _from;\n\n emit AcceptedCrossTransfer(\n _transactionHash,\n _originalTokenAddress,\n _to,\n _from,\n _amount,\n _blockHash,\n _logIndex\n );\n }\n\n\n function createSideToken(\n uint256 _typeId,\n address _originalTokenAddress,\n uint8 _originalTokenDecimals,\n string calldata _originalTokenSymbol,\n string calldata _originalTokenName\n ) external onlyOwner {\n require(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\n address sideToken = mappedTokens[_originalTokenAddress];\n require(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\n\n // Create side token\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\n\n mappedTokens[_originalTokenAddress] = sideToken;\n originalTokens[sideToken] = _originalTokenAddress;\n allowTokens.setToken(sideToken, _typeId);\n\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\n }\n\n function claim(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function claimFallback(ClaimData calldata _claimData)\n external override returns (uint256 receivedAmount) {\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\n receivedAmount = _claim(\n _claimData,\n _msgSender(),\n payable(address(0)),\n 0\n );\n return receivedAmount;\n }\n\n function getDigest(\n ClaimData memory _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline\n ) internal returns (bytes32) {\n return LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n CLAIM_TYPEHASH,\n _claimData.to,\n _claimData.amount,\n _claimData.transactionHash,\n _relayer,\n _fee,\n nonces[_claimData.to]++,\n _deadline\n )\n )\n );\n }\n\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external override returns (uint256 receivedAmount) {\n require(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\n\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\n\n receivedAmount = _claim(\n _claimData,\n _claimData.to,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claim(\n ClaimData calldata _claimData,\n address payable _reciever,\n address payable _relayer,\n uint256 _fee\n ) internal nonReentrant returns (uint256 receivedAmount) {\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\n require(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\n\n bytes32 transactionDataHash = getTransactionDataHash(\n _claimData.to,\n _claimData.amount,\n _claimData.blockHash,\n _claimData.transactionHash,\n _claimData.logIndex\n );\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\n require(!claimed[transactionDataHash], \"Bridge: Already claimed\");\n\n claimed[transactionDataHash] = true;\n if (knownTokens[originalTokenAddress]) {\n receivedAmount =_claimCrossBackToToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n } else {\n receivedAmount =_claimCrossToSideToken(\n originalTokenAddress,\n _reciever,\n _claimData.amount,\n _relayer,\n _fee\n );\n }\n emit Claimed(\n _claimData.transactionHash,\n originalTokenAddress,\n _claimData.to,\n senderAddresses[_claimData.transactionHash],\n _claimData.amount,\n _claimData.blockHash,\n _claimData.logIndex,\n _reciever,\n _relayer,\n _fee\n );\n return receivedAmount;\n }\n\n function _claimCrossToSideToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n address sideToken = mappedTokens[_originalTokenAddress];\n uint256 granularity = IERC777(sideToken).granularity();\n uint256 formattedAmount = _amount.mul(granularity);\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n ISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\n if(_fee > 0) {\n ISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\n }\n return receivedAmount;\n }\n\n function _claimCrossBackToToken(\n address _originalTokenAddress,\n address payable _receiver,\n uint256 _amount,\n address payable _relayer,\n uint256 _fee\n ) internal returns (uint256 receivedAmount) {\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\n //As side tokens are ERC777 they will always have 18 decimals\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\n receivedAmount = formattedAmount - _fee;\n if(address(wrappedCurrency) == _originalTokenAddress) {\n wrappedCurrency.withdraw(formattedAmount);\n _receiver.transfer(receivedAmount);\n if(_fee > 0) {\n _relayer.transfer(_fee);\n }\n } else {\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\n if(_fee > 0) {\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\n }\n }\n return receivedAmount;\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\n address sender = _msgSender();\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, to, amount, \"\");\n }\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) override external payable {\n address sender = _msgSender();\n require(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\n wrappedCurrency.deposit{ value: msg.value }();\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \"\");\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external override(IBridge, IERC777Recipient){\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to this address\");\n address tokenToUse = _msgSender();\n require(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\n require(userData.length != 0 || !from.isContract(), \"Bridge: Specify receiver address in data\");\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\n crossTokens(tokenToUse, from, receiver, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\n internal whenNotUpgrading whenNotPaused nonReentrant {\n knownTokens[tokenToUse] = true;\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\n uint256 amountMinusFees = amount.sub(fee);\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n // We consider the amount before fees converted to 18 decimals to check the limits\n // updateTokenTransfer revert if token not allowed\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\n address originalTokenAddress = tokenToUse;\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\n //Side Token Crossing\n originalTokenAddress = originalTokens[tokenToUse];\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\n uint256 modulo = amountMinusFees.mod(granularity);\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n }\n\n emit Cross(\n originalTokenAddress,\n from,\n to,\n amountMinusFees,\n userData\n );\n\n if (fee > 0) {\n //Send the payment to the MultiSig of the Federation\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n }\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n )\n public pure override returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\n }\n\n function setFeePercentage(uint amount) external onlyOwner {\n require(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() external view override returns(uint) {\n return feePercentage;\n }\n\n function changeFederation(address newFederation) external onlyOwner {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\n require(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\n allowTokens = IAllowTokens(newAllowTokens);\n emit AllowTokensChanged(newAllowTokens);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function setUpgrading(bool _isUpgrading) external onlyOwner {\n isUpgrading = _isUpgrading;\n emit Upgrading(isUpgrading);\n }\n\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\n require(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\n wrappedCurrency = IWrapped(_wrappedCurrency);\n emit WrappedCurrencyChanged(_wrappedCurrency);\n }\n\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\n return transactionsDataHashes[transactionHash] != bytes32(0);\n }\n\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\n return claimed[transactionsDataHashes[transactionHash]];\n }\n\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an `IERC777` token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See `IERC1820Registry` and\n * `ERC1820Implementer`.\n */\ninterface IERC777 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See `operatorSend` and `operatorBurn`.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor`.\n *\n * Emits an `AuthorizedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor` and `defaultOperators`.\n *\n * Emits a `RevokedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if `authorizeOperator` was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * `revokeOperator`, in which case `isOperatorFor` will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n\n function decimals() external returns (uint8);\n\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n}\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\ninterface IBridge {\n\n struct ClaimData {\n address payable to;\n uint256 amount;\n bytes32 blockHash;\n bytes32 transactionHash;\n uint32 logIndex;\n }\n\n function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\n\n /**\n * Use network currency and cross it.\n */\n function depositTo(address to) external payable;\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\n */\n function acceptTransfer(\n address _originalTokenAddress,\n address payable _from,\n address payable _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external;\n\n /**\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\n */\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\n\n function claimGasless(\n ClaimData calldata _claimData,\n address payable _relayer,\n uint256 _fee,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external returns (uint256 receivedAmount);\n\n function getTransactionDataHash(\n address _to,\n uint256 _amount,\n bytes32 _blockHash,\n bytes32 _transactionHash,\n uint32 _logIndex\n ) external returns(bytes32);\n\n event Cross(\n address indexed _tokenAddress,\n address indexed _from,\n address indexed _to,\n uint256 _amount,\n bytes _userData\n );\n event NewSideToken(\n address indexed _newSideTokenAddress,\n address indexed _originalTokenAddress,\n string _newSymbol,\n uint256 _granularity\n );\n event AcceptedCrossTransfer(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _from,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex\n );\n event FeePercentageChanged(uint256 _amount);\n event Claimed(\n bytes32 indexed _transactionHash,\n address indexed _originalTokenAddress,\n address indexed _to,\n address _sender,\n uint256 _amount,\n bytes32 _blockHash,\n uint256 _logIndex,\n address _reciever,\n address _relayer,\n uint256 _fee\n );\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideToken {\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface ISideTokenFactory {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\n\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../SideToken/SideToken.sol\";\n\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\n\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\n external onlyPrimary override returns(address) {\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\n emit SideTokenCreated(sideToken, symbol, granularity);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\n */\nabstract contract Secondary is Context {\n address private _primary;\n\n /**\n * @dev Emitted when the primary contract changes.\n */\n event PrimaryTransferred(\n address recipient\n );\n\n /**\n * @dev Sets the primary account to the one that is creating the Secondary contract.\n */\n constructor () {\n _primary = _msgSender();\n emit PrimaryTransferred(_primary);\n }\n\n /**\n * @dev Reverts if called from any account other than the primary.\n */\n modifier onlyPrimary() {\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\n _;\n }\n\n /**\n * @return the address of the primary.\n */\n function primary() public view returns (address) {\n return _primary;\n }\n\n /**\n * @dev Transfers contract to a new primary.\n * @param recipient The address of new primary.\n */\n function transferPrimary(address recipient) public onlyPrimary {\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\n _primary = recipient;\n emit PrimaryTransferred(_primary);\n }\n}\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\nimport \"../interface/IERC677Receiver.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../lib/LibEIP712.sol\";\n\ncontract SideToken is ISideToken, ERC777 {\n using Address for address;\n using SafeMath for uint256;\n\n address public minter;\n uint256 private _granularity;\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n bytes32 public domainSeparator;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n // ERC677 Transfer Event\n event Transfer(address,address,uint256,bytes);\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\n minter = _minterAddr;\n _granularity = _newGranularity;\n\n uint chainId;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n chainId := chainid()\n }\n domainSeparator = LibEIP712.hashEIP712Domain(\n name(),\n \"1\",\n chainId,\n address(this)\n );\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter override\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n /**\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\n * @param recipient The address to transfer to.\n * @param amount The amount to be transferred.\n * @param data The extra data to be passed to the receiving contract.\n */\n function transferAndCall(address recipient, uint amount, bytes calldata data)\n external returns (bool success)\n {\n address from = _msgSender();\n\n _send(from, from, recipient, amount, data, \"\", false);\n emit Transfer(from, recipient, amount, data);\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\n return true;\n }\n\n function granularity() public view override returns (uint256) {\n return _granularity;\n }\n\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\n bytes32 digest = LibEIP712.hashEIP712Message(\n domainSeparator,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../../token/ERC20/IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\n // See https://github.com/ethereum/solidity/issues/4024.\n\n // keccak256(\"ERC777TokensSender\")\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\n\n // keccak256(\"ERC777TokensRecipient\")\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping (address => mapping (address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(\n string memory aName,\n string memory aSymbol,\n address[] memory theDefaultOperators\n ) {\n _name = aName;\n _symbol = aSymbol;\n\n _defaultOperatorsArray = theDefaultOperators;\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\n _defaultOperators[_defaultOperatorsArray[i]] = true;\n }\n\n // register interfaces\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view override(IERC777) returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view override(IERC777) returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20Detailed-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override(IERC777) returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n\n address from = _msgSender();\n\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\n\n _move(from, from, recipient, amount, \"\", \"\");\n\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(\n address operator,\n address tokenHolder\n ) public view override(IERC777) returns (bool) {\n return operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) external override(IERC777) {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) external override(IERC777) {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n )\n external override(IERC777)\n {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {Transfer} events.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\n external override(IERC777) {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\n _burn(_msgSender(), account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender)\n public view override(IERC20) returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {Transfer} and {Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount)\n external override(IERC20) returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n require(holder != address(0), \"ERC777: transfer from zero address\");\n\n address spender = _msgSender();\n\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\n\n _move(spender, holder, recipient, amount, \"\", \"\");\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\n\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address operator,\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n require(account != address(0), \"ERC777: mint to zero address\");\n\n // Update state variables\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n internal\n {\n require(from != address(0), \"ERC777: send from zero address\");\n require(to != address(0), \"ERC777: send to zero address\");\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param operator address operator requesting the operation\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(\n address operator,\n address from,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n )\n internal\n {\n require(from != address(0), \"ERC777: burn from zero address\");\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n // Update state variables\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\n _balances[to] = _balances[to].add(amount);\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n function _approve(address holder, address spender, uint256 value) internal {\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\n // currently unnecessary.\n //require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n private\n {\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n}\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * `IERC777` Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an `IERC777` token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "contracts/Bridge/BridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n// Import base Initializable contract\nimport \"../zeppelin/upgradable/Initializable.sol\";\n// Import interface and library from OpenZeppelin contracts\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/utils/Address.sol\";\nimport \"../zeppelin/math/SafeMath.sol\";\n\nimport \"./IBridgeV2.sol\";\nimport \"../interface/ISideToken.sol\";\nimport \"../interface/ISideTokenFactory.sol\";\nimport \"../AllowTokens/AllowTokensV0.sol\";\nimport \"../Utils/UtilsV1.sol\";\n\ncontract BridgeV2 is Initializable, IBridgeV2, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n address constant private NULL_ADDRESS = address(0);\n bytes32 constant private NULL_HASH = bytes32(0);\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n address private federation;\n uint256 private feePercentage;\n string public symbolPrefix;\n uint256 public lastDay;\n uint256 public spentToday;\n\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\n mapping (address => bool) public knownTokens; // OriginalToken => true\n mapping(bytes32 => bool) public processed; // ProcessedHash => true\n AllowTokensV0 public allowTokens;\n ISideTokenFactory public sideTokenFactory;\n //Bridge_v1 variables\n bool public isUpgrading;\n uint256 constant public FEE_PERCENTAGE_DIVIDER = 10000; // Percentage with up to 2 decimals\n bool private alreadyRun;\n\n event FederationChanged(address _newFederation);\n event SideTokenFactoryChanged(address _newSideTokenFactory);\n event Upgrading(bool isUpgrading);\n function initialize(\n address _manager,\n address _federation,\n address _allowTokens,\n address _sideTokenFactory,\n string memory _symbolPrefix\n ) public initializer {\n UpgradableOwnable.initialize(_manager);\n UpgradablePausable.__Pausable_init(_manager);\n symbolPrefix = _symbolPrefix;\n allowTokens = AllowTokensV0(_allowTokens);\n _changeSideTokenFactory(_sideTokenFactory);\n _changeFederation(_federation);\n //keccak256(\"ERC777TokensRecipient\")\n ERC_1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function version() external pure override returns (string memory) {\n return \"v2\";\n }\n\n modifier onlyFederation() {\n require(msg.sender == federation, \"Bridge: Sender not Federation\");\n _;\n }\n\n modifier whenNotUpgrading() {\n require(!isUpgrading, \"Bridge: Upgrading\");\n _;\n }\n\n function acceptTransfer(\n address tokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity\n ) external onlyFederation whenNotPaused nonReentrant override returns(bool) {\n require(tokenAddress != NULL_ADDRESS, \"Bridge: Token is null\");\n require(receiver != NULL_ADDRESS, \"Bridge: Receiver is null\");\n require(amount > 0, \"Bridge: Amount 0\");\n require(bytes(symbol).length > 0, \"Bridge: Empty symbol\");\n require(blockHash != NULL_HASH, \"Bridge: BlockHash is null\");\n require(transactionHash != NULL_HASH, \"Bridge: Transaction is null\");\n require(decimals <= 18, \"Bridge: Decimals bigger 18\");\n require(UtilsV1.granularityToDecimals(granularity) <= 18, \"Bridge: invalid granularity\");\n\n _processTransaction(blockHash, transactionHash, receiver, amount, logIndex);\n\n if (knownTokens[tokenAddress]) {\n _acceptCrossBackToToken(receiver, tokenAddress, decimals, granularity, amount);\n } else {\n _acceptCrossToSideToken(receiver, tokenAddress, decimals, granularity, amount, symbol);\n }\n return true;\n }\n\n function _acceptCrossToSideToken(\n address receiver,\n address tokenAddress,\n uint8 decimals,\n uint256 granularity,\n uint256 amount,\n string memory symbol\n ) private {\n\n (uint256 calculatedGranularity,uint256 formattedAmount) = UtilsV1.calculateGranularityAndAmount(decimals, granularity, amount);\n address sideToken = mappedTokens[tokenAddress];\n if (sideToken == NULL_ADDRESS) {\n sideToken = _createSideToken(tokenAddress, symbol, calculatedGranularity);\n } else {\n require(calculatedGranularity == IERC777(sideToken).granularity(), \"Bridge: Granularity differ from side token\");\n }\n ISideToken(sideToken).mint(receiver, formattedAmount, \"\", \"\");\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, 18, calculatedGranularity);\n }\n\n function _acceptCrossBackToToken(address receiver, address tokenAddress, uint8 decimals, uint256 granularity, uint256 amount) private {\n require(decimals == 18, \"Bridge: Invalid decimals cross back\");\n //As side tokens are ERC777 we need to convert granularity to decimals\n (uint8 calculatedDecimals, uint256 formattedAmount) = UtilsV1.calculateDecimalsAndAmount(tokenAddress, granularity, amount);\n IERC20(tokenAddress).safeTransfer(receiver, formattedAmount);\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, calculatedDecimals, 1);\n }\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokens(address tokenToUse, uint256 amount) override external whenNotUpgrading whenNotPaused nonReentrant returns(bool) {\n address sender = _msgSender();\n require(!sender.isContract(), \"Bridge: Sender can't be a contract\");\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\n crossTokens(tokenToUse, sender, amount, \"\");\n return true;\n }\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata\n ) external whenNotPaused whenNotUpgrading override(IBridgeV2, IERC777Recipient) {\n //Hook from ERC777address\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\n require(to == address(this), \"Bridge: Not to address\");\n address tokenToUse = _msgSender();\n //This can only be used with trusted contracts\n crossTokens(tokenToUse, from, amount, userData);\n }\n\n function crossTokens(address tokenToUse, address from, uint256 amount, bytes memory userData) private {\n bool isASideToken = originalTokens[tokenToUse] != NULL_ADDRESS;\n //Send the payment to the MultiSig of the Federation\n uint256 fee = amount.mul(feePercentage).div(FEE_PERCENTAGE_DIVIDER);\n uint256 amountMinusFees = amount.sub(fee);\n if (isASideToken) {\n uint256 modulo = amountMinusFees.mod(IERC777(tokenToUse).granularity());\n fee = fee.add(modulo);\n amountMinusFees = amountMinusFees.sub(modulo);\n }\n if(fee > 0) {\n IERC20(tokenToUse).safeTransfer(owner(), fee);\n }\n if (isASideToken) {\n verifyWithAllowTokens(tokenToUse, amount, isASideToken);\n //Side Token Crossing\n IERC777(tokenToUse).burn(amountMinusFees, userData);\n // solium-disable-next-line max-len\n emit Cross(originalTokens[tokenToUse], from, amountMinusFees, IERC777(tokenToUse).symbol(), userData, IERC777(tokenToUse).decimals(), IERC777(tokenToUse).granularity());\n } else {\n //Main Token Crossing\n knownTokens[tokenToUse] = true;\n (uint8 decimals, uint256 granularity, string memory symbol) = UtilsV1.getTokenInfo(tokenToUse);\n uint formattedAmount = amount;\n if(decimals != 18) {\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\n }\n //We consider the amount before fees converted to 18 decimals to check the limits\n verifyWithAllowTokens(tokenToUse, formattedAmount, isASideToken);\n emit Cross(tokenToUse, from, amountMinusFees, symbol, userData, decimals, granularity);\n }\n }\n\n function _createSideToken(address token, string memory symbol, uint256 granularity) private returns (address sideToken){\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, symbol));\n address sideTokenAddress = sideTokenFactory.createSideToken(newSymbol, newSymbol, granularity);\n sideToken = sideTokenAddress;\n mappedTokens[token] = sideToken;\n originalTokens[sideTokenAddress] = token;\n emit NewSideToken(sideTokenAddress, token, newSymbol, granularity);\n return sideToken;\n }\n\n function verifyWithAllowTokens(address tokenToUse, uint256 amount, bool isASideToken) private {\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\n // solium-disable-next-line security/no-block-members\n lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\n spentToday = 0;\n }\n require(allowTokens.isValidTokenTransfer(tokenToUse, amount, spentToday, isASideToken), \"Bridge: Bigger than limit\");\n spentToday = spentToday.add(amount);\n }\n\n function getTransactionId(\n bytes32 _blockHash,\n bytes32 _transactionHash,\n address _receiver,\n uint256 _amount,\n uint32 _logIndex\n )\n public pure returns(bytes32)\n {\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _receiver, _amount, _logIndex));\n }\n\n function _processTransaction(\n bytes32 _blockHash,\n bytes32 _transactionHash,\n address _receiver,\n uint256 _amount,\n uint32 _logIndex\n )\n private\n {\n bytes32 compiledId = getTransactionId(_blockHash, _transactionHash, _receiver, _amount, _logIndex);\n require(!processed[compiledId], \"Bridge: Already processed\");\n processed[compiledId] = true;\n }\n\n function setFeePercentage(uint amount) external onlyOwner whenNotPaused {\n require(amount < (FEE_PERCENTAGE_DIVIDER/10), \"Bridge: bigger than 10%\");\n feePercentage = amount;\n emit FeePercentageChanged(feePercentage);\n }\n\n function getFeePercentage() override external view returns(uint) {\n return feePercentage;\n }\n\n function calcMaxWithdraw() override external view returns (uint) {\n uint spent = spentToday;\n // solium-disable-next-line security/no-block-members\n if (block.timestamp > lastDay + 24 hours) // solhint-disable-line not-rely-on-time\n spent = 0;\n return allowTokens.calcMaxWithdraw(spent);\n }\n\n function changeFederation(address newFederation) external onlyOwner returns(bool) {\n _changeFederation(newFederation);\n return true;\n }\n\n function _changeFederation(address newFederation) internal {\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\n federation = newFederation;\n emit FederationChanged(federation);\n }\n\n function getFederation() external view returns(address) {\n return federation;\n }\n\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner returns(bool) {\n _changeSideTokenFactory(newSideTokenFactory);\n return true;\n }\n\n function _changeSideTokenFactory(address newSideTokenFactory) internal {\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\n emit SideTokenFactoryChanged(newSideTokenFactory);\n }\n\n function startUpgrade() external onlyOwner {\n isUpgrading = true;\n emit Upgrading(isUpgrading);\n }\n\n function endUpgrade() external onlyOwner {\n isUpgrading = false;\n emit Upgrading(isUpgrading);\n }\n\n //This method is only to recreate the USDT and USDC tokens on rsk without granularity restrictions.\n function clearSideToken() external onlyOwner returns(bool) {\n require(!alreadyRun, \"already done\");\n alreadyRun = true;\n address payable[4] memory sideTokens = [\n 0xe506F698b31a66049BD4653ed934E7a07Cbc5549,\n 0x5a42221D7AaE8e185BC0054Bb036D9757eC18857,\n 0xcdc8ccBbFB6407c53118fE47259e8d00C81F42CD,\n 0x6117C9529F15c52e2d3188d5285C745B757b5825\n ];\n for (uint i = 0; i < sideTokens.length; i++) {\n address originalToken = address(originalTokens[sideTokens[i]]);\n originalTokens[sideTokens[i]] = NULL_ADDRESS;\n mappedTokens[originalToken] = address(NULL_ADDRESS);\n }\n return true;\n }\n\n}\n"
+ },
+ "contracts/Bridge/IBridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\ninterface IBridgeV2 {function version() external pure returns (string memory);\n\n function getFeePercentage() external view returns(uint);\n\n function calcMaxWithdraw() external view returns (uint);\n\n /**\n * ERC-20 tokens approve and transferFrom pattern\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\n */\n function receiveTokens(address tokenToUse, uint256 amount) external returns(bool);\n\n /**\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\n */\n function tokensReceived (\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n\n /**\n * Accepts the transaction from the other chain that was voted and sent by the federation contract\n */\n function acceptTransfer(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity\n ) external returns(bool);\n\n event Cross(address indexed _tokenAddress, address indexed _to, uint256 _amount, string _symbol, bytes _userData,\n uint8 _decimals, uint256 _granularity);\n event NewSideToken(address indexed _newSideTokenAddress, address indexed _originalTokenAddress, string _newSymbol, uint256 _granularity);\n event AcceptedCrossTransfer(address indexed _tokenAddress, address indexed _to, uint256 _amount, uint8 _decimals, uint256 _granularity,\n uint256 _formattedAmount, uint8 _calculatedDecimals, uint256 _calculatedGranularity);\n event FeePercentageChanged(uint256 _amount);\n}"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract AllowTokensV0 is Ownable {\n using SafeMath for uint256;\n\n address constant private NULL_ADDRESS = address(0);\n\n mapping (address => bool) public allowedTokens;\n bool private validateAllowedTokens;\n uint256 private maxTokensAllowed;\n uint256 private minTokensAllowed;\n uint256 public dailyLimit;\n\n event AllowedTokenAdded(address indexed _tokenAddress);\n event AllowedTokenRemoved(address indexed _tokenAddress);\n event AllowedTokenValidation(bool _enabled);\n event MaxTokensAllowedChanged(uint256 _maxTokens);\n event MinTokensAllowedChanged(uint256 _minTokens);\n event DailyLimitChanged(uint256 dailyLimit);\n\n modifier notNull(address _address) {\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\n _;\n }\n\n constructor(address _manager) {\n transferOwnership(_manager);\n validateAllowedTokens = true;\n maxTokensAllowed = 10000 ether;\n minTokensAllowed = 1 ether;\n dailyLimit = 100000 ether;\n }\n\n function isValidatingAllowedTokens() external view returns(bool) {\n return validateAllowedTokens;\n }\n\n function getMaxTokensAllowed() external view returns(uint256) {\n return maxTokensAllowed;\n }\n\n function getMinTokensAllowed() external view returns(uint256) {\n return minTokensAllowed;\n }\n\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\n return allowedTokens[token];\n }\n\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\n if (validateAllowedTokens) {\n return allowedTokenExist(token);\n }\n return true;\n }\n\n function addAllowedToken(address token) external onlyOwner {\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\n allowedTokens[token] = true;\n emit AllowedTokenAdded(token);\n }\n\n function removeAllowedToken(address token) external onlyOwner {\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\n allowedTokens[token] = false;\n emit AllowedTokenRemoved(token);\n }\n\n function enableAllowedTokensValidation() external onlyOwner {\n validateAllowedTokens = true;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function disableAllowedTokensValidation() external onlyOwner {\n // Before disabling Allowed Tokens Validations some kind of contract validation system\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\n validateAllowedTokens = false;\n emit AllowedTokenValidation(validateAllowedTokens);\n }\n\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\n maxTokensAllowed = maxTokens;\n emit MaxTokensAllowedChanged(maxTokensAllowed);\n }\n\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\n minTokensAllowed = minTokens;\n emit MinTokensAllowedChanged(minTokensAllowed);\n }\n\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\n dailyLimit = _dailyLimit;\n emit DailyLimitChanged(_dailyLimit);\n }\n\n // solium-disable-next-line max-len\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\n if(amount > maxTokensAllowed)\n return false;\n if(amount < minTokensAllowed)\n return false;\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\n return false;\n if(!isSideToken && !isTokenAllowed(tokenToUse))\n return false;\n return true;\n }\n\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\n uint maxWithrow = dailyLimit - spentToday;\n if (dailyLimit < spentToday)\n return 0;\n if(maxWithrow > maxTokensAllowed)\n maxWithrow = maxTokensAllowed;\n return maxWithrow;\n }\n\n}\n"
+ },
+ "contracts/Utils/UtilsV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/math/SafeMath.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\n\nlibrary UtilsV1 {\n using SafeMath for uint256;\n\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n // keccak256(\"ERC777Token\")\n bytes32 constant private TOKENS_ERC777_HASH = 0xac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054;\n\n function getTokenInfo(address tokenToUse) external view returns (uint8 decimals, uint256 granularity, string memory symbol) {\n decimals = getDecimals(tokenToUse);\n granularity = getGranularity(tokenToUse);\n symbol = getSymbol(tokenToUse);\n }\n\n function getSymbol(address tokenToUse) public view returns (string memory symbol) {\n //support 32 bytes or string symbol\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"symbol()\"));\n require(success, \"Utils: Token hasn't symbol()\");\n if (data.length == 32) {\n symbol = bytes32ToString(abi.decode(data, (bytes32)));\n } else {\n symbol = abi.decode(data, (string));\n }\n require(bytes(symbol).length > 0, \"Utils: Token empty symbol\");\n return symbol;\n }\n\n function getDecimals(address tokenToUse) public view returns (uint8) {\n //support decimals as uint256 or uint8\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"Utils: No decimals\");\n require(data.length == 32, \"Utils: Decimals not uint\");\n // uint: enc(X) is the big-endian encoding of X,\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\n uint256 decimalsDecoded = abi.decode(data, (uint256));\n require(decimalsDecoded <= 18, \"Utils: Decimals not in 0 to 18\");\n return uint8(decimalsDecoded);\n }\n\n function getGranularity(address tokenToUse) public view returns (uint256 granularity) {\n granularity = 1;\n //support granularity if ERC777\n address implementer = ERC_1820.getInterfaceImplementer(tokenToUse, TOKENS_ERC777_HASH);\n if (implementer != address(0)) {\n granularity = IERC777(implementer).granularity();\n //Verify granularity is power of 10 to keep it compatible with ERC20 decimals\n granularityToDecimals(granularity);\n }\n return granularity;\n }\n\n /* bytes32 (fixed-size array) to string (dynamically-sized array) */\n function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) {\n uint8 i = 0;\n while(i < 32 && _bytes32[i] != 0) {\n i++;\n }\n bytes memory bytesArray = new bytes(i);\n for (i = 0; i < 32 && _bytes32[i] != 0; i++) {\n bytesArray[i] = _bytes32[i];\n }\n return string(bytesArray);\n }\n\n function decimalsToGranularity(uint8 decimals) public pure returns (uint256) {\n require(decimals <= 18, \"Utils: Decimals not in 0 to 18\");\n return uint256(10)**(18-decimals);\n }\n\n function granularityToDecimals(uint256 granularity) public pure returns (uint8) {\n if(granularity == 1) return 18;\n if(granularity == 10) return 17;\n if(granularity == 100) return 16;\n if(granularity == 1000) return 15;\n if(granularity == 10000) return 14;\n if(granularity == 100000) return 13;\n if(granularity == 1000000) return 12;\n if(granularity == 10000000) return 11;\n if(granularity == 100000000) return 10;\n if(granularity == 1000000000) return 9;\n if(granularity == 10000000000) return 8;\n if(granularity == 100000000000) return 7;\n if(granularity == 1000000000000) return 6;\n if(granularity == 10000000000000) return 5;\n if(granularity == 100000000000000) return 4;\n if(granularity == 1000000000000000) return 3;\n if(granularity == 10000000000000000) return 2;\n if(granularity == 100000000000000000) return 1;\n if(granularity == 1000000000000000000) return 0;\n require(false, \"Utils: invalid granularity\");\n return 0;\n }\n\n function calculateGranularityAndAmount(uint8 decimals, uint256 granularity, uint256 amount) external pure\n returns(uint256 calculatedGranularity, uint256 formattedAmount) {\n\n if(decimals == 18) {\n //tokenAddress is a ERC20 with 18 decimals should have 1 granularity\n //tokenAddress is a ERC777 token we give the same granularity\n calculatedGranularity = granularity;\n formattedAmount = amount;\n } else {\n //tokenAddress is a ERC20 with other than 18 decimals\n calculatedGranularity = decimalsToGranularity(decimals);\n formattedAmount = amount.mul(calculatedGranularity);\n }\n }\n\n function calculateDecimalsAndAmount(address tokenAddress, uint256 granularity, uint256 amount)\n external view returns (uint8 calculatedDecimals, uint256 formattedAmount) {\n uint8 tokenDecimals = getDecimals(tokenAddress);\n //As side tokens are ERC777 we need to convert granularity to decimals\n calculatedDecimals = granularityToDecimals(granularity);\n require(tokenDecimals == calculatedDecimals, \"Utils: Token decimals differ from decimals - granularity\");\n formattedAmount = amount.div(granularity);\n }\n\n}\n"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () {\n _owner = _msgSender();\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Returns true if the caller is the current owner.\n */\n function isOwner() public view returns (bool) {\n return _msgSender() == _owner;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../interface/IBridge.sol\";\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockReceiveTokensCall is IERC777Recipient {\n address public bridge;\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor(address _bridge) {\n bridge = _bridge;\n //keccak256(\"ERC777TokensRecipient\")\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\n }\n\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount) external {\n IERC20(tokenToUse).approve(bridge, amount);\n IBridge(bridge).receiveTokensTo(tokenToUse, receiver, amount);\n }\n\n function callDepositTo(address receiver) external payable {\n IBridge(bridge).depositTo{ value: msg.value }(receiver);\n }\n\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\n IERC777(tokenToUse).send(bridge, amount, data);\n }\n\n // Mandatory for IERC777Recipient\n function tokensReceived(\n address,\n address,\n address,\n uint,\n bytes calldata,\n bytes calldata\n ) override external view {\n this;\n }\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\n\ncontract mockERC777Recipient is IERC777Recipient {\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n constructor() {\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\n }\n\n event Success(\n address operator,\n address from,\n address to,\n uint amount,\n bytes userData,\n bytes operatorData);\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) override external {\n emit Success(operator, from, to, amount, userData, operatorData);\n }\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\n\ncontract SideTokenV1 is ERC777 {\n address public minter;\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\n minter = _minterAddr;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"../SideToken/SideTokenV1.sol\";\n\ncontract SideTokenFactoryV1 is Secondary {\n event CreatedSideToken(address sideToken, string symbol);\n\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\n emit CreatedSideToken(address(sideToken), symbol);\n return sideToken;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using SafeMath for uint256;\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping (uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /*\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri_) {\n _setURI(uri_);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) external view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: balance query for the zero address\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(amount);\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, address(0), id, amount);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\n /**\n @dev Handles the receipt of a single ERC1155 token type. This function is\n called at the end of a `safeTransferFrom` after the balance has been updated.\n To accept the transfer, this must return\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n (i.e. 0xf23a6e61, or its own function selector).\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n )\n external\n returns(bytes4);\n\n /**\n @dev Handles the receipt of a multiple ERC1155 token types. This function\n is called at the end of a `safeBatchTransferFrom` after the balances have\n been updated. To accept the transfer(s), this must return\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n (i.e. 0xbc197c81, or its own function selector).\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match values array)\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n )\n external\n returns(bytes4);\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC1155 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Pausable is ERC1155, Pausable {\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n internal\n virtual\n override\n {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../GSN/Context.sol\";\nimport \"../access/roles/PauserRole.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context, PauserRole {\n /**\n * @dev Emitted when the pause is triggered by a pauser (`account`).\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by a pauser (`account`).\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\n * to the deployer.\n */\n constructor () {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!_paused, \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(_paused, \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Called by a pauser to pause, triggers stopped state.\n */\n function pause() public onlyPauser whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Called by a pauser to unpause, returns to normal state.\n */\n function unpause() public onlyPauser whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract PauserRole is Context {\n using Roles for Roles.Role;\n\n event PauserAdded(address indexed account);\n event PauserRemoved(address indexed account);\n\n Roles.Role private _pausers;\n\n constructor () {\n _addPauser(_msgSender());\n }\n\n modifier onlyPauser() {\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\n _;\n }\n\n function isPauser(address account) public view returns (bool) {\n return _pausers.has(account);\n }\n\n function addPauser(address account) public onlyPauser {\n _addPauser(account);\n }\n\n function renouncePauser() public {\n _removePauser(_msgSender());\n }\n\n function _addPauser(address account) internal {\n _pausers.add(account);\n emit PauserAdded(account);\n }\n\n function _removePauser(address account) internal {\n _pausers.remove(account);\n emit PauserRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC721.sol\";\nimport \"../../lifecycle/Pausable.sol\";\n\n/**\n * @dev ERC721 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC721Pausable is ERC721, Pausable {\n /**\n * @dev See {ERC721-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\n }\n}\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../../zeppelin/ownership/Ownable.sol\";\nimport \"../../zeppelin/math/SafeMath.sol\";\nimport \"../../zeppelin/utils/Strings.sol\";\nimport \"./OpenSeaEIP712Base.sol\";\n\n\n/**\n * @title OpenSea721\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\n */\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\n using SafeMath for uint256;\n\n uint256 private _currentTokenId = 0;\n\n constructor(\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n _initializeEIP712(_name);\n }\n\n function baseTokenURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/api/creature/\";\n }\n\n function contractURI() public pure returns (string memory) {\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\n }\n\n /**\n * @dev Mints a token to an address with a tokenURI.\n * @param _to address of the future owner of the token\n */\n function mintTo(address _to) public onlyOwner {\n uint256 newTokenId = _getNextTokenId();\n _mint(_to, newTokenId);\n _incrementTokenId();\n }\n\n /**\n * @dev calculates the next token ID based on value of _currentTokenId\n * @return uint256 for the next token ID\n */\n function _getNextTokenId() private view returns (uint256) {\n return _currentTokenId.add(1);\n }\n\n /**\n * @dev increments the value of _currentTokenId\n */\n function _incrementTokenId() private {\n _currentTokenId++;\n }\n\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\n }\n\n}"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../zeppelin/upgradable/Initializable.sol\";\n\ncontract OpenSeaEIP712Base is Initializable {\n struct EIP712Domain {\n string name;\n string version;\n address verifyingContract;\n bytes32 salt;\n }\n\n string constant public ERC712_VERSION = \"1\";\n\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\n bytes(\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\n )\n );\n bytes32 internal domainSeperator;\n\n // supposed to be called once while initializing.\n // one of the contracts that inherits this contract follows proxy pattern\n // so it is not possible to do this in a constructor\n function _initializeEIP712(\n string memory name\n )\n internal\n initializer\n {\n _setDomainSeperator(name);\n }\n\n function _setDomainSeperator(string memory name) internal {\n domainSeperator = keccak256(\n abi.encode(\n EIP712_DOMAIN_TYPEHASH,\n keccak256(bytes(name)),\n keccak256(bytes(ERC712_VERSION)),\n address(this),\n bytes32(getChainId())\n )\n );\n }\n\n function getDomainSeperator() public view returns (bytes32) {\n return domainSeperator;\n }\n\n function getChainId() public pure returns (uint256) {\n uint256 id;\n assembly {\n id := chainid()\n }\n return id;\n }\n\n /**\n * Accept message hash and returns hash message in EIP712 compatible form\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\n * https://eips.ethereum.org/EIPS/eip-712\n * \"\\\\x19\" makes the encoding deterministic\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\n */\n function toTypedMessageHash(bytes32 messageHash)\n internal\n view\n returns (bytes32)\n {\n return\n keccak256(\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\n );\n }\n}\n"
+ },
+ "contracts/Federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../interface/IBridge.sol\";\n\ncontract FederationV2 is Initializable, UpgradableOwnable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridge public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\n public validRequirement(_members.length, _required) initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n }\n\n function version() external pure returns (string memory) {\n return \"v2\";\n }\n\n function setBridge(address _bridge) external onlyOwner {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridge(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n )\n public onlyMember returns(bool)\n {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n );\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n logIndex\n );\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32)\n {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}"
+ },
+ "contracts/Federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n// Upgradables\nimport \"../zeppelin/upgradable/Initializable.sol\";\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\n\nimport \"../nftbridge/INFTBridge.sol\";\nimport \"../interface/IBridge.sol\";\nimport \"../interface/IFederation.sol\";\n\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridge public bridge;\n address[] public members;\n\n /**\n @notice The minimum amount of votes to approve a transaction\n @dev It should have more members than the required amount\n */\n uint public required;\n\n /**\n @notice All the addresses that are members of the federation\n @dev The address should be a member to vote in transactions\n */\n mapping (address => bool) public isMember;\n\n /**\n (bytes32) transactionId = keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n ) => (\n (address) members => (bool) voted\n )\n @notice Votes by members by the transaction ID\n @dev usually the members should approve the transaction by 50% + 1\n */\n mapping (bytes32 => mapping (address => bool)) public votes;\n\n /**\n (bytes32) transactionId => (bool) voted\n @notice Check if that transaction was already processed\n */\n mapping(bytes32 => bool) public processed;\n\n /** Federator v3 variables */\n INFTBridge public bridgeNFT;\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Not Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n function initialize(address[] memory _members, uint _required, address _bridge, address owner, address _bridgeNFT) public\n validRequirement(_members.length, _required) initializer {\n UpgradableOwnable.initialize(owner);\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n _setBridge(_bridge);\n _setNFTBridge(_bridgeNFT);\n }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure override returns (string memory) {\n return \"v3\";\n }\n\n /**\n @notice Sets a new bridge contract\n @dev Emits BridgeChanged event\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external onlyOwner override {\n _setBridge(_bridge);\n }\n\n function _setBridge(address _bridge) internal {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridge(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n /**\n @notice Sets a new NFT bridge contract\n @dev Emits NFTBridgeChanged event\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external onlyOwner override {\n _setNFTBridge(_bridgeNFT);\n }\n\n function _setNFTBridge(address _bridgeNFT) internal {\n require(_bridgeNFT != NULL_ADDRESS, \"Federation: Empty NFT bridge\");\n bridgeNFT = INFTBridge(_bridgeNFT);\n emit NFTBridgeChanged(_bridgeNFT);\n }\n\n function validateTransaction(bytes32 transactionId) internal view returns(bool) {\n uint transactionCount = getTransactionCount(transactionId);\n return transactionCount >= required && transactionCount >= members.length / 2 + 1;\n }\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) external onlyMember override {\n bytes32 transactionId = getTransactionId(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n if (processed[transactionId])\n return;\n\n if (votes[transactionId][_msgSender()])\n return;\n\n votes[transactionId][_msgSender()] = true;\n emit Voted(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n logIndex\n );\n\n if (validateTransaction(transactionId)) {\n processed[transactionId] = true;\n acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex,\n tokenType\n );\n\n emit Executed(\n _msgSender(),\n transactionHash,\n transactionId,\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n logIndex\n );\n return;\n }\n }\n\n function acceptTransfer(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) internal {\n if (tokenType == TokenType.NFT) {\n require(address(bridgeNFT) != NULL_ADDRESS, \"Federation: Empty NFTBridge\");\n bridgeNFT.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n return;\n }\n\n bridge.acceptTransfer(\n originalTokenAddress,\n sender,\n receiver,\n value,\n blockHash,\n transactionHash,\n logIndex\n );\n }\n\n /**\n @notice Get the amount of approved votes for that transactionId\n @param transactionId The transaction hashed from getTransactionId function\n */\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n /**\n @notice Gets the hash of transaction from the following parameters encoded and keccaked\n @dev It encodes and applies keccak256 to the parameters received in the same order\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param amount Could be the amount or the tokenId\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @return The hash generated by the parameters.\n */\n function getTransactionId(\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex\n ) public pure returns(bytes32) {\n return keccak256(\n abi.encodePacked(\n originalTokenAddress,\n sender,\n receiver,\n amount,\n blockHash,\n transactionHash,\n logIndex\n )\n );\n }\n\n function addMember(address _newMember) external onlyOwner override\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner override\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove an element from the end of the array.\n emit MemberRemoval(_oldMember);\n }\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view override returns (address[] memory) {\n return members;\n }\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @dev Emits the RequirementChange event\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n /**\n @notice It emits an HeartBeat like an health check\n @dev Emits HeartBeat event\n */\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external onlyMember override {\n emit HeartBeat(\n _msgSender(),\n fedRskBlock,\n fedEthBlock,\n federatorVersion,\n nodeRskInfo,\n nodeEthInfo\n );\n }\n}\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\npragma abicoder v2;\n\ninterface IFederation {\n enum TokenType{ COIN, NFT }\n\n /**\n @notice Current version of the contract\n @return version in v{Number}\n */\n function version() external pure returns (string memory);\n\n /**\n @notice Sets a new bridge contract\n @param _bridge the new bridge contract address that should implement the IBridge interface\n */\n function setBridge(address _bridge) external;\n\n /**\n @notice Sets a new NFT bridge contract\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\n */\n function setNFTBridge(address _bridgeNFT) external;\n\n /**\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\n @param originalTokenAddress The address of the token in the origin (main) chain\n @param sender The address who solicited the cross token\n @param receiver Who is going to receive the token in the opposite chain\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\n @param blockHash The block hash in which the transaction with the cross event occurred\n @param transactionHash The transaction in which the cross event occurred\n @param logIndex Index of the event in the logs\n @param tokenType Is the type of bridge to be used\n */\n function voteTransaction(\n address originalTokenAddress,\n address payable sender,\n address payable receiver,\n uint256 value,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n TokenType tokenType\n ) external;\n\n /**\n @notice Add a new member to the federation\n @param _newMember address of the new member\n */\n function addMember(address _newMember) external;\n\n /**\n @notice Remove a member of the federation\n @param _oldMember address of the member to be removed from federation\n */\n function removeMember(address _oldMember) external;\n\n /**\n @notice Return all the current members of the federation\n @return Current members\n */\n function getMembers() external view returns (address[] memory);\n\n /**\n @notice Changes the number of required members to vote and approve an transaction\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\n */\n function changeRequirement(uint _required) external;\n\n /**\n @notice It emmits an HeartBeat like an healthy check\n */\n function emitHeartbeat(\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string calldata federatorVersion,\n string calldata nodeRskInfo,\n string calldata nodeEthInfo\n ) external;\n\n event Executed(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n event NFTBridgeChanged(address bridgeNFT);\n event Voted(\n address indexed federator,\n bytes32 indexed transactionHash,\n bytes32 indexed transactionId,\n address originalTokenAddress,\n address sender,\n address receiver,\n uint256 amount,\n bytes32 blockHash,\n uint32 logIndex\n );\n event HeartBeat(\n address indexed sender,\n uint256 fedRskBlock,\n uint256 fedEthBlock,\n string federatorVersion,\n string nodeRskInfo,\n string nodeEthInfo\n );\n\n}\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"../Roles.sol\";\n\nabstract contract MinterRole is Context {\n using Roles for Roles.Role;\n\n event MinterAdded(address indexed account);\n event MinterRemoved(address indexed account);\n\n Roles.Role private _minters;\n\n constructor () {\n _addMinter(_msgSender());\n }\n\n modifier onlyMinter() {\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\n _;\n }\n\n function isMinter(address account) public view returns (bool) {\n return _minters.has(account);\n }\n\n function addMinter(address account) public onlyMinter {\n _addMinter(account);\n }\n\n function renounceMinter() public {\n _removeMinter(_msgSender());\n }\n\n function _addMinter(address account) internal {\n _minters.add(account);\n emit MinterAdded(account);\n }\n\n function _removeMinter(address account) internal {\n _minters.remove(account);\n emit MinterRemoved(account);\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20Mintable}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() override public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) override public view returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) override public returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) override public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) override public returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20};\n *\n * Requirements:\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal {\n require(sender != address(0), \"ERC20: transfer from zero address\");\n require(recipient != address(0), \"ERC20: transfer to zero address\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: mint to zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal {\n require(account != address(0), \"ERC20: burn from zero address\");\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n *\n * This is internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal {\n require(owner != address(0), \"ERC20: approve from zero address\");\n require(spender != address(0), \"ERC20: approve to zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\n * from the caller's allowance.\n *\n * See {_burn} and {_approve}.\n */\n function _burnFrom(address account, uint256 amount) internal {\n _burn(account, amount);\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\n }\n}\n"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\nimport \"../interface/IERC677Receiver.sol\";\n\ncontract mockERC677Receiver is IERC677Receiver {\n event Success(address _sender, uint _value, bytes _data);\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\n emit Success(_sender, _value, _data);\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Optional functions from the ERC20 standard.\n */\nabstract contract ERC20Detailed is IERC20 {\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\n * these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\n _name = aName;\n _symbol = aSymbol;\n _decimals = theDecimals;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./Proxy.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n *\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\n * {TransparentUpgradeableProxy}.\n */\ncontract UpgradeableProxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _setImplementation(_logic);\n if(_data.length > 0) {\n Address.functionDelegateCall(_logic, _data);\n }\n }\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n bytes32 slot = _IMPLEMENTATION_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n impl := sload(slot)\n }\n }\n\n /**\n * @dev Upgrades the proxy to a new implementation.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal virtual {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\n\n bytes32 slot = _IMPLEMENTATION_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newImplementation)\n }\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive () external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./UpgradeableProxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _setAdmin(admin_);\n }\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _admin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _admin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\n emit AdminChanged(_admin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external virtual ifAdmin {\n _upgradeTo(newImplementation);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\n _upgradeTo(newImplementation);\n Address.functionDelegateCall(newImplementation, data);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address adm) {\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n adm := sload(slot)\n }\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n bytes32 slot = _ADMIN_SLOT;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, newAdmin)\n }\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"../../ownership/Ownable.sol\";\nimport \"./TransparentUpgradeableProxy.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
+ },
+ "contracts/Federation/FederationV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../Bridge/IBridgeV2.sol\";\nimport \"../zeppelin/ownership/Ownable.sol\";\n\ncontract FederationV1 is Ownable {\n uint constant public MAX_MEMBER_COUNT = 50;\n address constant private NULL_ADDRESS = address(0);\n\n IBridgeV2 public bridge;\n address[] public members;\n uint public required;\n\n mapping (address => bool) public isMember;\n mapping (bytes32 => mapping (address => bool)) public votes;\n mapping(bytes32 => bool) public processed;\n // solium-disable-next-line max-len\n event Voted(address indexed sender, bytes32 indexed transactionId, address originalTokenAddress, address receiver, uint256 amount, string symbol, bytes32 blockHash, bytes32 indexed transactionHash, uint32 logIndex, uint8 decimals, uint256 granularity);\n event Executed(bytes32 indexed transactionId);\n event MemberAddition(address indexed member);\n event MemberRemoval(address indexed member);\n event RequirementChange(uint required);\n event BridgeChanged(address bridge);\n\n modifier onlyMember() {\n require(isMember[_msgSender()], \"Federation: Caller not a Federator\");\n _;\n }\n\n modifier validRequirement(uint membersCount, uint _required) {\n // solium-disable-next-line max-len\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\n _;\n }\n\n constructor(address[] memory _members, uint _required) validRequirement(_members.length, _required) {\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Members larger than max allowed\");\n members = _members;\n for (uint i = 0; i < _members.length; i++) {\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\n isMember[_members[i]] = true;\n emit MemberAddition(_members[i]);\n }\n required = _required;\n emit RequirementChange(required);\n }\n\n function setBridge(address _bridge) external onlyOwner {\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\n bridge = IBridgeV2(_bridge);\n emit BridgeChanged(_bridge);\n }\n\n function voteTransaction(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string calldata symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity)\n external onlyMember returns(bool)\n {\n // solium-disable-next-line max-len\n bytes32 transactionId = getTransactionId(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n if (processed[transactionId])\n return true;\n\n if (votes[transactionId][_msgSender()])\n return true;\n\n votes[transactionId][_msgSender()] = true;\n // solium-disable-next-line max-len\n emit Voted(_msgSender(), transactionId, originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n\n uint transactionCount = getTransactionCount(transactionId);\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\n processed[transactionId] = true;\n bool acceptTransfer = bridge.acceptTransfer(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\n require(acceptTransfer, \"Federation: Bridge acceptTransfer error\");\n emit Executed(transactionId);\n return true;\n }\n\n return true;\n }\n\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\n uint count = 0;\n for (uint i = 0; i < members.length; i++) {\n if (votes[transactionId][members[i]])\n count += 1;\n }\n return count;\n }\n\n function hasVoted(bytes32 transactionId) external view returns(bool)\n {\n return votes[transactionId][_msgSender()];\n }\n\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\n {\n return processed[transactionId];\n }\n\n function getTransactionId(\n address originalTokenAddress,\n address receiver,\n uint256 amount,\n string memory symbol,\n bytes32 blockHash,\n bytes32 transactionHash,\n uint32 logIndex,\n uint8 decimals,\n uint256 granularity)\n public pure returns(bytes32)\n {\n // solium-disable-next-line max-len\n return keccak256(abi.encodePacked(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity));\n }\n\n function addMember(address _newMember) external onlyOwner\n {\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(!isMember[_newMember], \"Federation: Member already exists\");\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\n\n isMember[_newMember] = true;\n members.push(_newMember);\n emit MemberAddition(_newMember);\n }\n\n function removeMember(address _oldMember) external onlyOwner\n {\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\n require(members.length > 1, \"Federation: Can't remove all the members\");\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\n\n isMember[_oldMember] = false;\n for (uint i = 0; i < members.length - 1; i++) {\n if (members[i] == _oldMember) {\n members[i] = members[members.length - 1];\n break;\n }\n }\n members.pop(); // remove last element\n emit MemberRemoval(_oldMember);\n }\n\n function getMembers() external view returns (address[] memory)\n {\n return members;\n }\n\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\n {\n require(_required >= 2, \"Federation: Requires at least 2\");\n required = _required;\n emit RequirementChange(_required);\n }\n\n}"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\n\ncontract BridgeProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}\n\ncontract FederationProxy is TransparentUpgradeableProxy {\n // solhint-disable-next-line no-empty-blocks\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\n}"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract MainToken is ERC20Detailed, ERC20 {\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\n ERC20Detailed(name, symbol, decimals)\n {\n _mint(msg.sender, totalSupply);\n }\n\n /**\n * ERC-677's only method implementation\n * See https://github.com/ethereum/EIPs/issues/677 for details\n */\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\n bool result = transfer(_to, _value);\n if (!result) return false;\n\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\n receiver.tokenFallback(msg.sender, _value, _data);\n\n // IMPORTANT: the ERC-677 specification does not say\n // anything about the use of the receiver contract's\n // tokenFallback method return value. Given\n // its return type matches with this method's return\n // type, returning it could be a possibility.\n // We here take the more conservative approach and\n // ignore the return value, returning true\n // to signal a succesful transfer despite tokenFallback's\n // return value -- fact being tokens are transferred\n // in any case.\n return true;\n }\n}\n\ninterface ERC677TransferReceiver {\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\n}"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\n\ncontract AlternativeERC20Detailed is ERC20 {\n string private _name;\n bytes32 private _symbol;\n uint256 private _decimals;\n\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\n {\n _name = aName;\n _symbol = aSymbol;\n _decimals = someDecimals;\n _mint(msg.sender, aTotalSupply);\n }\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (bytes32) {\n return _symbol;\n }\n\n function decimals() public view returns (uint256) {\n return _decimals;\n }\n}"
+ },
+ "contracts/test/nftbridge/NFTERC721TestToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.6;\n\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\n\ncontract NFTERC721TestToken is ERC721 {\n\n string private _contractURI;\n\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\n\n function safeMint(address to, uint256 tokenId) public {\n _safeMint(to, tokenId);\n }\n\n function setBaseURI(string memory baseURI) public {\n _setBaseURI(baseURI);\n }\n\n function setContractURI(string memory contractURI_) public {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n function setTokenURI(uint256 tokenId, string memory _tokenURI) public {\n _setTokenURI(tokenId, _tokenURI);\n }\n\n}\n"
+ },
+ "contracts/nftbridge/SideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ISideNFTToken.sol\";\nimport \"../zeppelin/token/ERC721/ERC721.sol\";\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\n\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\n address public minter;\n string private _contractURI;\n\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\n require(_minter != address(0), \"SideToken: Empty Minter\");\n minter = _minter;\n _setBaseURI(_baseURI);\n _setContractURI(contractURI_);\n }\n\n function _setContractURI(string memory contractURI_) internal {\n _contractURI = contractURI_;\n }\n\n function contractURI() public view returns (string memory) {\n return _contractURI;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(address account, uint256 tokenId) external onlyMinter override {\n _mint(account, tokenId);\n }\n}"
+ },
+ "contracts/nftbridge/SideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../zeppelin/ownership/Secondary.sol\";\nimport \"./ISideNFTTokenFactory.sol\";\nimport \"./SideNFTToken.sol\";\n\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\n\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\n string calldata contractURI) external onlyPrimary override returns(address) {\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\n return sideTokenAddress;\n }\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() {\n _registerInterface(\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\n );\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC721Receiver.sol\";\n\n /**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers. \n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./ERC1155.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Burnable is ERC1155 {\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n}\n"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../lib/LibUtils.sol\";\n\ncontract LibUtilsHarness {\n\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\n return LibUtils.decimalsToGranularity(decimals);\n }\n\n function getDecimals(address tokenToUse) external view returns (uint8) {\n return LibUtils.getDecimals(tokenToUse);\n }\n\n function getGranularity(address tokenToUse) external view returns (uint256) {\n return LibUtils.getGranularity(tokenToUse);\n }\n\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\n return LibUtils.bytesToAddress(bys);\n }\n\n}\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/.chainId b/bridge/deployments/rsktestnetrinkeby/.chainId
new file mode 100644
index 000000000..b74e882ae
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/.chainId
@@ -0,0 +1 @@
+31
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/AllowTokens.json b/bridge/deployments/rsktestnetrinkeby/AllowTokens.json
new file mode 100644
index 000000000..11ec17dbc
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/AllowTokens.json
@@ -0,0 +1,1196 @@
+{
+ "address": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ }
+ ],
+ "name": "AllowedTokenRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "ConfirmationsChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ }
+ ],
+ "name": "SetToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_typeDescription",
+ "type": "string"
+ }
+ ],
+ "name": "TokenTypeAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "indexed": false,
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "TypeLimitsChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_lastDay",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_spentToday",
+ "type": "uint256"
+ }
+ ],
+ "name": "UpdateTokensTransfered",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_TYPES",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Secondary_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "description",
+ "type": "string"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "addTokenType",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "len",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "allowedTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "calcMaxWithdraw",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "maxWithdraw",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "smallAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "getInfoAndLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spentToday",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "lastDay",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokenInfo",
+ "name": "info",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limit",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypeDescriptions",
+ "outputs": [
+ {
+ "internalType": "string[]",
+ "name": "descriptions",
+ "type": "string[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypeDescriptionsLength",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTypesLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits[]",
+ "name": "limits",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_primary",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "string",
+ "name": "description",
+ "type": "string"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TypeInfo[]",
+ "name": "typesInfo",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "isTokenAllowed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "largeAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "mediumAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "removeAllowedToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_smallAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_mediumAmountConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_largeAmountConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "setConfirmations",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.TokensAndType[]",
+ "name": "tokensAndTypes",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "setMultipleTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ }
+ ],
+ "name": "setToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "typeId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IAllowTokens.Limits",
+ "name": "limits",
+ "type": "tuple"
+ }
+ ],
+ "name": "setTypeLimits",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "smallAmountConfirmations",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "typeDescriptions",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "typeLimits",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "min",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "max",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "daily",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "mediumAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "largeAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "updateTokenTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x1bb281132f786550c542308757385a3f02ad972469b4129c6ddc80210cfc1d08",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "transactionIndex": 0,
+ "gasUsed": "2459902",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x5fcccfe02a3fda3576471319cfdc9aae44e2110f00d0faf8cd9725f941587e9c",
+ "transactionHash": "0x1bb281132f786550c542308757385a3f02ad972469b4129c6ddc80210cfc1d08",
+ "logs": [],
+ "blockNumber": 2170830,
+ "cumulativeGasUsed": "2459902",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"}],\"name\":\"AllowedTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"}],\"name\":\"ConfirmationsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"}],\"name\":\"SetToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_typeDescription\",\"type\":\"string\"}],\"name\":\"TokenTypeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"TypeLimitsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_lastDay\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_spentToday\",\"type\":\"uint256\"}],\"name\":\"UpdateTokensTransfered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_TYPES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__Secondary_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"addTokenType\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"len\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowedTokens\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"spentToday\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastDay\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"calcMaxWithdraw\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"maxWithdraw\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"smallAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getInfoAndLimits\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"spentToday\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastDay\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.TokenInfo\",\"name\":\"info\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limit\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypeDescriptions\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"descriptions\",\"type\":\"string[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypeDescriptionsLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTypesLimits\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits[]\",\"name\":\"limits\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_primary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"internalType\":\"struct IAllowTokens.TypeInfo[]\",\"name\":\"typesInfo\",\"type\":\"tuple[]\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isTokenAllowed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"largeAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mediumAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"removeAllowedToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_smallAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_mediumAmountConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_largeAmountConfirmations\",\"type\":\"uint256\"}],\"name\":\"setConfirmations\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.TokensAndType[]\",\"name\":\"tokensAndTypes\",\"type\":\"tuple[]\"}],\"name\":\"setMultipleTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"}],\"name\":\"setToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"typeId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowTokens.Limits\",\"name\":\"limits\",\"type\":\"tuple\"}],\"name\":\"setTypeLimits\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"smallAmountConfirmations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"typeDescriptions\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"typeLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"min\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"daily\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mediumAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"largeAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"updateTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"__Secondary_init(address)\":{\"details\":\"Sets the primary account to the one that is creating the Secondary contract.\"},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/AllowTokens/AllowTokens.sol\":\"AllowTokens\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/AllowTokens/AllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../zeppelin/math/SafeMath.sol\\\";\\r\\n// Upgradables\\r\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\\\";\\r\\n\\r\\nimport \\\"../interface/IAllowTokens.sol\\\";\\r\\n\\r\\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\\r\\n using SafeMath for uint256;\\r\\n\\r\\n address constant private NULL_ADDRESS = address(0);\\r\\n uint256 constant public MAX_TYPES = 250;\\r\\n mapping (address => TokenInfo) public allowedTokens;\\r\\n mapping (uint256 => Limits) public typeLimits;\\r\\n uint256 public smallAmountConfirmations;\\r\\n uint256 public mediumAmountConfirmations;\\r\\n uint256 public largeAmountConfirmations;\\r\\n string[] public typeDescriptions;\\r\\n\\r\\n event SetToken(address indexed _tokenAddress, uint256 _typeId);\\r\\n event AllowedTokenRemoved(address indexed _tokenAddress);\\r\\n event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\\r\\n event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\\r\\n event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\\r\\n event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\\r\\n\\r\\n\\r\\n modifier notNull(address _address) {\\r\\n require(_address != NULL_ADDRESS, \\\"AllowTokens: Null Address\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function initialize(\\r\\n address _manager,\\r\\n address _primary,\\r\\n uint256 _smallAmountConfirmations,\\r\\n uint256 _mediumAmountConfirmations,\\r\\n uint256 _largeAmountConfirmations,\\r\\n TypeInfo[] memory typesInfo) public initializer {\\r\\n UpgradableOwnable.initialize(_manager);\\r\\n UpgradableSecondary.__Secondary_init(_primary);\\r\\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\r\\n for(uint i = 0; i < typesInfo.length; i = i + 1) {\\r\\n _addTokenType(typesInfo[i].description, typesInfo[i].limits);\\r\\n }\\r\\n }\\r\\n\\r\\n function version() override external pure returns (string memory) {\\r\\n return \\\"v1\\\";\\r\\n }\\r\\n\\r\\n function getInfoAndLimits(address token) override public view\\r\\n returns (TokenInfo memory info, Limits memory limit) {\\r\\n info = allowedTokens[token];\\r\\n limit = typeLimits[info.typeId];\\r\\n return (info, limit);\\r\\n }\\r\\n function calcMaxWithdraw(address token) override public view returns (uint256 maxWithdraw) {\\r\\n (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\\r\\n return _calcMaxWithdraw(info, limits);\\r\\n }\\r\\n\\r\\n function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\\r\\n // solium-disable-next-line security/no-block-members\\r\\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\\r\\n info.spentToday = 0;\\r\\n }\\r\\n if (limits.daily <= info.spentToday)\\r\\n return 0;\\r\\n maxWithdraw = limits.daily - info.spentToday;\\r\\n if(maxWithdraw > limits.max)\\r\\n maxWithdraw = limits.max;\\r\\n return maxWithdraw;\\r\\n }\\r\\n\\r\\n // solium-disable-next-line max-len\\r\\n function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\\r\\n (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\\r\\n require(isTokenAllowed(token), \\\"AllowTokens: Not whitelisted\\\");\\r\\n require(amount >= limit.min, \\\"AllowTokens: Lower than limit\\\");\\r\\n\\r\\n // solium-disable-next-line security/no-block-members\\r\\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\\r\\n // solium-disable-next-line security/no-block-members\\r\\n info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\\r\\n info.spentToday = 0;\\r\\n }\\r\\n uint maxWithdraw = _calcMaxWithdraw(info, limit);\\r\\n require(amount <= maxWithdraw, \\\"AllowTokens: Exceeded limit\\\");\\r\\n info.spentToday = info.spentToday.add(amount);\\r\\n allowedTokens[token] = info;\\r\\n\\r\\n emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\\r\\n }\\r\\n\\r\\n function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\\r\\n require(bytes(description).length > 0, \\\"AllowTokens: Empty description\\\");\\r\\n len = typeDescriptions.length;\\r\\n require(len + 1 <= MAX_TYPES, \\\"AllowTokens: Reached MAX_TYPES\\\");\\r\\n typeDescriptions.push(description);\\r\\n _setTypeLimits(len, limits);\\r\\n emit TokenTypeAdded(len, description);\\r\\n return len;\\r\\n }\\r\\n\\r\\n function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\\r\\n return _addTokenType(description, limits);\\r\\n }\\r\\n\\r\\n function _setTypeLimits(uint256 typeId, Limits memory limits) private {\\r\\n require(typeId < typeDescriptions.length, \\\"AllowTokens: bigger than typeDescriptions\\\");\\r\\n require(limits.max >= limits.min, \\\"AllowTokens: maxTokens smaller than minTokens\\\");\\r\\n require(limits.daily >= limits.max, \\\"AllowTokens: dailyLimit smaller than maxTokens\\\");\\r\\n require(limits.mediumAmount > limits.min, \\\"AllowTokens: limits.mediumAmount smaller than min\\\");\\r\\n require(limits.largeAmount > limits.mediumAmount, \\\"AllowTokens: limits.largeAmount smaller than mediumAmount\\\");\\r\\n typeLimits[typeId] = limits;\\r\\n emit TypeLimitsChanged(typeId, limits);\\r\\n }\\r\\n\\r\\n function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\\r\\n _setTypeLimits(typeId, limits);\\r\\n }\\r\\n\\r\\n function getTypesLimits() external view override returns(Limits[] memory limits) {\\r\\n limits = new Limits[](typeDescriptions.length);\\r\\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\\r\\n limits[i] = typeLimits[i];\\r\\n }\\r\\n return limits;\\r\\n }\\r\\n\\r\\n function getTypeDescriptionsLength() external view override returns(uint256) {\\r\\n return typeDescriptions.length;\\r\\n }\\r\\n\\r\\n function getTypeDescriptions() external view override returns(string[] memory descriptions) {\\r\\n descriptions = new string[](typeDescriptions.length);\\r\\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\\r\\n descriptions[i] = typeDescriptions[i];\\r\\n }\\r\\n return descriptions;\\r\\n }\\r\\n\\r\\n function isTokenAllowed(address token) public view notNull(token) override returns (bool) {\\r\\n return allowedTokens[token].allowed;\\r\\n }\\r\\n\\r\\n function setToken(address token, uint256 typeId) override public notNull(token) {\\r\\n require(isOwner() || _msgSender() == primary(), \\\"AllowTokens: unauthorized sender\\\");\\r\\n require(typeId < typeDescriptions.length, \\\"AllowTokens: typeId does not exist\\\");\\r\\n TokenInfo memory info = allowedTokens[token];\\r\\n info.allowed = true;\\r\\n info.typeId = typeId;\\r\\n allowedTokens[token] = info;\\r\\n emit SetToken(token, typeId);\\r\\n }\\r\\n\\r\\n function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\\r\\n require(tokensAndTypes.length > 0, \\\"AllowTokens: empty tokens\\\");\\r\\n for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\\r\\n setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\\r\\n }\\r\\n }\\r\\n\\r\\n function removeAllowedToken(address token) external notNull(token) onlyOwner {\\r\\n TokenInfo memory info = allowedTokens[token];\\r\\n require(info.allowed, \\\"AllowTokens: Not Allowed\\\");\\r\\n info.allowed = false;\\r\\n allowedTokens[token] = info;\\r\\n emit AllowedTokenRemoved(token);\\r\\n }\\r\\n\\r\\n function setConfirmations(\\r\\n uint256 _smallAmountConfirmations,\\r\\n uint256 _mediumAmountConfirmations,\\r\\n uint256 _largeAmountConfirmations) external onlyOwner {\\r\\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\r\\n }\\r\\n\\r\\n function _setConfirmations(\\r\\n uint256 _smallAmountConfirmations,\\r\\n uint256 _mediumAmountConfirmations,\\r\\n uint256 _largeAmountConfirmations) private {\\r\\n require(_smallAmountConfirmations <= _mediumAmountConfirmations, \\\"AllowTokens: small bigger than medium confirmations\\\");\\r\\n require(_mediumAmountConfirmations <= _largeAmountConfirmations, \\\"AllowTokens: medium bigger than large confirmations\\\");\\r\\n smallAmountConfirmations = _smallAmountConfirmations;\\r\\n mediumAmountConfirmations = _mediumAmountConfirmations;\\r\\n largeAmountConfirmations = _largeAmountConfirmations;\\r\\n emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\\r\\n }\\r\\n\\r\\n function getConfirmations() external view override\\r\\n returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount) {\\r\\n return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0xdac780e7561bcb0746bf9523707cc6158999ba1efc93fc7175f2ba798196d638\",\"license\":\"MIT\"},\"contracts/interface/IAllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IAllowTokens {\\r\\n\\r\\n struct Limits {\\r\\n uint256 min;\\r\\n uint256 max;\\r\\n uint256 daily;\\r\\n uint256 mediumAmount;\\r\\n uint256 largeAmount;\\r\\n }\\r\\n\\r\\n struct TokenInfo {\\r\\n bool allowed;\\r\\n uint256 typeId;\\r\\n uint256 spentToday;\\r\\n uint256 lastDay;\\r\\n }\\r\\n\\r\\n struct TypeInfo {\\r\\n string description;\\r\\n Limits limits;\\r\\n }\\r\\n\\r\\n struct TokensAndType {\\r\\n address token;\\r\\n uint256 typeId;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\\r\\n\\r\\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\\r\\n\\r\\n function getTypesLimits() external view returns(Limits[] memory limits);\\r\\n\\r\\n function getTypeDescriptionsLength() external view returns(uint256);\\r\\n\\r\\n function getTypeDescriptions() external view returns(string[] memory descriptions);\\r\\n\\r\\n function setToken(address token, uint256 typeId) external;\\r\\n\\r\\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\\r\\n\\r\\n function isTokenAllowed(address token) external view returns (bool);\\r\\n\\r\\n function updateTokenTransfer(address token, uint256 amount) external;\\r\\n}\",\"keccak256\":\"0xe565b0887688d1625e70316993d66adecc65890012d190a6e450ea7cb7d981b1\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\r\\n * checks.\\r\\n *\\r\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\r\\n * in bugs, because programmers usually assume that an overflow raises an\\r\\n * error, which is the standard behavior in high level programming languages.\\r\\n * `SafeMath` restores this intuition by reverting the transaction when an\\r\\n * operation overflows.\\r\\n *\\r\\n * Using this library instead of the unchecked operations eliminates an entire\\r\\n * class of bugs, so it's recommended to use it always.\\r\\n */\\r\\nlibrary SafeMath {\\r\\n /**\\r\\n * @dev Returns the addition of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `+` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Addition cannot overflow.\\r\\n */\\r\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n uint256 c = a + b;\\r\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n */\\r\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b <= a, errorMessage);\\r\\n uint256 c = a - b;\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `*` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Multiplication cannot overflow.\\r\\n */\\r\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\r\\n // benefit is lost if 'b' is also tested.\\r\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\r\\n if (a == 0) {\\r\\n return 0;\\r\\n }\\r\\n\\r\\n uint256 c = a * b;\\r\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n // Solidity only automatically asserts when dividing by 0\\r\\n require(b > 0, errorMessage);\\r\\n uint256 c = a / b;\\r\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts with custom message when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b != 0, errorMessage);\\r\\n return a % b;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x29ffa7ff59806a3add585615cc102b70b43049587dcc73649f77b427f35b009d\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @title Initializable\\r\\n *\\r\\n * @dev Helper contract to support initializer functions. To use it, replace\\r\\n * the constructor with a function that has the `initializer` modifier.\\r\\n * WARNING: Unlike constructors, initializer functions must be manually\\r\\n * invoked. This applies both to deploying an Initializable contract, as well\\r\\n * as extending an Initializable contract via inheritance.\\r\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\r\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\r\\n * because this is not dealt with automatically as with constructors.\\r\\n */\\r\\ncontract Initializable {\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract has been initialized.\\r\\n */\\r\\n bool private initialized;\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract is in the process of being initialized.\\r\\n */\\r\\n bool private initializing;\\r\\n\\r\\n /**\\r\\n * @dev Modifier to use in the initializer function of a contract.\\r\\n */\\r\\n modifier initializer() {\\r\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\r\\n\\r\\n bool isTopLevelCall = !initializing;\\r\\n if (isTopLevelCall) {\\r\\n initializing = true;\\r\\n initialized = true;\\r\\n }\\r\\n\\r\\n _;\\r\\n\\r\\n if (isTopLevelCall) {\\r\\n initializing = false;\\r\\n }\\r\\n }\\r\\n\\r\\n // Reserved storage space to allow for layout changes in the future.\\r\\n uint256[50] private ______gap;\\r\\n}\",\"keccak256\":\"0xc1f4d917648f0e17ba6a023a168173ad6163f3120e24d1c97ae294430e42eaf3\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Contract module which provides a basic access control mechanism, where\\r\\n * there is an account (an owner) that can be granted exclusive access to\\r\\n * specific functions.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the modifier\\r\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\r\\n * the owner.\\r\\n */\\r\\ncontract UpgradableOwnable is Initializable, Context {\\r\\n address private _owner;\\r\\n\\r\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract setting the deployer as the initial owner.\\r\\n */\\r\\n function initialize(address sender) public initializer {\\r\\n _owner = sender;\\r\\n emit OwnershipTransferred(address(0), _owner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the address of the current owner.\\r\\n */\\r\\n function owner() public view returns (address) {\\r\\n return _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Throws if called by any account other than the owner.\\r\\n */\\r\\n modifier onlyOwner() {\\r\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the caller is the current owner.\\r\\n */\\r\\n function isOwner() public view returns (bool) {\\r\\n return _msgSender() == _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Leaves the contract without owner. It will not be possible to call\\r\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\r\\n *\\r\\n * > Note: Renouncing ownership will leave the contract without an owner,\\r\\n * thereby removing any functionality that is only available to the owner.\\r\\n */\\r\\n function renounceOwnership() public onlyOwner {\\r\\n emit OwnershipTransferred(_owner, address(0));\\r\\n _owner = address(0);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n * Can only be called by the current owner.\\r\\n */\\r\\n function transferOwnership(address newOwner) public onlyOwner {\\r\\n _transferOwnership(newOwner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n */\\r\\n function _transferOwnership(address newOwner) internal {\\r\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\r\\n emit OwnershipTransferred(_owner, newOwner);\\r\\n _owner = newOwner;\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0xea920007e371a3300245b5885f72cecc472c4780818365f0025fae65a767273d\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\r\\n */\\r\\ncontract UpgradableSecondary is Initializable, Context {\\r\\n address private _primary;\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the primary contract changes.\\r\\n */\\r\\n event PrimaryTransferred(\\r\\n address recipient\\r\\n );\\r\\n\\r\\n /**\\r\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\r\\n */\\r\\n function __Secondary_init(address sender) public initializer {\\r\\n _primary = sender;\\r\\n emit PrimaryTransferred(_primary);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Reverts if called from any account other than the primary.\\r\\n */\\r\\n modifier onlyPrimary() {\\r\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @return the address of the primary.\\r\\n */\\r\\n function primary() public view returns (address) {\\r\\n return _primary;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers contract to a new primary.\\r\\n * @param recipient The address of new primary.\\r\\n */\\r\\n function transferPrimary(address recipient) public onlyPrimary {\\r\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\r\\n _primary = recipient;\\r\\n emit PrimaryTransferred(recipient);\\r\\n }\\r\\n\\r\\n}\",\"keccak256\":\"0xd98360c430635ed9e840b65faf7d40d1636ed49d391d889f04d9bc977d1a36aa\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50612331806100206000396000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80638f32d59b1161010f578063c4d66de8116100a2578063e4f89ae411610071578063e4f89ae4146103e3578063e744092e146103f6578063f2fde38b14610419578063f9eaee0d1461042c576101e5565b8063c4d66de8146103ad578063c6dbdf61146103c0578063d4164b5d146103c8578063d7516faa146103db576101e5565b8063adfeb5eb116100de578063adfeb5eb1461035d578063b348a29f14610370578063bb698dad14610383578063c361ce8314610396576101e5565b80638f32d59b1461030c57806390469a9d146103215780639d27d22614610334578063a81a8b1f14610355576101e5565b806354fd4d50116101875780637d496be9116101565780637d496be9146102d45780638c34bc55146102dc5780638da5cb5b146102ef5780638de52dd714610304576101e5565b806354fd4d501461029e578063601ad4c9146102a6578063715018a6146102b957806378bf2b53146102c1576101e5565b80632348238c116101c35780632348238c1461024c578063250540cf146102615780633777804f1461027457806353a8b57414610289576101e5565b806307fc9eb9146101ea5780630a9763d7146102175780631c21a08f1461022c575b600080fd5b6101fd6101f8366004611a65565b61043f565b60405161020e9594939291906122b4565b60405180910390f35b61021f61046e565b60405161020e9190612287565b61023f61023a366004611a65565b610473565b60405161020e9190611c39565b61025f61025a366004611725565b61051c565b005b61021f61026f366004611725565b6105db565b61027c610601565b60405161020e9190611bc3565b6102916106da565b60405161020e9190611b63565b61023f6107f9565b61025f6102b4366004611aa9565b610815565b61025f610849565b61025f6102cf366004611928565b6108b7565b61021f610a00565b61025f6102ea366004611928565b610a06565b6102f7610b7f565b60405161020e9190611b4f565b61021f610b8e565b610314610b94565b60405161020e9190611c11565b61025f61032f366004611725565b610bba565b610347610342366004611725565b610ce7565b60405161020e92919061224d565b61021f610d93565b61025f61036b366004611725565b610d99565b61025f61037e366004611a7d565b610e68565b61021f6103913660046119c1565b610e96565b61039e610f14565b60405161020e9392919061229e565b61025f6103bb366004611725565b610f22565b6102f7610fe6565b61025f6103d636600461173f565b610ff5565b61021f6110db565b61025f6103f1366004611951565b6110e1565b610409610404366004611725565b611175565b60405161020e9493929190611c1c565b61025f610427366004611725565b6111a0565b61031461043a366004611725565b6111d0565b603660205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b60fa81565b603a818154811061048357600080fd5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152935090918301828280156105145780601f106104e957610100808354040283529160200191610514565b820191906000526020600020905b8154815290600101906020018083116104f757829003601f168201915b505050505081565b6034546001600160a01b0316610530611219565b6001600160a01b03161461055f5760405162461bcd60e51b815260040161055690612143565b60405180910390fd5b6001600160a01b0381166105855760405162461bcd60e51b815260040161055690611f4b565b603480546001600160a01b0319166001600160a01b0383161790556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9906105d0908390611b4f565b60405180910390a150565b60008060006105e984610ce7565b915091506105f7828261121d565b925050505b919050565b603a5460609067ffffffffffffffff8111801561061d57600080fd5b5060405190808252806020026020018201604052801561065757816020015b6106446115b4565b81526020019060019003908161063c5790505b50905060005b603a548110156106d657603660008281526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250508282815181106106c357fe5b602090810291909101015260010161065d565b5090565b603a5460609067ffffffffffffffff811180156106f657600080fd5b5060405190808252806020026020018201604052801561072a57816020015b60608152602001906001900390816107155790505b50905060005b603a548110156106d657603a818154811061074757fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156107d55780601f106107aa576101008083540402835291602001916107d5565b820191906000526020600020905b8154815290600101906020018083116107b857829003601f168201915b50505050508282815181106107e657fe5b6020908102919091010152600101610730565b604080518082019091526002815261763160f01b602082015290565b61081d610b94565b6108395760405162461bcd60e51b815260040161055690611eb9565b610844838383611275565b505050565b610851610b94565b61086d5760405162461bcd60e51b815260040161055690611eb9565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b816001600160a01b0381166108de5760405162461bcd60e51b815260040161055690611e4d565b6108e6610b94565b8061091057506108f4610fe6565b6001600160a01b0316610905611219565b6001600160a01b0316145b61092c5760405162461bcd60e51b815260040161055690611e84565b603a54821061094d5760405162461bcd60e51b815260040161055690611cf1565b6001600160a01b038316600081815260356020818152604080842081516080810183528154600283018054838601908152600385018054606086019081526001808752868a018f81529b8d9052999098528451151560ff1990941693909317855597519690930195909555945190559051909155519091907f720764556647dd167f4229d6a4255ac86018e302a50fc29dd67a70edb7b314d0906109f2908690612287565b60405180910390a250505050565b60395481565b6034546001600160a01b0316610a1a611219565b6001600160a01b031614610a405760405162461bcd60e51b815260040161055690612143565b600080610a4c84610ce7565b91509150610a59846111d0565b610a755760405162461bcd60e51b8152600401610556906121d1565b8051831015610a965760405162461bcd60e51b815260040161055690612208565b81606001516201518001421115610ab557426060830152600060408301525b6000610ac1838361121d565b905080841115610ae35760405162461bcd60e51b815260040161055690611c4c565b6040830151610af29085611305565b60408481019182526001600160a01b038716600081815260356020908152908390208751815460ff191690151517815590870151600182015592516002840181905560608701516003909401849055915190927f84480cc6a063ffd72c3eddf21e3ffd30db3e2b8e386ec3abf09c98ee9e0e8d3492610b7092612290565b60405180910390a25050505050565b6033546001600160a01b031690565b60385481565b6033546000906001600160a01b0316610bab611219565b6001600160a01b031614905090565b806001600160a01b038116610be15760405162461bcd60e51b815260040161055690611e4d565b610be9610b94565b610c055760405162461bcd60e51b815260040161055690611eb9565b6001600160a01b0382166000908152603560209081526040918290208251608081018452815460ff161515808252600183015493820193909352600282015493810193909352600301546060830152610c705760405162461bcd60e51b815260040161055690612068565b60008082526001600160a01b0384168082526035602090815260408084208551815460ff191690151517815591850151600183015580850151600283015560608501516003909201919091555190917fbf996b4fd74f0c7159bb017b1db415b0d9a6f13129f46d0b93309d170b78df3191a2505050565b610cef6115e3565b610cf76115b4565b50506001600160a01b03166000908152603560209081526040808320815160808082018452825460ff1615158252600180840154838701819052600280860154858801526003958601546060808701919091529189526036885297869020865160a08101885281548152928101549783019790975296860154948101949094529184015494830194909452600490920154918101919091529091565b60375481565b600054610100900460ff1680610db2575060005460ff16155b610dce5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610df9576000805460ff1961ff0019909116610100171660011790555b603480546001600160a01b0319166001600160a01b0384811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610e4a921690611b4f565b60405180910390a18015610e64576000805461ff00191690555b5050565b610e70610b94565b610e8c5760405162461bcd60e51b815260040161055690611eb9565b610e64828261132a565b6000610ea0610b94565b610ebc5760405162461bcd60e51b815260040161055690611eb9565b610f0a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f059250505036859003850185611a4a565b61145c565b90505b9392505050565b603754603854603954909192565b600054610100900460ff1680610f3b575060005460ff16155b610f575760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610f82576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e64576000805461ff00191690555050565b6034546001600160a01b031690565b600054610100900460ff168061100e575060005460ff16155b61102a5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015611055576000805460ff1961ff0019909116610100171660011790555b61105e87610f22565b61106786610d99565b611072858585611275565b60005b82518110156110bf576110b683828151811061108d57fe5b6020026020010151600001518483815181106110a557fe5b60200260200101516020015161145c565b50600101611075565b5080156110d2576000805461ff00191690555b50505050505050565b603a5490565b6110e9610b94565b6111055760405162461bcd60e51b815260040161055690611eb9565b806111225760405162461bcd60e51b815260040161055690611dc8565b60005b818110156108445761116d83838381811061113c57fe5b6111529260206040909202019081019150611725565b84848481811061115e57fe5b905060400201602001356108b7565b600101611125565b603560205260009081526040902080546001820154600283015460039093015460ff90921692909184565b6111a8610b94565b6111c45760405162461bcd60e51b815260040161055690611eb9565b6111cd81611532565b50565b6000816001600160a01b0381166111f95760405162461bcd60e51b815260040161055690611e4d565b50506001600160a01b031660009081526035602052604090205460ff1690565b3390565b60008260600151620151800142111561123857600060408401525b826040015182604001511161124f5750600061126f565b82604001518260400151039050816020015181111561126f575060208101515b92915050565b818311156112955760405162461bcd60e51b815260040161055690611fde565b808211156112b55760405162461bcd60e51b8152600401610556906120f0565b6037839055603882905560398190556040517ffcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219906112f89085908590859061229e565b60405180910390a1505050565b600082820183811015610f0d5760405162461bcd60e51b815260040161055690611cba565b603a54821061134b5760405162461bcd60e51b815260040161055690611f95565b8051602082015110156113705760405162461bcd60e51b815260040161055690611d7b565b8060200151816040015110156113985760405162461bcd60e51b815260040161055690611dff565b80516060820151116113bc5760405162461bcd60e51b81526004016105569061209f565b80606001518160800151116113e35760405162461bcd60e51b815260040161055690611eee565b600082815260366020908152604091829020835181559083015160018201558183015160028201556060830151600382015560808301516004909101555182907f1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb9061145090849061223f565b60405180910390a25050565b60008083511161147e5760405162461bcd60e51b815260040161055690611c83565b50603a5460fa6001820111156114a65760405162461bcd60e51b815260040161055690612031565b603a805460018101825560009190915283516114e9917fa2999d817b6757290b50e8ecf3fa939673403dd35c97de392fdb343b4015ce9e0190602086019061160d565b506114f4818361132a565b807fb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0846040516115249190611c39565b60405180910390a292915050565b6001600160a01b0381166115585760405162461bcd60e51b81526004016105569061218f565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806000151581526020016000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826116435760008555611689565b82601f1061165c57805160ff1916838001178555611689565b82800160010185558215611689579182015b8281111561168957825182559160200191906001019061166e565b506106d69291505b808211156106d65760008155600101611691565b80356001600160a01b03811681146105fc57600080fd5b600060a082840312156116cd578081fd5b60405160a0810181811067ffffffffffffffff821117156116ea57fe5b806040525080915082358152602083013560208201526040830135604082015260608301356060820152608083013560808201525092915050565b600060208284031215611736578081fd5b610f0d826116a5565b60008060008060008060c08789031215611757578182fd5b611760876116a5565b955061176e602088016116a5565b945060408701359350606087013592506080870135915067ffffffffffffffff60a0880135111561179d578081fd5b60a0870135870188601f8201126117b2578182fd5b67ffffffffffffffff813511156117c557fe5b6117d4602080833502016122d7565b81358152602080820191908301845b84358110156119165760c0823586018e03601f19011215611802578586fd5b60405180604082011067ffffffffffffffff6040830111171561182157fe5b6040810160405267ffffffffffffffff60208435880101351115611843578687fd5b82358601602081013501603f018e1361185a578687fd5b67ffffffffffffffff60208435880181810135010135111561187857fe5b61189883358701602081810135909101810135601f01601f1916016122d7565b60208435880181810135019081013580835260409101018f10156118ba578788fd5b602084358801818101350180820135916040909101908301378335870160208181013582018101358301018990529082526118f9908f906040016116bc565b6020828101919091529085529384019391909101906001016117e3565b50508093505050509295509295509295565b6000806040838503121561193a578182fd5b611943836116a5565b946020939093013593505050565b60008060208385031215611963578182fd5b823567ffffffffffffffff8082111561197a578384fd5b818501915085601f83011261198d578384fd5b81358181111561199b578485fd5b8660206040830285010111156119af578485fd5b60209290920196919550909350505050565b600080600083850360c08112156119d6578384fd5b843567ffffffffffffffff808211156119ed578586fd5b818701915087601f830112611a00578586fd5b813581811115611a0e578687fd5b886020828501011115611a1f578687fd5b60209290920195509093505060a0601f1982011215611a3c578182fd5b506020840190509250925092565b600060a08284031215611a5b578081fd5b610f0d83836116bc565b600060208284031215611a76578081fd5b5035919050565b60008060c08385031215611a8f578182fd5b82359150611aa084602085016116bc565b90509250929050565b600080600060608486031215611abd578283fd5b505081359360208301359350604090920135919050565b60008151808452815b81811015611af957602081850181015186830182015201611add565b81811115611b0a5782602083870101525b50601f01601f19169290920160200192915050565b80518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b6001600160a01b0391909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611bb657603f19888603018452611ba4858351611ad4565b94509285019290850190600101611b88565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611c0557611bf2838551611b1f565b9284019260a09290920191600101611bdf565b50909695505050505050565b901515815260200190565b931515845260208401929092526040830152606082015260800190565b600060208252610f0d6020830184611ad4565b6020808252601b908201527f416c6c6f77546f6b656e733a204578636565646564206c696d69740000000000604082015260600190565b6020808252601e908201527f416c6c6f77546f6b656e733a20456d707479206465736372697074696f6e0000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526022908201527f416c6c6f77546f6b656e733a2074797065496420646f6573206e6f74206578696040820152611cdd60f21b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252602d908201527f416c6c6f77546f6b656e733a206d6178546f6b656e7320736d616c6c6572207460408201526c68616e206d696e546f6b656e7360981b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a20656d70747920746f6b656e7300000000000000604082015260600190565b6020808252602e908201527f416c6c6f77546f6b656e733a206461696c794c696d697420736d616c6c65722060408201526d7468616e206d6178546f6b656e7360901b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a204e756c6c204164647265737300000000000000604082015260600190565b6020808252818101527f416c6c6f77546f6b656e733a20756e617574686f72697a65642073656e646572604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526039908201527f416c6c6f77546f6b656e733a206c696d6974732e6c61726765416d6f756e742060408201527f736d616c6c6572207468616e206d656469756d416d6f756e7400000000000000606082015260800190565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f416c6c6f77546f6b656e733a20626967676572207468616e20747970654465736040820152686372697074696f6e7360b81b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a20736d616c6c20626967676572207468616e206d604082015272656469756d20636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252601e908201527f416c6c6f77546f6b656e733a2052656163686564204d41585f54595045530000604082015260600190565b60208082526018908201527f416c6c6f77546f6b656e733a204e6f7420416c6c6f7765640000000000000000604082015260600190565b60208082526031908201527f416c6c6f77546f6b656e733a206c696d6974732e6d656469756d416d6f756e746040820152701039b6b0b63632b9103a3430b71036b4b760791b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a206d656469756d20626967676572207468616e206040820152726c6172676520636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601c908201527f416c6c6f77546f6b656e733a204e6f742077686974656c697374656400000000604082015260600190565b6020808252601d908201527f416c6c6f77546f6b656e733a204c6f776572207468616e206c696d6974000000604082015260600190565b60a0810161126f8284611b1f565b600061012082019050835115158252602084015160208301526040840151604083015260608401516060830152610f0d6080830184611b1f565b90815260200190565b918252602082015260400190565b9283526020830191909152604082015260600190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff811182821017156122f357fe5b60405291905056fea2646970667358221220b8c803062aae1399048c52f7f09ef284f71855e36a2571b9d23d23a44a20ce7864736f6c63430007060033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101e55760003560e01c80638f32d59b1161010f578063c4d66de8116100a2578063e4f89ae411610071578063e4f89ae4146103e3578063e744092e146103f6578063f2fde38b14610419578063f9eaee0d1461042c576101e5565b8063c4d66de8146103ad578063c6dbdf61146103c0578063d4164b5d146103c8578063d7516faa146103db576101e5565b8063adfeb5eb116100de578063adfeb5eb1461035d578063b348a29f14610370578063bb698dad14610383578063c361ce8314610396576101e5565b80638f32d59b1461030c57806390469a9d146103215780639d27d22614610334578063a81a8b1f14610355576101e5565b806354fd4d50116101875780637d496be9116101565780637d496be9146102d45780638c34bc55146102dc5780638da5cb5b146102ef5780638de52dd714610304576101e5565b806354fd4d501461029e578063601ad4c9146102a6578063715018a6146102b957806378bf2b53146102c1576101e5565b80632348238c116101c35780632348238c1461024c578063250540cf146102615780633777804f1461027457806353a8b57414610289576101e5565b806307fc9eb9146101ea5780630a9763d7146102175780631c21a08f1461022c575b600080fd5b6101fd6101f8366004611a65565b61043f565b60405161020e9594939291906122b4565b60405180910390f35b61021f61046e565b60405161020e9190612287565b61023f61023a366004611a65565b610473565b60405161020e9190611c39565b61025f61025a366004611725565b61051c565b005b61021f61026f366004611725565b6105db565b61027c610601565b60405161020e9190611bc3565b6102916106da565b60405161020e9190611b63565b61023f6107f9565b61025f6102b4366004611aa9565b610815565b61025f610849565b61025f6102cf366004611928565b6108b7565b61021f610a00565b61025f6102ea366004611928565b610a06565b6102f7610b7f565b60405161020e9190611b4f565b61021f610b8e565b610314610b94565b60405161020e9190611c11565b61025f61032f366004611725565b610bba565b610347610342366004611725565b610ce7565b60405161020e92919061224d565b61021f610d93565b61025f61036b366004611725565b610d99565b61025f61037e366004611a7d565b610e68565b61021f6103913660046119c1565b610e96565b61039e610f14565b60405161020e9392919061229e565b61025f6103bb366004611725565b610f22565b6102f7610fe6565b61025f6103d636600461173f565b610ff5565b61021f6110db565b61025f6103f1366004611951565b6110e1565b610409610404366004611725565b611175565b60405161020e9493929190611c1c565b61025f610427366004611725565b6111a0565b61031461043a366004611725565b6111d0565b603660205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b60fa81565b603a818154811061048357600080fd5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152935090918301828280156105145780601f106104e957610100808354040283529160200191610514565b820191906000526020600020905b8154815290600101906020018083116104f757829003601f168201915b505050505081565b6034546001600160a01b0316610530611219565b6001600160a01b03161461055f5760405162461bcd60e51b815260040161055690612143565b60405180910390fd5b6001600160a01b0381166105855760405162461bcd60e51b815260040161055690611f4b565b603480546001600160a01b0319166001600160a01b0383161790556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9906105d0908390611b4f565b60405180910390a150565b60008060006105e984610ce7565b915091506105f7828261121d565b925050505b919050565b603a5460609067ffffffffffffffff8111801561061d57600080fd5b5060405190808252806020026020018201604052801561065757816020015b6106446115b4565b81526020019060019003908161063c5790505b50905060005b603a548110156106d657603660008281526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250508282815181106106c357fe5b602090810291909101015260010161065d565b5090565b603a5460609067ffffffffffffffff811180156106f657600080fd5b5060405190808252806020026020018201604052801561072a57816020015b60608152602001906001900390816107155790505b50905060005b603a548110156106d657603a818154811061074757fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156107d55780601f106107aa576101008083540402835291602001916107d5565b820191906000526020600020905b8154815290600101906020018083116107b857829003601f168201915b50505050508282815181106107e657fe5b6020908102919091010152600101610730565b604080518082019091526002815261763160f01b602082015290565b61081d610b94565b6108395760405162461bcd60e51b815260040161055690611eb9565b610844838383611275565b505050565b610851610b94565b61086d5760405162461bcd60e51b815260040161055690611eb9565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b816001600160a01b0381166108de5760405162461bcd60e51b815260040161055690611e4d565b6108e6610b94565b8061091057506108f4610fe6565b6001600160a01b0316610905611219565b6001600160a01b0316145b61092c5760405162461bcd60e51b815260040161055690611e84565b603a54821061094d5760405162461bcd60e51b815260040161055690611cf1565b6001600160a01b038316600081815260356020818152604080842081516080810183528154600283018054838601908152600385018054606086019081526001808752868a018f81529b8d9052999098528451151560ff1990941693909317855597519690930195909555945190559051909155519091907f720764556647dd167f4229d6a4255ac86018e302a50fc29dd67a70edb7b314d0906109f2908690612287565b60405180910390a250505050565b60395481565b6034546001600160a01b0316610a1a611219565b6001600160a01b031614610a405760405162461bcd60e51b815260040161055690612143565b600080610a4c84610ce7565b91509150610a59846111d0565b610a755760405162461bcd60e51b8152600401610556906121d1565b8051831015610a965760405162461bcd60e51b815260040161055690612208565b81606001516201518001421115610ab557426060830152600060408301525b6000610ac1838361121d565b905080841115610ae35760405162461bcd60e51b815260040161055690611c4c565b6040830151610af29085611305565b60408481019182526001600160a01b038716600081815260356020908152908390208751815460ff191690151517815590870151600182015592516002840181905560608701516003909401849055915190927f84480cc6a063ffd72c3eddf21e3ffd30db3e2b8e386ec3abf09c98ee9e0e8d3492610b7092612290565b60405180910390a25050505050565b6033546001600160a01b031690565b60385481565b6033546000906001600160a01b0316610bab611219565b6001600160a01b031614905090565b806001600160a01b038116610be15760405162461bcd60e51b815260040161055690611e4d565b610be9610b94565b610c055760405162461bcd60e51b815260040161055690611eb9565b6001600160a01b0382166000908152603560209081526040918290208251608081018452815460ff161515808252600183015493820193909352600282015493810193909352600301546060830152610c705760405162461bcd60e51b815260040161055690612068565b60008082526001600160a01b0384168082526035602090815260408084208551815460ff191690151517815591850151600183015580850151600283015560608501516003909201919091555190917fbf996b4fd74f0c7159bb017b1db415b0d9a6f13129f46d0b93309d170b78df3191a2505050565b610cef6115e3565b610cf76115b4565b50506001600160a01b03166000908152603560209081526040808320815160808082018452825460ff1615158252600180840154838701819052600280860154858801526003958601546060808701919091529189526036885297869020865160a08101885281548152928101549783019790975296860154948101949094529184015494830194909452600490920154918101919091529091565b60375481565b600054610100900460ff1680610db2575060005460ff16155b610dce5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610df9576000805460ff1961ff0019909116610100171660011790555b603480546001600160a01b0319166001600160a01b0384811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610e4a921690611b4f565b60405180910390a18015610e64576000805461ff00191690555b5050565b610e70610b94565b610e8c5760405162461bcd60e51b815260040161055690611eb9565b610e64828261132a565b6000610ea0610b94565b610ebc5760405162461bcd60e51b815260040161055690611eb9565b610f0a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f059250505036859003850185611a4a565b61145c565b90505b9392505050565b603754603854603954909192565b600054610100900460ff1680610f3b575060005460ff16155b610f575760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015610f82576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e64576000805461ff00191690555050565b6034546001600160a01b031690565b600054610100900460ff168061100e575060005460ff16155b61102a5760405162461bcd60e51b815260040161055690611d33565b600054610100900460ff16158015611055576000805460ff1961ff0019909116610100171660011790555b61105e87610f22565b61106786610d99565b611072858585611275565b60005b82518110156110bf576110b683828151811061108d57fe5b6020026020010151600001518483815181106110a557fe5b60200260200101516020015161145c565b50600101611075565b5080156110d2576000805461ff00191690555b50505050505050565b603a5490565b6110e9610b94565b6111055760405162461bcd60e51b815260040161055690611eb9565b806111225760405162461bcd60e51b815260040161055690611dc8565b60005b818110156108445761116d83838381811061113c57fe5b6111529260206040909202019081019150611725565b84848481811061115e57fe5b905060400201602001356108b7565b600101611125565b603560205260009081526040902080546001820154600283015460039093015460ff90921692909184565b6111a8610b94565b6111c45760405162461bcd60e51b815260040161055690611eb9565b6111cd81611532565b50565b6000816001600160a01b0381166111f95760405162461bcd60e51b815260040161055690611e4d565b50506001600160a01b031660009081526035602052604090205460ff1690565b3390565b60008260600151620151800142111561123857600060408401525b826040015182604001511161124f5750600061126f565b82604001518260400151039050816020015181111561126f575060208101515b92915050565b818311156112955760405162461bcd60e51b815260040161055690611fde565b808211156112b55760405162461bcd60e51b8152600401610556906120f0565b6037839055603882905560398190556040517ffcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219906112f89085908590859061229e565b60405180910390a1505050565b600082820183811015610f0d5760405162461bcd60e51b815260040161055690611cba565b603a54821061134b5760405162461bcd60e51b815260040161055690611f95565b8051602082015110156113705760405162461bcd60e51b815260040161055690611d7b565b8060200151816040015110156113985760405162461bcd60e51b815260040161055690611dff565b80516060820151116113bc5760405162461bcd60e51b81526004016105569061209f565b80606001518160800151116113e35760405162461bcd60e51b815260040161055690611eee565b600082815260366020908152604091829020835181559083015160018201558183015160028201556060830151600382015560808301516004909101555182907f1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb9061145090849061223f565b60405180910390a25050565b60008083511161147e5760405162461bcd60e51b815260040161055690611c83565b50603a5460fa6001820111156114a65760405162461bcd60e51b815260040161055690612031565b603a805460018101825560009190915283516114e9917fa2999d817b6757290b50e8ecf3fa939673403dd35c97de392fdb343b4015ce9e0190602086019061160d565b506114f4818361132a565b807fb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0846040516115249190611c39565b60405180910390a292915050565b6001600160a01b0381166115585760405162461bcd60e51b81526004016105569061218f565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806000151581526020016000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826116435760008555611689565b82601f1061165c57805160ff1916838001178555611689565b82800160010185558215611689579182015b8281111561168957825182559160200191906001019061166e565b506106d69291505b808211156106d65760008155600101611691565b80356001600160a01b03811681146105fc57600080fd5b600060a082840312156116cd578081fd5b60405160a0810181811067ffffffffffffffff821117156116ea57fe5b806040525080915082358152602083013560208201526040830135604082015260608301356060820152608083013560808201525092915050565b600060208284031215611736578081fd5b610f0d826116a5565b60008060008060008060c08789031215611757578182fd5b611760876116a5565b955061176e602088016116a5565b945060408701359350606087013592506080870135915067ffffffffffffffff60a0880135111561179d578081fd5b60a0870135870188601f8201126117b2578182fd5b67ffffffffffffffff813511156117c557fe5b6117d4602080833502016122d7565b81358152602080820191908301845b84358110156119165760c0823586018e03601f19011215611802578586fd5b60405180604082011067ffffffffffffffff6040830111171561182157fe5b6040810160405267ffffffffffffffff60208435880101351115611843578687fd5b82358601602081013501603f018e1361185a578687fd5b67ffffffffffffffff60208435880181810135010135111561187857fe5b61189883358701602081810135909101810135601f01601f1916016122d7565b60208435880181810135019081013580835260409101018f10156118ba578788fd5b602084358801818101350180820135916040909101908301378335870160208181013582018101358301018990529082526118f9908f906040016116bc565b6020828101919091529085529384019391909101906001016117e3565b50508093505050509295509295509295565b6000806040838503121561193a578182fd5b611943836116a5565b946020939093013593505050565b60008060208385031215611963578182fd5b823567ffffffffffffffff8082111561197a578384fd5b818501915085601f83011261198d578384fd5b81358181111561199b578485fd5b8660206040830285010111156119af578485fd5b60209290920196919550909350505050565b600080600083850360c08112156119d6578384fd5b843567ffffffffffffffff808211156119ed578586fd5b818701915087601f830112611a00578586fd5b813581811115611a0e578687fd5b886020828501011115611a1f578687fd5b60209290920195509093505060a0601f1982011215611a3c578182fd5b506020840190509250925092565b600060a08284031215611a5b578081fd5b610f0d83836116bc565b600060208284031215611a76578081fd5b5035919050565b60008060c08385031215611a8f578182fd5b82359150611aa084602085016116bc565b90509250929050565b600080600060608486031215611abd578283fd5b505081359360208301359350604090920135919050565b60008151808452815b81811015611af957602081850181015186830182015201611add565b81811115611b0a5782602083870101525b50601f01601f19169290920160200192915050565b80518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b6001600160a01b0391909116815260200190565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611bb657603f19888603018452611ba4858351611ad4565b94509285019290850190600101611b88565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611c0557611bf2838551611b1f565b9284019260a09290920191600101611bdf565b50909695505050505050565b901515815260200190565b931515845260208401929092526040830152606082015260800190565b600060208252610f0d6020830184611ad4565b6020808252601b908201527f416c6c6f77546f6b656e733a204578636565646564206c696d69740000000000604082015260600190565b6020808252601e908201527f416c6c6f77546f6b656e733a20456d707479206465736372697074696f6e0000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526022908201527f416c6c6f77546f6b656e733a2074797065496420646f6573206e6f74206578696040820152611cdd60f21b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252602d908201527f416c6c6f77546f6b656e733a206d6178546f6b656e7320736d616c6c6572207460408201526c68616e206d696e546f6b656e7360981b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a20656d70747920746f6b656e7300000000000000604082015260600190565b6020808252602e908201527f416c6c6f77546f6b656e733a206461696c794c696d697420736d616c6c65722060408201526d7468616e206d6178546f6b656e7360901b606082015260800190565b60208082526019908201527f416c6c6f77546f6b656e733a204e756c6c204164647265737300000000000000604082015260600190565b6020808252818101527f416c6c6f77546f6b656e733a20756e617574686f72697a65642073656e646572604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526039908201527f416c6c6f77546f6b656e733a206c696d6974732e6c61726765416d6f756e742060408201527f736d616c6c6572207468616e206d656469756d416d6f756e7400000000000000606082015260800190565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f416c6c6f77546f6b656e733a20626967676572207468616e20747970654465736040820152686372697074696f6e7360b81b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a20736d616c6c20626967676572207468616e206d604082015272656469756d20636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252601e908201527f416c6c6f77546f6b656e733a2052656163686564204d41585f54595045530000604082015260600190565b60208082526018908201527f416c6c6f77546f6b656e733a204e6f7420416c6c6f7765640000000000000000604082015260600190565b60208082526031908201527f416c6c6f77546f6b656e733a206c696d6974732e6d656469756d416d6f756e746040820152701039b6b0b63632b9103a3430b71036b4b760791b606082015260800190565b60208082526033908201527f416c6c6f77546f6b656e733a206d656469756d20626967676572207468616e206040820152726c6172676520636f6e6669726d6174696f6e7360681b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601c908201527f416c6c6f77546f6b656e733a204e6f742077686974656c697374656400000000604082015260600190565b6020808252601d908201527f416c6c6f77546f6b656e733a204c6f776572207468616e206c696d6974000000604082015260600190565b60a0810161126f8284611b1f565b600061012082019050835115158252602084015160208301526040840151604083015260608401516060830152610f0d6080830184611b1f565b90815260200190565b918252602082015260400190565b9283526020830191909152604082015260600190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff811182821017156122f357fe5b60405291905056fea2646970667358221220b8c803062aae1399048c52f7f09ef284f71855e36a2571b9d23d23a44a20ce7864736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "__Secondary_init(address)": {
+ "details": "Sets the primary account to the one that is creating the Secondary contract."
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15789,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15792,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15832,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16076,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 16209,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_address"
+ },
+ {
+ "astId": 31,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "allowedTokens",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_mapping(t_address,t_struct(TokenInfo)7131_storage)"
+ },
+ {
+ "astId": 35,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeLimits",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_mapping(t_uint256,t_struct(Limits)7122_storage)"
+ },
+ {
+ "astId": 37,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "smallAmountConfirmations",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 39,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "mediumAmountConfirmations",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 41,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "largeAmountConfirmations",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 44,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeDescriptions",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_array(t_string_storage)dyn_storage"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "base": "t_string_storage",
+ "encoding": "dynamic_array",
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_struct(TokenInfo)7131_storage)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => struct IAllowTokens.TokenInfo)",
+ "numberOfBytes": "32",
+ "value": "t_struct(TokenInfo)7131_storage"
+ },
+ "t_mapping(t_uint256,t_struct(Limits)7122_storage)": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => struct IAllowTokens.Limits)",
+ "numberOfBytes": "32",
+ "value": "t_struct(Limits)7122_storage"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(Limits)7122_storage": {
+ "encoding": "inplace",
+ "label": "struct IAllowTokens.Limits",
+ "members": [
+ {
+ "astId": 7113,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "min",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7115,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "max",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7117,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "daily",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7119,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "mediumAmount",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7121,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "largeAmount",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "160"
+ },
+ "t_struct(TokenInfo)7131_storage": {
+ "encoding": "inplace",
+ "label": "struct IAllowTokens.TokenInfo",
+ "members": [
+ {
+ "astId": 7124,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "allowed",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 7126,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "typeId",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7128,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "spentToday",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 7130,
+ "contract": "contracts/AllowTokens/AllowTokens.sol:AllowTokens",
+ "label": "lastDay",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_uint256"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/AllowTokensProxy.json b/bridge/deployments/rsktestnetrinkeby/AllowTokensProxy.json
new file mode 100644
index 000000000..9385077ca
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/AllowTokensProxy.json
@@ -0,0 +1,426 @@
+{
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "transactionIndex": 0,
+ "gasUsed": "1808069",
+ "logsBloom": "0x04000000000000000000000000010800000000000000200000800000000000000000000000000000000000000000000000002000020400000000000000040000000010000000000000000020000000000001000100040000000000000000000008000000020000000000800000000800000000000000000000000000000040400000000400000000000000000004001100000800000000000000000000000008000000000000000000000100000004000000000000800000002000080000400000000000000004000000000000000000000008008000000000000000000060200000000080000000000000000000000000000020008000000000000000100000",
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273",
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ],
+ "data": "0x0000000000000000000000008c8a34fe13400169a8da50908dffde4985237d19",
+ "logIndex": 1,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0xfcc55d4aea72e6d2d439843942c59b3141c952375a217e381f6a40e0b5ac4219"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 2,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "data": "0x00000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000015af1d78b58c400000000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a0000",
+ "logIndex": 3,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034254430000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 4,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000001"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000028a857425466f800000000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000429d069189e0000",
+ "logIndex": 5,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000001"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034554480000000000000000000000000000000000000000000000000000000000",
+ "logIndex": 6,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000002"
+ ],
+ "data": "0x00000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000878678326eac90000000000000000000000000000000000000000000000000010f0cf064dd59200000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a0000",
+ "logIndex": 7,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000002"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000083c31303030757364000000000000000000000000000000000000000000000000",
+ "logIndex": 8,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000003"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000054b40b1f852bda00000000000000000000000000000000000000000000000000a968163f0a57b4000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000008ac7230489e80000",
+ "logIndex": 9,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000003"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000073c31303075736400000000000000000000000000000000000000000000000000",
+ "logIndex": 10,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000004"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000002116545850052128000000000000000000000000000000000000000000000000422ca8b0a00a4250000000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000056bc75e2d63100000",
+ "logIndex": 11,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000004"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000053d31757364000000000000000000000000000000000000000000000000000000",
+ "logIndex": 12,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000005"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000cecb8f27f4200f3a0000000000000000000000000000000000000000000000019d971e4fe8401e740000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea00000",
+ "logIndex": 13,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000005"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000053c31757364000000000000000000000000000000000000000000000000000000",
+ "logIndex": 14,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0x1d2b256bb06ebc298b1980410a5e3b1e9bc4be642e8f26a58dc8a97d7fe2bbbb",
+ "0x0000000000000000000000000000000000000000000000000000000000000006"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000050c783eb9b5c85f2a80000000000000000000000000000000000000000000000a18f07d736b90be5500000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea00000",
+ "logIndex": 15,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170832,
+ "transactionHash": "0x98c6d029a1f060108cd8452e1e5825518638aedd7a3775151d6ba8314c2dc83e",
+ "address": "0x71f228664e2A118dEcD19B68C5151014769757a0",
+ "topics": [
+ "0xb30844b47136a66c1307afd352145423a1c237692b6ba474578f06f4614b35a0",
+ "0x0000000000000000000000000000000000000000000000000000000000000006"
+ ],
+ "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000063c3163656e740000000000000000000000000000000000000000000000000000",
+ "logIndex": 16,
+ "blockHash": "0x340c2f6b9bcf1304546868de011e05722280e5c6dce4ffc3c3c8b2a231f90273"
+ }
+ ],
+ "blockNumber": 2170832,
+ "cumulativeGasUsed": "1808069",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0xAE3852306015df037D458a65173BBc7527F4680b",
+ "0x8C35e166d2Dea7a8A28aaeA11AD7933cDae4b0aB",
+ "0xd4164b5d0000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b0000000000000000000000008c8a34fe13400169a8da50908dffde4985237d1900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000015af1d78b58c400000000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000000003425443000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000028a857425466f800000000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000429d069189e00000000000000000000000000000000000000000000000000000000000000000003455448000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000878678326eac90000000000000000000000000000000000000000000000000010f0cf064dd59200000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000083c3130303075736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000054b40b1f852bda00000000000000000000000000000000000000000000000000a968163f0a57b4000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000073c3130307573640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000002116545850052128000000000000000000000000000000000000000000000000422ca8b0a00a4250000000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000053d3175736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000cecb8f27f4200f3a0000000000000000000000000000000000000000000000019d971e4fe8401e740000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000053c3175736400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000050c783eb9b5c85f2a80000000000000000000000000000000000000000000000a18f07d736b90be5500000000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000063c3163656e740000000000000000000000000000000000000000000000000000"
+ ],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"stateVariables\":{\"_ADMIN_SLOT\":{\"details\":\"Storage slot with the admin of the contract. This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\r\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\r\\n * be specified by overriding the virtual {_implementation} function.\\r\\n *\\r\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\r\\n * different contract through the {_delegate} function.\\r\\n *\\r\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\r\\n */\\r\\nabstract contract Proxy {\\r\\n /**\\r\\n * @dev Delegates the current call to `implementation`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _delegate(address implementation) internal virtual {\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n // Copy msg.data. We take full control of memory in this inline assembly\\r\\n // block because it will not return to Solidity code. We overwrite the\\r\\n // Solidity scratch pad at memory position 0.\\r\\n calldatacopy(0, 0, calldatasize())\\r\\n\\r\\n // Call the implementation.\\r\\n // out and outsize are 0 because we don't know the size yet.\\r\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\r\\n\\r\\n // Copy the returned data.\\r\\n returndatacopy(0, 0, returndatasize())\\r\\n\\r\\n switch result\\r\\n // delegatecall returns 0 on error.\\r\\n case 0 { revert(0, returndatasize()) }\\r\\n default { return(0, returndatasize()) }\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\r\\n * and {_fallback} should delegate.\\r\\n */\\r\\n function _implementation() internal view virtual returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _fallback() internal virtual {\\r\\n _beforeFallback();\\r\\n _delegate(_implementation());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\r\\n * function in the contract matches the call data.\\r\\n */\\r\\n fallback () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\r\\n * is empty.\\r\\n */\\r\\n receive () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\r\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\r\\n *\\r\\n * If overriden should call `super._beforeFallback()`.\\r\\n */\\r\\n function _beforeFallback() internal virtual {\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x6374180266624d2291abb230bdf0d364858fa164844f5d2d83ad5325852390c9\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./UpgradeableProxy.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\r\\n *\\r\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\r\\n * clashing], which can potentially be used in an attack, this contract uses the\\r\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\r\\n * things that go hand in hand:\\r\\n *\\r\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\r\\n * that call matches one of the admin functions exposed by the proxy itself.\\r\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\r\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\r\\n * \\\"admin cannot fallback to proxy target\\\".\\r\\n *\\r\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\r\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\r\\n * to sudden errors when trying to call a function from the proxy implementation.\\r\\n *\\r\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\r\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\r\\n */\\r\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\r\\n /**\\r\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\r\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\r\\n */\\r\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\r\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\r\\n _setAdmin(admin_);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the admin account has changed.\\r\\n */\\r\\n event AdminChanged(address previousAdmin, address newAdmin);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the admin of the contract.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\r\\n\\r\\n /**\\r\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\r\\n */\\r\\n modifier ifAdmin() {\\r\\n if (msg.sender == _admin()) {\\r\\n _;\\r\\n } else {\\r\\n _fallback();\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\r\\n */\\r\\n function admin() external ifAdmin returns (address admin_) {\\r\\n admin_ = _admin();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\r\\n */\\r\\n function implementation() external ifAdmin returns (address implementation_) {\\r\\n implementation_ = _implementation();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Changes the admin of the proxy.\\r\\n *\\r\\n * Emits an {AdminChanged} event.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\r\\n */\\r\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\r\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\r\\n emit AdminChanged(_admin(), newAdmin);\\r\\n _setAdmin(newAdmin);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\r\\n */\\r\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\r\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\r\\n * proxied contract.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\r\\n */\\r\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n Address.functionDelegateCall(newImplementation, data);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n */\\r\\n function _admin() internal view virtual returns (address adm) {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n adm := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 admin slot.\\r\\n */\\r\\n function _setAdmin(address newAdmin) private {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newAdmin)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\r\\n */\\r\\n function _beforeFallback() internal virtual override {\\r\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\r\\n super._beforeFallback();\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x7496c2c54dd8e648d6999687cf759521e6ab229d0d8ddb4db62f3b51dbe68811\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./Proxy.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\r\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\r\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\r\\n * implementation behind the proxy.\\r\\n *\\r\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\r\\n * {TransparentUpgradeableProxy}.\\r\\n */\\r\\ncontract UpgradeableProxy is Proxy {\\r\\n /**\\r\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\r\\n *\\r\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\r\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\r\\n */\\r\\n constructor(address _logic, bytes memory _data) payable {\\r\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\r\\n _setImplementation(_logic);\\r\\n if(_data.length > 0) {\\r\\n Address.functionDelegateCall(_logic, _data);\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the implementation is upgraded.\\r\\n */\\r\\n event Upgraded(address indexed implementation);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the address of the current implementation.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation address.\\r\\n */\\r\\n function _implementation() internal view virtual override returns (address impl) {\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n impl := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrades the proxy to a new implementation.\\r\\n *\\r\\n * Emits an {Upgraded} event.\\r\\n */\\r\\n function _upgradeTo(address newImplementation) internal virtual {\\r\\n _setImplementation(newImplementation);\\r\\n emit Upgraded(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 implementation slot.\\r\\n */\\r\\n function _setImplementation(address newImplementation) private {\\r\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\r\\n\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newImplementation)\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x4d3fcb8487e53abb8658817c4b90038b24d81d0a32d989f03b54d4cfab929f62\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000c9f38038062000c9f83398101604081905262000026916200022e565b8281620000338262000071565b8051156200005457620000528282620000d360201b620002ca1760201c565b505b506200005d9050565b620000688262000102565b5050506200041d565b62000087816200012660201b620002f61760201c565b620000af5760405162461bcd60e51b8152600401620000a69062000347565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6060620000fb838360405180606001604052806027815260200162000c786027913962000130565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b60606200013d8462000126565b6200015c5760405162461bcd60e51b8152600401620000a690620003a4565b600080856001600160a01b031685604051620001799190620002f4565b600060405180830381855af49150503d8060008114620001b6576040519150601f19603f3d011682016040523d82523d6000602084013e620001bb565b606091505b509092509050620001ce828286620001d8565b9695505050505050565b60608315620001e9575081620000fb565b825115620001fa5782518084602001fd5b8160405162461bcd60e51b8152600401620000a6919062000312565b80516001600160a01b03811681146200012b57600080fd5b60008060006060848603121562000243578283fd5b6200024e8462000216565b92506200025e6020850162000216565b60408501519092506001600160401b03808211156200027b578283fd5b818601915086601f8301126200028f578283fd5b8151818111156200029c57fe5b604051601f8201601f191681016020018381118282101715620002bb57fe5b604052818152838201602001891015620002d3578485fd5b620002e6826020830160208701620003ea565b809450505050509250925092565b6000825162000308818460208701620003ea565b9190910192915050565b600060208252825180602084015262000333816040850160208701620003ea565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b8381101562000407578181015183820152602001620003ed565b8381111562000417576000848401525b50505050565b61084b806200042d6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209ba77a19de177ea34b608207423a21765cca1077e9d39a414a7175e09fb147e464736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209ba77a19de177ea34b608207423a21765cca1077e9d39a414a7175e09fb147e464736f6c63430007060033",
+ "devdoc": {
+ "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.",
+ "events": {
+ "AdminChanged(address,address)": {
+ "details": "Emitted when the admin account has changed."
+ }
+ },
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "constructor": {
+ "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "stateVariables": {
+ "_ADMIN_SLOT": {
+ "details": "Storage slot with the admin of the contract. This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/Bridge.json b/bridge/deployments/rsktestnetrinkeby/Bridge.json
new file mode 100644
index 000000000..9bec4ce3e
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/Bridge.json
@@ -0,0 +1,1684 @@
+{
+ "address": "0x7E339118346364d7D86AB67cb0775CBB808E65F7",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ }
+ ],
+ "name": "AcceptedCrossTransfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "AllowTokensChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_reciever",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ }
+ ],
+ "name": "Claimed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "_userData",
+ "type": "bytes"
+ }
+ ],
+ "name": "Cross",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "FederationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "FeePercentageChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_newSideTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_newSymbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "NewSideToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Paused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "SideTokenFactoryChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Unpaused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "Upgrading",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "WrappedCurrencyChanged",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "CLAIM_TYPEHASH",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Pausable_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__PauserRol_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "acceptTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "addPauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "allowTokens",
+ "outputs": [
+ {
+ "internalType": "contract IAllowTokens",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "changeAllowTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "changeFederation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newSideTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "changeSideTokenFactory",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claim",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claimFallback",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct IBridge.ClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_relayer",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_fee",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_deadline",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_v",
+ "type": "uint8"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_r",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_s",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimGasless",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "receivedAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_typeId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint8",
+ "name": "_originalTokenDecimals",
+ "type": "uint8"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenName",
+ "type": "string"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "domainSeparator",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "feePercentageDivider",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFederation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFeePercentage",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "getTransactionDataHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasBeenClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasCrossed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initDomainSeparator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_federation",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_allowTokens",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_sideTokenFactory",
+ "type": "address"
+ },
+ {
+ "internalType": "string",
+ "name": "_symbolPrefix",
+ "type": "string"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isPauser",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isUpgrading",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "knownTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "mappedTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "nonces",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "originalTokenAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "originalTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "pause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "paused",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenToUse",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "receiveTokensTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renouncePauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "senderAddresses",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "setFeePercentage",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "setUpgrading",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_wrappedCurrency",
+ "type": "address"
+ }
+ ],
+ "name": "setWrappedCurrency",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "sideTokenFactory",
+ "outputs": [
+ {
+ "internalType": "contract ISideTokenFactory",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbolPrefix",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "userData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "tokensReceived",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionsDataHashes",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unpause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "wrappedCurrency",
+ "outputs": [
+ {
+ "internalType": "contract IWrapped",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xf7f9a778313aafd42a06b232f704d6283c34a1c3bc7eee9cd90cb4fd59be943d",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0x7E339118346364d7D86AB67cb0775CBB808E65F7",
+ "transactionIndex": 0,
+ "gasUsed": "4545139",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x326ad42bc248d8b497012363c4769fcee79034550c487030059337f6044f9025",
+ "transactionHash": "0xf7f9a778313aafd42a06b232f704d6283c34a1c3bc7eee9cd90cb4fd59be943d",
+ "logs": [],
+ "blockNumber": 2170824,
+ "cumulativeGasUsed": "4545139",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"}],\"name\":\"AcceptedCrossTransfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newAllowTokens\",\"type\":\"address\"}],\"name\":\"AllowTokensChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_reciever\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_relayer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"Claimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_userData\",\"type\":\"bytes\"}],\"name\":\"Cross\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newFederation\",\"type\":\"address\"}],\"name\":\"FederationChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"FeePercentageChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newSideTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_newSymbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_granularity\",\"type\":\"uint256\"}],\"name\":\"NewSideToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newSideTokenFactory\",\"type\":\"address\"}],\"name\":\"SideTokenFactoryChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"Upgrading\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_wrappedCurrency\",\"type\":\"address\"}],\"name\":\"WrappedCurrencyChanged\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"CLAIM_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__Pausable_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__PauserRol_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"}],\"name\":\"acceptTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"addPauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allowTokens\",\"outputs\":[{\"internalType\":\"contract IAllowTokens\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAllowTokens\",\"type\":\"address\"}],\"name\":\"changeAllowTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFederation\",\"type\":\"address\"}],\"name\":\"changeFederation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newSideTokenFactory\",\"type\":\"address\"}],\"name\":\"changeSideTokenFactory\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claim\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claimFallback\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct IBridge.ClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"},{\"internalType\":\"address payable\",\"name\":\"_relayer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_s\",\"type\":\"bytes32\"}],\"name\":\"claimGasless\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"claimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_typeId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"_originalTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"_originalTokenSymbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_originalTokenName\",\"type\":\"string\"}],\"name\":\"createSideToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"domainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePercentageDivider\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFederation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeePercentage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"}],\"name\":\"getTransactionDataHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasBeenClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasCrossed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initDomainSeparator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_federation\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_allowTokens\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_sideTokenFactory\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbolPrefix\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isPauser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUpgrading\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"knownTokens\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mappedTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"originalTokenAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"originalTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenToUse\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"receiveTokensTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renouncePauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"senderAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"setFeePercentage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"setUpgrading\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_wrappedCurrency\",\"type\":\"address\"}],\"name\":\"setWrappedCurrency\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sideTokenFactory\",\"outputs\":[{\"internalType\":\"contract ISideTokenFactory\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbolPrefix\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"userData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transactionsDataHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wrappedCurrency\",\"outputs\":[{\"internalType\":\"contract IWrapped\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"__Pausable_init(address)\":{\"details\":\"Initializes the contract in unpaused state. Assigns the Pauser role to the deployer.\"},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pause()\":{\"details\":\"Called by a pauser to pause, triggers stopped state.\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"unpause()\":{\"details\":\"Called by a pauser to unpause, returns to normal state.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"acceptTransfer(address,address,address,uint256,bytes32,bytes32,uint32)\":{\"notice\":\"Accepts the transaction from the other chain that was voted and sent by the Federation contract\"},\"claim((address,uint256,bytes32,bytes32,uint32))\":{\"notice\":\"Claims the crossed transaction using the hash, this sends the funds to the address indicated in\"},\"depositTo(address)\":{\"notice\":\"Use network currency and cross it.\"},\"receiveTokensTo(address,address,uint256)\":{\"notice\":\"ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction See https://eips.ethereum.org/EIPS/eip-777#motivation for details\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Bridge/Bridge.sol\":\"Bridge\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Bridge/Bridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n// Import base Initializable contract\\r\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\r\\n// Import interface and library from OpenZeppelin contracts\\r\\nimport \\\"../zeppelin/upgradable/utils/ReentrancyGuard.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\r\\n\\r\\nimport \\\"../zeppelin/introspection/IERC1820Registry.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC777/IERC777Recipient.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC20/IERC20.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC20/SafeERC20.sol\\\";\\r\\nimport \\\"../zeppelin/utils/Address.sol\\\";\\r\\nimport \\\"../zeppelin/math/SafeMath.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC777/IERC777.sol\\\";\\r\\n\\r\\nimport \\\"../lib/LibEIP712.sol\\\";\\r\\nimport \\\"../lib/LibUtils.sol\\\";\\r\\n\\r\\nimport \\\"../interface/IBridge.sol\\\";\\r\\nimport \\\"../interface/ISideToken.sol\\\";\\r\\nimport \\\"../interface/ISideTokenFactory.sol\\\";\\r\\nimport \\\"../interface/IAllowTokens.sol\\\";\\r\\nimport \\\"../interface/IWrapped.sol\\\";\\r\\n\\r\\n// solhint-disable-next-line max-states-count\\r\\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\\r\\n using SafeMath for uint256;\\r\\n using SafeERC20 for IERC20;\\r\\n using Address for address;\\r\\n\\r\\n address constant internal NULL_ADDRESS = address(0);\\r\\n bytes32 constant internal NULL_HASH = bytes32(0);\\r\\n IERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\r\\n\\r\\n address internal federation;\\r\\n uint256 internal feePercentage;\\r\\n string public symbolPrefix;\\r\\n // replaces uint256 internal _depprecatedLastDay;\\r\\n bytes32 public domainSeparator;\\r\\n uint256 internal _deprecatedSpentToday;\\r\\n\\r\\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\\r\\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\\r\\n mapping (address => bool) public knownTokens; // OriginalToken => true\\r\\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\\r\\n IAllowTokens public allowTokens;\\r\\n ISideTokenFactory public sideTokenFactory;\\r\\n //Bridge_v1 variables\\r\\n bool public isUpgrading;\\r\\n // Percentage with up to 2 decimals\\r\\n uint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\\r\\n //Bridge_v3 variables\\r\\n bytes32 constant internal _erc777Interface = keccak256(\\\"ERC777Token\\\"); // solhint-disable-line const-name-snakecase\\r\\n IWrapped public wrappedCurrency;\\r\\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\\r\\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\\r\\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\\r\\n\\r\\n // keccak256(\\\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\\\");\\r\\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\\r\\n mapping(address => uint) public nonces;\\r\\n\\r\\n event AllowTokensChanged(address _newAllowTokens);\\r\\n event FederationChanged(address _newFederation);\\r\\n event SideTokenFactoryChanged(address _newSideTokenFactory);\\r\\n event Upgrading(bool _isUpgrading);\\r\\n event WrappedCurrencyChanged(address _wrappedCurrency);\\r\\n\\r\\n function initialize(\\r\\n address _manager,\\r\\n address _federation,\\r\\n address _allowTokens,\\r\\n address _sideTokenFactory,\\r\\n string memory _symbolPrefix\\r\\n ) public initializer {\\r\\n UpgradableOwnable.initialize(_manager);\\r\\n UpgradablePausable.__Pausable_init(_manager);\\r\\n symbolPrefix = _symbolPrefix;\\r\\n allowTokens = IAllowTokens(_allowTokens);\\r\\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\\r\\n federation = _federation;\\r\\n //keccak256(\\\"ERC777TokensRecipient\\\")\\r\\n ERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\\r\\n initDomainSeparator();\\r\\n }\\r\\n\\r\\n receive () external payable {\\r\\n // The fallback function is needed to use WRBTC\\r\\n require(_msgSender() == address(wrappedCurrency), \\\"Bridge: not wrappedCurrency\\\");\\r\\n }\\r\\n\\r\\n function version() override external pure returns (string memory) {\\r\\n return \\\"v3\\\";\\r\\n }\\r\\n\\r\\n function initDomainSeparator() public {\\r\\n uint chainId;\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n chainId := chainid()\\r\\n }\\r\\n domainSeparator = LibEIP712.hashEIP712Domain(\\r\\n \\\"RSK Token Bridge\\\",\\r\\n \\\"1\\\",\\r\\n chainId,\\r\\n address(this)\\r\\n );\\r\\n }\\r\\n\\r\\n modifier whenNotUpgrading() {\\r\\n require(!isUpgrading, \\\"Bridge: Upgrading\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function acceptTransfer(\\r\\n address _originalTokenAddress,\\r\\n address payable _from,\\r\\n address payable _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external whenNotPaused nonReentrant override {\\r\\n require(_msgSender() == federation, \\\"Bridge: Not Federation\\\");\\r\\n require(knownTokens[_originalTokenAddress] ||\\r\\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\\r\\n \\\"Bridge: Unknown token\\\"\\r\\n );\\r\\n require(_to != NULL_ADDRESS, \\\"Bridge: Null To\\\");\\r\\n require(_amount > 0, \\\"Bridge: Amount 0\\\");\\r\\n require(_blockHash != NULL_HASH, \\\"Bridge: Null BlockHash\\\");\\r\\n require(_transactionHash != NULL_HASH, \\\"Bridge: Null TxHash\\\");\\r\\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \\\"Bridge: Already accepted\\\");\\r\\n\\r\\n bytes32 _transactionDataHash = getTransactionDataHash(\\r\\n _to,\\r\\n _amount,\\r\\n _blockHash,\\r\\n _transactionHash,\\r\\n _logIndex\\r\\n );\\r\\n // Do not remove, claimed also has the previously processed using the older bridge version\\r\\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\\r\\n require(!claimed[_transactionDataHash], \\\"Bridge: Already claimed\\\");\\r\\n\\r\\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\\r\\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\\r\\n senderAddresses[_transactionHash] = _from;\\r\\n\\r\\n emit AcceptedCrossTransfer(\\r\\n _transactionHash,\\r\\n _originalTokenAddress,\\r\\n _to,\\r\\n _from,\\r\\n _amount,\\r\\n _blockHash,\\r\\n _logIndex\\r\\n );\\r\\n }\\r\\n\\r\\n\\r\\n function createSideToken(\\r\\n uint256 _typeId,\\r\\n address _originalTokenAddress,\\r\\n uint8 _originalTokenDecimals,\\r\\n string calldata _originalTokenSymbol,\\r\\n string calldata _originalTokenName\\r\\n ) external onlyOwner {\\r\\n require(_originalTokenAddress != NULL_ADDRESS, \\\"Bridge: Null token\\\");\\r\\n address sideToken = mappedTokens[_originalTokenAddress];\\r\\n require(sideToken == NULL_ADDRESS, \\\"Bridge: Already exists\\\");\\r\\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\\r\\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\\r\\n\\r\\n // Create side token\\r\\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\\r\\n\\r\\n mappedTokens[_originalTokenAddress] = sideToken;\\r\\n originalTokens[sideToken] = _originalTokenAddress;\\r\\n allowTokens.setToken(sideToken, _typeId);\\r\\n\\r\\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\\r\\n }\\r\\n\\r\\n function claim(ClaimData calldata _claimData)\\r\\n external override returns (uint256 receivedAmount) {\\r\\n\\r\\n receivedAmount = _claim(\\r\\n _claimData,\\r\\n _claimData.to,\\r\\n payable(address(0)),\\r\\n 0\\r\\n );\\r\\n return receivedAmount;\\r\\n }\\r\\n\\r\\n function claimFallback(ClaimData calldata _claimData)\\r\\n external override returns (uint256 receivedAmount) {\\r\\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\\\"Bridge: invalid sender\\\");\\r\\n receivedAmount = _claim(\\r\\n _claimData,\\r\\n _msgSender(),\\r\\n payable(address(0)),\\r\\n 0\\r\\n );\\r\\n return receivedAmount;\\r\\n }\\r\\n\\r\\n function getDigest(\\r\\n ClaimData memory _claimData,\\r\\n address payable _relayer,\\r\\n uint256 _fee,\\r\\n uint256 _deadline\\r\\n ) internal returns (bytes32) {\\r\\n return LibEIP712.hashEIP712Message(\\r\\n domainSeparator,\\r\\n keccak256(\\r\\n abi.encode(\\r\\n CLAIM_TYPEHASH,\\r\\n _claimData.to,\\r\\n _claimData.amount,\\r\\n _claimData.transactionHash,\\r\\n _relayer,\\r\\n _fee,\\r\\n nonces[_claimData.to]++,\\r\\n _deadline\\r\\n )\\r\\n )\\r\\n );\\r\\n }\\r\\n\\r\\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\\r\\n function claimGasless(\\r\\n ClaimData calldata _claimData,\\r\\n address payable _relayer,\\r\\n uint256 _fee,\\r\\n uint256 _deadline,\\r\\n uint8 _v,\\r\\n bytes32 _r,\\r\\n bytes32 _s\\r\\n ) external override returns (uint256 receivedAmount) {\\r\\n require(_deadline >= block.timestamp, \\\"Bridge: EXPIRED\\\"); // solhint-disable-line not-rely-on-time\\r\\n\\r\\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\\r\\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\\r\\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \\\"Bridge: INVALID_SIGNATURE\\\");\\r\\n\\r\\n receivedAmount = _claim(\\r\\n _claimData,\\r\\n _claimData.to,\\r\\n _relayer,\\r\\n _fee\\r\\n );\\r\\n return receivedAmount;\\r\\n }\\r\\n\\r\\n function _claim(\\r\\n ClaimData calldata _claimData,\\r\\n address payable _reciever,\\r\\n address payable _relayer,\\r\\n uint256 _fee\\r\\n ) internal nonReentrant returns (uint256 receivedAmount) {\\r\\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\\r\\n require(originalTokenAddress != NULL_ADDRESS, \\\"Bridge: Tx not crossed\\\");\\r\\n\\r\\n bytes32 transactionDataHash = getTransactionDataHash(\\r\\n _claimData.to,\\r\\n _claimData.amount,\\r\\n _claimData.blockHash,\\r\\n _claimData.transactionHash,\\r\\n _claimData.logIndex\\r\\n );\\r\\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \\\"Bridge: Wrong transactionDataHash\\\");\\r\\n require(!claimed[transactionDataHash], \\\"Bridge: Already claimed\\\");\\r\\n\\r\\n claimed[transactionDataHash] = true;\\r\\n if (knownTokens[originalTokenAddress]) {\\r\\n receivedAmount =_claimCrossBackToToken(\\r\\n originalTokenAddress,\\r\\n _reciever,\\r\\n _claimData.amount,\\r\\n _relayer,\\r\\n _fee\\r\\n );\\r\\n } else {\\r\\n receivedAmount =_claimCrossToSideToken(\\r\\n originalTokenAddress,\\r\\n _reciever,\\r\\n _claimData.amount,\\r\\n _relayer,\\r\\n _fee\\r\\n );\\r\\n }\\r\\n emit Claimed(\\r\\n _claimData.transactionHash,\\r\\n originalTokenAddress,\\r\\n _claimData.to,\\r\\n senderAddresses[_claimData.transactionHash],\\r\\n _claimData.amount,\\r\\n _claimData.blockHash,\\r\\n _claimData.logIndex,\\r\\n _reciever,\\r\\n _relayer,\\r\\n _fee\\r\\n );\\r\\n return receivedAmount;\\r\\n }\\r\\n\\r\\n function _claimCrossToSideToken(\\r\\n address _originalTokenAddress,\\r\\n address payable _receiver,\\r\\n uint256 _amount,\\r\\n address payable _relayer,\\r\\n uint256 _fee\\r\\n ) internal returns (uint256 receivedAmount) {\\r\\n address sideToken = mappedTokens[_originalTokenAddress];\\r\\n uint256 granularity = IERC777(sideToken).granularity();\\r\\n uint256 formattedAmount = _amount.mul(granularity);\\r\\n require(_fee <= formattedAmount, \\\"Bridge: fee too high\\\");\\r\\n receivedAmount = formattedAmount - _fee;\\r\\n ISideToken(sideToken).mint(_receiver, receivedAmount, \\\"\\\", \\\"\\\");\\r\\n if(_fee > 0) {\\r\\n ISideToken(sideToken).mint(_relayer, _fee, \\\"\\\", \\\"relayer fee\\\");\\r\\n }\\r\\n return receivedAmount;\\r\\n }\\r\\n\\r\\n function _claimCrossBackToToken(\\r\\n address _originalTokenAddress,\\r\\n address payable _receiver,\\r\\n uint256 _amount,\\r\\n address payable _relayer,\\r\\n uint256 _fee\\r\\n ) internal returns (uint256 receivedAmount) {\\r\\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\\r\\n //As side tokens are ERC777 they will always have 18 decimals\\r\\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\\r\\n require(_fee <= formattedAmount, \\\"Bridge: fee too high\\\");\\r\\n receivedAmount = formattedAmount - _fee;\\r\\n if(address(wrappedCurrency) == _originalTokenAddress) {\\r\\n wrappedCurrency.withdraw(formattedAmount);\\r\\n _receiver.transfer(receivedAmount);\\r\\n if(_fee > 0) {\\r\\n _relayer.transfer(_fee);\\r\\n }\\r\\n } else {\\r\\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\\r\\n if(_fee > 0) {\\r\\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\\r\\n }\\r\\n }\\r\\n return receivedAmount;\\r\\n }\\r\\n\\r\\n /**\\r\\n * ERC-20 tokens approve and transferFrom pattern\\r\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\r\\n */\\r\\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\\r\\n address sender = _msgSender();\\r\\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\\r\\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\\r\\n crossTokens(tokenToUse, sender, to, amount, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * Use network currency and cross it.\\r\\n */\\r\\n function depositTo(address to) override external payable {\\r\\n address sender = _msgSender();\\r\\n require(address(wrappedCurrency) != NULL_ADDRESS, \\\"Bridge: wrappedCurrency empty\\\");\\r\\n wrappedCurrency.deposit{ value: msg.value }();\\r\\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\r\\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\r\\n */\\r\\n function tokensReceived (\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata\\r\\n ) external override(IBridge, IERC777Recipient){\\r\\n //Hook from ERC777address\\r\\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\\r\\n require(to == address(this), \\\"Bridge: Not to this address\\\");\\r\\n address tokenToUse = _msgSender();\\r\\n require(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \\\"Bridge: Not ERC777 token\\\");\\r\\n require(userData.length != 0 || !from.isContract(), \\\"Bridge: Specify receiver address in data\\\");\\r\\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\\r\\n crossTokens(tokenToUse, from, receiver, amount, userData);\\r\\n }\\r\\n\\r\\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\\r\\n internal whenNotUpgrading whenNotPaused nonReentrant {\\r\\n knownTokens[tokenToUse] = true;\\r\\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\\r\\n uint256 amountMinusFees = amount.sub(fee);\\r\\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\\r\\n uint formattedAmount = amount;\\r\\n if(decimals != 18) {\\r\\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\\r\\n }\\r\\n // We consider the amount before fees converted to 18 decimals to check the limits\\r\\n // updateTokenTransfer revert if token not allowed\\r\\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\\r\\n address originalTokenAddress = tokenToUse;\\r\\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\\r\\n //Side Token Crossing\\r\\n originalTokenAddress = originalTokens[tokenToUse];\\r\\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\\r\\n uint256 modulo = amountMinusFees.mod(granularity);\\r\\n fee = fee.add(modulo);\\r\\n amountMinusFees = amountMinusFees.sub(modulo);\\r\\n IERC777(tokenToUse).burn(amountMinusFees, userData);\\r\\n }\\r\\n\\r\\n emit Cross(\\r\\n originalTokenAddress,\\r\\n from,\\r\\n to,\\r\\n amountMinusFees,\\r\\n userData\\r\\n );\\r\\n\\r\\n if (fee > 0) {\\r\\n //Send the payment to the MultiSig of the Federation\\r\\n IERC20(tokenToUse).safeTransfer(owner(), fee);\\r\\n }\\r\\n }\\r\\n\\r\\n function getTransactionDataHash(\\r\\n address _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n )\\r\\n public pure override returns(bytes32)\\r\\n {\\r\\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\\r\\n }\\r\\n\\r\\n function setFeePercentage(uint amount) external onlyOwner {\\r\\n require(amount < (feePercentageDivider/10), \\\"Bridge: bigger than 10%\\\");\\r\\n feePercentage = amount;\\r\\n emit FeePercentageChanged(feePercentage);\\r\\n }\\r\\n\\r\\n function getFeePercentage() external view override returns(uint) {\\r\\n return feePercentage;\\r\\n }\\r\\n\\r\\n function changeFederation(address newFederation) external onlyOwner {\\r\\n require(newFederation != NULL_ADDRESS, \\\"Bridge: Federation is empty\\\");\\r\\n federation = newFederation;\\r\\n emit FederationChanged(federation);\\r\\n }\\r\\n\\r\\n\\r\\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\\r\\n require(newAllowTokens != NULL_ADDRESS, \\\"Bridge: AllowTokens is empty\\\");\\r\\n allowTokens = IAllowTokens(newAllowTokens);\\r\\n emit AllowTokensChanged(newAllowTokens);\\r\\n }\\r\\n\\r\\n function getFederation() external view returns(address) {\\r\\n return federation;\\r\\n }\\r\\n\\r\\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\\r\\n require(newSideTokenFactory != NULL_ADDRESS, \\\"Bridge: SideTokenFactory is empty\\\");\\r\\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\\r\\n emit SideTokenFactoryChanged(newSideTokenFactory);\\r\\n }\\r\\n\\r\\n function setUpgrading(bool _isUpgrading) external onlyOwner {\\r\\n isUpgrading = _isUpgrading;\\r\\n emit Upgrading(isUpgrading);\\r\\n }\\r\\n\\r\\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\\r\\n require(_wrappedCurrency != NULL_ADDRESS, \\\"Bridge: wrapp is empty\\\");\\r\\n wrappedCurrency = IWrapped(_wrappedCurrency);\\r\\n emit WrappedCurrencyChanged(_wrappedCurrency);\\r\\n }\\r\\n\\r\\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\\r\\n return transactionsDataHashes[transactionHash] != bytes32(0);\\r\\n }\\r\\n\\r\\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\\r\\n return claimed[transactionsDataHashes[transactionHash]];\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0x04b4af913df0dcd2c965b9550422687963b67ad588f9ba26cec50eb3c305ab7b\",\"license\":\"MIT\"},\"contracts/interface/IAllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IAllowTokens {\\r\\n\\r\\n struct Limits {\\r\\n uint256 min;\\r\\n uint256 max;\\r\\n uint256 daily;\\r\\n uint256 mediumAmount;\\r\\n uint256 largeAmount;\\r\\n }\\r\\n\\r\\n struct TokenInfo {\\r\\n bool allowed;\\r\\n uint256 typeId;\\r\\n uint256 spentToday;\\r\\n uint256 lastDay;\\r\\n }\\r\\n\\r\\n struct TypeInfo {\\r\\n string description;\\r\\n Limits limits;\\r\\n }\\r\\n\\r\\n struct TokensAndType {\\r\\n address token;\\r\\n uint256 typeId;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\\r\\n\\r\\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\\r\\n\\r\\n function getTypesLimits() external view returns(Limits[] memory limits);\\r\\n\\r\\n function getTypeDescriptionsLength() external view returns(uint256);\\r\\n\\r\\n function getTypeDescriptions() external view returns(string[] memory descriptions);\\r\\n\\r\\n function setToken(address token, uint256 typeId) external;\\r\\n\\r\\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\\r\\n\\r\\n function isTokenAllowed(address token) external view returns (bool);\\r\\n\\r\\n function updateTokenTransfer(address token, uint256 amount) external;\\r\\n}\",\"keccak256\":\"0xe565b0887688d1625e70316993d66adecc65890012d190a6e450ea7cb7d981b1\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IBridge {\\r\\n\\r\\n struct ClaimData {\\r\\n address payable to;\\r\\n uint256 amount;\\r\\n bytes32 blockHash;\\r\\n bytes32 transactionHash;\\r\\n uint32 logIndex;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getFeePercentage() external view returns(uint);\\r\\n\\r\\n /**\\r\\n * ERC-20 tokens approve and transferFrom pattern\\r\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\r\\n */\\r\\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\\r\\n\\r\\n /**\\r\\n * Use network currency and cross it.\\r\\n */\\r\\n function depositTo(address to) external payable;\\r\\n\\r\\n /**\\r\\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\r\\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\r\\n */\\r\\n function tokensReceived (\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\r\\n */\\r\\n function acceptTransfer(\\r\\n address _originalTokenAddress,\\r\\n address payable _from,\\r\\n address payable _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\r\\n */\\r\\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\r\\n\\r\\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\r\\n\\r\\n function claimGasless(\\r\\n ClaimData calldata _claimData,\\r\\n address payable _relayer,\\r\\n uint256 _fee,\\r\\n uint256 _deadline,\\r\\n uint8 _v,\\r\\n bytes32 _r,\\r\\n bytes32 _s\\r\\n ) external returns (uint256 receivedAmount);\\r\\n\\r\\n function getTransactionDataHash(\\r\\n address _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external returns(bytes32);\\r\\n\\r\\n event Cross(\\r\\n address indexed _tokenAddress,\\r\\n address indexed _from,\\r\\n address indexed _to,\\r\\n uint256 _amount,\\r\\n bytes _userData\\r\\n );\\r\\n event NewSideToken(\\r\\n address indexed _newSideTokenAddress,\\r\\n address indexed _originalTokenAddress,\\r\\n string _newSymbol,\\r\\n uint256 _granularity\\r\\n );\\r\\n event AcceptedCrossTransfer(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _from,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex\\r\\n );\\r\\n event FeePercentageChanged(uint256 _amount);\\r\\n event Claimed(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _sender,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex,\\r\\n address _reciever,\\r\\n address _relayer,\\r\\n uint256 _fee\\r\\n );\\r\\n}\",\"keccak256\":\"0x9e48ff075a1e3fd0533feec4b93f397a4678b5d267cbae021ea0faf8cc91a383\",\"license\":\"MIT\"},\"contracts/interface/ISideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideToken {\\r\\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\\r\\n}\",\"keccak256\":\"0x22b96c1de44cc83f38f93cb0bebac0d090b88e1d951373eefdceb2b4284d6ffa\",\"license\":\"MIT\"},\"contracts/interface/ISideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideTokenFactory {\\r\\n\\r\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\\r\\n\\r\\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\\r\\n}\",\"keccak256\":\"0xbac49cc8df91c7aae47037ac9b3956615399bc6fa01d2a49764a7e6e48085b14\",\"license\":\"MIT\"},\"contracts/interface/IWrapped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IWrapped {\\r\\n function balanceOf(address) external returns(uint);\\r\\n\\r\\n function deposit() external payable;\\r\\n\\r\\n function withdraw(uint wad) external;\\r\\n\\r\\n function totalSupply() external view returns (uint);\\r\\n\\r\\n function approve(address guy, uint wad) external returns (bool);\\r\\n\\r\\n function transfer(address dst, uint wad) external returns (bool);\\r\\n\\r\\n function transferFrom(address src, address dst, uint wad)\\r\\n external\\r\\n returns (bool);\\r\\n}\",\"keccak256\":\"0xb79b74797d9b4102d4ba69d452ed04bae742e34240c3aa72f654de525b29a5c7\",\"license\":\"MIT\"},\"contracts/lib/LibEIP712.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\\r\\nlibrary LibEIP712 {\\r\\n\\r\\n // Hash of the EIP712 Domain Separator Schema\\r\\n // keccak256(abi.encodePacked(\\r\\n // \\\"EIP712Domain(\\\",\\r\\n // \\\"string name,\\\",\\r\\n // \\\"string version,\\\",\\r\\n // \\\"uint256 chainId,\\\",\\r\\n // \\\"address verifyingContract\\\",\\r\\n // \\\")\\\"\\r\\n // ))\\r\\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\\r\\n\\r\\n /// @dev Calculates a EIP712 domain separator.\\r\\n /// @param name The EIP712 domain name.\\r\\n /// @param version The EIP712 domain version.\\r\\n /// @param verifyingContract The EIP712 verifying contract.\\r\\n /// @return result EIP712 domain separator.\\r\\n function hashEIP712Domain(\\r\\n string memory name,\\r\\n string memory version,\\r\\n uint256 chainId,\\r\\n address verifyingContract\\r\\n )\\r\\n internal\\r\\n pure\\r\\n returns (bytes32 result)\\r\\n {\\r\\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\\r\\n\\r\\n // Assembly for more efficient computing:\\r\\n // keccak256(abi.encodePacked(\\r\\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\\r\\n // keccak256(bytes(name)),\\r\\n // keccak256(bytes(version)),\\r\\n // chainId,\\r\\n // uint256(verifyingContract)\\r\\n // ))\\r\\n\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n // Calculate hashes of dynamic data\\r\\n let nameHash := keccak256(add(name, 32), mload(name))\\r\\n let versionHash := keccak256(add(version, 32), mload(version))\\r\\n\\r\\n // Load free memory pointer\\r\\n let memPtr := mload(64)\\r\\n\\r\\n // Store params in memory\\r\\n mstore(memPtr, schemaHash)\\r\\n mstore(add(memPtr, 32), nameHash)\\r\\n mstore(add(memPtr, 64), versionHash)\\r\\n mstore(add(memPtr, 96), chainId)\\r\\n mstore(add(memPtr, 128), verifyingContract)\\r\\n\\r\\n // Compute hash\\r\\n result := keccak256(memPtr, 160)\\r\\n }\\r\\n return result;\\r\\n }\\r\\n\\r\\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\\r\\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\\r\\n /// with getDomainHash().\\r\\n /// @param hashStruct The EIP712 hash struct.\\r\\n /// @return result EIP712 hash applied to the given EIP712 Domain.\\r\\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\\r\\n internal\\r\\n pure\\r\\n returns (bytes32 result)\\r\\n {\\r\\n // Assembly for more efficient computing:\\r\\n // keccak256(abi.encodePacked(\\r\\n // EIP191_HEADER,\\r\\n // EIP712_DOMAIN_HASH,\\r\\n // hashStruct\\r\\n // ));\\r\\n\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n // Load free memory pointer\\r\\n let memPtr := mload(64)\\r\\n\\r\\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\\r\\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\\r\\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\\r\\n\\r\\n // Compute hash\\r\\n result := keccak256(memPtr, 66)\\r\\n }\\r\\n return result;\\r\\n }\\r\\n}\",\"keccak256\":\"0xfcfcf60905df9a2644e372c9e76b8cc7a5034c5c4d6d9f44b1ffb56244551237\",\"license\":\"MIT\"},\"contracts/lib/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nlibrary LibUtils {\\r\\n\\r\\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\\r\\n require(decimals <= 18, \\\"LibUtils: Decimals not <= 18\\\");\\r\\n return uint256(10)**(18-decimals);\\r\\n }\\r\\n\\r\\n function getDecimals(address tokenToUse) internal view returns (uint8) {\\r\\n //support decimals as uint256 or uint8\\r\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"decimals()\\\"));\\r\\n require(success, \\\"LibUtils: No decimals\\\");\\r\\n // uint: enc(X) is the big-endian encoding of X,\\r\\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\\r\\n return uint8(abi.decode(data, (uint256)));\\r\\n }\\r\\n\\r\\n function getGranularity(address tokenToUse) internal view returns (uint256) {\\r\\n //support granularity if ERC777\\r\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"granularity()\\\"));\\r\\n require(success, \\\"LibUtils: No granularity\\\");\\r\\n\\r\\n return abi.decode(data, (uint256));\\r\\n }\\r\\n\\r\\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n addr := mload(add(bys,20))\\r\\n }\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0x9e289497bfdbde6ef762efab3d91e581cc83116929b69851e64da33a8d790196\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/access/Roles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @title Roles\\r\\n * @dev Library for managing addresses assigned to a Role.\\r\\n */\\r\\nlibrary Roles {\\r\\n struct Role {\\r\\n mapping (address => bool) bearer;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Give an account access to this role.\\r\\n */\\r\\n function add(Role storage role, address account) internal {\\r\\n require(!has(role, account), \\\"Roles: account already has role\\\");\\r\\n role.bearer[account] = true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Remove an account's access to this role.\\r\\n */\\r\\n function remove(Role storage role, address account) internal {\\r\\n require(has(role, account), \\\"Roles: account doesn't have role\\\");\\r\\n role.bearer[account] = false;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Check if an account has this role.\\r\\n * @return bool\\r\\n */\\r\\n function has(Role storage role, address account) internal view returns (bool) {\\r\\n require(account != address(0), \\\"Roles: account is the zero address\\\");\\r\\n return role.bearer[account];\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x51be0ac4cc78172ee6ee886a4779e6b8f289420541d28be81f3c427c5118c298\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC1820Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\r\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\r\\n * implementers for interfaces in this registry, as well as query support.\\r\\n *\\r\\n * Implementers may be shared by multiple accounts, and can also implement more\\r\\n * than a single interface for each account. Contracts can implement interfaces\\r\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\r\\n * contract.\\r\\n *\\r\\n * {IERC165} interfaces can also be queried via the registry.\\r\\n *\\r\\n * For an in-depth explanation and source code analysis, see the EIP text.\\r\\n */\\r\\ninterface IERC1820Registry {\\r\\n /**\\r\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\r\\n * account is able to set interface implementers for it.\\r\\n *\\r\\n * By default, each account is its own manager. Passing a value of `0x0` in\\r\\n * `newManager` will reset the manager to this initial state.\\r\\n *\\r\\n * Emits a {ManagerChanged} event.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the caller must be the current manager for `account`.\\r\\n */\\r\\n function setManager(address account, address newManager) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the manager for `account`.\\r\\n *\\r\\n * See {setManager}.\\r\\n */\\r\\n function getManager(address account) external view returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Sets the `implementer` contract as `account`'s implementer for\\r\\n * `interfaceHash`.\\r\\n *\\r\\n * `account` being the zero address is an alias for the caller's address.\\r\\n * The zero address can also be used in `implementer` to remove an old one.\\r\\n *\\r\\n * See {interfaceHash} to learn how these are created.\\r\\n *\\r\\n * Emits an {InterfaceImplementerSet} event.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the caller must be the current manager for `_account`.\\r\\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\r\\n * end in 28 zeroes).\\r\\n * - `_implementer` must implement {IERC1820Implementer} and return true when\\r\\n * queried for support, unless `implementer` is the caller. See\\r\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\r\\n */\\r\\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\\r\\n * implementer is registered, returns the zero address.\\r\\n *\\r\\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\r\\n * zeroes), `_account` will be queried for support of it.\\r\\n *\\r\\n * `account` being the zero address is an alias for the caller's address.\\r\\n */\\r\\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\r\\n * corresponding\\r\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\r\\n */\\r\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\r\\n\\r\\n /**\\r\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\r\\n * @param account Address of the contract for which to update the cache.\\r\\n * @param interfaceId ERC165 interface for which to update the cache.\\r\\n */\\r\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\r\\n\\r\\n /**\\r\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\r\\n * If the result is not cached a direct lookup on the contract address is performed.\\r\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\r\\n * {updateERC165Cache} with the contract address.\\r\\n * @param account Address of the contract to check.\\r\\n * @param interfaceId ERC165 interface to check.\\r\\n * @return True if `account` implements `interfaceId`, false otherwise.\\r\\n */\\r\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\\r\\n * @param account Address of the contract to check.\\r\\n * @param interfaceId ERC165 interface to check.\\r\\n * @return True if `account` implements `interfaceId`, false otherwise.\\r\\n */\\r\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\r\\n\\r\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\r\\n\\r\\n event ManagerChanged(address indexed account, address indexed newManager);\\r\\n}\\r\\n\",\"keccak256\":\"0x0c607a83a8f5ec2f214bc754ffb59428d90978e122108fcd91ba193d5fc78018\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\r\\n * checks.\\r\\n *\\r\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\r\\n * in bugs, because programmers usually assume that an overflow raises an\\r\\n * error, which is the standard behavior in high level programming languages.\\r\\n * `SafeMath` restores this intuition by reverting the transaction when an\\r\\n * operation overflows.\\r\\n *\\r\\n * Using this library instead of the unchecked operations eliminates an entire\\r\\n * class of bugs, so it's recommended to use it always.\\r\\n */\\r\\nlibrary SafeMath {\\r\\n /**\\r\\n * @dev Returns the addition of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `+` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Addition cannot overflow.\\r\\n */\\r\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n uint256 c = a + b;\\r\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n */\\r\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b <= a, errorMessage);\\r\\n uint256 c = a - b;\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `*` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Multiplication cannot overflow.\\r\\n */\\r\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\r\\n // benefit is lost if 'b' is also tested.\\r\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\r\\n if (a == 0) {\\r\\n return 0;\\r\\n }\\r\\n\\r\\n uint256 c = a * b;\\r\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n // Solidity only automatically asserts when dividing by 0\\r\\n require(b > 0, errorMessage);\\r\\n uint256 c = a / b;\\r\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts with custom message when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b != 0, errorMessage);\\r\\n return a % b;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x29ffa7ff59806a3add585615cc102b70b43049587dcc73649f77b427f35b009d\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\r\\n * the optional functions; to access them see {ERC20Detailed}.\\r\\n */\\r\\ninterface IERC20 {\\r\\n /**\\r\\n * @dev Returns the amount of tokens in existence.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens owned by `account`.\\r\\n */\\r\\n function balanceOf(address account) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transfer(address recipient, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Returns the remaining number of tokens that `spender` will be\\r\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\r\\n * zero by default.\\r\\n *\\r\\n * This value changes when {approve} or {transferFrom} are called.\\r\\n */\\r\\n function allowance(address owner, address spender) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\r\\n * that someone may use both the old and the new allowance by unfortunate\\r\\n * transaction ordering. One possible solution to mitigate this race\\r\\n * condition is to first reduce the spender's allowance to 0 and set the\\r\\n * desired value afterwards:\\r\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\r\\n *\\r\\n * Emits an {Approval} event.\\r\\n */\\r\\n function approve(address spender, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\r\\n * allowance mechanism. `amount` is then deducted from the caller's\\r\\n * allowance.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\r\\n * another (`to`).\\r\\n *\\r\\n * Note that `value` may be zero.\\r\\n */\\r\\n event Transfer(address indexed from, address indexed to, uint256 value);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\r\\n * a call to {approve}. `value` is the new allowance.\\r\\n */\\r\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\r\\n}\\r\\n\",\"keccak256\":\"0x7531f90b8a5a04fd225fb07a30e0792068438a7c82127a22db870c1849460dfc\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./IERC20.sol\\\";\\r\\nimport \\\"../../math/SafeMath.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title SafeERC20\\r\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\r\\n * contract returns false). Tokens that return no value (and instead revert or\\r\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\r\\n * successful.\\r\\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\\r\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\r\\n */\\r\\nlibrary SafeERC20 {\\r\\n using SafeMath for uint256;\\r\\n using Address for address;\\r\\n\\r\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\r\\n }\\r\\n\\r\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\r\\n }\\r\\n\\r\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\r\\n // safeApprove should only be called when setting an initial allowance,\\r\\n // or when resetting it to zero. To increase and decrease it, use\\r\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\r\\n // solhint-disable-next-line max-line-length\\r\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\r\\n \\\"SafeERC20: approve non-zero to non-zero allowance\\\"\\r\\n );\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\r\\n }\\r\\n\\r\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\r\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\r\\n }\\r\\n\\r\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\r\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\r\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\r\\n * @param token The token targeted by the call.\\r\\n * @param data The call data (encoded using abi.encode or one of its variants).\\r\\n */\\r\\n function callOptionalReturn(IERC20 token, bytes memory data) private {\\r\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\r\\n // we're implementing it ourselves.\\r\\n\\r\\n // A Solidity high level call has three parts:\\r\\n // 1. The target address is checked to verify it contains contract code\\r\\n // 2. The call itself is made, and success asserted\\r\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\r\\n // solhint-disable-next-line max-line-length\\r\\n require(address(token).isContract(), \\\"SafeERC20: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = address(token).call(data);\\r\\n require(success, \\\"SafeERC20: low-level call failed\\\");\\r\\n\\r\\n if (returndata.length > 0) { // Return data is optional\\r\\n // solhint-disable-next-line max-line-length\\r\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x393fa2aef898c565ba8c8816ac0e2d0e31865d2866e4807f39f1a8cef95f5a81\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC777Token standard as defined in the EIP.\\r\\n *\\r\\n * This contract uses the\\r\\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\\r\\n * token holders and recipients react to token movements by using setting implementers\\r\\n * for the associated interfaces in said registry. See `IERC1820Registry` and\\r\\n * `ERC1820Implementer`.\\r\\n */\\r\\ninterface IERC777 {\\r\\n /**\\r\\n * @dev Returns the name of the token.\\r\\n */\\r\\n function name() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the symbol of the token, usually a shorter version of the\\r\\n * name.\\r\\n */\\r\\n function symbol() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the smallest part of the token that is not divisible. This\\r\\n * means all token operations (creation, movement and destruction) must have\\r\\n * amounts that are a multiple of this number.\\r\\n *\\r\\n * For most token contracts, this value will equal 1.\\r\\n */\\r\\n function granularity() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens in existence.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens owned by an account (`owner`).\\r\\n */\\r\\n function balanceOf(address owner) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\r\\n *\\r\\n * If send or receive hooks are registered for the caller and `recipient`,\\r\\n * the corresponding functions will be called with `data` and empty\\r\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\r\\n *\\r\\n * Emits a `Sent` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - the caller must have at least `amount` tokens.\\r\\n * - `recipient` cannot be the zero address.\\r\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\r\\n * interface.\\r\\n */\\r\\n function send(address recipient, uint256 amount, bytes calldata data) external;\\r\\n\\r\\n /**\\r\\n * @dev Destroys `amount` tokens from the caller's account, reducing the\\r\\n * total supply.\\r\\n *\\r\\n * If a send hook is registered for the caller, the corresponding function\\r\\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\\r\\n *\\r\\n * Emits a `Burned` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - the caller must have at least `amount` tokens.\\r\\n */\\r\\n function burn(uint256 amount, bytes calldata data) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns true if an account is an operator of `tokenHolder`.\\r\\n * Operators can send and burn tokens on behalf of their owners. All\\r\\n * accounts are their own operator.\\r\\n *\\r\\n * See `operatorSend` and `operatorBurn`.\\r\\n */\\r\\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Make an account an operator of the caller.\\r\\n *\\r\\n * See `isOperatorFor`.\\r\\n *\\r\\n * Emits an `AuthorizedOperator` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `operator` cannot be calling address.\\r\\n */\\r\\n function authorizeOperator(address operator) external;\\r\\n\\r\\n /**\\r\\n * @dev Make an account an operator of the caller.\\r\\n *\\r\\n * See `isOperatorFor` and `defaultOperators`.\\r\\n *\\r\\n * Emits a `RevokedOperator` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `operator` cannot be calling address.\\r\\n */\\r\\n function revokeOperator(address operator) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the list of default operators. These accounts are operators\\r\\n * for all token holders, even if `authorizeOperator` was never called on\\r\\n * them.\\r\\n *\\r\\n * This list is immutable, but individual holders may revoke these via\\r\\n * `revokeOperator`, in which case `isOperatorFor` will return false.\\r\\n */\\r\\n function defaultOperators() external view returns (address[] memory);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\\r\\n * be an operator of `sender`.\\r\\n *\\r\\n * If send or receive hooks are registered for `sender` and `recipient`,\\r\\n * the corresponding functions will be called with `data` and\\r\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\r\\n *\\r\\n * Emits a `Sent` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `sender` cannot be the zero address.\\r\\n * - `sender` must have at least `amount` tokens.\\r\\n * - the caller must be an operator for `sender`.\\r\\n * - `recipient` cannot be the zero address.\\r\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\r\\n * interface.\\r\\n */\\r\\n function operatorSend(\\r\\n address sender,\\r\\n address recipient,\\r\\n uint256 amount,\\r\\n bytes calldata data,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\\r\\n * The caller must be an operator of `account`.\\r\\n *\\r\\n * If a send hook is registered for `account`, the corresponding function\\r\\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\\r\\n *\\r\\n * Emits a `Burned` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `account` cannot be the zero address.\\r\\n * - `account` must have at least `amount` tokens.\\r\\n * - the caller must be an operator for `account`.\\r\\n */\\r\\n function operatorBurn(\\r\\n address account,\\r\\n uint256 amount,\\r\\n bytes calldata data,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n\\r\\n event Sent(\\r\\n address indexed operator,\\r\\n address indexed from,\\r\\n address indexed to,\\r\\n uint256 amount,\\r\\n bytes data,\\r\\n bytes operatorData\\r\\n );\\r\\n\\r\\n function decimals() external returns (uint8);\\r\\n\\r\\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\\r\\n\\r\\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\\r\\n\\r\\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\\r\\n\\r\\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\\r\\n}\\r\\n\",\"keccak256\":\"0xf9947f4f7572e74766fcb4de1d58c6c26cd31379fd5d4b885cdbdf14a16dbe94\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\r\\n *\\r\\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\\r\\n * contract implement this interface (contract holders can be their own\\r\\n * implementer) and registering it on the\\r\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\r\\n *\\r\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\r\\n */\\r\\ninterface IERC777Recipient {\\r\\n /**\\r\\n * @dev Called by an `IERC777` token contract whenever tokens are being\\r\\n * moved or created into a registered account (`to`). The type of operation\\r\\n * is conveyed by `from` being the zero address or not.\\r\\n *\\r\\n * This call occurs _after_ the token contract's state is updated, so\\r\\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\\r\\n *\\r\\n * This function may revert to prevent the operation from being executed.\\r\\n */\\r\\n function tokensReceived(\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n}\\r\\n\",\"keccak256\":\"0x1f43e427174c60bacb510e63053626e5b24d825333e9921bb7c1ea673b1c6e1e\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @title Initializable\\r\\n *\\r\\n * @dev Helper contract to support initializer functions. To use it, replace\\r\\n * the constructor with a function that has the `initializer` modifier.\\r\\n * WARNING: Unlike constructors, initializer functions must be manually\\r\\n * invoked. This applies both to deploying an Initializable contract, as well\\r\\n * as extending an Initializable contract via inheritance.\\r\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\r\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\r\\n * because this is not dealt with automatically as with constructors.\\r\\n */\\r\\ncontract Initializable {\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract has been initialized.\\r\\n */\\r\\n bool private initialized;\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract is in the process of being initialized.\\r\\n */\\r\\n bool private initializing;\\r\\n\\r\\n /**\\r\\n * @dev Modifier to use in the initializer function of a contract.\\r\\n */\\r\\n modifier initializer() {\\r\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\r\\n\\r\\n bool isTopLevelCall = !initializing;\\r\\n if (isTopLevelCall) {\\r\\n initializing = true;\\r\\n initialized = true;\\r\\n }\\r\\n\\r\\n _;\\r\\n\\r\\n if (isTopLevelCall) {\\r\\n initializing = false;\\r\\n }\\r\\n }\\r\\n\\r\\n // Reserved storage space to allow for layout changes in the future.\\r\\n uint256[50] private ______gap;\\r\\n}\",\"keccak256\":\"0xc1f4d917648f0e17ba6a023a168173ad6163f3120e24d1c97ae294430e42eaf3\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../../GSN/Context.sol\\\";\\r\\nimport \\\"../../../access/Roles.sol\\\";\\r\\n\\r\\ncontract UpgradablePauserRole is Initializable, Context {\\r\\n using Roles for Roles.Role;\\r\\n\\r\\n event PauserAdded(address indexed account);\\r\\n event PauserRemoved(address indexed account);\\r\\n\\r\\n Roles.Role private _pausers;\\r\\n\\r\\n function __PauserRol_init(address sender) public initializer {\\r\\n if (!isPauser(sender)) {\\r\\n _addPauser(sender);\\r\\n }\\r\\n }\\r\\n\\r\\n modifier onlyPauser() {\\r\\n require(isPauser(_msgSender()), \\\"PauserRole: caller doesn't have the role\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function isPauser(address account) public view returns (bool) {\\r\\n return _pausers.has(account);\\r\\n }\\r\\n\\r\\n function addPauser(address account) public onlyPauser {\\r\\n _addPauser(account);\\r\\n }\\r\\n\\r\\n function renouncePauser() public {\\r\\n _removePauser(_msgSender());\\r\\n }\\r\\n\\r\\n function _addPauser(address account) internal {\\r\\n _pausers.add(account);\\r\\n emit PauserAdded(account);\\r\\n }\\r\\n\\r\\n function _removePauser(address account) internal {\\r\\n _pausers.remove(account);\\r\\n emit PauserRemoved(account);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x175465830c1ec77cab5ebdcfaeca43c79d33f3becded5332ed6136adac3f99eb\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"../access/roles/UpgradablePauserRole.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Contract module which allows children to implement an emergency stop\\r\\n * mechanism that can be triggered by an authorized account.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the\\r\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\r\\n * the functions of your contract. Note that they will not be pausable by\\r\\n * simply including this module, only once the modifiers are put in place.\\r\\n */\\r\\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\\r\\n /**\\r\\n * @dev Emitted when the pause is triggered by a pauser (`account`).\\r\\n */\\r\\n event Paused(address account);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the pause is lifted by a pauser (`account`).\\r\\n */\\r\\n event Unpaused(address account);\\r\\n\\r\\n bool private _paused;\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\\r\\n * to the deployer.\\r\\n */\\r\\n function __Pausable_init(address sender) public initializer {\\r\\n UpgradablePauserRole.__PauserRol_init(sender);\\r\\n\\r\\n _paused = false;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the contract is paused, and false otherwise.\\r\\n */\\r\\n function paused() public view returns (bool) {\\r\\n return _paused;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Modifier to make a function callable only when the contract is not paused.\\r\\n */\\r\\n modifier whenNotPaused() {\\r\\n require(!_paused, \\\"Pausable: paused\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Modifier to make a function callable only when the contract is paused.\\r\\n */\\r\\n modifier whenPaused() {\\r\\n require(_paused, \\\"Pausable: not paused\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Called by a pauser to pause, triggers stopped state.\\r\\n */\\r\\n function pause() public onlyPauser whenNotPaused {\\r\\n _paused = true;\\r\\n emit Paused(_msgSender());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Called by a pauser to unpause, returns to normal state.\\r\\n */\\r\\n function unpause() public onlyPauser whenPaused {\\r\\n _paused = false;\\r\\n emit Unpaused(_msgSender());\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x0837df4a389f73b7210b97b1b64ba8f9cc842367b473f8fc856c4e892f212ac4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Contract module which provides a basic access control mechanism, where\\r\\n * there is an account (an owner) that can be granted exclusive access to\\r\\n * specific functions.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the modifier\\r\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\r\\n * the owner.\\r\\n */\\r\\ncontract UpgradableOwnable is Initializable, Context {\\r\\n address private _owner;\\r\\n\\r\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract setting the deployer as the initial owner.\\r\\n */\\r\\n function initialize(address sender) public initializer {\\r\\n _owner = sender;\\r\\n emit OwnershipTransferred(address(0), _owner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the address of the current owner.\\r\\n */\\r\\n function owner() public view returns (address) {\\r\\n return _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Throws if called by any account other than the owner.\\r\\n */\\r\\n modifier onlyOwner() {\\r\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the caller is the current owner.\\r\\n */\\r\\n function isOwner() public view returns (bool) {\\r\\n return _msgSender() == _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Leaves the contract without owner. It will not be possible to call\\r\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\r\\n *\\r\\n * > Note: Renouncing ownership will leave the contract without an owner,\\r\\n * thereby removing any functionality that is only available to the owner.\\r\\n */\\r\\n function renounceOwnership() public onlyOwner {\\r\\n emit OwnershipTransferred(_owner, address(0));\\r\\n _owner = address(0);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n * Can only be called by the current owner.\\r\\n */\\r\\n function transferOwnership(address newOwner) public onlyOwner {\\r\\n _transferOwnership(newOwner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n */\\r\\n function _transferOwnership(address newOwner) internal {\\r\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\r\\n emit OwnershipTransferred(_owner, newOwner);\\r\\n _owner = newOwner;\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0xea920007e371a3300245b5885f72cecc472c4780818365f0025fae65a767273d\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title Helps contracts guard against reentrancy attacks.\\r\\n * @author Remco Bloemen , Eenae \\r\\n * @dev If you mark a function `nonReentrant`, you should also\\r\\n * mark it `external`.\\r\\n */\\r\\ncontract ReentrancyGuard is Initializable {\\r\\n /// @dev counter to allow mutex lock with only one SSTORE operation\\r\\n uint256 private _guardCounter;\\r\\n\\r\\n function initialize() public initializer {\\r\\n // The counter starts at one to prevent changing it from zero to a non-zero\\r\\n // value, which is a more expensive operation.\\r\\n _guardCounter = 1;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\r\\n * Calling a `nonReentrant` function from another `nonReentrant`\\r\\n * function is not supported. It is possible to prevent this from happening\\r\\n * by making the `nonReentrant` function external, and make it call a\\r\\n * `private` function that does the actual work.\\r\\n */\\r\\n modifier nonReentrant() {\\r\\n _guardCounter += 1;\\r\\n uint256 localCounter = _guardCounter;\\r\\n _;\\r\\n require(localCounter == _guardCounter, \\\"ReentrancyGuard: no reentrant allowed\\\");\\r\\n }\\r\\n}\",\"keccak256\":\"0x67a8148c8357409eac291fc0954ca7a2d023b0534294be95f34eba0b15d748a5\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b506141d0806100206000396000f3fe6080604052600436106103025760003560e01c80638456cb5911610190578063c4d66de8116100dc578063e6fc774411610095578063f2fde38b1161006f578063f2fde38b146108b0578063f698da25146108d0578063f74032f0146108e5578063fa0caa16146109055761034c565b8063e6fc774414610866578063ea2170911461087b578063eb16136f146108905761034c565b8063c4d66de8146107b1578063ca07140c146107d1578063cc3c0f06146107f1578063d12e825d14610811578063da67703714610826578063e6ede14d146108465761034c565b8063ae06c1b711610149578063b50277bb11610123578063b50277bb14610754578063b760faf914610774578063b794726214610787578063b86f60d21461079c5761034c565b8063ae06c1b7146106ff578063afad80ac1461071f578063b0e1268e1461073f5761034c565b80638456cb591461066b5780638da5cb5b146106805780638f32d59b14610695578063916dc59d146106aa578063a53d6e6e146106ca578063adc5fb64146106df5761034c565b80634beea5061161024f5780636b0509b1116102085780637813bea2116101e25780637813bea2146105f65780637ecebe00146106165780638129fc1c1461063657806382dc1ec41461064b5761034c565b80636b0509b1146105b75780636ef8d66d146105cc578063715018a6146105e15761034c565b80634beea5061461050b57806354fd4d501461052b57806359a8a8671461054d5780635c975abb146105625780635d447129146105775780636a863191146105975761034c565b80632fb3b361116102bc5780633cf3058b116102965780633cf3058b146104895780633f4ba83a146104b657806342cdb2c6146104cb57806346fbf68e146104eb5761034c565b80632fb3b3611461041c5780633500c1dc1461043c57806337e761091461045c5761034c565b806223de2914610351578063026976191461037157806307c8f7b0146103a757806311efbf61146103c757806320e3bb00146103dc5780632f3cca4e146103fc5761034c565b3661034c576041546001600160a01b031661031b610925565b6001600160a01b03161461034a5760405162461bcd60e51b815260040161034190613e39565b60405180910390fd5b005b600080fd5b34801561035d57600080fd5b5061034a61036c3660046130c0565b610929565b34801561037d57600080fd5b5061039161038c366004613237565b610b20565b60405161039e9190613693565b60405180910390f35b3480156103b357600080fd5b5061034a6103c23660046131ff565b610b32565b3480156103d357600080fd5b50610391610bb0565b3480156103e857600080fd5b5061034a6103f7366004613368565b610bb6565b34801561040857600080fd5b5061034a610417366004612f3e565b610df1565b34801561042857600080fd5b5061034a610437366004612fec565b610e7a565b34801561044857600080fd5b5061034a610457366004612f3e565b610fea565b34801561046857600080fd5b5061047c610477366004613237565b61107f565b60405161039e9190613688565b34801561049557600080fd5b506104a96104a4366004613237565b6110a4565b60405161039e919061351f565b3480156104c257600080fd5b5061034a6110bf565b3480156104d757600080fd5b5061034a6104e6366004612f3e565b611152565b3480156104f757600080fd5b5061047c610506366004612f3e565b6111e5565b34801561051757600080fd5b5061039161052636600461326a565b6111f8565b34801561053757600080fd5b50610540611312565b60405161039e919061374f565b34801561055957600080fd5b5061054061132e565b34801561056e57600080fd5b5061047c6113bc565b34801561058357600080fd5b5061047c610592366004612f3e565b6113c5565b3480156105a357600080fd5b5061034a6105b2366004612f76565b6113da565b3480156105c357600080fd5b5061039161163e565b3480156105d857600080fd5b5061034a611662565b3480156105ed57600080fd5b5061034a611674565b34801561060257600080fd5b5061034a61061136600461316e565b6116e8565b34801561062257600080fd5b50610391610631366004612f3e565b61172b565b34801561064257600080fd5b5061034a61173d565b34801561065757600080fd5b5061034a610666366004612f3e565b6117b7565b34801561067757600080fd5b5061034a6117e7565b34801561068c57600080fd5b506104a9611867565b3480156106a157600080fd5b5061047c61187b565b3480156106b657600080fd5b5061034a6106c5366004612f3e565b6118a6565b3480156106d657600080fd5b506104a961193b565b3480156106eb57600080fd5b506103916106fa36600461324f565b61194a565b34801561070b57600080fd5b5061034a61071a366004613237565b6119a9565b34801561072b57600080fd5b5061039161073a3660046131ae565b611a23565b34801561074b57600080fd5b506104a9611a5f565b34801561076057600080fd5b5061039161076f36600461324f565b611a6e565b61034a610782366004612f3e565b611a81565b34801561079357600080fd5b5061047c611b50565b3480156107a857600080fd5b506104a9611b60565b3480156107bd57600080fd5b5061034a6107cc366004612f3e565b611b6f565b3480156107dd57600080fd5b506104a96107ec366004613237565b611c3a565b3480156107fd57600080fd5b5061047c61080c366004613237565b611c55565b34801561081d57600080fd5b5061034a611c6a565b34801561083257600080fd5b5061047c610841366004613237565b611cc2565b34801561085257600080fd5b506104a9610861366004612f3e565b611cd6565b34801561087257600080fd5b50610391611cf1565b34801561088757600080fd5b506104a9611cf7565b34801561089c57600080fd5b5061034a6108ab366004612f3e565b611d06565b3480156108bc57600080fd5b5061034a6108cb366004612f3e565b611d91565b3480156108dc57600080fd5b50610391611dbe565b3480156108f157600080fd5b506104a9610900366004612f3e565b611dc4565b34801561091157600080fd5b5061034a610920366004612f3e565b611ddf565b3390565b6001600160a01b03881630141561093f57610b16565b6001600160a01b03861630146109675760405162461bcd60e51b815260040161034190613b0d565b6000610971610925565b60405163555ddc6560e11b8152909150600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906109d09085907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce217705490600401613627565b60206040518083038186803b1580156109e857600080fd5b505afa1580156109fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a209190612f5a565b6001600160a01b03161415610a475760405162461bcd60e51b815260040161034190613f0e565b83151580610a645750610a62886001600160a01b0316611e7a565b155b610a805760405162461bcd60e51b815260040161034190613b74565b60008415610acc57610ac786868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e8092505050565b610ace565b885b9050610b13828a838a8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e8792505050565b50505b5050505050505050565b60426020526000908152604090205481565b610b3a61187b565b610b565760405162461bcd60e51b815260040161034190613d8b565b6040805460ff60a01b1916600160a01b83151581029190911780835591517f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad992610ba59260ff91041690613688565b60405180910390a150565b60375490565b610bbe61187b565b610bda5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b038616610c005760405162461bcd60e51b815260040161034190613d5f565b6001600160a01b038087166000908152603b6020526040902054168015610c395760405162461bcd60e51b81526004016103419061402f565b6000610c448761213a565b9050600060388787604051602001610c5e939291906134a6565b60408051601f1981840301815282825290546326d9e96360e01b83529092506001600160a01b0316906326d9e96390610ca1908890889086908890600401613700565b602060405180830381600087803b158015610cbb57600080fd5b505af1158015610ccf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf39190612f5a565b6001600160a01b03808b166000818152603b6020908152604080832080548688166001600160a01b03199182168117909255908452603c909252918290208054909116909217909155603f5490516378bf2b5360e01b815292955016906378bf2b5390610d669086908e90600401613627565b600060405180830381600087803b158015610d8057600080fd5b505af1158015610d94573d6000803e3d6000fd5b50505050886001600160a01b0316836001600160a01b03167f2ef93c4e96a4ef0b19497ff60c9e7360a8734f3d2cd27ae5318e43851734d17f8385604051610ddd929190613762565b60405180910390a350505050505050505050565b600054610100900460ff1680610e0a575060005460ff16155b610e265760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015610e51576000805460ff1961ff0019909116610100171660011790555b610e5a82611d06565b6034805460ff191690558015610e76576000805461ff00191690555b5050565b600054610100900460ff1680610e93575060005460ff16155b610eaf5760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015610eda576000805460ff1961ff0019909116610100171660011790555b610ee386611b6f565b610eec86610df1565b8151610eff906038906020850190612e1a565b50603f80546001600160a01b038087166001600160a01b031992831617909255604080548684169083161781556036805493891693909216929092179055516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90610f969030907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b908290600401613533565b600060405180830381600087803b158015610fb057600080fd5b505af1158015610fc4573d6000803e3d6000fd5b50505050610fd0611c6a565b8015610fe2576000805461ff00191690555b505050505050565b610ff261187b565b61100e5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b0381166110345760405162461bcd60e51b815260040161034190613aae565b604180546001600160a01b0319166001600160a01b0383161790556040517f0966c958966f6fac9ff807af074f8117eb2e9ce2b76390db7a158e9bdeb2485c90610ba590839061351f565b6000818152604260209081526040808320548352603e90915290205460ff165b919050565b6044602052600090815260409020546001600160a01b031681565b6110ca610506610925565b6110e65760405162461bcd60e51b815260040161034190613a05565b60345460ff166111085760405162461bcd60e51b8152600401610341906137c9565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61113b610925565b604051611148919061351f565b60405180910390a1565b61115a61187b565b6111765760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b03811661119c5760405162461bcd60e51b815260040161034190613ca6565b604080546001600160a01b0319166001600160a01b038316178155517f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e318369252162590610ba590839061351f565b60006111f260338361216d565b92915050565b60004285101561121a5760405162461bcd60e51b815260040161034190613c7d565b600061123661122e368b90038b018b6132da565b8989896121b5565b905060006001828787876040516000815260200160405260405161125d94939291906136e2565b6020604051602081039080840390855afa15801561127f573d6000803e3d6000fd5b5050604051601f19015191506000905061129c60208c018c612f3e565b6001600160a01b0316141580156112d057506112bb60208b018b612f3e565b6001600160a01b0316816001600160a01b0316145b6112ec5760405162461bcd60e51b815260040161034190613a4d565b6113048a6112fd6020820182612f3e565b8b8b61224a565b9a9950505050505050505050565b604080518082019091526002815261763360f01b602082015290565b6038805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156113b45780601f10611389576101008083540402835291602001916113b4565b820191906000526020600020905b81548152906001019060200180831161139757829003601f168201915b505050505081565b60345460ff1690565b603d6020526000908152604090205460ff1681565b60345460ff16156113fd5760405162461bcd60e51b815260040161034190613c1c565b60358054600101908190556036546001600160a01b031661141c610925565b6001600160a01b0316146114425760405162461bcd60e51b815260040161034190613b44565b6001600160a01b0388166000908152603d602052604090205460ff168061148257506001600160a01b038881166000908152603b60205260409020541615155b61149e5760405162461bcd60e51b815260040161034190613ade565b6001600160a01b0386166114c45760405162461bcd60e51b815260040161034190613bf3565b600085116114e45760405162461bcd60e51b815260040161034190613a84565b836115015760405162461bcd60e51b815260040161034190613ea7565b8261151e5760405162461bcd60e51b815260040161034190613926565b6000838152604260205260409020541561154a5760405162461bcd60e51b815260040161034190613e70565b60006115598787878787611a23565b6000818152603e602052604090205490915060ff161561158b5760405162461bcd60e51b815260040161034190613e02565b60008481526042602090815260408083208490556043825280832080546001600160a01b03199081166001600160a01b038f811691821790935560449094529382902080549094168c821617909355519189169186907f2858b8803acb87882fd2de49ce7572ae3e741fb8073cbe772fa50ce00bdfba2290611614908d908c908c908b90613556565b60405180910390a4506035548114610b165760405162461bcd60e51b815260040161034190613784565b7ff18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd8043381565b61167261166d610925565b612463565b565b61167c61187b565b6116985760405162461bcd60e51b815260040161034190613d8b565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b60006116f2610925565b90506117096001600160a01b0385168230856124a5565b6117258482858560405180602001604052806000815250611e87565b50505050565b60456020526000908152604090205481565b600054610100900460ff1680611756575060005460ff16155b6117725760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff1615801561179d576000805460ff1961ff0019909116610100171660011790555b600160355580156117b4576000805461ff00191690555b50565b6117c2610506610925565b6117de5760405162461bcd60e51b815260040161034190613a05565b6117b4816124fd565b6117f2610506610925565b61180e5760405162461bcd60e51b815260040161034190613a05565b60345460ff16156118315760405162461bcd60e51b815260040161034190613c1c565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861113b610925565b60345461010090046001600160a01b031690565b60345460009061010090046001600160a01b0316611897610925565b6001600160a01b031614905090565b6118ae61187b565b6118ca5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b0381166118f05760405162461bcd60e51b815260040161034190613ed7565b603f80546001600160a01b0319166001600160a01b0383161790556040517f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e390610ba590839061351f565b603f546001600160a01b031681565b60608101356000908152604460205260408120546001600160a01b031661196f610925565b6001600160a01b0316146119955760405162461bcd60e51b8152600401610341906138f6565b6111f2826119a1610925565b60008061224a565b6119b161187b565b6119cd5760405162461bcd60e51b815260040161034190613d8b565b6103e881106119ee5760405162461bcd60e51b81526004016103419061405f565b60378190556040517f97e97c577f03bda90e2c9739011ec065ed5fbfb36ae217d20bb0d9be95e160cd90610ba5908390613693565b60008383878785604051602001611a3e959493929190613448565b60405160208183030381529060405280519060200120905095945050505050565b6041546001600160a01b031681565b60006111f2826119a16020820182612f3e565b6000611a8b610925565b6041549091506001600160a01b0316611ab65760405162461bcd60e51b815260040161034190613c46565b604160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611b0657600080fd5b505af1158015611b1a573d6000803e3d6000fd5b5050505050610e76604160009054906101000a90046001600160a01b031682843460405180602001604052806000815250611e87565b604054600160a01b900460ff1681565b6040546001600160a01b031681565b600054610100900460ff1680611b88575060005460ff16155b611ba45760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015611bcf576000805460ff1961ff0019909116610100171660011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e76576000805461ff00191690555050565b6043602052600090815260409020546001600160a01b031681565b603e6020526000908152604090205460ff1681565b6000469050611cbc6040518060400160405280601081526020016f52534b20546f6b656e2042726964676560801b815250604051806040016040528060018152602001603160f81b815250833061253f565b60395550565b600090815260426020526040902054151590565b603b602052600090815260409020546001600160a01b031681565b61271081565b6036546001600160a01b031690565b600054610100900460ff1680611d1f575060005460ff16155b611d3b5760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015611d66576000805460ff1961ff0019909116610100171660011790555b611d6f826111e5565b611d7c57611d7c826124fd565b8015610e76576000805461ff00191690555050565b611d9961187b565b611db55760405162461bcd60e51b815260040161034190613d8b565b6117b481612596565b60395481565b603c602052600090815260409020546001600160a01b031681565b611de761187b565b611e035760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b038116611e295760405162461bcd60e51b81526004016103419061385d565b603680546001600160a01b0319166001600160a01b0383811691909117918290556040517f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb92610ba592169061351f565b3b151590565b6014015190565b604054600160a01b900460ff1615611eb15760405162461bcd60e51b8152600401610341906138cb565b60345460ff1615611ed45760405162461bcd60e51b815260040161034190613c1c565b603580546001908101918290556001600160a01b0387166000908152603d60205260408120805460ff1916909217909155603754611f219061271090611f1b908790612623565b90612664565b90506000611f2f85836126a6565b90506000611f3c896126e8565b905085601260ff831614611f6157611f5e8760ff601285900316600a0a612623565b90505b603f54604051638c34bc5560e01b81526001600160a01b0390911690638c34bc5590611f93908d908590600401613627565b600060405180830381600087803b158015611fad57600080fd5b505af1158015611fc1573d6000803e3d6000fd5b5050506001600160a01b03808c166000908152603c60205260409020548c9250161561209b57506001600160a01b03808b166000908152603c60205260408120549091169061200f8c6127ac565b9050600061201d8683612854565b90506120298782612896565b965061203586826126a6565b60405163fe9d930360e01b81529096506001600160a01b038e169063fe9d9303906120669089908d9060040161410e565b600060405180830381600087803b15801561208057600080fd5b505af1158015612094573d6000803e3d6000fd5b5050505050505b886001600160a01b03168a6001600160a01b0316826001600160a01b03167f1e90de9ae4d02420648a650f45f089a1be18fbca324092544ea626f9833212b0878b6040516120ea92919061410e565b60405180910390a4841561211457612114612103611867565b6001600160a01b038d1690876128bb565b50505050506035548114610fe25760405162461bcd60e51b815260040161034190613784565b600060128260ff1611156121605760405162461bcd60e51b815260040161034190613ce7565b5060120360ff16600a0a90565b60006001600160a01b0382166121955760405162461bcd60e51b815260040161034190613dc0565b506001600160a01b03166000908152602091909152604090205460ff1690565b603954845160208087015160608801516001600160a01b038416600090815260458452604080822080546001810190915590519196612241969095612226957ff18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd8043395929490938d928d928d910161369c565b604051602081830303815290604052805190602001206128df565b95945050505050565b603580546001019081905560608501356000908152604360205260408120549091906001600160a01b0316806122925760405162461bcd60e51b815260040161034190613f45565b60006122c36122a460208a018a612f3e565b60208a013560408b013560608c013561073a60a08e0160808f01613402565b606089013560009081526042602052604090205490915081146122f85760405162461bcd60e51b8152600401610341906140cd565b6000818152603e602052604090205460ff16156123275760405162461bcd60e51b815260040161034190613e02565b6000818152603e60209081526040808320805460ff191660011790556001600160a01b0385168352603d90915290205460ff16156123775761237082888a6020013589896128fe565b935061238b565b61238882888a602001358989612a74565b93505b6123986020890189612f3e565b6001600160a01b0316826001600160a01b031689606001357f42b1cb6263e8da47edf0583516eda1de16f729d26282f5791dc5b7af1010e925604460008d60600135815260200190815260200160002060009054906101000a90046001600160a01b03168c602001358d604001358e60800160208101906124199190613402565b8e8e8e60405161242f9796959493929190613640565b60405180910390a45050603554811461245a5760405162461bcd60e51b815260040161034190613784565b50949350505050565b61246e603382612c0b565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b611725846323b872dd60e01b8585856040516024016124c693929190613603565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612c53565b612508603382612d37565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b6001600160a01b0381166125bc5760405162461bcd60e51b815260040161034190613fa3565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600082612632575060006111f2565b8282028284828161263f57fe5b041461265d5760405162461bcd60e51b815260040161034190613d1e565b9392505050565b600061265d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612d83565b600061265d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612dba565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b0386169161272e919061348a565b600060405180830381855afa9150503d8060008114612769576040519150601f19603f3d011682016040523d82523d6000602084013e61276e565b606091505b5091509150816127905760405162461bcd60e51b81526004016103419061382e565b808060200190518101906127a49190613350565b949350505050565b60408051600481526024810182526020810180516001600160e01b031663556f0dc760e01b1790529051600091829182916001600160a01b038616916127f2919061348a565b600060405180830381855afa9150503d806000811461282d576040519150601f19603f3d011682016040523d82523d6000602084013e612832565b606091505b5091509150816127905760405162461bcd60e51b815260040161034190613bbc565b600061265d83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250612de6565b60008282018381101561265d5760405162461bcd60e51b815260040161034190613894565b6128da8363a9059cbb60e01b84846040516024016124c6929190613627565b505050565b60405161190160f01b8152600281019290925260228201526042902090565b60008061290a876126e8565b60ff1690506000612922866012849003600a0a612664565b9050808411156129445760405162461bcd60e51b815260040161034190613f75565b60415484820393506001600160a01b0389811691161415612a3b57604154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d9061298f908490600401613693565b600060405180830381600087803b1580156129a957600080fd5b505af11580156129bd573d6000803e3d6000fd5b50506040516001600160a01b038a16925085156108fc02915085906000818181858888f193505050501580156129f7573d6000803e3d6000fd5b508315612a36576040516001600160a01b0386169085156108fc029086906000818181858888f19350505050158015612a34573d6000803e3d6000fd5b505b612a69565b612a4f6001600160a01b03891688856128bb565b8315612a6957612a696001600160a01b03891686866128bb565b505095945050505050565b6001600160a01b038086166000908152603b6020908152604080832054815163556f0dc760e01b81529151939416928492849263556f0dc79260048083019392829003018186803b158015612ac857600080fd5b505afa158015612adc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b009190613350565b90506000612b0e8783612623565b905080851115612b305760405162461bcd60e51b815260040161034190613f75565b604051630dcdc7dd60e41b815285820394506001600160a01b0384169063dcdc7dd090612b63908b9088906004016135cd565b600060405180830381600087803b158015612b7d57600080fd5b505af1158015612b91573d6000803e3d6000fd5b505050506000851115612bff57604051630dcdc7dd60e41b81526001600160a01b0384169063dcdc7dd090612bcc9089908990600401613582565b600060405180830381600087803b158015612be657600080fd5b505af1158015612bfa573d6000803e3d6000fd5b505050505b50505095945050505050565b612c15828261216d565b612c315760405162461bcd60e51b815260040161034190613953565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b612c65826001600160a01b0316611e7a565b612c815760405162461bcd60e51b815260040161034190614096565b600080836001600160a01b031683604051612c9c919061348a565b6000604051808303816000865af19150503d8060008114612cd9576040519150601f19603f3d011682016040523d82523d6000602084013e612cde565b606091505b509150915081612d005760405162461bcd60e51b815260040161034190613988565b8051156117255780806020019051810190612d1b919061321b565b6117255760405162461bcd60e51b815260040161034190613fe5565b612d41828261216d565b15612d5e5760405162461bcd60e51b8152600401610341906137f7565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60008183612da45760405162461bcd60e51b8152600401610341919061374f565b506000838581612db057fe5b0495945050505050565b60008184841115612dde5760405162461bcd60e51b8152600401610341919061374f565b505050900390565b60008183612e075760405162461bcd60e51b8152600401610341919061374f565b50828481612e1157fe5b06949350505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282612e505760008555612e96565b82601f10612e6957805160ff1916838001178555612e96565b82800160010185558215612e96579182015b82811115612e96578251825591602001919060010190612e7b565b50612ea2929150612ea6565b5090565b5b80821115612ea25760008155600101612ea7565b60008083601f840112612ecc578182fd5b50813567ffffffffffffffff811115612ee3578182fd5b602083019150836020828501011115612efb57600080fd5b9250929050565b600060a08284031215612f13578081fd5b50919050565b803563ffffffff8116811461109f57600080fd5b803560ff8116811461109f57600080fd5b600060208284031215612f4f578081fd5b813561265d81614177565b600060208284031215612f6b578081fd5b815161265d81614177565b600080600080600080600060e0888a031215612f90578283fd5b8735612f9b81614177565b96506020880135612fab81614177565b95506040880135612fbb81614177565b9450606088013593506080880135925060a08801359150612fde60c08901612f19565b905092959891949750929550565b600080600080600060a08688031215613003578081fd5b853561300e81614177565b945060208681013561301f81614177565b9450604087013561302f81614177565b9350606087013561303f81614177565b9250608087013567ffffffffffffffff8082111561305b578384fd5b818901915089601f83011261306e578384fd5b81358181111561307a57fe5b61308c601f8201601f19168501614127565b91508082528a848285010111156130a1578485fd5b8084840185840137810190920192909252949793965091945092919050565b60008060008060008060008060c0898b0312156130db578081fd5b88356130e681614177565b975060208901356130f681614177565b9650604089013561310681614177565b955060608901359450608089013567ffffffffffffffff80821115613129578283fd5b6131358c838d01612ebb565b909650945060a08b013591508082111561314d578283fd5b5061315a8b828c01612ebb565b999c989b5096995094979396929594505050565b600080600060608486031215613182578081fd5b833561318d81614177565b9250602084013561319d81614177565b929592945050506040919091013590565b600080600080600060a086880312156131c5578283fd5b85356131d081614177565b94506020860135935060408601359250606086013591506131f360808701612f19565b90509295509295909350565b600060208284031215613210578081fd5b813561265d8161418c565b60006020828403121561322c578081fd5b815161265d8161418c565b600060208284031215613248578081fd5b5035919050565b600060a08284031215613260578081fd5b61265d8383612f02565b6000806000806000806000610160888a031215613285578081fd5b61328f8989612f02565b965060a088013561329f81614177565b955060c0880135945060e088013593506132bc6101008901612f2d565b92506101208801359150610140880135905092959891949750929550565b600060a082840312156132eb578081fd5b60405160a0810181811067ffffffffffffffff8211171561330857fe5b604052823561331681614177565b8082525060208301356020820152604083013560408201526060830135606082015261334460808401612f19565b60808201529392505050565b600060208284031215613361578081fd5b5051919050565b600080600080600080600060a0888a031215613382578081fd5b87359650602088013561339481614177565b95506133a260408901612f2d565b9450606088013567ffffffffffffffff808211156133be578283fd5b6133ca8b838c01612ebb565b909650945060808a01359150808211156133e2578283fd5b506133ef8a828b01612ebb565b989b979a50959850939692959293505050565b600060208284031215613413578081fd5b61265d82612f19565b6000815180845261343481602086016020860161414b565b601f01601f19169290920160200192915050565b948552602085019390935260609190911b6bffffffffffffffffffffffff19166040840152605483015260e01b6001600160e01b031916607482015260780190565b6000825161349c81846020870161414b565b9190910192915050565b60008085546001808216600081146134c557600181146134dc5761350b565b60ff198316865260028304607f168601935061350b565b600283048986526020808720875b838110156135035781548a8201529085019082016134ea565b505050860193505b505050838582379092019182525092915050565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b6001600160a01b039490941684526020840192909252604083015263ffffffff16606082015260800190565b6001600160a01b03929092168252602082015260806040820181905260009082015260a060608201819052600b908201526a72656c617965722066656560a81b60c082015260e00190565b6001600160a01b039290921682526020820152608060408201819052600090820181905260a06060830181905282015260c00190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0397881681526020810196909652604086019490945263ffffffff9290921660608501528416608084015290921660a082015260c081019190915260e00190565b901515815260200190565b90815260200190565b9788526001600160a01b039687166020890152604088019590955260608701939093529316608085015260a084019290925260c083019190915260e08201526101000190565b93845260ff9290921660208401526040830152606082015260800190565b600060608252846060830152848660808401378060808684010152601f19601f8601168201608083820301602084015261373d608082018661341c565b91505082604083015295945050505050565b60006020825261265d602083018461341c565b600060408252613775604083018561341c565b90508260208301529392505050565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b6020808252601f908201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604082015260600190565b6020808252601590820152744c69625574696c733a204e6f20646563696d616c7360581b604082015260600190565b6020808252601b908201527f4272696467653a2046656465726174696f6e20697320656d7074790000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601190820152704272696467653a20557067726164696e6760781b604082015260600190565b602080825260169082015275213934b233b29d1034b73b30b634b21039b2b73232b960511b604082015260600190565b602080825260139082015272084e4d2c8ceca74409cead8d840a8f090c2e6d606b1b604082015260600190565b6020808252818101527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c65604082015260600190565b6020808252818101527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604082015260600190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b60208082526019908201527f4272696467653a20494e56414c49445f5349474e415455524500000000000000604082015260600190565b60208082526010908201526f04272696467653a20416d6f756e7420360841b604082015260600190565b6020808252601690820152754272696467653a20777261707020697320656d70747960501b604082015260600190565b602080825260159082015274213934b233b29d102ab735b737bbb7103a37b5b2b760591b604082015260600190565b6020808252601b908201527f4272696467653a204e6f7420746f207468697320616464726573730000000000604082015260600190565b602080825260169082015275213934b233b29d102737ba102332b232b930ba34b7b760511b604082015260600190565b60208082526028908201527f4272696467653a2053706563696679207265636569766572206164647265737360408201526720696e206461746160c01b606082015260800190565b60208082526018908201527f4c69625574696c733a204e6f206772616e756c61726974790000000000000000604082015260600190565b6020808252600f908201526e4272696467653a204e756c6c20546f60881b604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252601d908201527f4272696467653a207772617070656443757272656e637920656d707479000000604082015260600190565b6020808252600f908201526e109c9a5919d94e8811561412549151608a1b604082015260600190565b60208082526021908201527f4272696467653a2053696465546f6b656e466163746f727920697320656d70746040820152607960f81b606082015260800190565b6020808252601c908201527f4c69625574696c733a20446563696d616c73206e6f74203c3d20313800000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260129082015271213934b233b29d10273ab636103a37b5b2b760711b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526022908201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526017908201527f4272696467653a20416c726561647920636c61696d6564000000000000000000604082015260600190565b6020808252601b908201527f4272696467653a206e6f74207772617070656443757272656e63790000000000604082015260600190565b60208082526018908201527f4272696467653a20416c72656164792061636365707465640000000000000000604082015260600190565b602080825260169082015275084e4d2c8ceca74409cead8d84084d8dec6d690c2e6d60531b604082015260600190565b6020808252601c908201527f4272696467653a20416c6c6f77546f6b656e7320697320656d70747900000000604082015260600190565b60208082526018908201527f4272696467653a204e6f742045524337373720746f6b656e0000000000000000604082015260600190565b602080825260169082015275109c9a5919d94e88151e081b9bdd0818dc9bdcdcd95960521b604082015260600190565b602080825260149082015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b604082015260600190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601690820152754272696467653a20416c72656164792065786973747360501b604082015260600190565b60208082526017908201527f4272696467653a20626967676572207468616e20313025000000000000000000604082015260600190565b6020808252601f908201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604082015260600190565b60208082526021908201527f4272696467653a2057726f6e67207472616e73616374696f6e446174614861736040820152600d60fb1b606082015260800190565b6000838252604060208301526127a4604083018461341c565b60405181810167ffffffffffffffff8111828210171561414357fe5b604052919050565b60005b8381101561416657818101518382015260200161414e565b838111156117255750506000910152565b6001600160a01b03811681146117b457600080fd5b80151581146117b457600080fdfea26469706673582212204c589b204ecd046fc7fe66efcbaa8add03eceef2a33bb84785a9a9e908cd5c5664736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106103025760003560e01c80638456cb5911610190578063c4d66de8116100dc578063e6fc774411610095578063f2fde38b1161006f578063f2fde38b146108b0578063f698da25146108d0578063f74032f0146108e5578063fa0caa16146109055761034c565b8063e6fc774414610866578063ea2170911461087b578063eb16136f146108905761034c565b8063c4d66de8146107b1578063ca07140c146107d1578063cc3c0f06146107f1578063d12e825d14610811578063da67703714610826578063e6ede14d146108465761034c565b8063ae06c1b711610149578063b50277bb11610123578063b50277bb14610754578063b760faf914610774578063b794726214610787578063b86f60d21461079c5761034c565b8063ae06c1b7146106ff578063afad80ac1461071f578063b0e1268e1461073f5761034c565b80638456cb591461066b5780638da5cb5b146106805780638f32d59b14610695578063916dc59d146106aa578063a53d6e6e146106ca578063adc5fb64146106df5761034c565b80634beea5061161024f5780636b0509b1116102085780637813bea2116101e25780637813bea2146105f65780637ecebe00146106165780638129fc1c1461063657806382dc1ec41461064b5761034c565b80636b0509b1146105b75780636ef8d66d146105cc578063715018a6146105e15761034c565b80634beea5061461050b57806354fd4d501461052b57806359a8a8671461054d5780635c975abb146105625780635d447129146105775780636a863191146105975761034c565b80632fb3b361116102bc5780633cf3058b116102965780633cf3058b146104895780633f4ba83a146104b657806342cdb2c6146104cb57806346fbf68e146104eb5761034c565b80632fb3b3611461041c5780633500c1dc1461043c57806337e761091461045c5761034c565b806223de2914610351578063026976191461037157806307c8f7b0146103a757806311efbf61146103c757806320e3bb00146103dc5780632f3cca4e146103fc5761034c565b3661034c576041546001600160a01b031661031b610925565b6001600160a01b03161461034a5760405162461bcd60e51b815260040161034190613e39565b60405180910390fd5b005b600080fd5b34801561035d57600080fd5b5061034a61036c3660046130c0565b610929565b34801561037d57600080fd5b5061039161038c366004613237565b610b20565b60405161039e9190613693565b60405180910390f35b3480156103b357600080fd5b5061034a6103c23660046131ff565b610b32565b3480156103d357600080fd5b50610391610bb0565b3480156103e857600080fd5b5061034a6103f7366004613368565b610bb6565b34801561040857600080fd5b5061034a610417366004612f3e565b610df1565b34801561042857600080fd5b5061034a610437366004612fec565b610e7a565b34801561044857600080fd5b5061034a610457366004612f3e565b610fea565b34801561046857600080fd5b5061047c610477366004613237565b61107f565b60405161039e9190613688565b34801561049557600080fd5b506104a96104a4366004613237565b6110a4565b60405161039e919061351f565b3480156104c257600080fd5b5061034a6110bf565b3480156104d757600080fd5b5061034a6104e6366004612f3e565b611152565b3480156104f757600080fd5b5061047c610506366004612f3e565b6111e5565b34801561051757600080fd5b5061039161052636600461326a565b6111f8565b34801561053757600080fd5b50610540611312565b60405161039e919061374f565b34801561055957600080fd5b5061054061132e565b34801561056e57600080fd5b5061047c6113bc565b34801561058357600080fd5b5061047c610592366004612f3e565b6113c5565b3480156105a357600080fd5b5061034a6105b2366004612f76565b6113da565b3480156105c357600080fd5b5061039161163e565b3480156105d857600080fd5b5061034a611662565b3480156105ed57600080fd5b5061034a611674565b34801561060257600080fd5b5061034a61061136600461316e565b6116e8565b34801561062257600080fd5b50610391610631366004612f3e565b61172b565b34801561064257600080fd5b5061034a61173d565b34801561065757600080fd5b5061034a610666366004612f3e565b6117b7565b34801561067757600080fd5b5061034a6117e7565b34801561068c57600080fd5b506104a9611867565b3480156106a157600080fd5b5061047c61187b565b3480156106b657600080fd5b5061034a6106c5366004612f3e565b6118a6565b3480156106d657600080fd5b506104a961193b565b3480156106eb57600080fd5b506103916106fa36600461324f565b61194a565b34801561070b57600080fd5b5061034a61071a366004613237565b6119a9565b34801561072b57600080fd5b5061039161073a3660046131ae565b611a23565b34801561074b57600080fd5b506104a9611a5f565b34801561076057600080fd5b5061039161076f36600461324f565b611a6e565b61034a610782366004612f3e565b611a81565b34801561079357600080fd5b5061047c611b50565b3480156107a857600080fd5b506104a9611b60565b3480156107bd57600080fd5b5061034a6107cc366004612f3e565b611b6f565b3480156107dd57600080fd5b506104a96107ec366004613237565b611c3a565b3480156107fd57600080fd5b5061047c61080c366004613237565b611c55565b34801561081d57600080fd5b5061034a611c6a565b34801561083257600080fd5b5061047c610841366004613237565b611cc2565b34801561085257600080fd5b506104a9610861366004612f3e565b611cd6565b34801561087257600080fd5b50610391611cf1565b34801561088757600080fd5b506104a9611cf7565b34801561089c57600080fd5b5061034a6108ab366004612f3e565b611d06565b3480156108bc57600080fd5b5061034a6108cb366004612f3e565b611d91565b3480156108dc57600080fd5b50610391611dbe565b3480156108f157600080fd5b506104a9610900366004612f3e565b611dc4565b34801561091157600080fd5b5061034a610920366004612f3e565b611ddf565b3390565b6001600160a01b03881630141561093f57610b16565b6001600160a01b03861630146109675760405162461bcd60e51b815260040161034190613b0d565b6000610971610925565b60405163555ddc6560e11b8152909150600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906109d09085907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce217705490600401613627565b60206040518083038186803b1580156109e857600080fd5b505afa1580156109fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a209190612f5a565b6001600160a01b03161415610a475760405162461bcd60e51b815260040161034190613f0e565b83151580610a645750610a62886001600160a01b0316611e7a565b155b610a805760405162461bcd60e51b815260040161034190613b74565b60008415610acc57610ac786868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e8092505050565b610ace565b885b9050610b13828a838a8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e8792505050565b50505b5050505050505050565b60426020526000908152604090205481565b610b3a61187b565b610b565760405162461bcd60e51b815260040161034190613d8b565b6040805460ff60a01b1916600160a01b83151581029190911780835591517f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad992610ba59260ff91041690613688565b60405180910390a150565b60375490565b610bbe61187b565b610bda5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b038616610c005760405162461bcd60e51b815260040161034190613d5f565b6001600160a01b038087166000908152603b6020526040902054168015610c395760405162461bcd60e51b81526004016103419061402f565b6000610c448761213a565b9050600060388787604051602001610c5e939291906134a6565b60408051601f1981840301815282825290546326d9e96360e01b83529092506001600160a01b0316906326d9e96390610ca1908890889086908890600401613700565b602060405180830381600087803b158015610cbb57600080fd5b505af1158015610ccf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf39190612f5a565b6001600160a01b03808b166000818152603b6020908152604080832080548688166001600160a01b03199182168117909255908452603c909252918290208054909116909217909155603f5490516378bf2b5360e01b815292955016906378bf2b5390610d669086908e90600401613627565b600060405180830381600087803b158015610d8057600080fd5b505af1158015610d94573d6000803e3d6000fd5b50505050886001600160a01b0316836001600160a01b03167f2ef93c4e96a4ef0b19497ff60c9e7360a8734f3d2cd27ae5318e43851734d17f8385604051610ddd929190613762565b60405180910390a350505050505050505050565b600054610100900460ff1680610e0a575060005460ff16155b610e265760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015610e51576000805460ff1961ff0019909116610100171660011790555b610e5a82611d06565b6034805460ff191690558015610e76576000805461ff00191690555b5050565b600054610100900460ff1680610e93575060005460ff16155b610eaf5760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015610eda576000805460ff1961ff0019909116610100171660011790555b610ee386611b6f565b610eec86610df1565b8151610eff906038906020850190612e1a565b50603f80546001600160a01b038087166001600160a01b031992831617909255604080548684169083161781556036805493891693909216929092179055516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90610f969030907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b908290600401613533565b600060405180830381600087803b158015610fb057600080fd5b505af1158015610fc4573d6000803e3d6000fd5b50505050610fd0611c6a565b8015610fe2576000805461ff00191690555b505050505050565b610ff261187b565b61100e5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b0381166110345760405162461bcd60e51b815260040161034190613aae565b604180546001600160a01b0319166001600160a01b0383161790556040517f0966c958966f6fac9ff807af074f8117eb2e9ce2b76390db7a158e9bdeb2485c90610ba590839061351f565b6000818152604260209081526040808320548352603e90915290205460ff165b919050565b6044602052600090815260409020546001600160a01b031681565b6110ca610506610925565b6110e65760405162461bcd60e51b815260040161034190613a05565b60345460ff166111085760405162461bcd60e51b8152600401610341906137c9565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61113b610925565b604051611148919061351f565b60405180910390a1565b61115a61187b565b6111765760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b03811661119c5760405162461bcd60e51b815260040161034190613ca6565b604080546001600160a01b0319166001600160a01b038316178155517f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e318369252162590610ba590839061351f565b60006111f260338361216d565b92915050565b60004285101561121a5760405162461bcd60e51b815260040161034190613c7d565b600061123661122e368b90038b018b6132da565b8989896121b5565b905060006001828787876040516000815260200160405260405161125d94939291906136e2565b6020604051602081039080840390855afa15801561127f573d6000803e3d6000fd5b5050604051601f19015191506000905061129c60208c018c612f3e565b6001600160a01b0316141580156112d057506112bb60208b018b612f3e565b6001600160a01b0316816001600160a01b0316145b6112ec5760405162461bcd60e51b815260040161034190613a4d565b6113048a6112fd6020820182612f3e565b8b8b61224a565b9a9950505050505050505050565b604080518082019091526002815261763360f01b602082015290565b6038805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156113b45780601f10611389576101008083540402835291602001916113b4565b820191906000526020600020905b81548152906001019060200180831161139757829003601f168201915b505050505081565b60345460ff1690565b603d6020526000908152604090205460ff1681565b60345460ff16156113fd5760405162461bcd60e51b815260040161034190613c1c565b60358054600101908190556036546001600160a01b031661141c610925565b6001600160a01b0316146114425760405162461bcd60e51b815260040161034190613b44565b6001600160a01b0388166000908152603d602052604090205460ff168061148257506001600160a01b038881166000908152603b60205260409020541615155b61149e5760405162461bcd60e51b815260040161034190613ade565b6001600160a01b0386166114c45760405162461bcd60e51b815260040161034190613bf3565b600085116114e45760405162461bcd60e51b815260040161034190613a84565b836115015760405162461bcd60e51b815260040161034190613ea7565b8261151e5760405162461bcd60e51b815260040161034190613926565b6000838152604260205260409020541561154a5760405162461bcd60e51b815260040161034190613e70565b60006115598787878787611a23565b6000818152603e602052604090205490915060ff161561158b5760405162461bcd60e51b815260040161034190613e02565b60008481526042602090815260408083208490556043825280832080546001600160a01b03199081166001600160a01b038f811691821790935560449094529382902080549094168c821617909355519189169186907f2858b8803acb87882fd2de49ce7572ae3e741fb8073cbe772fa50ce00bdfba2290611614908d908c908c908b90613556565b60405180910390a4506035548114610b165760405162461bcd60e51b815260040161034190613784565b7ff18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd8043381565b61167261166d610925565b612463565b565b61167c61187b565b6116985760405162461bcd60e51b815260040161034190613d8b565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b60006116f2610925565b90506117096001600160a01b0385168230856124a5565b6117258482858560405180602001604052806000815250611e87565b50505050565b60456020526000908152604090205481565b600054610100900460ff1680611756575060005460ff16155b6117725760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff1615801561179d576000805460ff1961ff0019909116610100171660011790555b600160355580156117b4576000805461ff00191690555b50565b6117c2610506610925565b6117de5760405162461bcd60e51b815260040161034190613a05565b6117b4816124fd565b6117f2610506610925565b61180e5760405162461bcd60e51b815260040161034190613a05565b60345460ff16156118315760405162461bcd60e51b815260040161034190613c1c565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861113b610925565b60345461010090046001600160a01b031690565b60345460009061010090046001600160a01b0316611897610925565b6001600160a01b031614905090565b6118ae61187b565b6118ca5760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b0381166118f05760405162461bcd60e51b815260040161034190613ed7565b603f80546001600160a01b0319166001600160a01b0383161790556040517f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e390610ba590839061351f565b603f546001600160a01b031681565b60608101356000908152604460205260408120546001600160a01b031661196f610925565b6001600160a01b0316146119955760405162461bcd60e51b8152600401610341906138f6565b6111f2826119a1610925565b60008061224a565b6119b161187b565b6119cd5760405162461bcd60e51b815260040161034190613d8b565b6103e881106119ee5760405162461bcd60e51b81526004016103419061405f565b60378190556040517f97e97c577f03bda90e2c9739011ec065ed5fbfb36ae217d20bb0d9be95e160cd90610ba5908390613693565b60008383878785604051602001611a3e959493929190613448565b60405160208183030381529060405280519060200120905095945050505050565b6041546001600160a01b031681565b60006111f2826119a16020820182612f3e565b6000611a8b610925565b6041549091506001600160a01b0316611ab65760405162461bcd60e51b815260040161034190613c46565b604160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611b0657600080fd5b505af1158015611b1a573d6000803e3d6000fd5b5050505050610e76604160009054906101000a90046001600160a01b031682843460405180602001604052806000815250611e87565b604054600160a01b900460ff1681565b6040546001600160a01b031681565b600054610100900460ff1680611b88575060005460ff16155b611ba45760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015611bcf576000805460ff1961ff0019909116610100171660011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610e76576000805461ff00191690555050565b6043602052600090815260409020546001600160a01b031681565b603e6020526000908152604090205460ff1681565b6000469050611cbc6040518060400160405280601081526020016f52534b20546f6b656e2042726964676560801b815250604051806040016040528060018152602001603160f81b815250833061253f565b60395550565b600090815260426020526040902054151590565b603b602052600090815260409020546001600160a01b031681565b61271081565b6036546001600160a01b031690565b600054610100900460ff1680611d1f575060005460ff16155b611d3b5760405162461bcd60e51b8152600401610341906139bd565b600054610100900460ff16158015611d66576000805460ff1961ff0019909116610100171660011790555b611d6f826111e5565b611d7c57611d7c826124fd565b8015610e76576000805461ff00191690555050565b611d9961187b565b611db55760405162461bcd60e51b815260040161034190613d8b565b6117b481612596565b60395481565b603c602052600090815260409020546001600160a01b031681565b611de761187b565b611e035760405162461bcd60e51b815260040161034190613d8b565b6001600160a01b038116611e295760405162461bcd60e51b81526004016103419061385d565b603680546001600160a01b0319166001600160a01b0383811691909117918290556040517f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb92610ba592169061351f565b3b151590565b6014015190565b604054600160a01b900460ff1615611eb15760405162461bcd60e51b8152600401610341906138cb565b60345460ff1615611ed45760405162461bcd60e51b815260040161034190613c1c565b603580546001908101918290556001600160a01b0387166000908152603d60205260408120805460ff1916909217909155603754611f219061271090611f1b908790612623565b90612664565b90506000611f2f85836126a6565b90506000611f3c896126e8565b905085601260ff831614611f6157611f5e8760ff601285900316600a0a612623565b90505b603f54604051638c34bc5560e01b81526001600160a01b0390911690638c34bc5590611f93908d908590600401613627565b600060405180830381600087803b158015611fad57600080fd5b505af1158015611fc1573d6000803e3d6000fd5b5050506001600160a01b03808c166000908152603c60205260409020548c9250161561209b57506001600160a01b03808b166000908152603c60205260408120549091169061200f8c6127ac565b9050600061201d8683612854565b90506120298782612896565b965061203586826126a6565b60405163fe9d930360e01b81529096506001600160a01b038e169063fe9d9303906120669089908d9060040161410e565b600060405180830381600087803b15801561208057600080fd5b505af1158015612094573d6000803e3d6000fd5b5050505050505b886001600160a01b03168a6001600160a01b0316826001600160a01b03167f1e90de9ae4d02420648a650f45f089a1be18fbca324092544ea626f9833212b0878b6040516120ea92919061410e565b60405180910390a4841561211457612114612103611867565b6001600160a01b038d1690876128bb565b50505050506035548114610fe25760405162461bcd60e51b815260040161034190613784565b600060128260ff1611156121605760405162461bcd60e51b815260040161034190613ce7565b5060120360ff16600a0a90565b60006001600160a01b0382166121955760405162461bcd60e51b815260040161034190613dc0565b506001600160a01b03166000908152602091909152604090205460ff1690565b603954845160208087015160608801516001600160a01b038416600090815260458452604080822080546001810190915590519196612241969095612226957ff18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd8043395929490938d928d928d910161369c565b604051602081830303815290604052805190602001206128df565b95945050505050565b603580546001019081905560608501356000908152604360205260408120549091906001600160a01b0316806122925760405162461bcd60e51b815260040161034190613f45565b60006122c36122a460208a018a612f3e565b60208a013560408b013560608c013561073a60a08e0160808f01613402565b606089013560009081526042602052604090205490915081146122f85760405162461bcd60e51b8152600401610341906140cd565b6000818152603e602052604090205460ff16156123275760405162461bcd60e51b815260040161034190613e02565b6000818152603e60209081526040808320805460ff191660011790556001600160a01b0385168352603d90915290205460ff16156123775761237082888a6020013589896128fe565b935061238b565b61238882888a602001358989612a74565b93505b6123986020890189612f3e565b6001600160a01b0316826001600160a01b031689606001357f42b1cb6263e8da47edf0583516eda1de16f729d26282f5791dc5b7af1010e925604460008d60600135815260200190815260200160002060009054906101000a90046001600160a01b03168c602001358d604001358e60800160208101906124199190613402565b8e8e8e60405161242f9796959493929190613640565b60405180910390a45050603554811461245a5760405162461bcd60e51b815260040161034190613784565b50949350505050565b61246e603382612c0b565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b611725846323b872dd60e01b8585856040516024016124c693929190613603565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612c53565b612508603382612d37565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b6001600160a01b0381166125bc5760405162461bcd60e51b815260040161034190613fa3565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600082612632575060006111f2565b8282028284828161263f57fe5b041461265d5760405162461bcd60e51b815260040161034190613d1e565b9392505050565b600061265d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612d83565b600061265d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612dba565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b0386169161272e919061348a565b600060405180830381855afa9150503d8060008114612769576040519150601f19603f3d011682016040523d82523d6000602084013e61276e565b606091505b5091509150816127905760405162461bcd60e51b81526004016103419061382e565b808060200190518101906127a49190613350565b949350505050565b60408051600481526024810182526020810180516001600160e01b031663556f0dc760e01b1790529051600091829182916001600160a01b038616916127f2919061348a565b600060405180830381855afa9150503d806000811461282d576040519150601f19603f3d011682016040523d82523d6000602084013e612832565b606091505b5091509150816127905760405162461bcd60e51b815260040161034190613bbc565b600061265d83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250612de6565b60008282018381101561265d5760405162461bcd60e51b815260040161034190613894565b6128da8363a9059cbb60e01b84846040516024016124c6929190613627565b505050565b60405161190160f01b8152600281019290925260228201526042902090565b60008061290a876126e8565b60ff1690506000612922866012849003600a0a612664565b9050808411156129445760405162461bcd60e51b815260040161034190613f75565b60415484820393506001600160a01b0389811691161415612a3b57604154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d9061298f908490600401613693565b600060405180830381600087803b1580156129a957600080fd5b505af11580156129bd573d6000803e3d6000fd5b50506040516001600160a01b038a16925085156108fc02915085906000818181858888f193505050501580156129f7573d6000803e3d6000fd5b508315612a36576040516001600160a01b0386169085156108fc029086906000818181858888f19350505050158015612a34573d6000803e3d6000fd5b505b612a69565b612a4f6001600160a01b03891688856128bb565b8315612a6957612a696001600160a01b03891686866128bb565b505095945050505050565b6001600160a01b038086166000908152603b6020908152604080832054815163556f0dc760e01b81529151939416928492849263556f0dc79260048083019392829003018186803b158015612ac857600080fd5b505afa158015612adc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b009190613350565b90506000612b0e8783612623565b905080851115612b305760405162461bcd60e51b815260040161034190613f75565b604051630dcdc7dd60e41b815285820394506001600160a01b0384169063dcdc7dd090612b63908b9088906004016135cd565b600060405180830381600087803b158015612b7d57600080fd5b505af1158015612b91573d6000803e3d6000fd5b505050506000851115612bff57604051630dcdc7dd60e41b81526001600160a01b0384169063dcdc7dd090612bcc9089908990600401613582565b600060405180830381600087803b158015612be657600080fd5b505af1158015612bfa573d6000803e3d6000fd5b505050505b50505095945050505050565b612c15828261216d565b612c315760405162461bcd60e51b815260040161034190613953565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b612c65826001600160a01b0316611e7a565b612c815760405162461bcd60e51b815260040161034190614096565b600080836001600160a01b031683604051612c9c919061348a565b6000604051808303816000865af19150503d8060008114612cd9576040519150601f19603f3d011682016040523d82523d6000602084013e612cde565b606091505b509150915081612d005760405162461bcd60e51b815260040161034190613988565b8051156117255780806020019051810190612d1b919061321b565b6117255760405162461bcd60e51b815260040161034190613fe5565b612d41828261216d565b15612d5e5760405162461bcd60e51b8152600401610341906137f7565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60008183612da45760405162461bcd60e51b8152600401610341919061374f565b506000838581612db057fe5b0495945050505050565b60008184841115612dde5760405162461bcd60e51b8152600401610341919061374f565b505050900390565b60008183612e075760405162461bcd60e51b8152600401610341919061374f565b50828481612e1157fe5b06949350505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282612e505760008555612e96565b82601f10612e6957805160ff1916838001178555612e96565b82800160010185558215612e96579182015b82811115612e96578251825591602001919060010190612e7b565b50612ea2929150612ea6565b5090565b5b80821115612ea25760008155600101612ea7565b60008083601f840112612ecc578182fd5b50813567ffffffffffffffff811115612ee3578182fd5b602083019150836020828501011115612efb57600080fd5b9250929050565b600060a08284031215612f13578081fd5b50919050565b803563ffffffff8116811461109f57600080fd5b803560ff8116811461109f57600080fd5b600060208284031215612f4f578081fd5b813561265d81614177565b600060208284031215612f6b578081fd5b815161265d81614177565b600080600080600080600060e0888a031215612f90578283fd5b8735612f9b81614177565b96506020880135612fab81614177565b95506040880135612fbb81614177565b9450606088013593506080880135925060a08801359150612fde60c08901612f19565b905092959891949750929550565b600080600080600060a08688031215613003578081fd5b853561300e81614177565b945060208681013561301f81614177565b9450604087013561302f81614177565b9350606087013561303f81614177565b9250608087013567ffffffffffffffff8082111561305b578384fd5b818901915089601f83011261306e578384fd5b81358181111561307a57fe5b61308c601f8201601f19168501614127565b91508082528a848285010111156130a1578485fd5b8084840185840137810190920192909252949793965091945092919050565b60008060008060008060008060c0898b0312156130db578081fd5b88356130e681614177565b975060208901356130f681614177565b9650604089013561310681614177565b955060608901359450608089013567ffffffffffffffff80821115613129578283fd5b6131358c838d01612ebb565b909650945060a08b013591508082111561314d578283fd5b5061315a8b828c01612ebb565b999c989b5096995094979396929594505050565b600080600060608486031215613182578081fd5b833561318d81614177565b9250602084013561319d81614177565b929592945050506040919091013590565b600080600080600060a086880312156131c5578283fd5b85356131d081614177565b94506020860135935060408601359250606086013591506131f360808701612f19565b90509295509295909350565b600060208284031215613210578081fd5b813561265d8161418c565b60006020828403121561322c578081fd5b815161265d8161418c565b600060208284031215613248578081fd5b5035919050565b600060a08284031215613260578081fd5b61265d8383612f02565b6000806000806000806000610160888a031215613285578081fd5b61328f8989612f02565b965060a088013561329f81614177565b955060c0880135945060e088013593506132bc6101008901612f2d565b92506101208801359150610140880135905092959891949750929550565b600060a082840312156132eb578081fd5b60405160a0810181811067ffffffffffffffff8211171561330857fe5b604052823561331681614177565b8082525060208301356020820152604083013560408201526060830135606082015261334460808401612f19565b60808201529392505050565b600060208284031215613361578081fd5b5051919050565b600080600080600080600060a0888a031215613382578081fd5b87359650602088013561339481614177565b95506133a260408901612f2d565b9450606088013567ffffffffffffffff808211156133be578283fd5b6133ca8b838c01612ebb565b909650945060808a01359150808211156133e2578283fd5b506133ef8a828b01612ebb565b989b979a50959850939692959293505050565b600060208284031215613413578081fd5b61265d82612f19565b6000815180845261343481602086016020860161414b565b601f01601f19169290920160200192915050565b948552602085019390935260609190911b6bffffffffffffffffffffffff19166040840152605483015260e01b6001600160e01b031916607482015260780190565b6000825161349c81846020870161414b565b9190910192915050565b60008085546001808216600081146134c557600181146134dc5761350b565b60ff198316865260028304607f168601935061350b565b600283048986526020808720875b838110156135035781548a8201529085019082016134ea565b505050860193505b505050838582379092019182525092915050565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b6001600160a01b039490941684526020840192909252604083015263ffffffff16606082015260800190565b6001600160a01b03929092168252602082015260806040820181905260009082015260a060608201819052600b908201526a72656c617965722066656560a81b60c082015260e00190565b6001600160a01b039290921682526020820152608060408201819052600090820181905260a06060830181905282015260c00190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0397881681526020810196909652604086019490945263ffffffff9290921660608501528416608084015290921660a082015260c081019190915260e00190565b901515815260200190565b90815260200190565b9788526001600160a01b039687166020890152604088019590955260608701939093529316608085015260a084019290925260c083019190915260e08201526101000190565b93845260ff9290921660208401526040830152606082015260800190565b600060608252846060830152848660808401378060808684010152601f19601f8601168201608083820301602084015261373d608082018661341c565b91505082604083015295945050505050565b60006020825261265d602083018461341c565b600060408252613775604083018561341c565b90508260208301529392505050565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b6020808252601f908201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604082015260600190565b6020808252601590820152744c69625574696c733a204e6f20646563696d616c7360581b604082015260600190565b6020808252601b908201527f4272696467653a2046656465726174696f6e20697320656d7074790000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601190820152704272696467653a20557067726164696e6760781b604082015260600190565b602080825260169082015275213934b233b29d1034b73b30b634b21039b2b73232b960511b604082015260600190565b602080825260139082015272084e4d2c8ceca74409cead8d840a8f090c2e6d606b1b604082015260600190565b6020808252818101527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c65604082015260600190565b6020808252818101527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604082015260600190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b60208082526019908201527f4272696467653a20494e56414c49445f5349474e415455524500000000000000604082015260600190565b60208082526010908201526f04272696467653a20416d6f756e7420360841b604082015260600190565b6020808252601690820152754272696467653a20777261707020697320656d70747960501b604082015260600190565b602080825260159082015274213934b233b29d102ab735b737bbb7103a37b5b2b760591b604082015260600190565b6020808252601b908201527f4272696467653a204e6f7420746f207468697320616464726573730000000000604082015260600190565b602080825260169082015275213934b233b29d102737ba102332b232b930ba34b7b760511b604082015260600190565b60208082526028908201527f4272696467653a2053706563696679207265636569766572206164647265737360408201526720696e206461746160c01b606082015260800190565b60208082526018908201527f4c69625574696c733a204e6f206772616e756c61726974790000000000000000604082015260600190565b6020808252600f908201526e4272696467653a204e756c6c20546f60881b604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252601d908201527f4272696467653a207772617070656443757272656e637920656d707479000000604082015260600190565b6020808252600f908201526e109c9a5919d94e8811561412549151608a1b604082015260600190565b60208082526021908201527f4272696467653a2053696465546f6b656e466163746f727920697320656d70746040820152607960f81b606082015260800190565b6020808252601c908201527f4c69625574696c733a20446563696d616c73206e6f74203c3d20313800000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260129082015271213934b233b29d10273ab636103a37b5b2b760711b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526022908201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526017908201527f4272696467653a20416c726561647920636c61696d6564000000000000000000604082015260600190565b6020808252601b908201527f4272696467653a206e6f74207772617070656443757272656e63790000000000604082015260600190565b60208082526018908201527f4272696467653a20416c72656164792061636365707465640000000000000000604082015260600190565b602080825260169082015275084e4d2c8ceca74409cead8d84084d8dec6d690c2e6d60531b604082015260600190565b6020808252601c908201527f4272696467653a20416c6c6f77546f6b656e7320697320656d70747900000000604082015260600190565b60208082526018908201527f4272696467653a204e6f742045524337373720746f6b656e0000000000000000604082015260600190565b602080825260169082015275109c9a5919d94e88151e081b9bdd0818dc9bdcdcd95960521b604082015260600190565b602080825260149082015273084e4d2c8ceca7440cccaca40e8dede40d0d2ced60631b604082015260600190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601690820152754272696467653a20416c72656164792065786973747360501b604082015260600190565b60208082526017908201527f4272696467653a20626967676572207468616e20313025000000000000000000604082015260600190565b6020808252601f908201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604082015260600190565b60208082526021908201527f4272696467653a2057726f6e67207472616e73616374696f6e446174614861736040820152600d60fb1b606082015260800190565b6000838252604060208301526127a4604083018461341c565b60405181810167ffffffffffffffff8111828210171561414357fe5b604052919050565b60005b8381101561416657818101518382015260200161414e565b838111156117255750506000910152565b6001600160a01b03811681146117b457600080fd5b80151581146117b457600080fdfea26469706673582212204c589b204ecd046fc7fe66efcbaa8add03eceef2a33bb84785a9a9e908cd5c5664736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "__Pausable_init(address)": {
+ "details": "Initializes the contract in unpaused state. Assigns the Pauser role to the deployer."
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "pause()": {
+ "details": "Called by a pauser to pause, triggers stopped state."
+ },
+ "paused()": {
+ "details": "Returns true if the contract is paused, and false otherwise."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "unpause()": {
+ "details": "Called by a pauser to unpause, returns to normal state."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "acceptTransfer(address,address,address,uint256,bytes32,bytes32,uint32)": {
+ "notice": "Accepts the transaction from the other chain that was voted and sent by the Federation contract"
+ },
+ "claim((address,uint256,bytes32,bytes32,uint32))": {
+ "notice": "Claims the crossed transaction using the hash, this sends the funds to the address indicated in"
+ },
+ "depositTo(address)": {
+ "notice": "Use network currency and cross it."
+ },
+ "receiveTokensTo(address,address,uint256)": {
+ "notice": "ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom"
+ },
+ "tokensReceived(address,address,address,uint256,bytes,bytes)": {
+ "notice": "ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction See https://eips.ethereum.org/EIPS/eip-777#motivation for details"
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15789,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15792,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15832,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 15856,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_pausers",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_struct(Role)10133_storage"
+ },
+ {
+ "astId": 15978,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_paused",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16076,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_owner",
+ "offset": 1,
+ "slot": "52",
+ "type": "t_address"
+ },
+ {
+ "astId": 16790,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_guardCounter",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1282,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "federation",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_address"
+ },
+ {
+ "astId": 1284,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "feePercentage",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1286,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "symbolPrefix",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 1288,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "domainSeparator",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_bytes32"
+ },
+ {
+ "astId": 1290,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "_deprecatedSpentToday",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 1294,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "mappedTokens",
+ "offset": 0,
+ "slot": "59",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 1298,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originalTokens",
+ "offset": 0,
+ "slot": "60",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 1302,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "knownTokens",
+ "offset": 0,
+ "slot": "61",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 1306,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "claimed",
+ "offset": 0,
+ "slot": "62",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ },
+ {
+ "astId": 1308,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "allowTokens",
+ "offset": 0,
+ "slot": "63",
+ "type": "t_contract(IAllowTokens)7210"
+ },
+ {
+ "astId": 1310,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "sideTokenFactory",
+ "offset": 0,
+ "slot": "64",
+ "type": "t_contract(ISideTokenFactory)7607"
+ },
+ {
+ "astId": 1312,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "isUpgrading",
+ "offset": 20,
+ "slot": "64",
+ "type": "t_bool"
+ },
+ {
+ "astId": 1322,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "wrappedCurrency",
+ "offset": 0,
+ "slot": "65",
+ "type": "t_contract(IWrapped)7660"
+ },
+ {
+ "astId": 1326,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "transactionsDataHashes",
+ "offset": 0,
+ "slot": "66",
+ "type": "t_mapping(t_bytes32,t_bytes32)"
+ },
+ {
+ "astId": 1330,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "originalTokenAddresses",
+ "offset": 0,
+ "slot": "67",
+ "type": "t_mapping(t_bytes32,t_address)"
+ },
+ {
+ "astId": 1334,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "senderAddresses",
+ "offset": 0,
+ "slot": "68",
+ "type": "t_mapping(t_bytes32,t_address)"
+ },
+ {
+ "astId": 1341,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "nonces",
+ "offset": 0,
+ "slot": "69",
+ "type": "t_mapping(t_address,t_uint256)"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IAllowTokens)7210": {
+ "encoding": "inplace",
+ "label": "contract IAllowTokens",
+ "numberOfBytes": "20"
+ },
+ "t_contract(ISideTokenFactory)7607": {
+ "encoding": "inplace",
+ "label": "contract ISideTokenFactory",
+ "numberOfBytes": "20"
+ },
+ "t_contract(IWrapped)7660": {
+ "encoding": "inplace",
+ "label": "contract IWrapped",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_address)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_mapping(t_bytes32,t_address)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bytes32)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bytes32)",
+ "numberOfBytes": "32",
+ "value": "t_bytes32"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)10133_storage": {
+ "encoding": "inplace",
+ "label": "struct Roles.Role",
+ "members": [
+ {
+ "astId": 10132,
+ "contract": "contracts/Bridge/Bridge.sol:Bridge",
+ "label": "bearer",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_address,t_bool)"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/BridgeProxy.json b/bridge/deployments/rsktestnetrinkeby/BridgeProxy.json
new file mode 100644
index 000000000..24b09eacf
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/BridgeProxy.json
@@ -0,0 +1,234 @@
+{
+ "address": "0x8c8A34Fe13400169a8da50908dffDe4985237D19",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_admin",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xde703493a5b749f7c420237b898000f9b395e3cd002b75d31e3a4fb069fbb0fe",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0x8c8A34Fe13400169a8da50908dffDe4985237D19",
+ "transactionIndex": 0,
+ "gasUsed": "947657",
+ "logsBloom": "0x00000000020000000000000000008000000000000000000000800000000000001000000000000000000000000000002002000000000400000000000000000000000000000080000000000000000000000001000000000000000000000000000000000000020000000000000000040800000010004020000000000000000000400000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000200801000000000000000000000000000000000000000900000000000000000000000200000020000000000000000000000000000080000000000000000001000000000000000000",
+ "blockHash": "0xab974dc0e501f7f5868d1baec97f3234a5cbfa5a0803e457c26af7ab40c3b334",
+ "transactionHash": "0xde703493a5b749f7c420237b898000f9b395e3cd002b75d31e3a4fb069fbb0fe",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170825,
+ "transactionHash": "0xde703493a5b749f7c420237b898000f9b395e3cd002b75d31e3a4fb069fbb0fe",
+ "address": "0x8c8A34Fe13400169a8da50908dffDe4985237D19",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x00000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0xab974dc0e501f7f5868d1baec97f3234a5cbfa5a0803e457c26af7ab40c3b334"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170825,
+ "transactionHash": "0xde703493a5b749f7c420237b898000f9b395e3cd002b75d31e3a4fb069fbb0fe",
+ "address": "0x8c8A34Fe13400169a8da50908dffDe4985237D19",
+ "topics": [
+ "0x6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f8",
+ "0x00000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a"
+ ],
+ "data": "0x",
+ "logIndex": 1,
+ "blockHash": "0xab974dc0e501f7f5868d1baec97f3234a5cbfa5a0803e457c26af7ab40c3b334"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170825,
+ "transactionHash": "0xde703493a5b749f7c420237b898000f9b395e3cd002b75d31e3a4fb069fbb0fe",
+ "address": "0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24",
+ "topics": [
+ "0x93baa6efbd2244243bfee6ce4cfdd1d04fc4c0e9a786abd3a41313bd352db153",
+ "0x0000000000000000000000008c8a34fe13400169a8da50908dffde4985237d19",
+ "0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b",
+ "0x0000000000000000000000008c8a34fe13400169a8da50908dffde4985237d19"
+ ],
+ "data": "0x",
+ "logIndex": 2,
+ "blockHash": "0xab974dc0e501f7f5868d1baec97f3234a5cbfa5a0803e457c26af7ab40c3b334"
+ }
+ ],
+ "blockNumber": 2170825,
+ "cumulativeGasUsed": "947657",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0x7E339118346364d7D86AB67cb0775CBB808E65F7",
+ "0x8C35e166d2Dea7a8A28aaeA11AD7933cDae4b0aB",
+ "0x2fb3b36100000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a0000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b0000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b000000000000000000000000500f602f60b6d223f50aac3750625ec771ed3c5700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000047252696e00000000000000000000000000000000000000000000000000000000"
+ ],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Proxies.sol\":\"BridgeProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Proxies.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\\\";\\r\\n\\r\\ncontract BridgeProxy is TransparentUpgradeableProxy {\\r\\n // solhint-disable-next-line no-empty-blocks\\r\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\r\\n}\\r\\n\\r\\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\\r\\n // solhint-disable-next-line no-empty-blocks\\r\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\r\\n}\\r\\n\\r\\ncontract FederationProxy is TransparentUpgradeableProxy {\\r\\n // solhint-disable-next-line no-empty-blocks\\r\\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\\r\\n}\",\"keccak256\":\"0x85fcee3669ce6de4bbb104f8e0878435de0f12eb5437f30933966256196f42da\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\r\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\r\\n * be specified by overriding the virtual {_implementation} function.\\r\\n *\\r\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\r\\n * different contract through the {_delegate} function.\\r\\n *\\r\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\r\\n */\\r\\nabstract contract Proxy {\\r\\n /**\\r\\n * @dev Delegates the current call to `implementation`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _delegate(address implementation) internal virtual {\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n // Copy msg.data. We take full control of memory in this inline assembly\\r\\n // block because it will not return to Solidity code. We overwrite the\\r\\n // Solidity scratch pad at memory position 0.\\r\\n calldatacopy(0, 0, calldatasize())\\r\\n\\r\\n // Call the implementation.\\r\\n // out and outsize are 0 because we don't know the size yet.\\r\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\r\\n\\r\\n // Copy the returned data.\\r\\n returndatacopy(0, 0, returndatasize())\\r\\n\\r\\n switch result\\r\\n // delegatecall returns 0 on error.\\r\\n case 0 { revert(0, returndatasize()) }\\r\\n default { return(0, returndatasize()) }\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\r\\n * and {_fallback} should delegate.\\r\\n */\\r\\n function _implementation() internal view virtual returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _fallback() internal virtual {\\r\\n _beforeFallback();\\r\\n _delegate(_implementation());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\r\\n * function in the contract matches the call data.\\r\\n */\\r\\n fallback () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\r\\n * is empty.\\r\\n */\\r\\n receive () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\r\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\r\\n *\\r\\n * If overriden should call `super._beforeFallback()`.\\r\\n */\\r\\n function _beforeFallback() internal virtual {\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x6374180266624d2291abb230bdf0d364858fa164844f5d2d83ad5325852390c9\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./UpgradeableProxy.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\r\\n *\\r\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\r\\n * clashing], which can potentially be used in an attack, this contract uses the\\r\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\r\\n * things that go hand in hand:\\r\\n *\\r\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\r\\n * that call matches one of the admin functions exposed by the proxy itself.\\r\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\r\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\r\\n * \\\"admin cannot fallback to proxy target\\\".\\r\\n *\\r\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\r\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\r\\n * to sudden errors when trying to call a function from the proxy implementation.\\r\\n *\\r\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\r\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\r\\n */\\r\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\r\\n /**\\r\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\r\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\r\\n */\\r\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\r\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\r\\n _setAdmin(admin_);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the admin account has changed.\\r\\n */\\r\\n event AdminChanged(address previousAdmin, address newAdmin);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the admin of the contract.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\r\\n\\r\\n /**\\r\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\r\\n */\\r\\n modifier ifAdmin() {\\r\\n if (msg.sender == _admin()) {\\r\\n _;\\r\\n } else {\\r\\n _fallback();\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\r\\n */\\r\\n function admin() external ifAdmin returns (address admin_) {\\r\\n admin_ = _admin();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\r\\n */\\r\\n function implementation() external ifAdmin returns (address implementation_) {\\r\\n implementation_ = _implementation();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Changes the admin of the proxy.\\r\\n *\\r\\n * Emits an {AdminChanged} event.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\r\\n */\\r\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\r\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\r\\n emit AdminChanged(_admin(), newAdmin);\\r\\n _setAdmin(newAdmin);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\r\\n */\\r\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\r\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\r\\n * proxied contract.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\r\\n */\\r\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n Address.functionDelegateCall(newImplementation, data);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n */\\r\\n function _admin() internal view virtual returns (address adm) {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n adm := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 admin slot.\\r\\n */\\r\\n function _setAdmin(address newAdmin) private {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newAdmin)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\r\\n */\\r\\n function _beforeFallback() internal virtual override {\\r\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\r\\n super._beforeFallback();\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x7496c2c54dd8e648d6999687cf759521e6ab229d0d8ddb4db62f3b51dbe68811\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./Proxy.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\r\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\r\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\r\\n * implementation behind the proxy.\\r\\n *\\r\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\r\\n * {TransparentUpgradeableProxy}.\\r\\n */\\r\\ncontract UpgradeableProxy is Proxy {\\r\\n /**\\r\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\r\\n *\\r\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\r\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\r\\n */\\r\\n constructor(address _logic, bytes memory _data) payable {\\r\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\r\\n _setImplementation(_logic);\\r\\n if(_data.length > 0) {\\r\\n Address.functionDelegateCall(_logic, _data);\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the implementation is upgraded.\\r\\n */\\r\\n event Upgraded(address indexed implementation);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the address of the current implementation.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation address.\\r\\n */\\r\\n function _implementation() internal view virtual override returns (address impl) {\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n impl := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrades the proxy to a new implementation.\\r\\n *\\r\\n * Emits an {Upgraded} event.\\r\\n */\\r\\n function _upgradeTo(address newImplementation) internal virtual {\\r\\n _setImplementation(newImplementation);\\r\\n emit Upgraded(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 implementation slot.\\r\\n */\\r\\n function _setImplementation(address newImplementation) private {\\r\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\r\\n\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newImplementation)\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x4d3fcb8487e53abb8658817c4b90038b24d81d0a32d989f03b54d4cfab929f62\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000ca538038062000ca5833981016040819052620000269162000234565b8282828281620000368262000077565b8051156200005757620000558282620000d960201b620002ca1760201c565b505b50620000609050565b6200006b8262000108565b50505050505062000423565b6200008d816200012c60201b620002f61760201c565b620000b55760405162461bcd60e51b8152600401620000ac906200034d565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606062000101838360405180606001604052806027815260200162000c7e6027913962000136565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b606062000143846200012c565b620001625760405162461bcd60e51b8152600401620000ac90620003aa565b600080856001600160a01b0316856040516200017f9190620002fa565b600060405180830381855af49150503d8060008114620001bc576040519150601f19603f3d011682016040523d82523d6000602084013e620001c1565b606091505b509092509050620001d4828286620001de565b9695505050505050565b60608315620001ef57508162000101565b825115620002005782518084602001fd5b8160405162461bcd60e51b8152600401620000ac919062000318565b80516001600160a01b03811681146200013157600080fd5b60008060006060848603121562000249578283fd5b62000254846200021c565b925062000264602085016200021c565b60408501519092506001600160401b038082111562000281578283fd5b818601915086601f83011262000295578283fd5b815181811115620002a257fe5b604051601f8201601f191681016020018381118282101715620002c157fe5b604052818152838201602001891015620002d9578485fd5b620002ec826020830160208701620003f0565b809450505050509250925092565b600082516200030e818460208701620003f0565b9190910192915050565b600060208252825180602084015262000339816040850160208701620003f0565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b838110156200040d578181015183820152602001620003f3565b838111156200041d576000848401525b50505050565b61084b80620004336000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122062766c17e94a6c40528969924f0bd026491bb737bb1305a177de6512cf341cce64736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122062766c17e94a6c40528969924f0bd026491bb737bb1305a177de6512cf341cce64736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/Federation.json b/bridge/deployments/rsktestnetrinkeby/Federation.json
new file mode 100644
index 000000000..528afb029
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/Federation.json
@@ -0,0 +1,1094 @@
+{
+ "address": "0xF0C541AB4e8b780f3e4F5E32d2bA4f2149d8baec",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridge",
+ "type": "address"
+ }
+ ],
+ "name": "BridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Executed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "HeartBeat",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridgeNFT",
+ "type": "address"
+ }
+ ],
+ "name": "NFTBridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Voted",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_MEMBER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_newMember",
+ "type": "address"
+ }
+ ],
+ "name": "addMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridge",
+ "outputs": [
+ {
+ "internalType": "contract IBridge",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridgeNFT",
+ "outputs": [
+ {
+ "internalType": "contract INFTBridge",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "emitHeartbeat",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getMembers",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "getTransactionId",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_members",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridgeNFT",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isMember",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "members",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "processed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_oldMember",
+ "type": "address"
+ }
+ ],
+ "name": "removeMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ }
+ ],
+ "name": "setBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridgeNFT",
+ "type": "address"
+ }
+ ],
+ "name": "setNFTBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionWasProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "enum IFederation.TokenType",
+ "name": "tokenType",
+ "type": "uint8"
+ }
+ ],
+ "name": "voteTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "votes",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xa342145c6c4777662c77f8bbcb9596ae8b6ee30e6d3ab91d030805a82045d566",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0xF0C541AB4e8b780f3e4F5E32d2bA4f2149d8baec",
+ "transactionIndex": 0,
+ "gasUsed": "2089544",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x3e0bda1bcf3f800fa857a657105ca26d0094ee222610ae833e1fbd44937fc6dc",
+ "transactionHash": "0xa342145c6c4777662c77f8bbcb9596ae8b6ee30e6d3ab91d030805a82045d566",
+ "logs": [],
+ "blockNumber": 2170983,
+ "cumulativeGasUsed": "2089544",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"bridge\",\"type\":\"address\"}],\"name\":\"BridgeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"Executed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fedRskBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fedEthBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"federatorVersion\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"nodeRskInfo\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"nodeEthInfo\",\"type\":\"string\"}],\"name\":\"HeartBeat\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"bridgeNFT\",\"type\":\"address\"}],\"name\":\"NFTBridgeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"Voted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MEMBER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newMember\",\"type\":\"address\"}],\"name\":\"addMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contract IBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridgeNFT\",\"outputs\":[{\"internalType\":\"contract INFTBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fedRskBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fedEthBlock\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"federatorVersion\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nodeRskInfo\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nodeEthInfo\",\"type\":\"string\"}],\"name\":\"emitHeartbeat\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMembers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"getTransactionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"hasVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_members\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bridgeNFT\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMember\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"members\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"processed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_oldMember\",\"type\":\"address\"}],\"name\":\"removeMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"name\":\"setBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridgeNFT\",\"type\":\"address\"}],\"name\":\"setNFTBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"transactionWasProcessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"enum IFederation.TokenType\",\"name\":\"tokenType\",\"type\":\"uint8\"}],\"name\":\"voteTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"votes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addMember(address)\":{\"params\":{\"_newMember\":\"address of the new member\"}},\"changeRequirement(uint256)\":{\"details\":\"Emits the RequirementChange event\",\"params\":{\"_required\":\"the number of minimum members to approve an transaction, it has to be bigger than 1\"}},\"emitHeartbeat(uint256,uint256,string,string,string)\":{\"details\":\"Emits HeartBeat event\"},\"getMembers()\":{\"returns\":{\"_0\":\"Current members\"}},\"getTransactionCount(bytes32)\":{\"params\":{\"transactionId\":\"The transaction hashed from getTransactionId function\"}},\"getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32)\":{\"details\":\"It encodes and applies keccak256 to the parameters received in the same order\",\"params\":{\"amount\":\"Could be the amount or the tokenId\",\"blockHash\":\"The block hash in which the transaction with the cross event occurred\",\"logIndex\":\"Index of the event in the logs\",\"originalTokenAddress\":\"The address of the token in the origin (main) chain\",\"receiver\":\"Who is going to receive the token in the opposite chain\",\"sender\":\"The address who solicited the cross token\",\"transactionHash\":\"The transaction in which the cross event occurred\"},\"returns\":{\"_0\":\"The hash generated by the parameters.\"}},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"removeMember(address)\":{\"params\":{\"_oldMember\":\"address of the member to be removed from federation\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setBridge(address)\":{\"details\":\"Emits BridgeChanged event\",\"params\":{\"_bridge\":\"the new bridge contract address that should implement the IBridge interface\"}},\"setNFTBridge(address)\":{\"details\":\"Emits NFTBridgeChanged event\",\"params\":{\"_bridgeNFT\":\"the new NFT bridge contract address that should implement the INFTBridge interface\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"version()\":{\"returns\":{\"_0\":\"version in v{Number}\"}},\"voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint8)\":{\"params\":{\"blockHash\":\"The block hash in which the transaction with the cross event occurred\",\"logIndex\":\"Index of the event in the logs\",\"originalTokenAddress\":\"The address of the token in the origin (main) chain\",\"receiver\":\"Who is going to receive the token in the opposite chain\",\"sender\":\"The address who solicited the cross token\",\"tokenType\":\"Is the type of bridge to be used\",\"transactionHash\":\"The transaction in which the cross event occurred\",\"value\":\"Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\"}}},\"stateVariables\":{\"isMember\":{\"details\":\"The address should be a member to vote in transactions\"},\"required\":{\"details\":\"It should have more members than the required amount\"},\"votes\":{\"details\":\"usually the members should approve the transaction by 50% + 1\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addMember(address)\":{\"notice\":\"Add a new member to the federation\"},\"bridgeNFT()\":{\"notice\":\"Federator v3 variables \"},\"changeRequirement(uint256)\":{\"notice\":\"Changes the number of required members to vote and approve an transaction\"},\"emitHeartbeat(uint256,uint256,string,string,string)\":{\"notice\":\"It emits an HeartBeat like an health check\"},\"getMembers()\":{\"notice\":\"Return all the current members of the federation\"},\"getTransactionCount(bytes32)\":{\"notice\":\"Get the amount of approved votes for that transactionId\"},\"getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32)\":{\"notice\":\"Gets the hash of transaction from the following parameters encoded and keccaked\"},\"isMember(address)\":{\"notice\":\"All the addresses that are members of the federation\"},\"processed(bytes32)\":{\"notice\":\"(bytes32) transactionId => (bool) votedCheck if that transaction was already processed\"},\"removeMember(address)\":{\"notice\":\"Remove a member of the federation\"},\"required()\":{\"notice\":\"The minimum amount of votes to approve a transaction\"},\"setBridge(address)\":{\"notice\":\"Sets a new bridge contract\"},\"setNFTBridge(address)\":{\"notice\":\"Sets a new NFT bridge contract\"},\"version()\":{\"notice\":\"Current version of the contract\"},\"voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint8)\":{\"notice\":\"Vote in a transaction, if it has enough votes it accepts the transfer\"},\"votes(bytes32,address)\":{\"notice\":\"(bytes32) transactionId = keccak256( abi.encodePacked( originalTokenAddress, sender, receiver, amount, blockHash, transactionHash, logIndex ) ) => ( (address) members => (bool) voted )Votes by members by the transaction ID\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Federation/Federation.sol\":\"Federation\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Federation/Federation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n// Upgradables\\r\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\r\\n\\r\\nimport \\\"../nftbridge/INFTBridge.sol\\\";\\r\\nimport \\\"../interface/IBridge.sol\\\";\\r\\nimport \\\"../interface/IFederation.sol\\\";\\r\\n\\r\\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\\r\\n uint constant public MAX_MEMBER_COUNT = 50;\\r\\n address constant private NULL_ADDRESS = address(0);\\r\\n\\r\\n IBridge public bridge;\\r\\n address[] public members;\\r\\n\\r\\n /**\\r\\n @notice The minimum amount of votes to approve a transaction\\r\\n @dev It should have more members than the required amount\\r\\n */\\r\\n uint public required;\\r\\n\\r\\n /**\\r\\n @notice All the addresses that are members of the federation\\r\\n @dev The address should be a member to vote in transactions\\r\\n */\\r\\n mapping (address => bool) public isMember;\\r\\n\\r\\n /**\\r\\n (bytes32) transactionId = keccak256(\\r\\n abi.encodePacked(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n amount,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n )\\r\\n ) => (\\r\\n (address) members => (bool) voted\\r\\n )\\r\\n @notice Votes by members by the transaction ID\\r\\n @dev usually the members should approve the transaction by 50% + 1\\r\\n */\\r\\n mapping (bytes32 => mapping (address => bool)) public votes;\\r\\n\\r\\n /**\\r\\n (bytes32) transactionId => (bool) voted\\r\\n @notice Check if that transaction was already processed\\r\\n */\\r\\n mapping(bytes32 => bool) public processed;\\r\\n\\r\\n /** Federator v3 variables */\\r\\n INFTBridge public bridgeNFT;\\r\\n\\r\\n modifier onlyMember() {\\r\\n require(isMember[_msgSender()], \\\"Federation: Not Federator\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier validRequirement(uint membersCount, uint _required) {\\r\\n // solium-disable-next-line max-len\\r\\n require(_required <= membersCount && _required != 0 && membersCount != 0, \\\"Federation: Invalid requirements\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function initialize(address[] memory _members, uint _required, address _bridge, address owner, address _bridgeNFT) public\\r\\n validRequirement(_members.length, _required) initializer {\\r\\n UpgradableOwnable.initialize(owner);\\r\\n require(_members.length <= MAX_MEMBER_COUNT, \\\"Federation: Too many members\\\");\\r\\n members = _members;\\r\\n for (uint i = 0; i < _members.length; i++) {\\r\\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \\\"Federation: Invalid members\\\");\\r\\n isMember[_members[i]] = true;\\r\\n emit MemberAddition(_members[i]);\\r\\n }\\r\\n required = _required;\\r\\n emit RequirementChange(required);\\r\\n _setBridge(_bridge);\\r\\n _setNFTBridge(_bridgeNFT);\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Current version of the contract\\r\\n @return version in v{Number}\\r\\n */\\r\\n function version() external pure override returns (string memory) {\\r\\n return \\\"v3\\\";\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Sets a new bridge contract\\r\\n @dev Emits BridgeChanged event\\r\\n @param _bridge the new bridge contract address that should implement the IBridge interface\\r\\n */\\r\\n function setBridge(address _bridge) external onlyOwner override {\\r\\n _setBridge(_bridge);\\r\\n }\\r\\n\\r\\n function _setBridge(address _bridge) internal {\\r\\n require(_bridge != NULL_ADDRESS, \\\"Federation: Empty bridge\\\");\\r\\n bridge = IBridge(_bridge);\\r\\n emit BridgeChanged(_bridge);\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Sets a new NFT bridge contract\\r\\n @dev Emits NFTBridgeChanged event\\r\\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\\r\\n */\\r\\n function setNFTBridge(address _bridgeNFT) external onlyOwner override {\\r\\n _setNFTBridge(_bridgeNFT);\\r\\n }\\r\\n\\r\\n function _setNFTBridge(address _bridgeNFT) internal {\\r\\n require(_bridgeNFT != NULL_ADDRESS, \\\"Federation: Empty NFT bridge\\\");\\r\\n bridgeNFT = INFTBridge(_bridgeNFT);\\r\\n emit NFTBridgeChanged(_bridgeNFT);\\r\\n }\\r\\n\\r\\n function validateTransaction(bytes32 transactionId) internal view returns(bool) {\\r\\n uint transactionCount = getTransactionCount(transactionId);\\r\\n return transactionCount >= required && transactionCount >= members.length / 2 + 1;\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\\r\\n @param originalTokenAddress The address of the token in the origin (main) chain\\r\\n @param sender The address who solicited the cross token\\r\\n @param receiver Who is going to receive the token in the opposite chain\\r\\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\\r\\n @param blockHash The block hash in which the transaction with the cross event occurred\\r\\n @param transactionHash The transaction in which the cross event occurred\\r\\n @param logIndex Index of the event in the logs\\r\\n @param tokenType Is the type of bridge to be used\\r\\n */\\r\\n function voteTransaction(\\r\\n address originalTokenAddress,\\r\\n address payable sender,\\r\\n address payable receiver,\\r\\n uint256 value,\\r\\n bytes32 blockHash,\\r\\n bytes32 transactionHash,\\r\\n uint32 logIndex,\\r\\n TokenType tokenType\\r\\n ) external onlyMember override {\\r\\n bytes32 transactionId = getTransactionId(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n value,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n );\\r\\n if (processed[transactionId])\\r\\n return;\\r\\n\\r\\n if (votes[transactionId][_msgSender()])\\r\\n return;\\r\\n\\r\\n votes[transactionId][_msgSender()] = true;\\r\\n emit Voted(\\r\\n _msgSender(),\\r\\n transactionHash,\\r\\n transactionId,\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n value,\\r\\n blockHash,\\r\\n logIndex\\r\\n );\\r\\n\\r\\n if (validateTransaction(transactionId)) {\\r\\n processed[transactionId] = true;\\r\\n acceptTransfer(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n value,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex,\\r\\n tokenType\\r\\n );\\r\\n\\r\\n emit Executed(\\r\\n _msgSender(),\\r\\n transactionHash,\\r\\n transactionId,\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n value,\\r\\n blockHash,\\r\\n logIndex\\r\\n );\\r\\n return;\\r\\n }\\r\\n }\\r\\n\\r\\n function acceptTransfer(\\r\\n address originalTokenAddress,\\r\\n address payable sender,\\r\\n address payable receiver,\\r\\n uint256 value,\\r\\n bytes32 blockHash,\\r\\n bytes32 transactionHash,\\r\\n uint32 logIndex,\\r\\n TokenType tokenType\\r\\n ) internal {\\r\\n if (tokenType == TokenType.NFT) {\\r\\n require(address(bridgeNFT) != NULL_ADDRESS, \\\"Federation: Empty NFTBridge\\\");\\r\\n bridgeNFT.acceptTransfer(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n value,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n );\\r\\n return;\\r\\n }\\r\\n\\r\\n bridge.acceptTransfer(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n value,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n );\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Get the amount of approved votes for that transactionId\\r\\n @param transactionId The transaction hashed from getTransactionId function\\r\\n */\\r\\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\\r\\n uint count = 0;\\r\\n for (uint i = 0; i < members.length; i++) {\\r\\n if (votes[transactionId][members[i]])\\r\\n count += 1;\\r\\n }\\r\\n return count;\\r\\n }\\r\\n\\r\\n function hasVoted(bytes32 transactionId) external view returns(bool)\\r\\n {\\r\\n return votes[transactionId][_msgSender()];\\r\\n }\\r\\n\\r\\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\\r\\n {\\r\\n return processed[transactionId];\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Gets the hash of transaction from the following parameters encoded and keccaked\\r\\n @dev It encodes and applies keccak256 to the parameters received in the same order\\r\\n @param originalTokenAddress The address of the token in the origin (main) chain\\r\\n @param sender The address who solicited the cross token\\r\\n @param receiver Who is going to receive the token in the opposite chain\\r\\n @param amount Could be the amount or the tokenId\\r\\n @param blockHash The block hash in which the transaction with the cross event occurred\\r\\n @param transactionHash The transaction in which the cross event occurred\\r\\n @param logIndex Index of the event in the logs\\r\\n @return The hash generated by the parameters.\\r\\n */\\r\\n function getTransactionId(\\r\\n address originalTokenAddress,\\r\\n address sender,\\r\\n address receiver,\\r\\n uint256 amount,\\r\\n bytes32 blockHash,\\r\\n bytes32 transactionHash,\\r\\n uint32 logIndex\\r\\n ) public pure returns(bytes32) {\\r\\n return keccak256(\\r\\n abi.encodePacked(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n amount,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n )\\r\\n );\\r\\n }\\r\\n\\r\\n function addMember(address _newMember) external onlyOwner override\\r\\n {\\r\\n require(_newMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\r\\n require(!isMember[_newMember], \\\"Federation: Member already exists\\\");\\r\\n require(members.length < MAX_MEMBER_COUNT, \\\"Federation: Max members reached\\\");\\r\\n\\r\\n isMember[_newMember] = true;\\r\\n members.push(_newMember);\\r\\n emit MemberAddition(_newMember);\\r\\n }\\r\\n\\r\\n function removeMember(address _oldMember) external onlyOwner override\\r\\n {\\r\\n require(_oldMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\r\\n require(isMember[_oldMember], \\\"Federation: Member doesn't exists\\\");\\r\\n require(members.length > 1, \\\"Federation: Can't remove all the members\\\");\\r\\n require(members.length - 1 >= required, \\\"Federation: Can't have less than required members\\\");\\r\\n\\r\\n isMember[_oldMember] = false;\\r\\n for (uint i = 0; i < members.length - 1; i++) {\\r\\n if (members[i] == _oldMember) {\\r\\n members[i] = members[members.length - 1];\\r\\n break;\\r\\n }\\r\\n }\\r\\n members.pop(); // remove an element from the end of the array.\\r\\n emit MemberRemoval(_oldMember);\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Return all the current members of the federation\\r\\n @return Current members\\r\\n */\\r\\n function getMembers() external view override returns (address[] memory) {\\r\\n return members;\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice Changes the number of required members to vote and approve an transaction\\r\\n @dev Emits the RequirementChange event\\r\\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\\r\\n */\\r\\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\\r\\n require(_required >= 2, \\\"Federation: Requires at least 2\\\");\\r\\n required = _required;\\r\\n emit RequirementChange(_required);\\r\\n }\\r\\n\\r\\n /**\\r\\n @notice It emits an HeartBeat like an health check\\r\\n @dev Emits HeartBeat event\\r\\n */\\r\\n function emitHeartbeat(\\r\\n uint256 fedRskBlock,\\r\\n uint256 fedEthBlock,\\r\\n string calldata federatorVersion,\\r\\n string calldata nodeRskInfo,\\r\\n string calldata nodeEthInfo\\r\\n ) external onlyMember override {\\r\\n emit HeartBeat(\\r\\n _msgSender(),\\r\\n fedRskBlock,\\r\\n fedEthBlock,\\r\\n federatorVersion,\\r\\n nodeRskInfo,\\r\\n nodeEthInfo\\r\\n );\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xa0a2e0f2ad71ae15c4301dbccbd3a100904df70e291ddbde1f0bad759635e164\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IBridge {\\r\\n\\r\\n struct ClaimData {\\r\\n address payable to;\\r\\n uint256 amount;\\r\\n bytes32 blockHash;\\r\\n bytes32 transactionHash;\\r\\n uint32 logIndex;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getFeePercentage() external view returns(uint);\\r\\n\\r\\n /**\\r\\n * ERC-20 tokens approve and transferFrom pattern\\r\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\r\\n */\\r\\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\\r\\n\\r\\n /**\\r\\n * Use network currency and cross it.\\r\\n */\\r\\n function depositTo(address to) external payable;\\r\\n\\r\\n /**\\r\\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\r\\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\r\\n */\\r\\n function tokensReceived (\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\r\\n */\\r\\n function acceptTransfer(\\r\\n address _originalTokenAddress,\\r\\n address payable _from,\\r\\n address payable _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\r\\n */\\r\\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\r\\n\\r\\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\r\\n\\r\\n function claimGasless(\\r\\n ClaimData calldata _claimData,\\r\\n address payable _relayer,\\r\\n uint256 _fee,\\r\\n uint256 _deadline,\\r\\n uint8 _v,\\r\\n bytes32 _r,\\r\\n bytes32 _s\\r\\n ) external returns (uint256 receivedAmount);\\r\\n\\r\\n function getTransactionDataHash(\\r\\n address _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external returns(bytes32);\\r\\n\\r\\n event Cross(\\r\\n address indexed _tokenAddress,\\r\\n address indexed _from,\\r\\n address indexed _to,\\r\\n uint256 _amount,\\r\\n bytes _userData\\r\\n );\\r\\n event NewSideToken(\\r\\n address indexed _newSideTokenAddress,\\r\\n address indexed _originalTokenAddress,\\r\\n string _newSymbol,\\r\\n uint256 _granularity\\r\\n );\\r\\n event AcceptedCrossTransfer(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _from,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex\\r\\n );\\r\\n event FeePercentageChanged(uint256 _amount);\\r\\n event Claimed(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _sender,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex,\\r\\n address _reciever,\\r\\n address _relayer,\\r\\n uint256 _fee\\r\\n );\\r\\n}\",\"keccak256\":\"0x9e48ff075a1e3fd0533feec4b93f397a4678b5d267cbae021ea0faf8cc91a383\",\"license\":\"MIT\"},\"contracts/interface/IFederation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface IFederation {\\r\\n enum TokenType{ COIN, NFT }\\r\\n\\r\\n /**\\r\\n @notice Current version of the contract\\r\\n @return version in v{Number}\\r\\n */\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n /**\\r\\n @notice Sets a new bridge contract\\r\\n @param _bridge the new bridge contract address that should implement the IBridge interface\\r\\n */\\r\\n function setBridge(address _bridge) external;\\r\\n\\r\\n /**\\r\\n @notice Sets a new NFT bridge contract\\r\\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\\r\\n */\\r\\n function setNFTBridge(address _bridgeNFT) external;\\r\\n\\r\\n /**\\r\\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\\r\\n @param originalTokenAddress The address of the token in the origin (main) chain\\r\\n @param sender The address who solicited the cross token\\r\\n @param receiver Who is going to receive the token in the opposite chain\\r\\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\\r\\n @param blockHash The block hash in which the transaction with the cross event occurred\\r\\n @param transactionHash The transaction in which the cross event occurred\\r\\n @param logIndex Index of the event in the logs\\r\\n @param tokenType Is the type of bridge to be used\\r\\n */\\r\\n function voteTransaction(\\r\\n address originalTokenAddress,\\r\\n address payable sender,\\r\\n address payable receiver,\\r\\n uint256 value,\\r\\n bytes32 blockHash,\\r\\n bytes32 transactionHash,\\r\\n uint32 logIndex,\\r\\n TokenType tokenType\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n @notice Add a new member to the federation\\r\\n @param _newMember address of the new member\\r\\n */\\r\\n function addMember(address _newMember) external;\\r\\n\\r\\n /**\\r\\n @notice Remove a member of the federation\\r\\n @param _oldMember address of the member to be removed from federation\\r\\n */\\r\\n function removeMember(address _oldMember) external;\\r\\n\\r\\n /**\\r\\n @notice Return all the current members of the federation\\r\\n @return Current members\\r\\n */\\r\\n function getMembers() external view returns (address[] memory);\\r\\n\\r\\n /**\\r\\n @notice Changes the number of required members to vote and approve an transaction\\r\\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\\r\\n */\\r\\n function changeRequirement(uint _required) external;\\r\\n\\r\\n /**\\r\\n @notice It emmits an HeartBeat like an healthy check\\r\\n */\\r\\n function emitHeartbeat(\\r\\n uint256 fedRskBlock,\\r\\n uint256 fedEthBlock,\\r\\n string calldata federatorVersion,\\r\\n string calldata nodeRskInfo,\\r\\n string calldata nodeEthInfo\\r\\n ) external;\\r\\n\\r\\n event Executed(\\r\\n address indexed federator,\\r\\n bytes32 indexed transactionHash,\\r\\n bytes32 indexed transactionId,\\r\\n address originalTokenAddress,\\r\\n address sender,\\r\\n address receiver,\\r\\n uint256 amount,\\r\\n bytes32 blockHash,\\r\\n uint32 logIndex\\r\\n );\\r\\n event MemberAddition(address indexed member);\\r\\n event MemberRemoval(address indexed member);\\r\\n event RequirementChange(uint required);\\r\\n event BridgeChanged(address bridge);\\r\\n event NFTBridgeChanged(address bridgeNFT);\\r\\n event Voted(\\r\\n address indexed federator,\\r\\n bytes32 indexed transactionHash,\\r\\n bytes32 indexed transactionId,\\r\\n address originalTokenAddress,\\r\\n address sender,\\r\\n address receiver,\\r\\n uint256 amount,\\r\\n bytes32 blockHash,\\r\\n uint32 logIndex\\r\\n );\\r\\n event HeartBeat(\\r\\n address indexed sender,\\r\\n uint256 fedRskBlock,\\r\\n uint256 fedEthBlock,\\r\\n string federatorVersion,\\r\\n string nodeRskInfo,\\r\\n string nodeEthInfo\\r\\n );\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0x209134d6fd63a3f442a9cf086716baf7ac8639650c295e308a73a351ba077a21\",\"license\":\"MIT\"},\"contracts/nftbridge/INFTBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface INFTBridge {\\r\\n struct NFTClaimData {\\r\\n address payable to;\\r\\n address from;\\r\\n uint256 tokenId;\\r\\n address tokenAddress;\\r\\n bytes32 blockHash;\\r\\n bytes32 transactionHash;\\r\\n uint32 logIndex;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getFixedFee() external view returns (uint256);\\r\\n\\r\\n function receiveTokensTo(\\r\\n address tokenAddress,\\r\\n address to,\\r\\n uint256 tokenId\\r\\n ) external payable;\\r\\n\\r\\n /**\\r\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\r\\n */\\r\\n function acceptTransfer(\\r\\n address _originalTokenAddress,\\r\\n address payable _from,\\r\\n address payable _to,\\r\\n uint256 _tokenId,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\\r\\n */\\r\\n function claim(NFTClaimData calldata _claimData) external;\\r\\n\\r\\n function claimFallback(NFTClaimData calldata _claimData) external;\\r\\n\\r\\n function getTransactionDataHash(\\r\\n address _to,\\r\\n address _from,\\r\\n uint256 _tokenId,\\r\\n address _tokenAddress,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external returns (bytes32);\\r\\n\\r\\n event Cross(\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _from,\\r\\n address indexed _to,\\r\\n address _tokenCreator,\\r\\n bytes _userData,\\r\\n uint256 _totalSupply,\\r\\n uint256 _tokenId,\\r\\n string _tokenURI\\r\\n );\\r\\n event NewSideNFTToken(\\r\\n address indexed _newSideNFTTokenAddress,\\r\\n address indexed _originalTokenAddress,\\r\\n string _newSymbol\\r\\n );\\r\\n event AcceptedNFTCrossTransfer(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _from,\\r\\n uint256 _tokenId,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex\\r\\n );\\r\\n event FixedFeeNFTChanged(uint256 _amount);\\r\\n event ClaimedNFTToken(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _sender,\\r\\n uint256 _tokenId,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex,\\r\\n address _receiver\\r\\n );\\r\\n}\\r\\n\",\"keccak256\":\"0x2ae628c2bf573e402f83c817bb3bcf80a9f38aa82e328141f4cd9da1deadc88d\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @title Initializable\\r\\n *\\r\\n * @dev Helper contract to support initializer functions. To use it, replace\\r\\n * the constructor with a function that has the `initializer` modifier.\\r\\n * WARNING: Unlike constructors, initializer functions must be manually\\r\\n * invoked. This applies both to deploying an Initializable contract, as well\\r\\n * as extending an Initializable contract via inheritance.\\r\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\r\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\r\\n * because this is not dealt with automatically as with constructors.\\r\\n */\\r\\ncontract Initializable {\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract has been initialized.\\r\\n */\\r\\n bool private initialized;\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract is in the process of being initialized.\\r\\n */\\r\\n bool private initializing;\\r\\n\\r\\n /**\\r\\n * @dev Modifier to use in the initializer function of a contract.\\r\\n */\\r\\n modifier initializer() {\\r\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\r\\n\\r\\n bool isTopLevelCall = !initializing;\\r\\n if (isTopLevelCall) {\\r\\n initializing = true;\\r\\n initialized = true;\\r\\n }\\r\\n\\r\\n _;\\r\\n\\r\\n if (isTopLevelCall) {\\r\\n initializing = false;\\r\\n }\\r\\n }\\r\\n\\r\\n // Reserved storage space to allow for layout changes in the future.\\r\\n uint256[50] private ______gap;\\r\\n}\",\"keccak256\":\"0xc1f4d917648f0e17ba6a023a168173ad6163f3120e24d1c97ae294430e42eaf3\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Contract module which provides a basic access control mechanism, where\\r\\n * there is an account (an owner) that can be granted exclusive access to\\r\\n * specific functions.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the modifier\\r\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\r\\n * the owner.\\r\\n */\\r\\ncontract UpgradableOwnable is Initializable, Context {\\r\\n address private _owner;\\r\\n\\r\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract setting the deployer as the initial owner.\\r\\n */\\r\\n function initialize(address sender) public initializer {\\r\\n _owner = sender;\\r\\n emit OwnershipTransferred(address(0), _owner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the address of the current owner.\\r\\n */\\r\\n function owner() public view returns (address) {\\r\\n return _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Throws if called by any account other than the owner.\\r\\n */\\r\\n modifier onlyOwner() {\\r\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the caller is the current owner.\\r\\n */\\r\\n function isOwner() public view returns (bool) {\\r\\n return _msgSender() == _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Leaves the contract without owner. It will not be possible to call\\r\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\r\\n *\\r\\n * > Note: Renouncing ownership will leave the contract without an owner,\\r\\n * thereby removing any functionality that is only available to the owner.\\r\\n */\\r\\n function renounceOwnership() public onlyOwner {\\r\\n emit OwnershipTransferred(_owner, address(0));\\r\\n _owner = address(0);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n * Can only be called by the current owner.\\r\\n */\\r\\n function transferOwnership(address newOwner) public onlyOwner {\\r\\n _transferOwnership(newOwner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n */\\r\\n function _transferOwnership(address newOwner) internal {\\r\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\r\\n emit OwnershipTransferred(_owner, newOwner);\\r\\n _owner = newOwner;\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0xea920007e371a3300245b5885f72cecc472c4780818365f0025fae65a767273d\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50611dcb806100206000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c8063a481d59b116100f9578063ca6d56dc11610097578063ef1093a711610071578063ef1093a714610357578063f2fde38b1461035f578063f697aa2414610372578063fa6297ba14610385576101a9565b8063ca6d56dc14610334578063dc8452cd14610347578063e78cea921461034f576101a9565b8063b9a3b9dc116100d3578063b9a3b9dc146102e8578063ba51a6df146102fb578063c1f0808a1461030e578063c4d66de814610321576101a9565b8063a481d59b146102af578063a8e12e4c146102c2578063a93585f0146102d5576101a9565b80638da5cb5b116101665780639386775a116101405780639386775a146102615780639eab525314610274578063a1fb4acb14610289578063a230c5241461029c576101a9565b80638da5cb5b1461023e5780638dd14802146102465780638f32d59b14610259576101a9565b80630b1ca49a146101ae5780631b4613cb146101c357806354fd4d50146101ec5780635daf08ca14610201578063681fc92114610221578063715018a614610236575b600080fd5b6101c16101bc366004611456565b610398565b005b6101d66101d1366004611667565b6105a6565b6040516101e391906118c4565b60405180910390f35b6101f46105e2565b6040516101e391906118d8565b61021461020f366004611667565b6105fe565b6040516101e391906117df565b610229610628565b6040516101e391906118cf565b6101c161062d565b61021461069b565b6101c1610254366004611456565b6106aa565b6101d66106da565b6101d661026f36600461167f565b610700565b61027c610720565b6040516101e39190611877565b610229610297366004611667565b610782565b6101d66102aa366004611456565b6107f3565b6101c16102bd366004611456565b610808565b6101c16102d0366004611576565b610835565b6101d66102e3366004611667565b610aad565b6101c16102f63660046116ae565b610ac2565b6101c1610309366004611667565b610b67565b6101d661031c366004611667565b610c28565b6101c161032f366004611456565b610c3d565b6101c1610342366004611456565b610d02565b610229610e33565b610214610e39565b610214610e48565b6101c161036d366004611456565b610e57565b6101c1610380366004611472565b610e84565b610229610393366004611500565b61106a565b6103a06106da565b6103c55760405162461bcd60e51b81526004016103bc90611b8e565b60405180910390fd5b6001600160a01b0381166103eb5760405162461bcd60e51b81526004016103bc90611bfa565b6001600160a01b03811660009081526037602052604090205460ff166104235760405162461bcd60e51b81526004016103bc906119ce565b6035546001106104455760405162461bcd60e51b81526004016103bc90611c68565b60365460355460001901101561046d5760405162461bcd60e51b81526004016103bc90611b3d565b6001600160a01b0381166000908152603760205260408120805460ff191690555b6035546000190181101561054157816001600160a01b0316603582815481106104b357fe5b6000918252602090912001546001600160a01b03161415610539576035805460001981019081106104e057fe5b600091825260209091200154603580546001600160a01b03909216918390811061050657fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610541565b60010161048e565b50603580548061054d57fe5b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b6000818152603860205260408120816105bd6110ac565b6001600160a01b0316815260208101919091526040016000205460ff1690505b919050565b604080518082019091526002815261763360f01b602082015290565b6035818154811061060e57600080fd5b6000918252602090912001546001600160a01b0316905081565b603281565b6106356106da565b6106515760405162461bcd60e51b81526004016103bc90611b8e565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6106b26106da565b6106ce5760405162461bcd60e51b81526004016103bc90611b8e565b6106d7816110b0565b50565b6033546000906001600160a01b03166106f16110ac565b6001600160a01b031614905090565b603860209081526000928352604080842090915290825290205460ff1681565b6060603580548060200260200160405190810160405280929190818152602001828054801561077857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161075a575b5050505050905090565b600080805b6035548110156107ec57600084815260386020526040812060358054919291849081106107b057fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156107e4576001820191505b600101610787565b5092915050565b60376020526000908152604090205460ff1681565b6108106106da565b61082c5760405162461bcd60e51b81526004016103bc90611b8e565b6106d78161112c565b84518481811115801561084757508015155b801561085257508115155b61086e5760405162461bcd60e51b81526004016103bc9061192b565b600054610100900460ff1680610887575060005460ff16155b6108a35760405162461bcd60e51b81526004016103bc90611a0f565b600054610100900460ff161580156108ce576000805460ff1961ff0019909116610100171660011790555b6108d785610c3d565b6032885111156108f95760405162461bcd60e51b81526004016103bc90611997565b875161090c9060359060208b0190611376565b5060005b8851811015610a4157603760008a838151811061092957fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015610983575060006001600160a01b031689828151811061096f57fe5b60200260200101516001600160a01b031614155b61099f5760405162461bcd60e51b81526004016103bc90611a57565b6001603760008b84815181106109b157fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055508881815181106109fc57fe5b60200260200101516001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a2600101610910565b5060368790556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610a779089906118cf565b60405180910390a1610a88866110b0565b610a918461112c565b8015610aa3576000805461ff00191690555b5050505050505050565b60009081526039602052604090205460ff1690565b60376000610ace6110ac565b6001600160a01b0316815260208101919091526040016000205460ff16610b075760405162461bcd60e51b81526004016103bc90611cf2565b610b0f6110ac565b6001600160a01b03167fbb00e6cbdccbb5b7549e189335249187223d88583604555326aa1d7ccbcad4428989898989898989604051610b55989796959493929190611d29565b60405180910390a25050505050505050565b610b6f6106da565b610b8b5760405162461bcd60e51b81526004016103bc90611b8e565b60355481818111801590610b9e57508015155b8015610ba957508115155b610bc55760405162461bcd60e51b81526004016103bc9061192b565b6002831015610be65760405162461bcd60e51b81526004016103bc90611bc3565b60368390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610c1b9085906118cf565b60405180910390a1505050565b60396020526000908152604090205460ff1681565b600054610100900460ff1680610c56575060005460ff16155b610c725760405162461bcd60e51b81526004016103bc90611a0f565b600054610100900460ff16158015610c9d576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610cfe576000805461ff00191690555b5050565b610d0a6106da565b610d265760405162461bcd60e51b81526004016103bc90611b8e565b6001600160a01b038116610d4c5760405162461bcd60e51b81526004016103bc90611bfa565b6001600160a01b03811660009081526037602052604090205460ff1615610d855760405162461bcd60e51b81526004016103bc90611a8e565b603554603211610da75760405162461bcd60e51b81526004016103bc90611960565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b60365481565b6034546001600160a01b031681565b603a546001600160a01b031681565b610e5f6106da565b610e7b5760405162461bcd60e51b81526004016103bc90611b8e565b6106d78161119d565b60376000610e906110ac565b6001600160a01b0316815260208101919091526040016000205460ff16610ec95760405162461bcd60e51b81526004016103bc90611cf2565b6000610eda8989898989898961106a565b60008181526039602052604090205490915060ff1615610efa5750610aa3565b600081815260386020526040812090610f116110ac565b6001600160a01b0316815260208101919091526040016000205460ff1615610f395750610aa3565b6000818152603860205260408120600191610f526110ac565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558084610f846110ac565b6001600160a01b03167fd22894491aaa5bb67855bcff4b9730bdf7768be1e25f66ced9a7d7ad623bf2918c8c8c8c8c8b604051610fc696959493929190611839565b60405180910390a4610fd78161121f565b1561105f576000818152603960205260409020805460ff19166001179055611005898989898989898961124f565b808461100f6110ac565b6001600160a01b03167fe21e4d3d66ef78424137270e65cfafe938736bb770702ab4fd630383e7820b738c8c8c8c8c8b60405161105196959493929190611839565b60405180910390a450610aa3565b505050505050505050565b6000878787878787876040516020016110899796959493929190611781565b604051602081830303815290604052805190602001209050979650505050505050565b3390565b6001600160a01b0381166110d65760405162461bcd60e51b81526004016103bc90611acf565b603480546001600160a01b0319166001600160a01b0383161790556040517f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b92551782794497906111219083906117df565b60405180910390a150565b6001600160a01b0381166111525760405162461bcd60e51b81526004016103bc90611b06565b603a80546001600160a01b0319166001600160a01b0383161790556040517f41d363b5ede55d38b1fa8f7ba6188f9c20e353bc71e4a93de8938a20b27b6bc2906111219083906117df565b6001600160a01b0381166111c35760405162461bcd60e51b81526004016103bc90611cb0565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b60008061122b83610782565b905060365481101580156112485750603554600290046001018110155b9392505050565b600181600181111561125d57fe5b14156112fe57603a546001600160a01b031661128b5760405162461bcd60e51b81526004016103bc90611c31565b603a54604051636a86319160e01b81526001600160a01b0390911690636a863191906112c7908b908b908b908b908b908b908b906004016117f3565b600060405180830381600087803b1580156112e157600080fd5b505af11580156112f5573d6000803e3d6000fd5b50505050610aa3565b603454604051636a86319160e01b81526001600160a01b0390911690636a8631919061133a908b908b908b908b908b908b908b906004016117f3565b600060405180830381600087803b15801561135457600080fd5b505af1158015611368573d6000803e3d6000fd5b505050505050505050505050565b8280548282559060005260206000209081019282156113cb579160200282015b828111156113cb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190611396565b506113d79291506113db565b5090565b5b808211156113d757600081556001016113dc565b80356105dd81611d80565b60008083601f84011261140c578182fd5b50813567ffffffffffffffff811115611423578182fd5b60208301915083602082850101111561143b57600080fd5b9250929050565b803563ffffffff811681146105dd57600080fd5b600060208284031215611467578081fd5b813561124881611d80565b600080600080600080600080610100898b03121561148e578384fd5b883561149981611d80565b975060208901356114a981611d80565b965060408901356114b981611d80565b9550606089013594506080890135935060a089013592506114dc60c08a01611442565b915060e0890135600281106114ef578182fd5b809150509295985092959890939650565b600080600080600080600060e0888a03121561151a578283fd5b873561152581611d80565b9650602088013561153581611d80565b9550604088013561154581611d80565b9450606088013593506080880135925060a0880135915061156860c08901611442565b905092959891949750929550565b600080600080600060a0868803121561158d578081fd5b853567ffffffffffffffff808211156115a4578283fd5b818801915088601f8301126115b7578283fd5b81356020828211156115c557fe5b808202604051828282010181811086821117156115de57fe5b604052838152828101945085830182870184018e10156115fc578788fd5b8796505b8487101561162557611611816113f0565b865260019690960195948301948301611600565b50995050890135965061163f9250506040880190506113f0565b925061164d606087016113f0565b915061165b608087016113f0565b90509295509295909350565b600060208284031215611678578081fd5b5035919050565b60008060408385031215611691578182fd5b8235915060208301356116a381611d80565b809150509250929050565b60008060008060008060008060a0898b0312156116c9578384fd5b8835975060208901359650604089013567ffffffffffffffff808211156116ee578586fd5b6116fa8c838d016113fb565b909850965060608b0135915080821115611712578586fd5b61171e8c838d016113fb565b909650945060808b0135915080821115611736578384fd5b506117438b828c016113fb565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b606097881b6bffffffffffffffffffffffff19908116825296881b871660148201529490961b9094166028840152603c830191909152605c820152607c81019190915260e09190911b6001600160e01b031916609c82015260a00190565b6001600160a01b0391909116815260200190565b6001600160a01b03978816815295871660208701529390951660408501526060840191909152608083015260a082019290925263ffffffff90911660c082015260e00190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925263ffffffff90911660a082015260c00190565b6020808252825182820181905260009190848201906040850190845b818110156118b85783516001600160a01b031683529284019291840191600101611893565b50909695505050505050565b901515815260200190565b90815260200190565b6000602080835283518082850152825b81811015611904578581018301518582016040015282016118e8565b818111156119155783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f46656465726174696f6e3a20496e76616c696420726571756972656d656e7473604082015260600190565b6020808252601f908201527f46656465726174696f6e3a204d6178206d656d62657273207265616368656400604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20546f6f206d616e79206d656d6265727300000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746040820152607360f81b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252601b908201527f46656465726174696f6e3a20496e76616c6964206d656d626572730000000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746040820152607360f81b606082015260800190565b60208082526018908201527f46656465726174696f6e3a20456d707479206272696467650000000000000000604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20456d707479204e46542062726964676500000000604082015260600190565b60208082526031908201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604082015270207265717569726564206d656d6265727360781b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f46656465726174696f6e3a205265717569726573206174206c65617374203200604082015260600190565b60208082526018908201527f46656465726174696f6e3a20456d707479206d656d6265720000000000000000604082015260600190565b6020808252601b908201527f46656465726174696f6e3a20456d707479204e46544272696467650000000000604082015260600190565b60208082526028908201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604082015267206d656d6265727360c01b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526019908201527f46656465726174696f6e3a204e6f7420466564657261746f7200000000000000604082015260600190565b600089825288602083015260a06040830152611d4960a08301888a611757565b8281036060840152611d5c818789611757565b90508281036080840152611d71818587611757565b9b9a5050505050505050505050565b6001600160a01b03811681146106d757600080fdfea26469706673582212208aa1d2dd4590c44473c5e505bfb4d78ecb4c655a2f568f5eef1510b1514c437e64736f6c63430007060033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a95760003560e01c8063a481d59b116100f9578063ca6d56dc11610097578063ef1093a711610071578063ef1093a714610357578063f2fde38b1461035f578063f697aa2414610372578063fa6297ba14610385576101a9565b8063ca6d56dc14610334578063dc8452cd14610347578063e78cea921461034f576101a9565b8063b9a3b9dc116100d3578063b9a3b9dc146102e8578063ba51a6df146102fb578063c1f0808a1461030e578063c4d66de814610321576101a9565b8063a481d59b146102af578063a8e12e4c146102c2578063a93585f0146102d5576101a9565b80638da5cb5b116101665780639386775a116101405780639386775a146102615780639eab525314610274578063a1fb4acb14610289578063a230c5241461029c576101a9565b80638da5cb5b1461023e5780638dd14802146102465780638f32d59b14610259576101a9565b80630b1ca49a146101ae5780631b4613cb146101c357806354fd4d50146101ec5780635daf08ca14610201578063681fc92114610221578063715018a614610236575b600080fd5b6101c16101bc366004611456565b610398565b005b6101d66101d1366004611667565b6105a6565b6040516101e391906118c4565b60405180910390f35b6101f46105e2565b6040516101e391906118d8565b61021461020f366004611667565b6105fe565b6040516101e391906117df565b610229610628565b6040516101e391906118cf565b6101c161062d565b61021461069b565b6101c1610254366004611456565b6106aa565b6101d66106da565b6101d661026f36600461167f565b610700565b61027c610720565b6040516101e39190611877565b610229610297366004611667565b610782565b6101d66102aa366004611456565b6107f3565b6101c16102bd366004611456565b610808565b6101c16102d0366004611576565b610835565b6101d66102e3366004611667565b610aad565b6101c16102f63660046116ae565b610ac2565b6101c1610309366004611667565b610b67565b6101d661031c366004611667565b610c28565b6101c161032f366004611456565b610c3d565b6101c1610342366004611456565b610d02565b610229610e33565b610214610e39565b610214610e48565b6101c161036d366004611456565b610e57565b6101c1610380366004611472565b610e84565b610229610393366004611500565b61106a565b6103a06106da565b6103c55760405162461bcd60e51b81526004016103bc90611b8e565b60405180910390fd5b6001600160a01b0381166103eb5760405162461bcd60e51b81526004016103bc90611bfa565b6001600160a01b03811660009081526037602052604090205460ff166104235760405162461bcd60e51b81526004016103bc906119ce565b6035546001106104455760405162461bcd60e51b81526004016103bc90611c68565b60365460355460001901101561046d5760405162461bcd60e51b81526004016103bc90611b3d565b6001600160a01b0381166000908152603760205260408120805460ff191690555b6035546000190181101561054157816001600160a01b0316603582815481106104b357fe5b6000918252602090912001546001600160a01b03161415610539576035805460001981019081106104e057fe5b600091825260209091200154603580546001600160a01b03909216918390811061050657fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610541565b60010161048e565b50603580548061054d57fe5b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b6000818152603860205260408120816105bd6110ac565b6001600160a01b0316815260208101919091526040016000205460ff1690505b919050565b604080518082019091526002815261763360f01b602082015290565b6035818154811061060e57600080fd5b6000918252602090912001546001600160a01b0316905081565b603281565b6106356106da565b6106515760405162461bcd60e51b81526004016103bc90611b8e565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6106b26106da565b6106ce5760405162461bcd60e51b81526004016103bc90611b8e565b6106d7816110b0565b50565b6033546000906001600160a01b03166106f16110ac565b6001600160a01b031614905090565b603860209081526000928352604080842090915290825290205460ff1681565b6060603580548060200260200160405190810160405280929190818152602001828054801561077857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161075a575b5050505050905090565b600080805b6035548110156107ec57600084815260386020526040812060358054919291849081106107b057fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156107e4576001820191505b600101610787565b5092915050565b60376020526000908152604090205460ff1681565b6108106106da565b61082c5760405162461bcd60e51b81526004016103bc90611b8e565b6106d78161112c565b84518481811115801561084757508015155b801561085257508115155b61086e5760405162461bcd60e51b81526004016103bc9061192b565b600054610100900460ff1680610887575060005460ff16155b6108a35760405162461bcd60e51b81526004016103bc90611a0f565b600054610100900460ff161580156108ce576000805460ff1961ff0019909116610100171660011790555b6108d785610c3d565b6032885111156108f95760405162461bcd60e51b81526004016103bc90611997565b875161090c9060359060208b0190611376565b5060005b8851811015610a4157603760008a838151811061092957fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015610983575060006001600160a01b031689828151811061096f57fe5b60200260200101516001600160a01b031614155b61099f5760405162461bcd60e51b81526004016103bc90611a57565b6001603760008b84815181106109b157fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055508881815181106109fc57fe5b60200260200101516001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a2600101610910565b5060368790556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610a779089906118cf565b60405180910390a1610a88866110b0565b610a918461112c565b8015610aa3576000805461ff00191690555b5050505050505050565b60009081526039602052604090205460ff1690565b60376000610ace6110ac565b6001600160a01b0316815260208101919091526040016000205460ff16610b075760405162461bcd60e51b81526004016103bc90611cf2565b610b0f6110ac565b6001600160a01b03167fbb00e6cbdccbb5b7549e189335249187223d88583604555326aa1d7ccbcad4428989898989898989604051610b55989796959493929190611d29565b60405180910390a25050505050505050565b610b6f6106da565b610b8b5760405162461bcd60e51b81526004016103bc90611b8e565b60355481818111801590610b9e57508015155b8015610ba957508115155b610bc55760405162461bcd60e51b81526004016103bc9061192b565b6002831015610be65760405162461bcd60e51b81526004016103bc90611bc3565b60368390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610c1b9085906118cf565b60405180910390a1505050565b60396020526000908152604090205460ff1681565b600054610100900460ff1680610c56575060005460ff16155b610c725760405162461bcd60e51b81526004016103bc90611a0f565b600054610100900460ff16158015610c9d576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610cfe576000805461ff00191690555b5050565b610d0a6106da565b610d265760405162461bcd60e51b81526004016103bc90611b8e565b6001600160a01b038116610d4c5760405162461bcd60e51b81526004016103bc90611bfa565b6001600160a01b03811660009081526037602052604090205460ff1615610d855760405162461bcd60e51b81526004016103bc90611a8e565b603554603211610da75760405162461bcd60e51b81526004016103bc90611960565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b60365481565b6034546001600160a01b031681565b603a546001600160a01b031681565b610e5f6106da565b610e7b5760405162461bcd60e51b81526004016103bc90611b8e565b6106d78161119d565b60376000610e906110ac565b6001600160a01b0316815260208101919091526040016000205460ff16610ec95760405162461bcd60e51b81526004016103bc90611cf2565b6000610eda8989898989898961106a565b60008181526039602052604090205490915060ff1615610efa5750610aa3565b600081815260386020526040812090610f116110ac565b6001600160a01b0316815260208101919091526040016000205460ff1615610f395750610aa3565b6000818152603860205260408120600191610f526110ac565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558084610f846110ac565b6001600160a01b03167fd22894491aaa5bb67855bcff4b9730bdf7768be1e25f66ced9a7d7ad623bf2918c8c8c8c8c8b604051610fc696959493929190611839565b60405180910390a4610fd78161121f565b1561105f576000818152603960205260409020805460ff19166001179055611005898989898989898961124f565b808461100f6110ac565b6001600160a01b03167fe21e4d3d66ef78424137270e65cfafe938736bb770702ab4fd630383e7820b738c8c8c8c8c8b60405161105196959493929190611839565b60405180910390a450610aa3565b505050505050505050565b6000878787878787876040516020016110899796959493929190611781565b604051602081830303815290604052805190602001209050979650505050505050565b3390565b6001600160a01b0381166110d65760405162461bcd60e51b81526004016103bc90611acf565b603480546001600160a01b0319166001600160a01b0383161790556040517f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b92551782794497906111219083906117df565b60405180910390a150565b6001600160a01b0381166111525760405162461bcd60e51b81526004016103bc90611b06565b603a80546001600160a01b0319166001600160a01b0383161790556040517f41d363b5ede55d38b1fa8f7ba6188f9c20e353bc71e4a93de8938a20b27b6bc2906111219083906117df565b6001600160a01b0381166111c35760405162461bcd60e51b81526004016103bc90611cb0565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b60008061122b83610782565b905060365481101580156112485750603554600290046001018110155b9392505050565b600181600181111561125d57fe5b14156112fe57603a546001600160a01b031661128b5760405162461bcd60e51b81526004016103bc90611c31565b603a54604051636a86319160e01b81526001600160a01b0390911690636a863191906112c7908b908b908b908b908b908b908b906004016117f3565b600060405180830381600087803b1580156112e157600080fd5b505af11580156112f5573d6000803e3d6000fd5b50505050610aa3565b603454604051636a86319160e01b81526001600160a01b0390911690636a8631919061133a908b908b908b908b908b908b908b906004016117f3565b600060405180830381600087803b15801561135457600080fd5b505af1158015611368573d6000803e3d6000fd5b505050505050505050505050565b8280548282559060005260206000209081019282156113cb579160200282015b828111156113cb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190611396565b506113d79291506113db565b5090565b5b808211156113d757600081556001016113dc565b80356105dd81611d80565b60008083601f84011261140c578182fd5b50813567ffffffffffffffff811115611423578182fd5b60208301915083602082850101111561143b57600080fd5b9250929050565b803563ffffffff811681146105dd57600080fd5b600060208284031215611467578081fd5b813561124881611d80565b600080600080600080600080610100898b03121561148e578384fd5b883561149981611d80565b975060208901356114a981611d80565b965060408901356114b981611d80565b9550606089013594506080890135935060a089013592506114dc60c08a01611442565b915060e0890135600281106114ef578182fd5b809150509295985092959890939650565b600080600080600080600060e0888a03121561151a578283fd5b873561152581611d80565b9650602088013561153581611d80565b9550604088013561154581611d80565b9450606088013593506080880135925060a0880135915061156860c08901611442565b905092959891949750929550565b600080600080600060a0868803121561158d578081fd5b853567ffffffffffffffff808211156115a4578283fd5b818801915088601f8301126115b7578283fd5b81356020828211156115c557fe5b808202604051828282010181811086821117156115de57fe5b604052838152828101945085830182870184018e10156115fc578788fd5b8796505b8487101561162557611611816113f0565b865260019690960195948301948301611600565b50995050890135965061163f9250506040880190506113f0565b925061164d606087016113f0565b915061165b608087016113f0565b90509295509295909350565b600060208284031215611678578081fd5b5035919050565b60008060408385031215611691578182fd5b8235915060208301356116a381611d80565b809150509250929050565b60008060008060008060008060a0898b0312156116c9578384fd5b8835975060208901359650604089013567ffffffffffffffff808211156116ee578586fd5b6116fa8c838d016113fb565b909850965060608b0135915080821115611712578586fd5b61171e8c838d016113fb565b909650945060808b0135915080821115611736578384fd5b506117438b828c016113fb565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b606097881b6bffffffffffffffffffffffff19908116825296881b871660148201529490961b9094166028840152603c830191909152605c820152607c81019190915260e09190911b6001600160e01b031916609c82015260a00190565b6001600160a01b0391909116815260200190565b6001600160a01b03978816815295871660208701529390951660408501526060840191909152608083015260a082019290925263ffffffff90911660c082015260e00190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925263ffffffff90911660a082015260c00190565b6020808252825182820181905260009190848201906040850190845b818110156118b85783516001600160a01b031683529284019291840191600101611893565b50909695505050505050565b901515815260200190565b90815260200190565b6000602080835283518082850152825b81811015611904578581018301518582016040015282016118e8565b818111156119155783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f46656465726174696f6e3a20496e76616c696420726571756972656d656e7473604082015260600190565b6020808252601f908201527f46656465726174696f6e3a204d6178206d656d62657273207265616368656400604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20546f6f206d616e79206d656d6265727300000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746040820152607360f81b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252601b908201527f46656465726174696f6e3a20496e76616c6964206d656d626572730000000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746040820152607360f81b606082015260800190565b60208082526018908201527f46656465726174696f6e3a20456d707479206272696467650000000000000000604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20456d707479204e46542062726964676500000000604082015260600190565b60208082526031908201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604082015270207265717569726564206d656d6265727360781b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f46656465726174696f6e3a205265717569726573206174206c65617374203200604082015260600190565b60208082526018908201527f46656465726174696f6e3a20456d707479206d656d6265720000000000000000604082015260600190565b6020808252601b908201527f46656465726174696f6e3a20456d707479204e46544272696467650000000000604082015260600190565b60208082526028908201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604082015267206d656d6265727360c01b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526019908201527f46656465726174696f6e3a204e6f7420466564657261746f7200000000000000604082015260600190565b600089825288602083015260a06040830152611d4960a08301888a611757565b8281036060840152611d5c818789611757565b90508281036080840152611d71818587611757565b9b9a5050505050505050505050565b6001600160a01b03811681146106d757600080fdfea26469706673582212208aa1d2dd4590c44473c5e505bfb4d78ecb4c655a2f568f5eef1510b1514c437e64736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "addMember(address)": {
+ "params": {
+ "_newMember": "address of the new member"
+ }
+ },
+ "changeRequirement(uint256)": {
+ "details": "Emits the RequirementChange event",
+ "params": {
+ "_required": "the number of minimum members to approve an transaction, it has to be bigger than 1"
+ }
+ },
+ "emitHeartbeat(uint256,uint256,string,string,string)": {
+ "details": "Emits HeartBeat event"
+ },
+ "getMembers()": {
+ "returns": {
+ "_0": "Current members"
+ }
+ },
+ "getTransactionCount(bytes32)": {
+ "params": {
+ "transactionId": "The transaction hashed from getTransactionId function"
+ }
+ },
+ "getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32)": {
+ "details": "It encodes and applies keccak256 to the parameters received in the same order",
+ "params": {
+ "amount": "Could be the amount or the tokenId",
+ "blockHash": "The block hash in which the transaction with the cross event occurred",
+ "logIndex": "Index of the event in the logs",
+ "originalTokenAddress": "The address of the token in the origin (main) chain",
+ "receiver": "Who is going to receive the token in the opposite chain",
+ "sender": "The address who solicited the cross token",
+ "transactionHash": "The transaction in which the cross event occurred"
+ },
+ "returns": {
+ "_0": "The hash generated by the parameters."
+ }
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "removeMember(address)": {
+ "params": {
+ "_oldMember": "address of the member to be removed from federation"
+ }
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "setBridge(address)": {
+ "details": "Emits BridgeChanged event",
+ "params": {
+ "_bridge": "the new bridge contract address that should implement the IBridge interface"
+ }
+ },
+ "setNFTBridge(address)": {
+ "details": "Emits NFTBridgeChanged event",
+ "params": {
+ "_bridgeNFT": "the new NFT bridge contract address that should implement the INFTBridge interface"
+ }
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "version()": {
+ "returns": {
+ "_0": "version in v{Number}"
+ }
+ },
+ "voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint8)": {
+ "params": {
+ "blockHash": "The block hash in which the transaction with the cross event occurred",
+ "logIndex": "Index of the event in the logs",
+ "originalTokenAddress": "The address of the token in the origin (main) chain",
+ "receiver": "Who is going to receive the token in the opposite chain",
+ "sender": "The address who solicited the cross token",
+ "tokenType": "Is the type of bridge to be used",
+ "transactionHash": "The transaction in which the cross event occurred",
+ "value": "Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT"
+ }
+ }
+ },
+ "stateVariables": {
+ "isMember": {
+ "details": "The address should be a member to vote in transactions"
+ },
+ "required": {
+ "details": "It should have more members than the required amount"
+ },
+ "votes": {
+ "details": "usually the members should approve the transaction by 50% + 1"
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "addMember(address)": {
+ "notice": "Add a new member to the federation"
+ },
+ "bridgeNFT()": {
+ "notice": "Federator v3 variables "
+ },
+ "changeRequirement(uint256)": {
+ "notice": "Changes the number of required members to vote and approve an transaction"
+ },
+ "emitHeartbeat(uint256,uint256,string,string,string)": {
+ "notice": "It emits an HeartBeat like an health check"
+ },
+ "getMembers()": {
+ "notice": "Return all the current members of the federation"
+ },
+ "getTransactionCount(bytes32)": {
+ "notice": "Get the amount of approved votes for that transactionId"
+ },
+ "getTransactionId(address,address,address,uint256,bytes32,bytes32,uint32)": {
+ "notice": "Gets the hash of transaction from the following parameters encoded and keccaked"
+ },
+ "isMember(address)": {
+ "notice": "All the addresses that are members of the federation"
+ },
+ "processed(bytes32)": {
+ "notice": "(bytes32) transactionId => (bool) votedCheck if that transaction was already processed"
+ },
+ "removeMember(address)": {
+ "notice": "Remove a member of the federation"
+ },
+ "required()": {
+ "notice": "The minimum amount of votes to approve a transaction"
+ },
+ "setBridge(address)": {
+ "notice": "Sets a new bridge contract"
+ },
+ "setNFTBridge(address)": {
+ "notice": "Sets a new NFT bridge contract"
+ },
+ "version()": {
+ "notice": "Current version of the contract"
+ },
+ "voteTransaction(address,address,address,uint256,bytes32,bytes32,uint32,uint8)": {
+ "notice": "Vote in a transaction, if it has enough votes it accepts the transfer"
+ },
+ "votes(bytes32,address)": {
+ "notice": "(bytes32) transactionId = keccak256( abi.encodePacked( originalTokenAddress, sender, receiver, amount, blockHash, transactionHash, logIndex ) ) => ( (address) members => (bool) voted )Votes by members by the transaction ID"
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15789,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15792,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15832,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16076,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 4016,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "bridge",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_contract(IBridge)7398"
+ },
+ {
+ "astId": 4019,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "members",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 4022,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "required",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 4027,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "isMember",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 4034,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "votes",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_mapping(t_bytes32,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 4039,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "processed",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ },
+ {
+ "astId": 4042,
+ "contract": "contracts/Federation/Federation.sol:Federation",
+ "label": "bridgeNFT",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_contract(INFTBridge)7960"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IBridge)7398": {
+ "encoding": "inplace",
+ "label": "contract IBridge",
+ "numberOfBytes": "20"
+ },
+ "t_contract(INFTBridge)7960": {
+ "encoding": "inplace",
+ "label": "contract INFTBridge",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/FederationProxy.json b/bridge/deployments/rsktestnetrinkeby/FederationProxy.json
new file mode 100644
index 000000000..c0cc9414d
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/FederationProxy.json
@@ -0,0 +1,257 @@
+{
+ "address": "0xBC7a3f163b2fe1d6810a942417922F09F1fe82eD",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x01ebf7b7a03a29e32f145fd68e8f2560cb5d9d375b6626c7f397e8b6c23c81a8",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0xBC7a3f163b2fe1d6810a942417922F09F1fe82eD",
+ "transactionIndex": 0,
+ "gasUsed": "895606",
+ "logsBloom": "0x00000000020000000001000000008000000100000000000000800000000000000000000000000000000000000000000000000000000000000080000000000000000000800000000000000000000000100001000000000000000000000000000000000000020000000000000000040800000000000000000000000000000000400000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000008000008000000000000000000000004040000000000000000000000900000000000000000000000000000020000010000000000000000000000000000100000000000000000800000000000000",
+ "blockHash": "0x6ec4d9e9f8f2b74e1418ffd35dbf12930cffe4bb0c4fde0e6bbc4fe4b52dd580",
+ "transactionHash": "0x01ebf7b7a03a29e32f145fd68e8f2560cb5d9d375b6626c7f397e8b6c23c81a8",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170828,
+ "transactionHash": "0x01ebf7b7a03a29e32f145fd68e8f2560cb5d9d375b6626c7f397e8b6c23c81a8",
+ "address": "0xBC7a3f163b2fe1d6810a942417922F09F1fe82eD",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x00000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x6ec4d9e9f8f2b74e1418ffd35dbf12930cffe4bb0c4fde0e6bbc4fe4b52dd580"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170828,
+ "transactionHash": "0x01ebf7b7a03a29e32f145fd68e8f2560cb5d9d375b6626c7f397e8b6c23c81a8",
+ "address": "0xBC7a3f163b2fe1d6810a942417922F09F1fe82eD",
+ "topics": [
+ "0x72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c7",
+ "0x0000000000000000000000008f397ff074ff190fc650e5cab4da039a8163e12a"
+ ],
+ "data": "0x",
+ "logIndex": 1,
+ "blockHash": "0x6ec4d9e9f8f2b74e1418ffd35dbf12930cffe4bb0c4fde0e6bbc4fe4b52dd580"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170828,
+ "transactionHash": "0x01ebf7b7a03a29e32f145fd68e8f2560cb5d9d375b6626c7f397e8b6c23c81a8",
+ "address": "0xBC7a3f163b2fe1d6810a942417922F09F1fe82eD",
+ "topics": [
+ "0xa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a"
+ ],
+ "data": "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "logIndex": 2,
+ "blockHash": "0x6ec4d9e9f8f2b74e1418ffd35dbf12930cffe4bb0c4fde0e6bbc4fe4b52dd580"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170828,
+ "transactionHash": "0x01ebf7b7a03a29e32f145fd68e8f2560cb5d9d375b6626c7f397e8b6c23c81a8",
+ "address": "0xBC7a3f163b2fe1d6810a942417922F09F1fe82eD",
+ "topics": [
+ "0x9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b92551782794497"
+ ],
+ "data": "0x0000000000000000000000008c8a34fe13400169a8da50908dffde4985237d19",
+ "logIndex": 3,
+ "blockHash": "0x6ec4d9e9f8f2b74e1418ffd35dbf12930cffe4bb0c4fde0e6bbc4fe4b52dd580"
+ }
+ ],
+ "blockNumber": 2170828,
+ "cumulativeGasUsed": "895606",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0xBC383764ceBc13b66c04E1abeb36804a0Caaa5C6",
+ "0x8C35e166d2Dea7a8A28aaeA11AD7933cDae4b0aB",
+ "0xc1b4a1e3000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000008c8a34fe13400169a8da50908dffde4985237d1900000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000008f397ff074ff190fc650e5cab4da039a8163e12a"
+ ],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"stateVariables\":{\"_ADMIN_SLOT\":{\"details\":\"Storage slot with the admin of the contract. This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\r\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\r\\n * be specified by overriding the virtual {_implementation} function.\\r\\n *\\r\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\r\\n * different contract through the {_delegate} function.\\r\\n *\\r\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\r\\n */\\r\\nabstract contract Proxy {\\r\\n /**\\r\\n * @dev Delegates the current call to `implementation`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _delegate(address implementation) internal virtual {\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n // Copy msg.data. We take full control of memory in this inline assembly\\r\\n // block because it will not return to Solidity code. We overwrite the\\r\\n // Solidity scratch pad at memory position 0.\\r\\n calldatacopy(0, 0, calldatasize())\\r\\n\\r\\n // Call the implementation.\\r\\n // out and outsize are 0 because we don't know the size yet.\\r\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\r\\n\\r\\n // Copy the returned data.\\r\\n returndatacopy(0, 0, returndatasize())\\r\\n\\r\\n switch result\\r\\n // delegatecall returns 0 on error.\\r\\n case 0 { revert(0, returndatasize()) }\\r\\n default { return(0, returndatasize()) }\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\r\\n * and {_fallback} should delegate.\\r\\n */\\r\\n function _implementation() internal view virtual returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _fallback() internal virtual {\\r\\n _beforeFallback();\\r\\n _delegate(_implementation());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\r\\n * function in the contract matches the call data.\\r\\n */\\r\\n fallback () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\r\\n * is empty.\\r\\n */\\r\\n receive () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\r\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\r\\n *\\r\\n * If overriden should call `super._beforeFallback()`.\\r\\n */\\r\\n function _beforeFallback() internal virtual {\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x6374180266624d2291abb230bdf0d364858fa164844f5d2d83ad5325852390c9\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./UpgradeableProxy.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\r\\n *\\r\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\r\\n * clashing], which can potentially be used in an attack, this contract uses the\\r\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\r\\n * things that go hand in hand:\\r\\n *\\r\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\r\\n * that call matches one of the admin functions exposed by the proxy itself.\\r\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\r\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\r\\n * \\\"admin cannot fallback to proxy target\\\".\\r\\n *\\r\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\r\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\r\\n * to sudden errors when trying to call a function from the proxy implementation.\\r\\n *\\r\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\r\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\r\\n */\\r\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\r\\n /**\\r\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\r\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\r\\n */\\r\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\r\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\r\\n _setAdmin(admin_);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the admin account has changed.\\r\\n */\\r\\n event AdminChanged(address previousAdmin, address newAdmin);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the admin of the contract.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\r\\n\\r\\n /**\\r\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\r\\n */\\r\\n modifier ifAdmin() {\\r\\n if (msg.sender == _admin()) {\\r\\n _;\\r\\n } else {\\r\\n _fallback();\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\r\\n */\\r\\n function admin() external ifAdmin returns (address admin_) {\\r\\n admin_ = _admin();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\r\\n */\\r\\n function implementation() external ifAdmin returns (address implementation_) {\\r\\n implementation_ = _implementation();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Changes the admin of the proxy.\\r\\n *\\r\\n * Emits an {AdminChanged} event.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\r\\n */\\r\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\r\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\r\\n emit AdminChanged(_admin(), newAdmin);\\r\\n _setAdmin(newAdmin);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\r\\n */\\r\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\r\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\r\\n * proxied contract.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\r\\n */\\r\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n Address.functionDelegateCall(newImplementation, data);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n */\\r\\n function _admin() internal view virtual returns (address adm) {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n adm := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 admin slot.\\r\\n */\\r\\n function _setAdmin(address newAdmin) private {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newAdmin)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\r\\n */\\r\\n function _beforeFallback() internal virtual override {\\r\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\r\\n super._beforeFallback();\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x7496c2c54dd8e648d6999687cf759521e6ab229d0d8ddb4db62f3b51dbe68811\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./Proxy.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\r\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\r\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\r\\n * implementation behind the proxy.\\r\\n *\\r\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\r\\n * {TransparentUpgradeableProxy}.\\r\\n */\\r\\ncontract UpgradeableProxy is Proxy {\\r\\n /**\\r\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\r\\n *\\r\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\r\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\r\\n */\\r\\n constructor(address _logic, bytes memory _data) payable {\\r\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\r\\n _setImplementation(_logic);\\r\\n if(_data.length > 0) {\\r\\n Address.functionDelegateCall(_logic, _data);\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the implementation is upgraded.\\r\\n */\\r\\n event Upgraded(address indexed implementation);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the address of the current implementation.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation address.\\r\\n */\\r\\n function _implementation() internal view virtual override returns (address impl) {\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n impl := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrades the proxy to a new implementation.\\r\\n *\\r\\n * Emits an {Upgraded} event.\\r\\n */\\r\\n function _upgradeTo(address newImplementation) internal virtual {\\r\\n _setImplementation(newImplementation);\\r\\n emit Upgraded(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 implementation slot.\\r\\n */\\r\\n function _setImplementation(address newImplementation) private {\\r\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\r\\n\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newImplementation)\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x4d3fcb8487e53abb8658817c4b90038b24d81d0a32d989f03b54d4cfab929f62\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000c9f38038062000c9f83398101604081905262000026916200022e565b8281620000338262000071565b8051156200005457620000528282620000d360201b620002ca1760201c565b505b506200005d9050565b620000688262000102565b5050506200041d565b62000087816200012660201b620002f61760201c565b620000af5760405162461bcd60e51b8152600401620000a69062000347565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6060620000fb838360405180606001604052806027815260200162000c786027913962000130565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b60606200013d8462000126565b6200015c5760405162461bcd60e51b8152600401620000a690620003a4565b600080856001600160a01b031685604051620001799190620002f4565b600060405180830381855af49150503d8060008114620001b6576040519150601f19603f3d011682016040523d82523d6000602084013e620001bb565b606091505b509092509050620001ce828286620001d8565b9695505050505050565b60608315620001e9575081620000fb565b825115620001fa5782518084602001fd5b8160405162461bcd60e51b8152600401620000a6919062000312565b80516001600160a01b03811681146200012b57600080fd5b60008060006060848603121562000243578283fd5b6200024e8462000216565b92506200025e6020850162000216565b60408501519092506001600160401b03808211156200027b578283fd5b818601915086601f8301126200028f578283fd5b8151818111156200029c57fe5b604051601f8201601f191681016020018381118282101715620002bb57fe5b604052818152838201602001891015620002d3578485fd5b620002e6826020830160208701620003ea565b809450505050509250925092565b6000825162000308818460208701620003ea565b9190910192915050565b600060208252825180602084015262000333816040850160208701620003ea565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b8381101562000407578181015183820152602001620003ed565b8381111562000417576000848401525b50505050565b61084b806200042d6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209ba77a19de177ea34b608207423a21765cca1077e9d39a414a7175e09fb147e464736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209ba77a19de177ea34b608207423a21765cca1077e9d39a414a7175e09fb147e464736f6c63430007060033",
+ "devdoc": {
+ "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.",
+ "events": {
+ "AdminChanged(address,address)": {
+ "details": "Emitted when the admin account has changed."
+ }
+ },
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "constructor": {
+ "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "stateVariables": {
+ "_ADMIN_SLOT": {
+ "details": "Storage slot with the admin of the contract. This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/FederationV2.json b/bridge/deployments/rsktestnetrinkeby/FederationV2.json
new file mode 100644
index 000000000..74f385ff8
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/FederationV2.json
@@ -0,0 +1,905 @@
+{
+ "address": "0xBC383764ceBc13b66c04E1abeb36804a0Caaa5C6",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "bridge",
+ "type": "address"
+ }
+ ],
+ "name": "BridgeChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Executed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "HeartBeat",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "member",
+ "type": "address"
+ }
+ ],
+ "name": "MemberRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "federator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "Voted",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_MEMBER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_newMember",
+ "type": "address"
+ }
+ ],
+ "name": "addMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "bridge",
+ "outputs": [
+ {
+ "internalType": "contract IBridge",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "fedRskBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "fedEthBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "federatorVersion",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeRskInfo",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "nodeEthInfo",
+ "type": "string"
+ }
+ ],
+ "name": "emitHeartbeat",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getMembers",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "getTransactionId",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasVoted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_members",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isMember",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "members",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "processed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_oldMember",
+ "type": "address"
+ }
+ ],
+ "name": "removeMember",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_bridge",
+ "type": "address"
+ }
+ ],
+ "name": "setBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionWasProcessed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "voteTransaction",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "votes",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xaa8ea0fb005b3b828ecc4d56b300b4df25dd2577d100554b0e850824523a3206",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0xBC383764ceBc13b66c04E1abeb36804a0Caaa5C6",
+ "transactionIndex": 0,
+ "gasUsed": "1897118",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x3d7e0cbd379cf5a0ed55729097652fcee65be57aa579b2f3bc0193f133067c11",
+ "transactionHash": "0xaa8ea0fb005b3b828ecc4d56b300b4df25dd2577d100554b0e850824523a3206",
+ "logs": [],
+ "blockNumber": 2170827,
+ "cumulativeGasUsed": "1897118",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"bridge\",\"type\":\"address\"}],\"name\":\"BridgeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"Executed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fedRskBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fedEthBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"federatorVersion\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"nodeRskInfo\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"nodeEthInfo\",\"type\":\"string\"}],\"name\":\"HeartBeat\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"}],\"name\":\"MemberRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"federator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"Voted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MEMBER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newMember\",\"type\":\"address\"}],\"name\":\"addMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contract IBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fedRskBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fedEthBlock\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"federatorVersion\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nodeRskInfo\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nodeEthInfo\",\"type\":\"string\"}],\"name\":\"emitHeartbeat\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMembers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"getTransactionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"hasVoted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_members\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMember\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"members\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"processed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_oldMember\",\"type\":\"address\"}],\"name\":\"removeMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"name\":\"setBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionId\",\"type\":\"bytes32\"}],\"name\":\"transactionWasProcessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"name\":\"voteTransaction\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"votes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Federation/FederationV2.sol\":\"FederationV2\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Federation/FederationV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n// Upgradables\\r\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\r\\n\\r\\nimport \\\"../interface/IBridge.sol\\\";\\r\\n\\r\\ncontract FederationV2 is Initializable, UpgradableOwnable {\\r\\n uint constant public MAX_MEMBER_COUNT = 50;\\r\\n address constant private NULL_ADDRESS = address(0);\\r\\n\\r\\n IBridge public bridge;\\r\\n address[] public members;\\r\\n uint public required;\\r\\n\\r\\n mapping (address => bool) public isMember;\\r\\n mapping (bytes32 => mapping (address => bool)) public votes;\\r\\n mapping(bytes32 => bool) public processed;\\r\\n\\r\\n event Executed(\\r\\n address indexed federator,\\r\\n bytes32 indexed transactionHash,\\r\\n bytes32 indexed transactionId,\\r\\n address originalTokenAddress,\\r\\n address sender,\\r\\n address receiver,\\r\\n uint256 amount,\\r\\n bytes32 blockHash,\\r\\n uint32 logIndex\\r\\n );\\r\\n event MemberAddition(address indexed member);\\r\\n event MemberRemoval(address indexed member);\\r\\n event RequirementChange(uint required);\\r\\n event BridgeChanged(address bridge);\\r\\n event Voted(\\r\\n address indexed federator,\\r\\n bytes32 indexed transactionHash,\\r\\n bytes32 indexed transactionId,\\r\\n address originalTokenAddress,\\r\\n address sender,\\r\\n address receiver,\\r\\n uint256 amount,\\r\\n bytes32 blockHash,\\r\\n uint32 logIndex\\r\\n );\\r\\n event HeartBeat(\\r\\n address indexed sender,\\r\\n uint256 fedRskBlock,\\r\\n uint256 fedEthBlock,\\r\\n string federatorVersion,\\r\\n string nodeRskInfo,\\r\\n string nodeEthInfo\\r\\n );\\r\\n\\r\\n modifier onlyMember() {\\r\\n require(isMember[_msgSender()], \\\"Federation: Not Federator\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier validRequirement(uint membersCount, uint _required) {\\r\\n // solium-disable-next-line max-len\\r\\n require(_required <= membersCount && _required != 0 && membersCount != 0, \\\"Federation: Invalid requirements\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\\r\\n public validRequirement(_members.length, _required) initializer {\\r\\n UpgradableOwnable.initialize(owner);\\r\\n require(_members.length <= MAX_MEMBER_COUNT, \\\"Federation: Too many members\\\");\\r\\n members = _members;\\r\\n for (uint i = 0; i < _members.length; i++) {\\r\\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \\\"Federation: Invalid members\\\");\\r\\n isMember[_members[i]] = true;\\r\\n emit MemberAddition(_members[i]);\\r\\n }\\r\\n required = _required;\\r\\n emit RequirementChange(required);\\r\\n _setBridge(_bridge);\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory) {\\r\\n return \\\"v2\\\";\\r\\n }\\r\\n\\r\\n function setBridge(address _bridge) external onlyOwner {\\r\\n _setBridge(_bridge);\\r\\n }\\r\\n\\r\\n function _setBridge(address _bridge) internal {\\r\\n require(_bridge != NULL_ADDRESS, \\\"Federation: Empty bridge\\\");\\r\\n bridge = IBridge(_bridge);\\r\\n emit BridgeChanged(_bridge);\\r\\n }\\r\\n\\r\\n function voteTransaction(\\r\\n address originalTokenAddress,\\r\\n address payable sender,\\r\\n address payable receiver,\\r\\n uint256 amount,\\r\\n bytes32 blockHash,\\r\\n bytes32 transactionHash,\\r\\n uint32 logIndex\\r\\n )\\r\\n public onlyMember returns(bool)\\r\\n {\\r\\n bytes32 transactionId = getTransactionId(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n amount,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n );\\r\\n if (processed[transactionId])\\r\\n return true;\\r\\n\\r\\n if (votes[transactionId][_msgSender()])\\r\\n return true;\\r\\n\\r\\n votes[transactionId][_msgSender()] = true;\\r\\n emit Voted(\\r\\n _msgSender(),\\r\\n transactionHash,\\r\\n transactionId,\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n amount,\\r\\n blockHash,\\r\\n logIndex\\r\\n );\\r\\n\\r\\n uint transactionCount = getTransactionCount(transactionId);\\r\\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\\r\\n processed[transactionId] = true;\\r\\n bridge.acceptTransfer(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n amount,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n );\\r\\n emit Executed(\\r\\n _msgSender(),\\r\\n transactionHash,\\r\\n transactionId,\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n amount,\\r\\n blockHash,\\r\\n logIndex\\r\\n );\\r\\n return true;\\r\\n }\\r\\n\\r\\n return true;\\r\\n }\\r\\n\\r\\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\\r\\n uint count = 0;\\r\\n for (uint i = 0; i < members.length; i++) {\\r\\n if (votes[transactionId][members[i]])\\r\\n count += 1;\\r\\n }\\r\\n return count;\\r\\n }\\r\\n\\r\\n function hasVoted(bytes32 transactionId) external view returns(bool)\\r\\n {\\r\\n return votes[transactionId][_msgSender()];\\r\\n }\\r\\n\\r\\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\\r\\n {\\r\\n return processed[transactionId];\\r\\n }\\r\\n\\r\\n function getTransactionId(\\r\\n address originalTokenAddress,\\r\\n address sender,\\r\\n address receiver,\\r\\n uint256 amount,\\r\\n bytes32 blockHash,\\r\\n bytes32 transactionHash,\\r\\n uint32 logIndex\\r\\n ) public pure returns(bytes32)\\r\\n {\\r\\n return keccak256(\\r\\n abi.encodePacked(\\r\\n originalTokenAddress,\\r\\n sender,\\r\\n receiver,\\r\\n amount,\\r\\n blockHash,\\r\\n transactionHash,\\r\\n logIndex\\r\\n )\\r\\n );\\r\\n }\\r\\n\\r\\n function addMember(address _newMember) external onlyOwner\\r\\n {\\r\\n require(_newMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\r\\n require(!isMember[_newMember], \\\"Federation: Member already exists\\\");\\r\\n require(members.length < MAX_MEMBER_COUNT, \\\"Federation: Max members reached\\\");\\r\\n\\r\\n isMember[_newMember] = true;\\r\\n members.push(_newMember);\\r\\n emit MemberAddition(_newMember);\\r\\n }\\r\\n\\r\\n function removeMember(address _oldMember) external onlyOwner\\r\\n {\\r\\n require(_oldMember != NULL_ADDRESS, \\\"Federation: Empty member\\\");\\r\\n require(isMember[_oldMember], \\\"Federation: Member doesn't exists\\\");\\r\\n require(members.length > 1, \\\"Federation: Can't remove all the members\\\");\\r\\n require(members.length - 1 >= required, \\\"Federation: Can't have less than required members\\\");\\r\\n\\r\\n isMember[_oldMember] = false;\\r\\n for (uint i = 0; i < members.length - 1; i++) {\\r\\n if (members[i] == _oldMember) {\\r\\n members[i] = members[members.length - 1];\\r\\n break;\\r\\n }\\r\\n }\\r\\n members.pop(); // remove an element from the end of the array.\\r\\n emit MemberRemoval(_oldMember);\\r\\n }\\r\\n\\r\\n function getMembers() external view returns (address[] memory)\\r\\n {\\r\\n return members;\\r\\n }\\r\\n\\r\\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\\r\\n {\\r\\n require(_required >= 2, \\\"Federation: Requires at least 2\\\");\\r\\n required = _required;\\r\\n emit RequirementChange(_required);\\r\\n }\\r\\n\\r\\n function emitHeartbeat(\\r\\n uint256 fedRskBlock,\\r\\n uint256 fedEthBlock,\\r\\n string calldata federatorVersion,\\r\\n string calldata nodeRskInfo,\\r\\n string calldata nodeEthInfo\\r\\n ) external onlyMember {\\r\\n emit HeartBeat(\\r\\n _msgSender(),\\r\\n fedRskBlock,\\r\\n fedEthBlock,\\r\\n federatorVersion,\\r\\n nodeRskInfo,\\r\\n nodeEthInfo\\r\\n );\\r\\n }\\r\\n}\",\"keccak256\":\"0xaf2beb2559b7db4dc06994cc8b3518aa78b74ee6db87ea30df64597fd5aa3a7d\",\"license\":\"MIT\"},\"contracts/interface/IBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IBridge {\\r\\n\\r\\n struct ClaimData {\\r\\n address payable to;\\r\\n uint256 amount;\\r\\n bytes32 blockHash;\\r\\n bytes32 transactionHash;\\r\\n uint32 logIndex;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getFeePercentage() external view returns(uint);\\r\\n\\r\\n /**\\r\\n * ERC-20 tokens approve and transferFrom pattern\\r\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\r\\n */\\r\\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\\r\\n\\r\\n /**\\r\\n * Use network currency and cross it.\\r\\n */\\r\\n function depositTo(address to) external payable;\\r\\n\\r\\n /**\\r\\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\\r\\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\\r\\n */\\r\\n function tokensReceived (\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\r\\n */\\r\\n function acceptTransfer(\\r\\n address _originalTokenAddress,\\r\\n address payable _from,\\r\\n address payable _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\\r\\n */\\r\\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\r\\n\\r\\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\\r\\n\\r\\n function claimGasless(\\r\\n ClaimData calldata _claimData,\\r\\n address payable _relayer,\\r\\n uint256 _fee,\\r\\n uint256 _deadline,\\r\\n uint8 _v,\\r\\n bytes32 _r,\\r\\n bytes32 _s\\r\\n ) external returns (uint256 receivedAmount);\\r\\n\\r\\n function getTransactionDataHash(\\r\\n address _to,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external returns(bytes32);\\r\\n\\r\\n event Cross(\\r\\n address indexed _tokenAddress,\\r\\n address indexed _from,\\r\\n address indexed _to,\\r\\n uint256 _amount,\\r\\n bytes _userData\\r\\n );\\r\\n event NewSideToken(\\r\\n address indexed _newSideTokenAddress,\\r\\n address indexed _originalTokenAddress,\\r\\n string _newSymbol,\\r\\n uint256 _granularity\\r\\n );\\r\\n event AcceptedCrossTransfer(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _from,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex\\r\\n );\\r\\n event FeePercentageChanged(uint256 _amount);\\r\\n event Claimed(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _sender,\\r\\n uint256 _amount,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex,\\r\\n address _reciever,\\r\\n address _relayer,\\r\\n uint256 _fee\\r\\n );\\r\\n}\",\"keccak256\":\"0x9e48ff075a1e3fd0533feec4b93f397a4678b5d267cbae021ea0faf8cc91a383\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @title Initializable\\r\\n *\\r\\n * @dev Helper contract to support initializer functions. To use it, replace\\r\\n * the constructor with a function that has the `initializer` modifier.\\r\\n * WARNING: Unlike constructors, initializer functions must be manually\\r\\n * invoked. This applies both to deploying an Initializable contract, as well\\r\\n * as extending an Initializable contract via inheritance.\\r\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\r\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\r\\n * because this is not dealt with automatically as with constructors.\\r\\n */\\r\\ncontract Initializable {\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract has been initialized.\\r\\n */\\r\\n bool private initialized;\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract is in the process of being initialized.\\r\\n */\\r\\n bool private initializing;\\r\\n\\r\\n /**\\r\\n * @dev Modifier to use in the initializer function of a contract.\\r\\n */\\r\\n modifier initializer() {\\r\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\r\\n\\r\\n bool isTopLevelCall = !initializing;\\r\\n if (isTopLevelCall) {\\r\\n initializing = true;\\r\\n initialized = true;\\r\\n }\\r\\n\\r\\n _;\\r\\n\\r\\n if (isTopLevelCall) {\\r\\n initializing = false;\\r\\n }\\r\\n }\\r\\n\\r\\n // Reserved storage space to allow for layout changes in the future.\\r\\n uint256[50] private ______gap;\\r\\n}\",\"keccak256\":\"0xc1f4d917648f0e17ba6a023a168173ad6163f3120e24d1c97ae294430e42eaf3\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Contract module which provides a basic access control mechanism, where\\r\\n * there is an account (an owner) that can be granted exclusive access to\\r\\n * specific functions.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the modifier\\r\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\r\\n * the owner.\\r\\n */\\r\\ncontract UpgradableOwnable is Initializable, Context {\\r\\n address private _owner;\\r\\n\\r\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract setting the deployer as the initial owner.\\r\\n */\\r\\n function initialize(address sender) public initializer {\\r\\n _owner = sender;\\r\\n emit OwnershipTransferred(address(0), _owner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the address of the current owner.\\r\\n */\\r\\n function owner() public view returns (address) {\\r\\n return _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Throws if called by any account other than the owner.\\r\\n */\\r\\n modifier onlyOwner() {\\r\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the caller is the current owner.\\r\\n */\\r\\n function isOwner() public view returns (bool) {\\r\\n return _msgSender() == _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Leaves the contract without owner. It will not be possible to call\\r\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\r\\n *\\r\\n * > Note: Renouncing ownership will leave the contract without an owner,\\r\\n * thereby removing any functionality that is only available to the owner.\\r\\n */\\r\\n function renounceOwnership() public onlyOwner {\\r\\n emit OwnershipTransferred(_owner, address(0));\\r\\n _owner = address(0);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n * Can only be called by the current owner.\\r\\n */\\r\\n function transferOwnership(address newOwner) public onlyOwner {\\r\\n _transferOwnership(newOwner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n */\\r\\n function _transferOwnership(address newOwner) internal {\\r\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\r\\n emit OwnershipTransferred(_owner, newOwner);\\r\\n _owner = newOwner;\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0xea920007e371a3300245b5885f72cecc472c4780818365f0025fae65a767273d\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50611afa806100206000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063a1fb4acb116100de578063c1f0808a11610097578063dc8452cd11610071578063dc8452cd14610311578063e78cea9214610319578063f2fde38b14610321578063fa6297ba1461033457610173565b8063c1f0808a146102d8578063c4d66de8146102eb578063ca6d56dc146102fe57610173565b8063a1fb4acb14610266578063a230c52414610279578063a93585f01461028c578063b9a3b9dc1461029f578063ba51a6df146102b2578063c1b4a1e3146102c557610173565b8063715018a611610130578063715018a6146102135780638da5cb5b1461021b5780638dd14802146102235780638f32d59b146102365780639386775a1461023e5780639eab52531461025157610173565b80630b1ca49a146101785780631b4613cb1461018d57806335d4aa9e146101b657806354fd4d50146101c95780635daf08ca146101de578063681fc921146101fe575b600080fd5b61018b61018636600461128b565b610347565b005b6101a061019b366004611404565b610555565b6040516101ad9190611661565b60405180910390f35b6101a06101c43660046112ae565b610591565b6101d161080b565b6040516101ad9190611675565b6101f16101ec366004611404565b610827565b6040516101ad919061157c565b610206610851565b6040516101ad919061166c565b61018b610856565b6101f16108c4565b61018b61023136600461128b565b6108d3565b6101a0610903565b6101a061024c36600461141c565b610929565b610259610949565b6040516101ad9190611614565b610206610274366004611404565b6109ab565b6101a061028736600461128b565b610a1c565b6101a061029a366004611404565b610a31565b61018b6102ad36600461144b565b610a46565b61018b6102c0366004611404565b610aeb565b61018b6102d3366004611324565b610bac565b6101a06102e6366004611404565b610e1a565b61018b6102f936600461128b565b610e2f565b61018b61030c36600461128b565b610ef4565b610206611025565b6101f161102b565b61018b61032f36600461128b565b61103a565b6102066103423660046112ae565b611067565b61034f610903565b6103745760405162461bcd60e51b815260040161036b906118f4565b60405180910390fd5b6001600160a01b03811661039a5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff166103d25760405162461bcd60e51b815260040161036b9061176b565b6035546001106103f45760405162461bcd60e51b815260040161036b90611997565b60365460355460001901101561041c5760405162461bcd60e51b815260040161036b906118a3565b6001600160a01b0381166000908152603760205260408120805460ff191690555b603554600019018110156104f057816001600160a01b03166035828154811061046257fe5b6000918252602090912001546001600160a01b031614156104e85760358054600019810190811061048f57fe5b600091825260209091200154603580546001600160a01b0390921691839081106104b557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506104f0565b60010161043d565b5060358054806104fc57fe5b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b60008181526038602052604081208161056c6110a9565b6001600160a01b0316815260208101919091526040016000205460ff1690505b919050565b60006037600061059f6110a9565b6001600160a01b0316815260208101919091526040016000205460ff166105d85760405162461bcd60e51b815260040161036b90611a21565b60006105e989898989898989611067565b60008181526039602052604090205490915060ff161561060d576001915050610800565b6000818152603860205260408120906106246110a9565b6001600160a01b0316815260208101919091526040016000205460ff1615610650576001915050610800565b60008181526038602052604081206001916106696110a9565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055808461069b6110a9565b6001600160a01b03167fd22894491aaa5bb67855bcff4b9730bdf7768be1e25f66ced9a7d7ad623bf2918c8c8c8c8c8b6040516106dd969594939291906115d6565b60405180910390a460006106f0826109ab565b9050603654811015801561070d5750603554600290046001018110155b156107f95760008281526039602052604090819020805460ff191660011790556034549051636a86319160e01b81526001600160a01b0390911690636a86319190610768908d908d908d908d908d908d908d90600401611590565b600060405180830381600087803b15801561078257600080fd5b505af1158015610796573d6000803e3d6000fd5b5050505081856107a46110a9565b6001600160a01b03167fe21e4d3d66ef78424137270e65cfafe938736bb770702ab4fd630383e7820b738d8d8d8d8d8c6040516107e6969594939291906115d6565b60405180910390a4600192505050610800565b6001925050505b979650505050505050565b6040805180820190915260028152613b1960f11b602082015290565b6035818154811061083757600080fd5b6000918252602090912001546001600160a01b0316905081565b603281565b61085e610903565b61087a5760405162461bcd60e51b815260040161036b906118f4565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6108db610903565b6108f75760405162461bcd60e51b815260040161036b906118f4565b610900816110ad565b50565b6033546000906001600160a01b031661091a6110a9565b6001600160a01b031614905090565b603860209081526000928352604080842090915290825290205460ff1681565b606060358054806020026020016040519081016040528092919081815260200182805480156109a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610983575b5050505050905090565b600080805b603554811015610a1557600084815260386020526040812060358054919291849081106109d957fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0d576001820191505b6001016109b0565b5092915050565b60376020526000908152604090205460ff1681565b60009081526039602052604090205460ff1690565b60376000610a526110a9565b6001600160a01b0316815260208101919091526040016000205460ff16610a8b5760405162461bcd60e51b815260040161036b90611a21565b610a936110a9565b6001600160a01b03167fbb00e6cbdccbb5b7549e189335249187223d88583604555326aa1d7ccbcad4428989898989898989604051610ad9989796959493929190611a58565b60405180910390a25050505050505050565b610af3610903565b610b0f5760405162461bcd60e51b815260040161036b906118f4565b60355481818111801590610b2257508015155b8015610b2d57508115155b610b495760405162461bcd60e51b815260040161036b906116c8565b6002831015610b6a5760405162461bcd60e51b815260040161036b90611929565b60368390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610b9f90859061166c565b60405180910390a1505050565b835183818111158015610bbe57508015155b8015610bc957508115155b610be55760405162461bcd60e51b815260040161036b906116c8565b600054610100900460ff1680610bfe575060005460ff16155b610c1a5760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610c45576000805460ff1961ff0019909116610100171660011790555b610c4e84610e2f565b603287511115610c705760405162461bcd60e51b815260040161036b90611734565b8651610c839060359060208a01906111ab565b5060005b8751811015610db85760376000898381518110610ca057fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015610cfa575060006001600160a01b0316888281518110610ce657fe5b60200260200101516001600160a01b031614155b610d165760405162461bcd60e51b815260040161036b906117f4565b6001603760008a8481518110610d2857fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550878181518110610d7357fe5b60200260200101516001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a2600101610c87565b5060368690556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610dee90889061166c565b60405180910390a1610dff856110ad565b8015610e11576000805461ff00191690555b50505050505050565b60396020526000908152604090205460ff1681565b600054610100900460ff1680610e48575060005460ff16155b610e645760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610e8f576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610ef0576000805461ff00191690555b5050565b610efc610903565b610f185760405162461bcd60e51b815260040161036b906118f4565b6001600160a01b038116610f3e5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff1615610f775760405162461bcd60e51b815260040161036b9061182b565b603554603211610f995760405162461bcd60e51b815260040161036b906116fd565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b60365481565b6034546001600160a01b031681565b611042610903565b61105e5760405162461bcd60e51b815260040161036b906118f4565b61090081611129565b600087878787878787604051602001611086979695949392919061151e565b604051602081830303815290604052805190602001209050979650505050505050565b3390565b6001600160a01b0381166110d35760405162461bcd60e51b815260040161036b9061186c565b603480546001600160a01b0319166001600160a01b0383161790556040517f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b925517827944979061111e90839061157c565b60405180910390a150565b6001600160a01b03811661114f5760405162461bcd60e51b815260040161036b906119df565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b828054828255906000526020600020908101928215611200579160200282015b8281111561120057825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906111cb565b5061120c929150611210565b5090565b5b8082111561120c5760008155600101611211565b803561058c81611aaf565b60008083601f840112611241578182fd5b50813567ffffffffffffffff811115611258578182fd5b60208301915083602082850101111561127057600080fd5b9250929050565b803563ffffffff8116811461058c57600080fd5b60006020828403121561129c578081fd5b81356112a781611aaf565b9392505050565b600080600080600080600060e0888a0312156112c8578283fd5b87356112d381611aaf565b965060208801356112e381611aaf565b955060408801356112f381611aaf565b9450606088013593506080880135925060a0880135915061131660c08901611277565b905092959891949750929550565b60008060008060808587031215611339578384fd5b843567ffffffffffffffff80821115611350578586fd5b818701915087601f830112611363578586fd5b813560208282111561137157fe5b8082026040518282820101818110868211171561138a57fe5b604052838152828101945085830182870184018d10156113a8578a8bfd5b8a96505b848710156113d1576113bd81611225565b8652600196909601959483019483016113ac565b5098505088013595506113eb925050604087019050611225565b91506113f960608601611225565b905092959194509250565b600060208284031215611415578081fd5b5035919050565b6000806040838503121561142e578182fd5b82359150602083013561144081611aaf565b809150509250929050565b60008060008060008060008060a0898b031215611466578081fd5b8835975060208901359650604089013567ffffffffffffffff8082111561148b578283fd5b6114978c838d01611230565b909850965060608b01359150808211156114af578283fd5b6114bb8c838d01611230565b909650945060808b01359150808211156114d3578283fd5b506114e08b828c01611230565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b606097881b6bffffffffffffffffffffffff19908116825296881b871660148201529490961b9094166028840152603c830191909152605c820152607c81019190915260e09190911b6001600160e01b031916609c82015260a00190565b6001600160a01b0391909116815260200190565b6001600160a01b03978816815295871660208701529390951660408501526060840191909152608083015260a082019290925263ffffffff90911660c082015260e00190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925263ffffffff90911660a082015260c00190565b6020808252825182820181905260009190848201906040850190845b818110156116555783516001600160a01b031683529284019291840191600101611630565b50909695505050505050565b901515815260200190565b90815260200190565b6000602080835283518082850152825b818110156116a157858101830151858201604001528201611685565b818111156116b25783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f46656465726174696f6e3a20496e76616c696420726571756972656d656e7473604082015260600190565b6020808252601f908201527f46656465726174696f6e3a204d6178206d656d62657273207265616368656400604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20546f6f206d616e79206d656d6265727300000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746040820152607360f81b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252601b908201527f46656465726174696f6e3a20496e76616c6964206d656d626572730000000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746040820152607360f81b606082015260800190565b60208082526018908201527f46656465726174696f6e3a20456d707479206272696467650000000000000000604082015260600190565b60208082526031908201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604082015270207265717569726564206d656d6265727360781b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f46656465726174696f6e3a205265717569726573206174206c65617374203200604082015260600190565b60208082526018908201527f46656465726174696f6e3a20456d707479206d656d6265720000000000000000604082015260600190565b60208082526028908201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604082015267206d656d6265727360c01b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526019908201527f46656465726174696f6e3a204e6f7420466564657261746f7200000000000000604082015260600190565b600089825288602083015260a06040830152611a7860a08301888a6114f4565b8281036060840152611a8b8187896114f4565b90508281036080840152611aa08185876114f4565b9b9a5050505050505050505050565b6001600160a01b038116811461090057600080fdfea26469706673582212201ed28c73ed4ae70ef955780ff1194179b97395123f029d2daf12887f3e16603c64736f6c63430007060033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101735760003560e01c8063a1fb4acb116100de578063c1f0808a11610097578063dc8452cd11610071578063dc8452cd14610311578063e78cea9214610319578063f2fde38b14610321578063fa6297ba1461033457610173565b8063c1f0808a146102d8578063c4d66de8146102eb578063ca6d56dc146102fe57610173565b8063a1fb4acb14610266578063a230c52414610279578063a93585f01461028c578063b9a3b9dc1461029f578063ba51a6df146102b2578063c1b4a1e3146102c557610173565b8063715018a611610130578063715018a6146102135780638da5cb5b1461021b5780638dd14802146102235780638f32d59b146102365780639386775a1461023e5780639eab52531461025157610173565b80630b1ca49a146101785780631b4613cb1461018d57806335d4aa9e146101b657806354fd4d50146101c95780635daf08ca146101de578063681fc921146101fe575b600080fd5b61018b61018636600461128b565b610347565b005b6101a061019b366004611404565b610555565b6040516101ad9190611661565b60405180910390f35b6101a06101c43660046112ae565b610591565b6101d161080b565b6040516101ad9190611675565b6101f16101ec366004611404565b610827565b6040516101ad919061157c565b610206610851565b6040516101ad919061166c565b61018b610856565b6101f16108c4565b61018b61023136600461128b565b6108d3565b6101a0610903565b6101a061024c36600461141c565b610929565b610259610949565b6040516101ad9190611614565b610206610274366004611404565b6109ab565b6101a061028736600461128b565b610a1c565b6101a061029a366004611404565b610a31565b61018b6102ad36600461144b565b610a46565b61018b6102c0366004611404565b610aeb565b61018b6102d3366004611324565b610bac565b6101a06102e6366004611404565b610e1a565b61018b6102f936600461128b565b610e2f565b61018b61030c36600461128b565b610ef4565b610206611025565b6101f161102b565b61018b61032f36600461128b565b61103a565b6102066103423660046112ae565b611067565b61034f610903565b6103745760405162461bcd60e51b815260040161036b906118f4565b60405180910390fd5b6001600160a01b03811661039a5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff166103d25760405162461bcd60e51b815260040161036b9061176b565b6035546001106103f45760405162461bcd60e51b815260040161036b90611997565b60365460355460001901101561041c5760405162461bcd60e51b815260040161036b906118a3565b6001600160a01b0381166000908152603760205260408120805460ff191690555b603554600019018110156104f057816001600160a01b03166035828154811061046257fe5b6000918252602090912001546001600160a01b031614156104e85760358054600019810190811061048f57fe5b600091825260209091200154603580546001600160a01b0390921691839081106104b557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506104f0565b60010161043d565b5060358054806104fc57fe5b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f270bfc616dd36d5cb6b35aac93e6ef22b089c34e6f6ad6f0892797424840897b91a250565b60008181526038602052604081208161056c6110a9565b6001600160a01b0316815260208101919091526040016000205460ff1690505b919050565b60006037600061059f6110a9565b6001600160a01b0316815260208101919091526040016000205460ff166105d85760405162461bcd60e51b815260040161036b90611a21565b60006105e989898989898989611067565b60008181526039602052604090205490915060ff161561060d576001915050610800565b6000818152603860205260408120906106246110a9565b6001600160a01b0316815260208101919091526040016000205460ff1615610650576001915050610800565b60008181526038602052604081206001916106696110a9565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055808461069b6110a9565b6001600160a01b03167fd22894491aaa5bb67855bcff4b9730bdf7768be1e25f66ced9a7d7ad623bf2918c8c8c8c8c8b6040516106dd969594939291906115d6565b60405180910390a460006106f0826109ab565b9050603654811015801561070d5750603554600290046001018110155b156107f95760008281526039602052604090819020805460ff191660011790556034549051636a86319160e01b81526001600160a01b0390911690636a86319190610768908d908d908d908d908d908d908d90600401611590565b600060405180830381600087803b15801561078257600080fd5b505af1158015610796573d6000803e3d6000fd5b5050505081856107a46110a9565b6001600160a01b03167fe21e4d3d66ef78424137270e65cfafe938736bb770702ab4fd630383e7820b738d8d8d8d8d8c6040516107e6969594939291906115d6565b60405180910390a4600192505050610800565b6001925050505b979650505050505050565b6040805180820190915260028152613b1960f11b602082015290565b6035818154811061083757600080fd5b6000918252602090912001546001600160a01b0316905081565b603281565b61085e610903565b61087a5760405162461bcd60e51b815260040161036b906118f4565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b6108db610903565b6108f75760405162461bcd60e51b815260040161036b906118f4565b610900816110ad565b50565b6033546000906001600160a01b031661091a6110a9565b6001600160a01b031614905090565b603860209081526000928352604080842090915290825290205460ff1681565b606060358054806020026020016040519081016040528092919081815260200182805480156109a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610983575b5050505050905090565b600080805b603554811015610a1557600084815260386020526040812060358054919291849081106109d957fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0d576001820191505b6001016109b0565b5092915050565b60376020526000908152604090205460ff1681565b60009081526039602052604090205460ff1690565b60376000610a526110a9565b6001600160a01b0316815260208101919091526040016000205460ff16610a8b5760405162461bcd60e51b815260040161036b90611a21565b610a936110a9565b6001600160a01b03167fbb00e6cbdccbb5b7549e189335249187223d88583604555326aa1d7ccbcad4428989898989898989604051610ad9989796959493929190611a58565b60405180910390a25050505050505050565b610af3610903565b610b0f5760405162461bcd60e51b815260040161036b906118f4565b60355481818111801590610b2257508015155b8015610b2d57508115155b610b495760405162461bcd60e51b815260040161036b906116c8565b6002831015610b6a5760405162461bcd60e51b815260040161036b90611929565b60368390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610b9f90859061166c565b60405180910390a1505050565b835183818111158015610bbe57508015155b8015610bc957508115155b610be55760405162461bcd60e51b815260040161036b906116c8565b600054610100900460ff1680610bfe575060005460ff16155b610c1a5760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610c45576000805460ff1961ff0019909116610100171660011790555b610c4e84610e2f565b603287511115610c705760405162461bcd60e51b815260040161036b90611734565b8651610c839060359060208a01906111ab565b5060005b8751811015610db85760376000898381518110610ca057fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015610cfa575060006001600160a01b0316888281518110610ce657fe5b60200260200101516001600160a01b031614155b610d165760405162461bcd60e51b815260040161036b906117f4565b6001603760008a8481518110610d2857fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550878181518110610d7357fe5b60200260200101516001600160a01b03167f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c760405160405180910390a2600101610c87565b5060368690556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610dee90889061166c565b60405180910390a1610dff856110ad565b8015610e11576000805461ff00191690555b50505050505050565b60396020526000908152604090205460ff1681565b600054610100900460ff1680610e48575060005460ff16155b610e645760405162461bcd60e51b815260040161036b906117ac565b600054610100900460ff16158015610e8f576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015610ef0576000805461ff00191690555b5050565b610efc610903565b610f185760405162461bcd60e51b815260040161036b906118f4565b6001600160a01b038116610f3e5760405162461bcd60e51b815260040161036b90611960565b6001600160a01b03811660009081526037602052604090205460ff1615610f775760405162461bcd60e51b815260040161036b9061182b565b603554603211610f995760405162461bcd60e51b815260040161036b906116fd565b6001600160a01b038116600081815260376020526040808220805460ff1916600190811790915560358054918201815583527fcfa4bec1d3298408bb5afcfcd9c430549c5b31f8aa5c5848151c0a55f473c34d0180546001600160a01b03191684179055517f72114e270de66b9d2710ecf140403e5e99b1574767d6a8197bdc8d807a46e7c79190a250565b60365481565b6034546001600160a01b031681565b611042610903565b61105e5760405162461bcd60e51b815260040161036b906118f4565b61090081611129565b600087878787878787604051602001611086979695949392919061151e565b604051602081830303815290604052805190602001209050979650505050505050565b3390565b6001600160a01b0381166110d35760405162461bcd60e51b815260040161036b9061186c565b603480546001600160a01b0319166001600160a01b0383161790556040517f9775531310b2880b61484ed85cbb0b491c8fde3a07f289c63b925517827944979061111e90839061157c565b60405180910390a150565b6001600160a01b03811661114f5760405162461bcd60e51b815260040161036b906119df565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b828054828255906000526020600020908101928215611200579160200282015b8281111561120057825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906111cb565b5061120c929150611210565b5090565b5b8082111561120c5760008155600101611211565b803561058c81611aaf565b60008083601f840112611241578182fd5b50813567ffffffffffffffff811115611258578182fd5b60208301915083602082850101111561127057600080fd5b9250929050565b803563ffffffff8116811461058c57600080fd5b60006020828403121561129c578081fd5b81356112a781611aaf565b9392505050565b600080600080600080600060e0888a0312156112c8578283fd5b87356112d381611aaf565b965060208801356112e381611aaf565b955060408801356112f381611aaf565b9450606088013593506080880135925060a0880135915061131660c08901611277565b905092959891949750929550565b60008060008060808587031215611339578384fd5b843567ffffffffffffffff80821115611350578586fd5b818701915087601f830112611363578586fd5b813560208282111561137157fe5b8082026040518282820101818110868211171561138a57fe5b604052838152828101945085830182870184018d10156113a8578a8bfd5b8a96505b848710156113d1576113bd81611225565b8652600196909601959483019483016113ac565b5098505088013595506113eb925050604087019050611225565b91506113f960608601611225565b905092959194509250565b600060208284031215611415578081fd5b5035919050565b6000806040838503121561142e578182fd5b82359150602083013561144081611aaf565b809150509250929050565b60008060008060008060008060a0898b031215611466578081fd5b8835975060208901359650604089013567ffffffffffffffff8082111561148b578283fd5b6114978c838d01611230565b909850965060608b01359150808211156114af578283fd5b6114bb8c838d01611230565b909650945060808b01359150808211156114d3578283fd5b506114e08b828c01611230565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b606097881b6bffffffffffffffffffffffff19908116825296881b871660148201529490961b9094166028840152603c830191909152605c820152607c81019190915260e09190911b6001600160e01b031916609c82015260a00190565b6001600160a01b0391909116815260200190565b6001600160a01b03978816815295871660208701529390951660408501526060840191909152608083015260a082019290925263ffffffff90911660c082015260e00190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925263ffffffff90911660a082015260c00190565b6020808252825182820181905260009190848201906040850190845b818110156116555783516001600160a01b031683529284019291840191600101611630565b50909695505050505050565b901515815260200190565b90815260200190565b6000602080835283518082850152825b818110156116a157858101830151858201604001528201611685565b818111156116b25783604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f46656465726174696f6e3a20496e76616c696420726571756972656d656e7473604082015260600190565b6020808252601f908201527f46656465726174696f6e3a204d6178206d656d62657273207265616368656400604082015260600190565b6020808252601c908201527f46656465726174696f6e3a20546f6f206d616e79206d656d6265727300000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220646f65736e27742065786973746040820152607360f81b606082015260800190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b6020808252601b908201527f46656465726174696f6e3a20496e76616c6964206d656d626572730000000000604082015260600190565b60208082526021908201527f46656465726174696f6e3a204d656d62657220616c72656164792065786973746040820152607360f81b606082015260800190565b60208082526018908201527f46656465726174696f6e3a20456d707479206272696467650000000000000000604082015260600190565b60208082526031908201527f46656465726174696f6e3a2043616e27742068617665206c657373207468616e604082015270207265717569726564206d656d6265727360781b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f46656465726174696f6e3a205265717569726573206174206c65617374203200604082015260600190565b60208082526018908201527f46656465726174696f6e3a20456d707479206d656d6265720000000000000000604082015260600190565b60208082526028908201527f46656465726174696f6e3a2043616e27742072656d6f766520616c6c20746865604082015267206d656d6265727360c01b606082015260800190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526019908201527f46656465726174696f6e3a204e6f7420466564657261746f7200000000000000604082015260600190565b600089825288602083015260a06040830152611a7860a08301888a6114f4565b8281036060840152611a8b8187896114f4565b90508281036080840152611aa08185876114f4565b9b9a5050505050505050505050565b6001600160a01b038116811461090057600080fdfea26469706673582212201ed28c73ed4ae70ef955780ff1194179b97395123f029d2daf12887f3e16603c64736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15789,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15792,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15832,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 16076,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_address"
+ },
+ {
+ "astId": 5414,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "bridge",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_contract(IBridge)7398"
+ },
+ {
+ "astId": 5417,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "members",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 5419,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "required",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 5423,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "isMember",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 5429,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "votes",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_mapping(t_bytes32,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 5433,
+ "contract": "contracts/Federation/FederationV2.sol:FederationV2",
+ "label": "processed",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IBridge)7398": {
+ "encoding": "inplace",
+ "label": "contract IBridge",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/MultiSigWallet.json b/bridge/deployments/rsktestnetrinkeby/MultiSigWallet.json
new file mode 100644
index 000000000..0cba5232a
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/MultiSigWallet.json
@@ -0,0 +1,843 @@
+{
+ "address": "0x88f6b2bc66f4c31a3669b9b1359524abf79cfc4a",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_owners",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Confirmation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposit",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Execution",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "ExecutionFailure",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnerAddition",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnerRemoval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "required",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequirementChange",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Revocation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "Submission",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_OWNER_COUNT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "addOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_required",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeRequirement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "confirmTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "confirmations",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "executeTransaction",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getConfirmationCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "count",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getConfirmations",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "_confirmations",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getOwners",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "pending",
+ "type": "bool"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "name": "getTransactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "count",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "from",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "to",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "pending",
+ "type": "bool"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "name": "getTransactionIds",
+ "outputs": [
+ {
+ "internalType": "uint256[]",
+ "name": "_transactionIds",
+ "type": "uint256[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "isConfirmed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "owners",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "removeOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "replaceOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "required",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "name": "revokeConfirmation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "destination",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "submitTransaction",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "transactionId",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "transactionCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "transactions",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "destination",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bool",
+ "name": "executed",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0x3220b2ff54a523efde76537b235936e6dd8382bf5482db2c8433f6bdd558e172",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x6fd64b716Ef38Cbcdc966bfF1517F5B34CaA43F1",
+ "transactionIndex": 0,
+ "gasUsed": "2019878",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x879ccf214b2f36d116c885abe787bd0b2590a85bb773539465443a9750bf9284",
+ "transactionHash": "0x3220b2ff54a523efde76537b235936e6dd8382bf5482db2c8433f6bdd558e172",
+ "logs": [],
+ "blockNumber": 2152170,
+ "cumulativeGasUsed": "2019878",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ [
+ "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8"
+ ],
+ 1
+ ],
+ "solcInputHash": "3b83f9cb61a99eec06a616e65f41d75c",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_owners\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Confirmation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Execution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"ExecutionFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnerAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnerRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"}],\"name\":\"RequirementChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Revocation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"Submission\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_OWNER_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"addOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"changeRequirement\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"confirmTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"confirmations\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"executeTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"getConfirmationCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"getConfirmations\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_confirmations\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pending\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"name\":\"getTransactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"from\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"to\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"pending\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"name\":\"getTransactionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_transactionIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"isConfirmed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"owners\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"removeOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"replaceOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"name\":\"revokeConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"submitTransaction\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"transactionId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transactionCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"transactions\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bool\",\"name\":\"executed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"author\":\"Stefan George - \",\"kind\":\"dev\",\"methods\":{\"addOwner(address)\":{\"details\":\"Allows to add a new owner. Transaction has to be sent by wallet.\",\"params\":{\"owner\":\"Address of new owner.\"}},\"changeRequirement(uint256)\":{\"details\":\"Allows to change the number of required confirmations. Transaction has to be sent by wallet.\",\"params\":{\"_required\":\"Number of required confirmations.\"}},\"confirmTransaction(uint256)\":{\"details\":\"Allows an owner to confirm a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"constructor\":{\"details\":\"Contract constructor sets initial owners and required number of confirmations.\",\"params\":{\"_owners\":\"List of initial owners.\",\"_required\":\"Number of required confirmations.\"}},\"executeTransaction(uint256)\":{\"details\":\"Allows anyone to execute a confirmed transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"getConfirmationCount(uint256)\":{\"details\":\"Returns number of confirmations of a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"count\":\"Number of confirmations.\"}},\"getConfirmations(uint256)\":{\"details\":\"Returns array with owner addresses, which confirmed transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"_confirmations\":\"Returns array of owner addresses.\"}},\"getOwners()\":{\"details\":\"Returns list of owners.\",\"returns\":{\"_0\":\"List of owner addresses.\"}},\"getTransactionCount(bool,bool)\":{\"details\":\"Returns total number of transactions after filers are applied.\",\"params\":{\"executed\":\"Include executed transactions.\",\"pending\":\"Include pending transactions.\"},\"returns\":{\"count\":\"Total number of transactions after filters are applied.\"}},\"getTransactionIds(uint256,uint256,bool,bool)\":{\"details\":\"Returns list of transaction IDs in defined range.\",\"params\":{\"executed\":\"Include executed transactions.\",\"from\":\"Index start position of transaction array.\",\"pending\":\"Include pending transactions.\",\"to\":\"Index end position of transaction array.\"},\"returns\":{\"_transactionIds\":\"Returns array of transaction IDs.\"}},\"isConfirmed(uint256)\":{\"details\":\"Returns the confirmation status of a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"},\"returns\":{\"_0\":\"Confirmation status.\"}},\"removeOwner(address)\":{\"details\":\"Allows to remove an owner. Transaction has to be sent by wallet.\",\"params\":{\"owner\":\"Address of owner.\"}},\"replaceOwner(address,address)\":{\"details\":\"Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\",\"params\":{\"newOwner\":\"Address of new owner.\",\"owner\":\"Address of owner to be replaced.\"}},\"revokeConfirmation(uint256)\":{\"details\":\"Allows an owner to revoke a confirmation for a transaction.\",\"params\":{\"transactionId\":\"Transaction ID.\"}},\"submitTransaction(address,uint256,bytes)\":{\"details\":\"Allows an owner to submit and confirm a transaction.\",\"params\":{\"data\":\"Transaction data payload.\",\"destination\":\"Transaction target address.\",\"value\":\"Transaction ether value.\"},\"returns\":{\"transactionId\":\"Returns transaction ID.\"}}},\"title\":\"Multisignature wallet - Allows multiple parties to agree on transactions before execution.\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/MultiSigWallet.sol\":\"MultiSigWallet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/MultiSigWallet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.\\n/// @author Stefan George - \\ncontract MultiSigWallet {\\n\\n /*\\n * Events\\n */\\n event Confirmation(address indexed sender, uint indexed transactionId);\\n event Revocation(address indexed sender, uint indexed transactionId);\\n event Submission(uint indexed transactionId);\\n event Execution(uint indexed transactionId);\\n event ExecutionFailure(uint indexed transactionId);\\n event Deposit(address indexed sender, uint value);\\n event OwnerAddition(address indexed owner);\\n event OwnerRemoval(address indexed owner);\\n event RequirementChange(uint required);\\n\\n /*\\n * views\\n */\\n uint constant public MAX_OWNER_COUNT = 50;\\n\\n /*\\n * Storage\\n */\\n mapping (uint => Transaction) public transactions;\\n mapping (uint => mapping (address => bool)) public confirmations;\\n mapping (address => bool) public isOwner;\\n address[] public owners;\\n uint public required;\\n uint public transactionCount;\\n\\n struct Transaction {\\n address destination;\\n uint value;\\n bytes data;\\n bool executed;\\n }\\n\\n /*\\n * Modifiers\\n */\\n modifier onlyWallet() {\\n require(msg.sender == address(this), \\\"Only wallet allowed\\\");\\n _;\\n }\\n\\n modifier ownerDoesNotExist(address owner) {\\n require(!isOwner[owner], \\\"The owner already exists\\\");\\n _;\\n }\\n\\n modifier ownerExists(address owner) {\\n require(isOwner[owner], \\\"The owner does not exist\\\");\\n _;\\n }\\n\\n modifier transactionExists(uint transactionId) {\\n require(transactions[transactionId].destination != address(0), \\\"Transaction does not exist\\\");\\n _;\\n }\\n\\n modifier confirmed(uint transactionId, address owner) {\\n require(confirmations[transactionId][owner], \\\"Transaction is not confirmed by owner\\\");\\n _;\\n }\\n\\n modifier notConfirmed(uint transactionId, address owner) {\\n require(!confirmations[transactionId][owner], \\\"Transaction is already confirmed by owner\\\");\\n _;\\n }\\n\\n modifier notExecuted(uint transactionId) {\\n require(!transactions[transactionId].executed, \\\"Transaction was already executed\\\");\\n _;\\n }\\n\\n modifier notNull(address _address) {\\n require(_address != address(0), \\\"Address cannot be empty\\\");\\n _;\\n }\\n\\n modifier validRequirement(uint ownerCount, uint _required) {\\n // solium-disable-next-line max-len\\n require(ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && _required != 0 && ownerCount != 0, \\\"Required value is invalid for the current owners count\\\");\\n _;\\n }\\n\\n /// @dev Fallback function allows to deposit ether.\\n receive ()\\n external\\n payable\\n {\\n if (msg.value > 0)\\n emit Deposit(msg.sender, msg.value);\\n }\\n\\n /*\\n * Public functions\\n */\\n /// @dev Contract constructor sets initial owners and required number of confirmations.\\n /// @param _owners List of initial owners.\\n /// @param _required Number of required confirmations.\\n constructor(address[] memory _owners, uint _required)\\n validRequirement(_owners.length, _required)\\n {\\n for (uint i = 0; i < _owners.length; i++) {\\n require(!isOwner[_owners[i]] && _owners[i] != address(0), \\\"Owners addresses are invalid\\\");\\n isOwner[_owners[i]] = true;\\n }\\n owners = _owners;\\n required = _required;\\n }\\n\\n /// @dev Allows to add a new owner. Transaction has to be sent by wallet.\\n /// @param owner Address of new owner.\\n function addOwner(address owner)\\n public\\n onlyWallet\\n ownerDoesNotExist(owner)\\n notNull(owner)\\n validRequirement(owners.length + 1, required)\\n {\\n isOwner[owner] = true;\\n owners.push(owner);\\n emit OwnerAddition(owner);\\n }\\n\\n /// @dev Allows to remove an owner. Transaction has to be sent by wallet.\\n /// @param owner Address of owner.\\n function removeOwner(address owner)\\n public\\n onlyWallet\\n ownerExists(owner)\\n {\\n isOwner[owner] = false;\\n for (uint i = 0; i < owners.length - 1; i++)\\n if (owners[i] == owner) {\\n owners[i] = owners[owners.length - 1];\\n break;\\n }\\n owners.pop(); // remove an element from the end of the array.\\n if (required > owners.length)\\n changeRequirement(owners.length);\\n emit OwnerRemoval(owner);\\n }\\n\\n /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\\n /// @param owner Address of owner to be replaced.\\n /// @param newOwner Address of new owner.\\n function replaceOwner(address owner, address newOwner)\\n public\\n onlyWallet\\n ownerExists(owner)\\n ownerDoesNotExist(newOwner)\\n {\\n for (uint i = 0; i < owners.length; i++)\\n if (owners[i] == owner) {\\n owners[i] = newOwner;\\n break;\\n }\\n isOwner[owner] = false;\\n isOwner[newOwner] = true;\\n emit OwnerRemoval(owner);\\n emit OwnerAddition(newOwner);\\n }\\n\\n /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.\\n /// @param _required Number of required confirmations.\\n function changeRequirement(uint _required)\\n public\\n onlyWallet\\n validRequirement(owners.length, _required)\\n {\\n required = _required;\\n emit RequirementChange(_required);\\n }\\n\\n /// @dev Allows an owner to submit and confirm a transaction.\\n /// @param destination Transaction target address.\\n /// @param value Transaction ether value.\\n /// @param data Transaction data payload.\\n /// @return transactionId Returns transaction ID.\\n function submitTransaction(address destination, uint value, bytes memory data)\\n public\\n returns (uint transactionId)\\n {\\n transactionId = addTransaction(destination, value, data);\\n confirmTransaction(transactionId);\\n }\\n\\n /// @dev Allows an owner to confirm a transaction.\\n /// @param transactionId Transaction ID.\\n function confirmTransaction(uint transactionId)\\n public\\n ownerExists(msg.sender)\\n transactionExists(transactionId)\\n notConfirmed(transactionId, msg.sender)\\n {\\n confirmations[transactionId][msg.sender] = true;\\n emit Confirmation(msg.sender, transactionId);\\n executeTransaction(transactionId);\\n }\\n\\n /// @dev Allows an owner to revoke a confirmation for a transaction.\\n /// @param transactionId Transaction ID.\\n function revokeConfirmation(uint transactionId)\\n public\\n ownerExists(msg.sender)\\n confirmed(transactionId, msg.sender)\\n notExecuted(transactionId)\\n {\\n confirmations[transactionId][msg.sender] = false;\\n emit Revocation(msg.sender, transactionId);\\n }\\n\\n /// @dev Allows anyone to execute a confirmed transaction.\\n /// @param transactionId Transaction ID.\\n function executeTransaction(uint transactionId)\\n public\\n ownerExists(msg.sender)\\n confirmed(transactionId, msg.sender)\\n notExecuted(transactionId)\\n {\\n if (isConfirmed(transactionId)) {\\n Transaction storage txn = transactions[transactionId];\\n txn.executed = true;\\n if (external_call(txn.destination, txn.value, txn.data.length, txn.data))\\n emit Execution(transactionId);\\n else {\\n emit ExecutionFailure(transactionId);\\n txn.executed = false;\\n }\\n }\\n }\\n\\n // call has been separated into its own function in order to take advantage\\n // of the Solidity's code generator to produce a loop that copies tx.data into memory.\\n function external_call(address destination, uint value, uint dataLength, bytes memory data) internal returns (bool) {\\n bool result;\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n let x := mload(0x40) // \\\"Allocate\\\" memory for output (0x40 is where \\\"free memory\\\" pointer is stored by convention)\\n let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that\\n result := call(\\n sub(gas(), 34710), // 34710 is the value that solidity is currently emitting\\n // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +\\n // callNewAccountGas (25000, in case the destination address does not exist and needs creating)\\n destination,\\n value,\\n d,\\n dataLength, // Size of the input (in bytes) - this is what fixes the padding problem\\n x,\\n 0 // Output is ignored, therefore the output size is zero\\n )\\n }\\n return result;\\n }\\n\\n /// @dev Returns the confirmation status of a transaction.\\n /// @param transactionId Transaction ID.\\n /// @return Confirmation status.\\n function isConfirmed(uint transactionId)\\n public\\n view\\n returns (bool)\\n {\\n uint count = 0;\\n for (uint i = 0; i < owners.length; i++) {\\n if (confirmations[transactionId][owners[i]])\\n count += 1;\\n if (count == required)\\n return true;\\n }\\n return false;\\n }\\n\\n /*\\n * Internal functions\\n */\\n /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.\\n /// @param destination Transaction target address.\\n /// @param value Transaction ether value.\\n /// @param data Transaction data payload.\\n /// @return transactionId Returns transaction ID.\\n function addTransaction(address destination, uint value, bytes memory data)\\n internal\\n notNull(destination)\\n returns (uint transactionId)\\n {\\n transactionId = transactionCount;\\n transactions[transactionId] = Transaction({\\n destination: destination,\\n value: value,\\n data: data,\\n executed: false\\n });\\n transactionCount += 1;\\n emit Submission(transactionId);\\n }\\n\\n /*\\n * Web3 call functions\\n */\\n /// @dev Returns number of confirmations of a transaction.\\n /// @param transactionId Transaction ID.\\n /// @return count Number of confirmations.\\n function getConfirmationCount(uint transactionId)\\n public\\n view\\n returns (uint count)\\n {\\n for (uint i = 0; i < owners.length; i++) {\\n if (confirmations[transactionId][owners[i]]) {\\n count += 1;\\n }\\n }\\n }\\n\\n /// @dev Returns total number of transactions after filers are applied.\\n /// @param pending Include pending transactions.\\n /// @param executed Include executed transactions.\\n /// @return count Total number of transactions after filters are applied.\\n function getTransactionCount(bool pending, bool executed)\\n public\\n view\\n returns (uint count)\\n {\\n for (uint i = 0; i < transactionCount; i++) {\\n if ( pending && !transactions[i].executed || executed && transactions[i].executed) {\\n count += 1;\\n }\\n }\\n }\\n\\n /// @dev Returns list of owners.\\n /// @return List of owner addresses.\\n function getOwners()\\n public\\n view\\n returns (address[] memory)\\n {\\n return owners;\\n }\\n\\n /// @dev Returns array with owner addresses, which confirmed transaction.\\n /// @param transactionId Transaction ID.\\n /// @return _confirmations Returns array of owner addresses.\\n function getConfirmations(uint transactionId)\\n public\\n view\\n returns (address[] memory _confirmations)\\n {\\n address[] memory confirmationsTemp = new address[](owners.length);\\n uint count = 0;\\n uint i;\\n for (i = 0; i < owners.length; i++)\\n if (confirmations[transactionId][owners[i]]) {\\n confirmationsTemp[count] = owners[i];\\n count += 1;\\n }\\n _confirmations = new address[](count);\\n for (i = 0; i < count; i++)\\n _confirmations[i] = confirmationsTemp[i];\\n }\\n\\n /// @dev Returns list of transaction IDs in defined range.\\n /// @param from Index start position of transaction array.\\n /// @param to Index end position of transaction array.\\n /// @param pending Include pending transactions.\\n /// @param executed Include executed transactions.\\n /// @return _transactionIds Returns array of transaction IDs.\\n function getTransactionIds(uint from, uint to, bool pending, bool executed)\\n public\\n view\\n returns (uint[] memory _transactionIds)\\n {\\n uint[] memory transactionIdsTemp = new uint[](transactionCount);\\n uint count = 0;\\n uint i;\\n for (i = 0; i < transactionCount; i++)\\n if ( pending && !transactions[i].executed || executed && transactions[i].executed)\\n {\\n transactionIdsTemp[count] = i;\\n count += 1;\\n }\\n _transactionIds = new uint[](to - from);\\n for (i = from; i < to; i++)\\n _transactionIds[i - from] = transactionIdsTemp[i];\\n }\\n}\",\"keccak256\":\"0x48128d95302f2405b2ca70996b8f12f7d9c52224aadf3b381139246bf2baa31b\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x60806040523480156200001157600080fd5b5060405162001e5838038062001e58833981016040819052620000349162000231565b81518160328211158015620000495750818111155b80156200005557508015155b80156200006157508115155b620000895760405162461bcd60e51b81526004016200008090620002f7565b60405180910390fd5b60005b8451811015620001705760026000868381518110620000a757fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1615801562000103575060006001600160a01b0316858281518110620000ef57fe5b60200260200101516001600160a01b031614155b620001225760405162461bcd60e51b8152600401620000809062000354565b6001600260008784815181106200013557fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff19169115159190911790556001016200008c565b5083516200018690600390602087019062000193565b505050600455506200038b565b828054828255906000526020600020908101928215620001eb579160200282015b82811115620001eb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620001b4565b50620001f9929150620001fd565b5090565b5b80821115620001f95760008155600101620001fe565b80516001600160a01b03811681146200022c57600080fd5b919050565b6000806040838503121562000244578182fd5b82516001600160401b03808211156200025b578384fd5b818501915085601f8301126200026f578384fd5b81516020828211156200027e57fe5b808202604051828282010181811086821117156200029857fe5b604052838152828101945085830182870184018b1015620002b7578889fd5b8896505b84871015620002e457620002cf8162000214565b865260019690960195948301948301620002bb565b5097909101519698969750505050505050565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f7220746860408201527f652063757272656e74206f776e65727320636f756e7400000000000000000000606082015260800190565b6020808252601c908201527f4f776e657273206164647265737365732061726520696e76616c696400000000604082015260600190565b611abd806200039b6000396000f3fe60806040526004361061012e5760003560e01c8063a0e67e2b116100ab578063c01a8c841161006f578063c01a8c84146103a6578063c6427474146103c6578063d74f8edd146103e6578063dc8452cd146103fb578063e20056e614610410578063ee22610b146104305761017d565b8063a0e67e2b14610302578063a8abe69a14610324578063b5dc40c314610351578063b77bf60014610371578063ba51a6df146103865761017d565b806354741525116100f257806354741525146102455780637065cb4814610272578063784547a7146102925780638b51d13f146102b25780639ace38c2146102d25761017d565b8063025e7c2714610182578063173825d9146101b857806320ea8d86146101d85780632f54bf6e146101f85780633411c81c146102255761017d565b3661017d57341561017b57336001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040516101729190611a7e565b60405180910390a25b005b600080fd5b34801561018e57600080fd5b506101a261019d3660046116ba565b610450565b6040516101af919061173f565b60405180910390f35b3480156101c457600080fd5b5061017b6101d3366004611594565b61047a565b3480156101e457600080fd5b5061017b6101f33660046116ba565b61062e565b34801561020457600080fd5b50610218610213366004611594565b61071d565b6040516101af9190611851565b34801561023157600080fd5b506102186102403660046116d2565b610732565b34801561025157600080fd5b50610265610260366004611691565b610752565b6040516101af9190611a7e565b34801561027e57600080fd5b5061017b61028d366004611594565b6107be565b34801561029e57600080fd5b506102186102ad3660046116ba565b61091e565b3480156102be57600080fd5b506102656102cd3660046116ba565b6109a9565b3480156102de57600080fd5b506102f26102ed3660046116ba565b610a18565b6040516101af9493929190611753565b34801561030e57600080fd5b50610317610ad6565b6040516101af91906117cc565b34801561033057600080fd5b5061034461033f3660046116f4565b610b38565b6040516101af9190611819565b34801561035d57600080fd5b5061031761036c3660046116ba565b610c92565b34801561037d57600080fd5b50610265610e37565b34801561039257600080fd5b5061017b6103a13660046116ba565b610e3d565b3480156103b257600080fd5b5061017b6103c13660046116ba565b610ee5565b3480156103d257600080fd5b506102656103e13660046115e0565b610fe5565b3480156103f257600080fd5b50610265611004565b34801561040757600080fd5b50610265611009565b34801561041c57600080fd5b5061017b61042b3660046115ae565b61100f565b34801561043c57600080fd5b5061017b61044b3660046116ba565b6111c5565b6003818154811061046057600080fd5b6000918252602090912001546001600160a01b0316905081565b3330146104a25760405162461bcd60e51b815260040161049990611977565b60405180910390fd5b6001600160a01b038116600090815260026020526040902054819060ff166104dc5760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b0382166000908152600260205260408120805460ff191690555b600354600019018110156105b057826001600160a01b03166003828154811061052257fe5b6000918252602090912001546001600160a01b031614156105a85760038054600019810190811061054f57fe5b600091825260209091200154600380546001600160a01b03909216918390811061057557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506105b0565b6001016104fd565b5060038054806105bc57fe5b600082815260209020810160001990810180546001600160a01b031916905501905560035460045411156105f6576003546105f690610e3d565b6040516001600160a01b038316907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a25050565b3360008181526002602052604090205460ff1661065d5760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff1661069a5760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156106ce5760405162461bcd60e51b815260040161049990611a49565b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b6005548110156107b75783801561077f575060008181526020819052604090206003015460ff16155b806107a357508280156107a3575060008181526020819052604090206003015460ff165b156107af576001820191505b600101610756565b5092915050565b3330146107dd5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038116600090815260026020526040902054819060ff16156108185760405162461bcd60e51b815260040161049990611a12565b816001600160a01b03811661083f5760405162461bcd60e51b815260040161049990611940565b6003805490506001016004546032821115801561085c5750818111155b801561086757508015155b801561087257508115155b61088e5760405162461bcd60e51b8152600401610499906118a5565b6001600160a01b038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b60035481101561099d576000848152600160205260408120600380549192918490811061094c57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610980576001820191505b600454821415610995576001925050506109a4565b600101610923565b5060009150505b919050565b6000805b600354811015610a1257600083815260016020526040812060038054919291849081106109d657fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0a576001820191505b6001016109ad565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f81018890048802840188019096528583526001600160a01b0390931695909491929190830182828015610ac35780601f10610a9857610100808354040283529160200191610ac3565b820191906000526020600020905b815481529060010190602001808311610aa657829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610b2e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b10575b5050505050905090565b6060600060055467ffffffffffffffff81118015610b5557600080fd5b50604051908082528060200260200182016040528015610b7f578160200160208202803683370190505b5090506000805b600554811015610c0057858015610baf575060008181526020819052604090206003015460ff16155b80610bd35750848015610bd3575060008181526020819052604090206003015460ff165b15610bf85780838381518110610be557fe5b6020026020010181815250506001820191505b600101610b86565b87870367ffffffffffffffff81118015610c1957600080fd5b50604051908082528060200260200182016040528015610c43578160200160208202803683370190505b5093508790505b86811015610c8757828181518110610c5e57fe5b60200260200101518489830381518110610c7457fe5b6020908102919091010152600101610c4a565b505050949350505050565b60035460609060009067ffffffffffffffff81118015610cb157600080fd5b50604051908082528060200260200182016040528015610cdb578160200160208202803683370190505b5090506000805b600354811015610d9e5760008581526001602052604081206003805491929184908110610d0b57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610d965760038181548110610d4557fe5b9060005260206000200160009054906101000a90046001600160a01b0316838381518110610d6f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001820191505b600101610ce2565b8167ffffffffffffffff81118015610db557600080fd5b50604051908082528060200260200182016040528015610ddf578160200160208202803683370190505b509350600090505b81811015610e2f57828181518110610dfb57fe5b6020026020010151848281518110610e0f57fe5b6001600160a01b0390921660209283029190910190910152600101610de7565b505050919050565b60055481565b333014610e5c5760405162461bcd60e51b815260040161049990611977565b6003548160328211801590610e715750818111155b8015610e7c57508015155b8015610e8757508115155b610ea35760405162461bcd60e51b8152600401610499906118a5565b60048390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610ed8908590611a7e565b60405180910390a1505050565b3360008181526002602052604090205460ff16610f145760405162461bcd60e51b8152600401610499906119a4565b60008281526020819052604090205482906001600160a01b0316610f4a5760405162461bcd60e51b8152600401610499906119db565b60008381526001602090815260408083203380855292529091205484919060ff1615610f885760405162461bcd60e51b81526004016104999061185c565b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3610fde856111c5565b5050505050565b6000610ff28484846113b5565b9050610ffd81610ee5565b9392505050565b603281565b60045481565b33301461102e5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038216600090815260026020526040902054829060ff166110685760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b038216600090815260026020526040902054829060ff16156110a35760405162461bcd60e51b815260040161049990611a12565b60005b60035481101561112b57846001600160a01b0316600382815481106110c757fe5b6000918252602090912001546001600160a01b031614156111235783600382815481106110f057fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061112b565b6001016110a6565b506001600160a01b03808516600081815260026020526040808220805460ff1990811690915593871682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a26040516001600160a01b038416907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a250505050565b3360008181526002602052604090205460ff166111f45760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff166112315760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156112655760405162461bcd60e51b815260040161049990611a49565b61126e8561091e565b15610fde576000858152602081815260409182902060038101805460ff19166001908117909155815481830154600280850180548851601f600019978316156101000297909701909116929092049485018790048702820187019097528381529395611340956001600160a01b039093169491939283908301828280156113365780601f1061130b57610100808354040283529160200191611336565b820191906000526020600020905b81548152906001019060200180831161131957829003601f168201915b50505050506114a9565b156113755760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26113ad565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038101805460ff191690555b505050505050565b6000836001600160a01b0381166113de5760405162461bcd60e51b815260040161049990611940565b600554604080516080810182526001600160a01b038881168252602080830189815283850189815260006060860181905287815280845295909520845181546001600160a01b031916941693909317835551600183015592518051949650919390926114519260028501929101906114cc565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b6000806040516020840160008287838a8c6187965a03f198975050505050505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826115025760008555611548565b82601f1061151b57805160ff1916838001178555611548565b82800160010185558215611548579182015b8281111561154857825182559160200191906001019061152d565b50611554929150611558565b5090565b5b808211156115545760008155600101611559565b80356001600160a01b03811681146109a457600080fd5b803580151581146109a457600080fd5b6000602082840312156115a5578081fd5b610ffd8261156d565b600080604083850312156115c0578081fd5b6115c98361156d565b91506115d76020840161156d565b90509250929050565b6000806000606084860312156115f4578081fd5b6115fd8461156d565b92506020808501359250604085013567ffffffffffffffff80821115611621578384fd5b818701915087601f830112611634578384fd5b81358181111561164057fe5b604051601f8201601f191681018501838111828210171561165d57fe5b60405281815283820185018a1015611673578586fd5b81858501868301378585838301015280955050505050509250925092565b600080604083850312156116a3578182fd5b6116ac83611584565b91506115d760208401611584565b6000602082840312156116cb578081fd5b5035919050565b600080604083850312156116e4578182fd5b823591506115d76020840161156d565b60008060008060808587031215611709578081fd5b843593506020850135925061172060408601611584565b915061172e60608601611584565b905092959194509250565b15159052565b6001600160a01b0391909116815260200190565b600060018060a01b038616825260208581840152608060408401528451806080850152825b818110156117945786810183015185820160a001528201611778565b818111156117a5578360a083870101525b50601f01601f1916830160a00191506117c390506060830184611739565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d5783516001600160a01b0316835292840192918401916001016117e8565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d57835183529284019291840191600101611835565b901515815260200190565b60208082526029908201527f5472616e73616374696f6e20697320616c726561647920636f6e6669726d656460408201526810313c9037bbb732b960b91b606082015260800190565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f72207468604082015275194818dd5c9c995b9d081bdddb995c9cc818dbdd5b9d60521b606082015260800190565b60208082526025908201527f5472616e73616374696f6e206973206e6f7420636f6e6669726d65642062792060408201526437bbb732b960d91b606082015260800190565b60208082526017908201527f416464726573732063616e6e6f7420626520656d707479000000000000000000604082015260600190565b60208082526013908201527213db9b1e481dd85b1b195d08185b1b1bddd959606a1b604082015260600190565b60208082526018908201527f546865206f776e657220646f6573206e6f742065786973740000000000000000604082015260600190565b6020808252601a908201527f5472616e73616374696f6e20646f6573206e6f74206578697374000000000000604082015260600190565b60208082526018908201527f546865206f776e657220616c7265616479206578697374730000000000000000604082015260600190565b6020808252818101527f5472616e73616374696f6e2077617320616c7265616479206578656375746564604082015260600190565b9081526020019056fea264697066735822122062c2739111652d12775c1bfdbf576765e75e1ef9880050cc336a31164f199d6c64736f6c63430007060033",
+ "deployedBytecode": "0x60806040526004361061012e5760003560e01c8063a0e67e2b116100ab578063c01a8c841161006f578063c01a8c84146103a6578063c6427474146103c6578063d74f8edd146103e6578063dc8452cd146103fb578063e20056e614610410578063ee22610b146104305761017d565b8063a0e67e2b14610302578063a8abe69a14610324578063b5dc40c314610351578063b77bf60014610371578063ba51a6df146103865761017d565b806354741525116100f257806354741525146102455780637065cb4814610272578063784547a7146102925780638b51d13f146102b25780639ace38c2146102d25761017d565b8063025e7c2714610182578063173825d9146101b857806320ea8d86146101d85780632f54bf6e146101f85780633411c81c146102255761017d565b3661017d57341561017b57336001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040516101729190611a7e565b60405180910390a25b005b600080fd5b34801561018e57600080fd5b506101a261019d3660046116ba565b610450565b6040516101af919061173f565b60405180910390f35b3480156101c457600080fd5b5061017b6101d3366004611594565b61047a565b3480156101e457600080fd5b5061017b6101f33660046116ba565b61062e565b34801561020457600080fd5b50610218610213366004611594565b61071d565b6040516101af9190611851565b34801561023157600080fd5b506102186102403660046116d2565b610732565b34801561025157600080fd5b50610265610260366004611691565b610752565b6040516101af9190611a7e565b34801561027e57600080fd5b5061017b61028d366004611594565b6107be565b34801561029e57600080fd5b506102186102ad3660046116ba565b61091e565b3480156102be57600080fd5b506102656102cd3660046116ba565b6109a9565b3480156102de57600080fd5b506102f26102ed3660046116ba565b610a18565b6040516101af9493929190611753565b34801561030e57600080fd5b50610317610ad6565b6040516101af91906117cc565b34801561033057600080fd5b5061034461033f3660046116f4565b610b38565b6040516101af9190611819565b34801561035d57600080fd5b5061031761036c3660046116ba565b610c92565b34801561037d57600080fd5b50610265610e37565b34801561039257600080fd5b5061017b6103a13660046116ba565b610e3d565b3480156103b257600080fd5b5061017b6103c13660046116ba565b610ee5565b3480156103d257600080fd5b506102656103e13660046115e0565b610fe5565b3480156103f257600080fd5b50610265611004565b34801561040757600080fd5b50610265611009565b34801561041c57600080fd5b5061017b61042b3660046115ae565b61100f565b34801561043c57600080fd5b5061017b61044b3660046116ba565b6111c5565b6003818154811061046057600080fd5b6000918252602090912001546001600160a01b0316905081565b3330146104a25760405162461bcd60e51b815260040161049990611977565b60405180910390fd5b6001600160a01b038116600090815260026020526040902054819060ff166104dc5760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b0382166000908152600260205260408120805460ff191690555b600354600019018110156105b057826001600160a01b03166003828154811061052257fe5b6000918252602090912001546001600160a01b031614156105a85760038054600019810190811061054f57fe5b600091825260209091200154600380546001600160a01b03909216918390811061057557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506105b0565b6001016104fd565b5060038054806105bc57fe5b600082815260209020810160001990810180546001600160a01b031916905501905560035460045411156105f6576003546105f690610e3d565b6040516001600160a01b038316907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a25050565b3360008181526002602052604090205460ff1661065d5760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff1661069a5760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156106ce5760405162461bcd60e51b815260040161049990611a49565b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b6005548110156107b75783801561077f575060008181526020819052604090206003015460ff16155b806107a357508280156107a3575060008181526020819052604090206003015460ff165b156107af576001820191505b600101610756565b5092915050565b3330146107dd5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038116600090815260026020526040902054819060ff16156108185760405162461bcd60e51b815260040161049990611a12565b816001600160a01b03811661083f5760405162461bcd60e51b815260040161049990611940565b6003805490506001016004546032821115801561085c5750818111155b801561086757508015155b801561087257508115155b61088e5760405162461bcd60e51b8152600401610499906118a5565b6001600160a01b038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b60035481101561099d576000848152600160205260408120600380549192918490811061094c57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610980576001820191505b600454821415610995576001925050506109a4565b600101610923565b5060009150505b919050565b6000805b600354811015610a1257600083815260016020526040812060038054919291849081106109d657fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610a0a576001820191505b6001016109ad565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f81018890048802840188019096528583526001600160a01b0390931695909491929190830182828015610ac35780601f10610a9857610100808354040283529160200191610ac3565b820191906000526020600020905b815481529060010190602001808311610aa657829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610b2e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b10575b5050505050905090565b6060600060055467ffffffffffffffff81118015610b5557600080fd5b50604051908082528060200260200182016040528015610b7f578160200160208202803683370190505b5090506000805b600554811015610c0057858015610baf575060008181526020819052604090206003015460ff16155b80610bd35750848015610bd3575060008181526020819052604090206003015460ff165b15610bf85780838381518110610be557fe5b6020026020010181815250506001820191505b600101610b86565b87870367ffffffffffffffff81118015610c1957600080fd5b50604051908082528060200260200182016040528015610c43578160200160208202803683370190505b5093508790505b86811015610c8757828181518110610c5e57fe5b60200260200101518489830381518110610c7457fe5b6020908102919091010152600101610c4a565b505050949350505050565b60035460609060009067ffffffffffffffff81118015610cb157600080fd5b50604051908082528060200260200182016040528015610cdb578160200160208202803683370190505b5090506000805b600354811015610d9e5760008581526001602052604081206003805491929184908110610d0b57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff1615610d965760038181548110610d4557fe5b9060005260206000200160009054906101000a90046001600160a01b0316838381518110610d6f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001820191505b600101610ce2565b8167ffffffffffffffff81118015610db557600080fd5b50604051908082528060200260200182016040528015610ddf578160200160208202803683370190505b509350600090505b81811015610e2f57828181518110610dfb57fe5b6020026020010151848281518110610e0f57fe5b6001600160a01b0390921660209283029190910190910152600101610de7565b505050919050565b60055481565b333014610e5c5760405162461bcd60e51b815260040161049990611977565b6003548160328211801590610e715750818111155b8015610e7c57508015155b8015610e8757508115155b610ea35760405162461bcd60e51b8152600401610499906118a5565b60048390556040517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a90610ed8908590611a7e565b60405180910390a1505050565b3360008181526002602052604090205460ff16610f145760405162461bcd60e51b8152600401610499906119a4565b60008281526020819052604090205482906001600160a01b0316610f4a5760405162461bcd60e51b8152600401610499906119db565b60008381526001602090815260408083203380855292529091205484919060ff1615610f885760405162461bcd60e51b81526004016104999061185c565b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3610fde856111c5565b5050505050565b6000610ff28484846113b5565b9050610ffd81610ee5565b9392505050565b603281565b60045481565b33301461102e5760405162461bcd60e51b815260040161049990611977565b6001600160a01b038216600090815260026020526040902054829060ff166110685760405162461bcd60e51b8152600401610499906119a4565b6001600160a01b038216600090815260026020526040902054829060ff16156110a35760405162461bcd60e51b815260040161049990611a12565b60005b60035481101561112b57846001600160a01b0316600382815481106110c757fe5b6000918252602090912001546001600160a01b031614156111235783600382815481106110f057fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061112b565b6001016110a6565b506001600160a01b03808516600081815260026020526040808220805460ff1990811690915593871682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a26040516001600160a01b038416907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a250505050565b3360008181526002602052604090205460ff166111f45760405162461bcd60e51b8152600401610499906119a4565b60008281526001602090815260408083203380855292529091205483919060ff166112315760405162461bcd60e51b8152600401610499906118fb565b600084815260208190526040902060030154849060ff16156112655760405162461bcd60e51b815260040161049990611a49565b61126e8561091e565b15610fde576000858152602081815260409182902060038101805460ff19166001908117909155815481830154600280850180548851601f600019978316156101000297909701909116929092049485018790048702820187019097528381529395611340956001600160a01b039093169491939283908301828280156113365780601f1061130b57610100808354040283529160200191611336565b820191906000526020600020905b81548152906001019060200180831161131957829003601f168201915b50505050506114a9565b156113755760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26113ad565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038101805460ff191690555b505050505050565b6000836001600160a01b0381166113de5760405162461bcd60e51b815260040161049990611940565b600554604080516080810182526001600160a01b038881168252602080830189815283850189815260006060860181905287815280845295909520845181546001600160a01b031916941693909317835551600183015592518051949650919390926114519260028501929101906114cc565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b6000806040516020840160008287838a8c6187965a03f198975050505050505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826115025760008555611548565b82601f1061151b57805160ff1916838001178555611548565b82800160010185558215611548579182015b8281111561154857825182559160200191906001019061152d565b50611554929150611558565b5090565b5b808211156115545760008155600101611559565b80356001600160a01b03811681146109a457600080fd5b803580151581146109a457600080fd5b6000602082840312156115a5578081fd5b610ffd8261156d565b600080604083850312156115c0578081fd5b6115c98361156d565b91506115d76020840161156d565b90509250929050565b6000806000606084860312156115f4578081fd5b6115fd8461156d565b92506020808501359250604085013567ffffffffffffffff80821115611621578384fd5b818701915087601f830112611634578384fd5b81358181111561164057fe5b604051601f8201601f191681018501838111828210171561165d57fe5b60405281815283820185018a1015611673578586fd5b81858501868301378585838301015280955050505050509250925092565b600080604083850312156116a3578182fd5b6116ac83611584565b91506115d760208401611584565b6000602082840312156116cb578081fd5b5035919050565b600080604083850312156116e4578182fd5b823591506115d76020840161156d565b60008060008060808587031215611709578081fd5b843593506020850135925061172060408601611584565b915061172e60608601611584565b905092959194509250565b15159052565b6001600160a01b0391909116815260200190565b600060018060a01b038616825260208581840152608060408401528451806080850152825b818110156117945786810183015185820160a001528201611778565b818111156117a5578360a083870101525b50601f01601f1916830160a00191506117c390506060830184611739565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d5783516001600160a01b0316835292840192918401916001016117e8565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561180d57835183529284019291840191600101611835565b901515815260200190565b60208082526029908201527f5472616e73616374696f6e20697320616c726561647920636f6e6669726d656460408201526810313c9037bbb732b960b91b606082015260800190565b60208082526036908201527f52657175697265642076616c756520697320696e76616c696420666f72207468604082015275194818dd5c9c995b9d081bdddb995c9cc818dbdd5b9d60521b606082015260800190565b60208082526025908201527f5472616e73616374696f6e206973206e6f7420636f6e6669726d65642062792060408201526437bbb732b960d91b606082015260800190565b60208082526017908201527f416464726573732063616e6e6f7420626520656d707479000000000000000000604082015260600190565b60208082526013908201527213db9b1e481dd85b1b195d08185b1b1bddd959606a1b604082015260600190565b60208082526018908201527f546865206f776e657220646f6573206e6f742065786973740000000000000000604082015260600190565b6020808252601a908201527f5472616e73616374696f6e20646f6573206e6f74206578697374000000000000604082015260600190565b60208082526018908201527f546865206f776e657220616c7265616479206578697374730000000000000000604082015260600190565b6020808252818101527f5472616e73616374696f6e2077617320616c7265616479206578656375746564604082015260600190565b9081526020019056fea264697066735822122062c2739111652d12775c1bfdbf576765e75e1ef9880050cc336a31164f199d6c64736f6c63430007060033",
+ "devdoc": {
+ "author": "Stefan George - ",
+ "kind": "dev",
+ "methods": {
+ "addOwner(address)": {
+ "details": "Allows to add a new owner. Transaction has to be sent by wallet.",
+ "params": {
+ "owner": "Address of new owner."
+ }
+ },
+ "changeRequirement(uint256)": {
+ "details": "Allows to change the number of required confirmations. Transaction has to be sent by wallet.",
+ "params": {
+ "_required": "Number of required confirmations."
+ }
+ },
+ "confirmTransaction(uint256)": {
+ "details": "Allows an owner to confirm a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "constructor": {
+ "details": "Contract constructor sets initial owners and required number of confirmations.",
+ "params": {
+ "_owners": "List of initial owners.",
+ "_required": "Number of required confirmations."
+ }
+ },
+ "executeTransaction(uint256)": {
+ "details": "Allows anyone to execute a confirmed transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "getConfirmationCount(uint256)": {
+ "details": "Returns number of confirmations of a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "count": "Number of confirmations."
+ }
+ },
+ "getConfirmations(uint256)": {
+ "details": "Returns array with owner addresses, which confirmed transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "_confirmations": "Returns array of owner addresses."
+ }
+ },
+ "getOwners()": {
+ "details": "Returns list of owners.",
+ "returns": {
+ "_0": "List of owner addresses."
+ }
+ },
+ "getTransactionCount(bool,bool)": {
+ "details": "Returns total number of transactions after filers are applied.",
+ "params": {
+ "executed": "Include executed transactions.",
+ "pending": "Include pending transactions."
+ },
+ "returns": {
+ "count": "Total number of transactions after filters are applied."
+ }
+ },
+ "getTransactionIds(uint256,uint256,bool,bool)": {
+ "details": "Returns list of transaction IDs in defined range.",
+ "params": {
+ "executed": "Include executed transactions.",
+ "from": "Index start position of transaction array.",
+ "pending": "Include pending transactions.",
+ "to": "Index end position of transaction array."
+ },
+ "returns": {
+ "_transactionIds": "Returns array of transaction IDs."
+ }
+ },
+ "isConfirmed(uint256)": {
+ "details": "Returns the confirmation status of a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ },
+ "returns": {
+ "_0": "Confirmation status."
+ }
+ },
+ "removeOwner(address)": {
+ "details": "Allows to remove an owner. Transaction has to be sent by wallet.",
+ "params": {
+ "owner": "Address of owner."
+ }
+ },
+ "replaceOwner(address,address)": {
+ "details": "Allows to replace an owner with a new owner. Transaction has to be sent by wallet.",
+ "params": {
+ "newOwner": "Address of new owner.",
+ "owner": "Address of owner to be replaced."
+ }
+ },
+ "revokeConfirmation(uint256)": {
+ "details": "Allows an owner to revoke a confirmation for a transaction.",
+ "params": {
+ "transactionId": "Transaction ID."
+ }
+ },
+ "submitTransaction(address,uint256,bytes)": {
+ "details": "Allows an owner to submit and confirm a transaction.",
+ "params": {
+ "data": "Transaction data payload.",
+ "destination": "Transaction target address.",
+ "value": "Transaction ether value."
+ },
+ "returns": {
+ "transactionId": "Returns transaction ID."
+ }
+ }
+ },
+ "title": "Multisignature wallet - Allows multiple parties to agree on transactions before execution.",
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 52,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "transactions",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_uint256,t_struct(Transaction)78_storage)"
+ },
+ {
+ "astId": 58,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "confirmations",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_mapping(t_uint256,t_mapping(t_address,t_bool))"
+ },
+ {
+ "astId": 62,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "isOwner",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 65,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "owners",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_array(t_address)dyn_storage"
+ },
+ {
+ "astId": 67,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "required",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 69,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "transactionCount",
+ "offset": 0,
+ "slot": "5",
+ "type": "t_uint256"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "base": "t_address",
+ "encoding": "dynamic_array",
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes_storage": {
+ "encoding": "bytes",
+ "label": "bytes",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_uint256,t_mapping(t_address,t_bool))": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => mapping(address => bool))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_bool)"
+ },
+ "t_mapping(t_uint256,t_struct(Transaction)78_storage)": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => struct MultiSigWallet.Transaction)",
+ "numberOfBytes": "32",
+ "value": "t_struct(Transaction)78_storage"
+ },
+ "t_struct(Transaction)78_storage": {
+ "encoding": "inplace",
+ "label": "struct MultiSigWallet.Transaction",
+ "members": [
+ {
+ "astId": 71,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "destination",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ },
+ {
+ "astId": 73,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "value",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 75,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "data",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_bytes_storage"
+ },
+ {
+ "astId": 77,
+ "contract": "contracts/MultiSigWallet.sol:MultiSigWallet",
+ "label": "executed",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_bool"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/NFTBridge.json b/bridge/deployments/rsktestnetrinkeby/NFTBridge.json
new file mode 100644
index 000000000..4b831b593
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/NFTBridge.json
@@ -0,0 +1,1419 @@
+{
+ "address": "0xdc8E3000ED0aCAC926A37ead0f0B0F675182AC3b",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_tokenId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ }
+ ],
+ "name": "AcceptedNFTCrossTransfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "AllowTokensChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_tokenId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_logIndex",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_receiver",
+ "type": "address"
+ }
+ ],
+ "name": "ClaimedNFTToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_tokenCreator",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "_userData",
+ "type": "bytes"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_totalSupply",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_tokenId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_tokenURI",
+ "type": "string"
+ }
+ ],
+ "name": "Cross",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "FederationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "FixedFeeNFTChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_newSideNFTTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "_newSymbol",
+ "type": "string"
+ }
+ ],
+ "name": "NewSideNFTToken",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Paused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "PauserRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_newSideNFTTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "SideTokenFactoryChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "Unpaused",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "Upgrading",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__Pausable_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "__PauserRol_init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_tokenId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "acceptTransfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "addPauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "allowTokens",
+ "outputs": [
+ {
+ "internalType": "contract IAllowTokens",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAllowTokens",
+ "type": "address"
+ }
+ ],
+ "name": "changeAllowTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "newFederation",
+ "type": "address"
+ }
+ ],
+ "name": "changeFederation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newSideNFTTokenFactory",
+ "type": "address"
+ }
+ ],
+ "name": "changeSideTokenFactory",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct INFTBridge.NFTClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claim",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address payable",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "logIndex",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct INFTBridge.NFTClaimData",
+ "name": "_claimData",
+ "type": "tuple"
+ }
+ ],
+ "name": "claimFallback",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "claimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_originalTokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenSymbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_originalTokenName",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_baseURI",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_contractURI",
+ "type": "string"
+ }
+ ],
+ "name": "createSideNFTToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFederation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFixedFee",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getTokenCreator",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_tokenId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_transactionHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_logIndex",
+ "type": "uint32"
+ }
+ ],
+ "name": "getTransactionDataHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasBeenClaimed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "hasCrossed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "address payable",
+ "name": "_federation",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_allowTokens",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_sideTokenFactory",
+ "type": "address"
+ },
+ {
+ "internalType": "string",
+ "name": "_symbolPrefix",
+ "type": "string"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isAddressFromCrossedOriginalToken",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isPauser",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isUpgrading",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "onERC721Received",
+ "outputs": [
+ {
+ "internalType": "bytes4",
+ "name": "",
+ "type": "bytes4"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "originalTokenAddressBySideTokenAddress",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "pause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "paused",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "receiveTokensTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renouncePauser",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "setFixedFee",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_isUpgrading",
+ "type": "bool"
+ }
+ ],
+ "name": "setUpgrading",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "sideTokenAddressByOriginalTokenAddress",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "sideTokenFactory",
+ "outputs": [
+ {
+ "internalType": "contract ISideNFTTokenFactory",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbolPrefix",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "name": "transactionDataHashes",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unpause",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x6ce41ced78a1a3525440fe542abf60ad84542502560ae4de84677589a27b70a1",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0xdc8E3000ED0aCAC926A37ead0f0B0F675182AC3b",
+ "transactionIndex": 0,
+ "gasUsed": "3300880",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x4b41262ec8a657b44ae7aabb7f055917d4a8a8a6a1099ed3efded4ba2491d5fa",
+ "transactionHash": "0x6ce41ced78a1a3525440fe542abf60ad84542502560ae4de84677589a27b70a1",
+ "logs": [],
+ "blockNumber": 2170980,
+ "cumulativeGasUsed": "3300880",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"}],\"name\":\"AcceptedNFTCrossTransfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newAllowTokens\",\"type\":\"address\"}],\"name\":\"AllowTokensChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_logIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"ClaimedNFTToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_tokenCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_userData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_totalSupply\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_tokenURI\",\"type\":\"string\"}],\"name\":\"Cross\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newFederation\",\"type\":\"address\"}],\"name\":\"FederationChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"FixedFeeNFTChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newSideNFTTokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_newSymbol\",\"type\":\"string\"}],\"name\":\"NewSideNFTToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"PauserRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newSideNFTTokenFactory\",\"type\":\"address\"}],\"name\":\"SideTokenFactoryChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"Upgrading\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__Pausable_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"__PauserRol_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"}],\"name\":\"acceptTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"addPauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allowTokens\",\"outputs\":[{\"internalType\":\"contract IAllowTokens\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAllowTokens\",\"type\":\"address\"}],\"name\":\"changeAllowTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"newFederation\",\"type\":\"address\"}],\"name\":\"changeFederation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newSideNFTTokenFactory\",\"type\":\"address\"}],\"name\":\"changeSideTokenFactory\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct INFTBridge.NFTClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct INFTBridge.NFTClaimData\",\"name\":\"_claimData\",\"type\":\"tuple\"}],\"name\":\"claimFallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"claimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_originalTokenAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_originalTokenSymbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_originalTokenName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_baseURI\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_contractURI\",\"type\":\"string\"}],\"name\":\"createSideNFTToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFederation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFixedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getTokenCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_transactionHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_logIndex\",\"type\":\"uint32\"}],\"name\":\"getTransactionDataHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasBeenClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transactionHash\",\"type\":\"bytes32\"}],\"name\":\"hasCrossed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"_federation\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_allowTokens\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_sideTokenFactory\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbolPrefix\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isAddressFromCrossedOriginalToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isPauser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUpgrading\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"originalTokenAddressBySideTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"receiveTokensTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renouncePauser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"setFixedFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_isUpgrading\",\"type\":\"bool\"}],\"name\":\"setUpgrading\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"sideTokenAddressByOriginalTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sideTokenFactory\",\"outputs\":[{\"internalType\":\"contract ISideNFTTokenFactory\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbolPrefix\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transactionDataHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"__Pausable_init(address)\":{\"details\":\"Initializes the contract in unpaused state. Assigns the Pauser role to the deployer.\"},\"initialize(address)\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pause()\":{\"details\":\"Called by a pauser to pause, triggers stopped state.\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"unpause()\":{\"details\":\"Called by a pauser to unpause, returns to normal state.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"claim((address,address,uint256,address,bytes32,bytes32,uint32))\":{\"notice\":\"Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Always returns `IERC721Receiver.onERC721Received.selector`.\"},\"receiveTokensTo(address,address,uint256)\":{\"notice\":\"ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/nftbridge/NFTBridge.sol\":\"NFTBridge\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interface/IAllowTokens.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IAllowTokens {\\r\\n\\r\\n struct Limits {\\r\\n uint256 min;\\r\\n uint256 max;\\r\\n uint256 daily;\\r\\n uint256 mediumAmount;\\r\\n uint256 largeAmount;\\r\\n }\\r\\n\\r\\n struct TokenInfo {\\r\\n bool allowed;\\r\\n uint256 typeId;\\r\\n uint256 spentToday;\\r\\n uint256 lastDay;\\r\\n }\\r\\n\\r\\n struct TypeInfo {\\r\\n string description;\\r\\n Limits limits;\\r\\n }\\r\\n\\r\\n struct TokensAndType {\\r\\n address token;\\r\\n uint256 typeId;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\\r\\n\\r\\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\\r\\n\\r\\n function getTypesLimits() external view returns(Limits[] memory limits);\\r\\n\\r\\n function getTypeDescriptionsLength() external view returns(uint256);\\r\\n\\r\\n function getTypeDescriptions() external view returns(string[] memory descriptions);\\r\\n\\r\\n function setToken(address token, uint256 typeId) external;\\r\\n\\r\\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\\r\\n\\r\\n function isTokenAllowed(address token) external view returns (bool);\\r\\n\\r\\n function updateTokenTransfer(address token, uint256 amount) external;\\r\\n}\",\"keccak256\":\"0xe565b0887688d1625e70316993d66adecc65890012d190a6e450ea7cb7d981b1\",\"license\":\"MIT\"},\"contracts/interface/IWrapped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\ninterface IWrapped {\\r\\n function balanceOf(address) external returns(uint);\\r\\n\\r\\n function deposit() external payable;\\r\\n\\r\\n function withdraw(uint wad) external;\\r\\n\\r\\n function totalSupply() external view returns (uint);\\r\\n\\r\\n function approve(address guy, uint wad) external returns (bool);\\r\\n\\r\\n function transfer(address dst, uint wad) external returns (bool);\\r\\n\\r\\n function transferFrom(address src, address dst, uint wad)\\r\\n external\\r\\n returns (bool);\\r\\n}\",\"keccak256\":\"0xb79b74797d9b4102d4ba69d452ed04bae742e34240c3aa72f654de525b29a5c7\",\"license\":\"MIT\"},\"contracts/lib/LibEIP712.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\\r\\nlibrary LibEIP712 {\\r\\n\\r\\n // Hash of the EIP712 Domain Separator Schema\\r\\n // keccak256(abi.encodePacked(\\r\\n // \\\"EIP712Domain(\\\",\\r\\n // \\\"string name,\\\",\\r\\n // \\\"string version,\\\",\\r\\n // \\\"uint256 chainId,\\\",\\r\\n // \\\"address verifyingContract\\\",\\r\\n // \\\")\\\"\\r\\n // ))\\r\\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\\r\\n\\r\\n /// @dev Calculates a EIP712 domain separator.\\r\\n /// @param name The EIP712 domain name.\\r\\n /// @param version The EIP712 domain version.\\r\\n /// @param verifyingContract The EIP712 verifying contract.\\r\\n /// @return result EIP712 domain separator.\\r\\n function hashEIP712Domain(\\r\\n string memory name,\\r\\n string memory version,\\r\\n uint256 chainId,\\r\\n address verifyingContract\\r\\n )\\r\\n internal\\r\\n pure\\r\\n returns (bytes32 result)\\r\\n {\\r\\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\\r\\n\\r\\n // Assembly for more efficient computing:\\r\\n // keccak256(abi.encodePacked(\\r\\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\\r\\n // keccak256(bytes(name)),\\r\\n // keccak256(bytes(version)),\\r\\n // chainId,\\r\\n // uint256(verifyingContract)\\r\\n // ))\\r\\n\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n // Calculate hashes of dynamic data\\r\\n let nameHash := keccak256(add(name, 32), mload(name))\\r\\n let versionHash := keccak256(add(version, 32), mload(version))\\r\\n\\r\\n // Load free memory pointer\\r\\n let memPtr := mload(64)\\r\\n\\r\\n // Store params in memory\\r\\n mstore(memPtr, schemaHash)\\r\\n mstore(add(memPtr, 32), nameHash)\\r\\n mstore(add(memPtr, 64), versionHash)\\r\\n mstore(add(memPtr, 96), chainId)\\r\\n mstore(add(memPtr, 128), verifyingContract)\\r\\n\\r\\n // Compute hash\\r\\n result := keccak256(memPtr, 160)\\r\\n }\\r\\n return result;\\r\\n }\\r\\n\\r\\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\\r\\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\\r\\n /// with getDomainHash().\\r\\n /// @param hashStruct The EIP712 hash struct.\\r\\n /// @return result EIP712 hash applied to the given EIP712 Domain.\\r\\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\\r\\n internal\\r\\n pure\\r\\n returns (bytes32 result)\\r\\n {\\r\\n // Assembly for more efficient computing:\\r\\n // keccak256(abi.encodePacked(\\r\\n // EIP191_HEADER,\\r\\n // EIP712_DOMAIN_HASH,\\r\\n // hashStruct\\r\\n // ));\\r\\n\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n // Load free memory pointer\\r\\n let memPtr := mload(64)\\r\\n\\r\\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\\r\\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\\r\\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\\r\\n\\r\\n // Compute hash\\r\\n result := keccak256(memPtr, 66)\\r\\n }\\r\\n return result;\\r\\n }\\r\\n}\",\"keccak256\":\"0xfcfcf60905df9a2644e372c9e76b8cc7a5034c5c4d6d9f44b1ffb56244551237\",\"license\":\"MIT\"},\"contracts/lib/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nlibrary LibUtils {\\r\\n\\r\\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\\r\\n require(decimals <= 18, \\\"LibUtils: Decimals not <= 18\\\");\\r\\n return uint256(10)**(18-decimals);\\r\\n }\\r\\n\\r\\n function getDecimals(address tokenToUse) internal view returns (uint8) {\\r\\n //support decimals as uint256 or uint8\\r\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"decimals()\\\"));\\r\\n require(success, \\\"LibUtils: No decimals\\\");\\r\\n // uint: enc(X) is the big-endian encoding of X,\\r\\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\\r\\n return uint8(abi.decode(data, (uint256)));\\r\\n }\\r\\n\\r\\n function getGranularity(address tokenToUse) internal view returns (uint256) {\\r\\n //support granularity if ERC777\\r\\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\\\"granularity()\\\"));\\r\\n require(success, \\\"LibUtils: No granularity\\\");\\r\\n\\r\\n return abi.decode(data, (uint256));\\r\\n }\\r\\n\\r\\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n addr := mload(add(bys,20))\\r\\n }\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0x9e289497bfdbde6ef762efab3d91e581cc83116929b69851e64da33a8d790196\",\"license\":\"MIT\"},\"contracts/nftbridge/INFTBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface INFTBridge {\\r\\n struct NFTClaimData {\\r\\n address payable to;\\r\\n address from;\\r\\n uint256 tokenId;\\r\\n address tokenAddress;\\r\\n bytes32 blockHash;\\r\\n bytes32 transactionHash;\\r\\n uint32 logIndex;\\r\\n }\\r\\n\\r\\n function version() external pure returns (string memory);\\r\\n\\r\\n function getFixedFee() external view returns (uint256);\\r\\n\\r\\n function receiveTokensTo(\\r\\n address tokenAddress,\\r\\n address to,\\r\\n uint256 tokenId\\r\\n ) external payable;\\r\\n\\r\\n /**\\r\\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\\r\\n */\\r\\n function acceptTransfer(\\r\\n address _originalTokenAddress,\\r\\n address payable _from,\\r\\n address payable _to,\\r\\n uint256 _tokenId,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\\r\\n */\\r\\n function claim(NFTClaimData calldata _claimData) external;\\r\\n\\r\\n function claimFallback(NFTClaimData calldata _claimData) external;\\r\\n\\r\\n function getTransactionDataHash(\\r\\n address _to,\\r\\n address _from,\\r\\n uint256 _tokenId,\\r\\n address _tokenAddress,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external returns (bytes32);\\r\\n\\r\\n event Cross(\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _from,\\r\\n address indexed _to,\\r\\n address _tokenCreator,\\r\\n bytes _userData,\\r\\n uint256 _totalSupply,\\r\\n uint256 _tokenId,\\r\\n string _tokenURI\\r\\n );\\r\\n event NewSideNFTToken(\\r\\n address indexed _newSideNFTTokenAddress,\\r\\n address indexed _originalTokenAddress,\\r\\n string _newSymbol\\r\\n );\\r\\n event AcceptedNFTCrossTransfer(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _from,\\r\\n uint256 _tokenId,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex\\r\\n );\\r\\n event FixedFeeNFTChanged(uint256 _amount);\\r\\n event ClaimedNFTToken(\\r\\n bytes32 indexed _transactionHash,\\r\\n address indexed _originalTokenAddress,\\r\\n address indexed _to,\\r\\n address _sender,\\r\\n uint256 _tokenId,\\r\\n bytes32 _blockHash,\\r\\n uint256 _logIndex,\\r\\n address _receiver\\r\\n );\\r\\n}\\r\\n\",\"keccak256\":\"0x2ae628c2bf573e402f83c817bb3bcf80a9f38aa82e328141f4cd9da1deadc88d\",\"license\":\"MIT\"},\"contracts/nftbridge/ISideNFTToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideNFTToken {\\r\\n function mint(address account, uint256 tokenId) external;\\r\\n}\",\"keccak256\":\"0xcedb55e825518cb74679fa8a249cc36f5621d3787075cfaf483729e44cd605d3\",\"license\":\"MIT\"},\"contracts/nftbridge/ISideNFTTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideNFTTokenFactory {\\r\\n\\r\\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\\r\\n string calldata contractURI) external returns(address);\\r\\n\\r\\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\\r\\n}\",\"keccak256\":\"0x94993f1c48d9cc1e806d04fc5468566c5314f992705729024c4f9bcdd1eeb99f\",\"license\":\"MIT\"},\"contracts/nftbridge/NFTBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n// Import base Initializable contract\\r\\nimport \\\"../zeppelin/upgradable/Initializable.sol\\\";\\r\\n// Import interface and library from OpenZeppelin contracts\\r\\nimport \\\"../zeppelin/upgradable/utils/ReentrancyGuard.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\\\";\\r\\nimport \\\"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\\\";\\r\\n\\r\\nimport \\\"../zeppelin/introspection/IERC1820Registry.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC20/IERC20.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC20/SafeERC20.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC721/IERC721.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC721/IERC721Metadata.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC721/IERC721Enumerable.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC721/IERC721Receiver.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC721/ERC721Burnable.sol\\\";\\r\\nimport \\\"../zeppelin/utils/Address.sol\\\";\\r\\nimport \\\"../zeppelin/math/SafeMath.sol\\\";\\r\\n\\r\\nimport \\\"../lib/LibEIP712.sol\\\";\\r\\nimport \\\"../lib/LibUtils.sol\\\";\\r\\n\\r\\nimport \\\"./INFTBridge.sol\\\";\\r\\nimport \\\"./ISideNFTToken.sol\\\";\\r\\nimport \\\"./ISideNFTTokenFactory.sol\\\";\\r\\nimport \\\"../interface/IAllowTokens.sol\\\";\\r\\nimport \\\"../interface/IWrapped.sol\\\";\\r\\n\\r\\n// solhint-disable-next-line max-states-count\\r\\ncontract NFTBridge is\\r\\n Initializable,\\r\\n INFTBridge,\\r\\n UpgradablePausable,\\r\\n UpgradableOwnable,\\r\\n ReentrancyGuard,\\r\\n IERC721Receiver {\\r\\n using SafeMath for uint256;\\r\\n using SafeERC20 for IERC20;\\r\\n using Address for address;\\r\\n\\r\\n address internal constant NULL_ADDRESS = address(0);\\r\\n bytes32 internal constant NULL_HASH = bytes32(0);\\r\\n IERC1820Registry internal constant ERC1820 =\\r\\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\r\\n\\r\\n address payable internal federation;\\r\\n uint256 internal fixedFee;\\r\\n string public symbolPrefix;\\r\\n\\r\\n mapping(address => address) public sideTokenAddressByOriginalTokenAddress;\\r\\n mapping(address => address) public originalTokenAddressBySideTokenAddress;\\r\\n mapping(address => bool) public isAddressFromCrossedOriginalToken; // address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\\r\\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\\r\\n IAllowTokens public allowTokens;\\r\\n ISideNFTTokenFactory public sideTokenFactory;\\r\\n bool public isUpgrading;\\r\\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\\r\\n\\r\\n event AllowTokensChanged(address _newAllowTokens);\\r\\n event FederationChanged(address _newFederation);\\r\\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\\r\\n event Upgrading(bool _isUpgrading);\\r\\n\\r\\n function initialize(\\r\\n address _manager,\\r\\n address payable _federation,\\r\\n address _allowTokens,\\r\\n address _sideTokenFactory,\\r\\n string memory _symbolPrefix\\r\\n ) public initializer {\\r\\n UpgradableOwnable.initialize(_manager);\\r\\n UpgradablePausable.__Pausable_init(_manager);\\r\\n symbolPrefix = _symbolPrefix;\\r\\n allowTokens = IAllowTokens(_allowTokens);\\r\\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\\r\\n federation = _federation;\\r\\n ERC1820.setInterfaceImplementer(\\r\\n address(this),\\r\\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\\r\\n address(this)\\r\\n );\\r\\n }\\r\\n\\r\\n function version() external pure override returns (string memory) {\\r\\n return \\\"v1\\\";\\r\\n }\\r\\n\\r\\n modifier whenNotUpgrading() {\\r\\n require(!isUpgrading, \\\"Bridge: Upgrading\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function acceptTransfer(\\r\\n address _tokenAddress,\\r\\n address payable _from,\\r\\n address payable _to,\\r\\n uint256 _tokenId,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) external whenNotPaused nonReentrant override {\\r\\n require(_msgSender() == federation, \\\"NFTBridge: Not Federation\\\");\\r\\n require(\\r\\n isAddressFromCrossedOriginalToken[_tokenAddress] ||\\r\\n sideTokenAddressByOriginalTokenAddress[_tokenAddress] != NULL_ADDRESS,\\r\\n \\\"NFTBridge: Unknown token\\\"\\r\\n );\\r\\n require(_to != NULL_ADDRESS, \\\"NFTBridge: Null To\\\");\\r\\n require(_from != NULL_ADDRESS, \\\"NFTBridge: Null From\\\");\\r\\n require(_blockHash != NULL_HASH, \\\"NFTBridge: Null BlockHash\\\");\\r\\n require(_transactionHash != NULL_HASH, \\\"NFTBridge: Null TxHash\\\");\\r\\n require(\\r\\n transactionDataHashes[_transactionHash] == bytes32(0),\\r\\n \\\"NFTBridge: Already accepted\\\"\\r\\n );\\r\\n\\r\\n bytes32 _transactionDataHash = getTransactionDataHash(\\r\\n _to,\\r\\n _from,\\r\\n _tokenId,\\r\\n _tokenAddress,\\r\\n _blockHash,\\r\\n _transactionHash,\\r\\n _logIndex\\r\\n );\\r\\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\\r\\n require(!claimed[_transactionDataHash], \\\"NFTBridge: Already claimed\\\");\\r\\n\\r\\n transactionDataHashes[_transactionHash] = _transactionDataHash;\\r\\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\\r\\n// senderAddresses[_transactionHash] = _from;\\r\\n\\r\\n emit AcceptedNFTCrossTransfer(\\r\\n _transactionHash,\\r\\n _tokenAddress,\\r\\n _to,\\r\\n _from,\\r\\n _tokenId,\\r\\n _blockHash,\\r\\n _logIndex\\r\\n );\\r\\n }\\r\\n\\r\\n function createSideNFTToken(\\r\\n address _originalTokenAddress,\\r\\n string calldata _originalTokenSymbol,\\r\\n string calldata _originalTokenName,\\r\\n string calldata _baseURI,\\r\\n string calldata _contractURI\\r\\n ) external onlyOwner {\\r\\n require(_originalTokenAddress != NULL_ADDRESS, \\\"NFTBridge: Null original token address\\\");\\r\\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[_originalTokenAddress];\\r\\n require(sideTokenAddress == NULL_ADDRESS, \\\"NFTBridge: Side token already exists\\\");\\r\\n string memory sideTokenSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\\r\\n\\r\\n // Create side token\\r\\n sideTokenAddress = sideTokenFactory.createSideNFTToken(_originalTokenName, sideTokenSymbol, _baseURI, _contractURI);\\r\\n\\r\\n sideTokenAddressByOriginalTokenAddress[_originalTokenAddress] = sideTokenAddress;\\r\\n originalTokenAddressBySideTokenAddress[sideTokenAddress] = _originalTokenAddress;\\r\\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, sideTokenSymbol);\\r\\n }\\r\\n\\r\\n function claim(NFTClaimData calldata _claimData) external override {\\r\\n _claim(_claimData, _claimData.to);\\r\\n }\\r\\n\\r\\n function claimFallback(NFTClaimData calldata _claimData) external override {\\r\\n require(_msgSender() == _claimData.from, \\\"NFTBridge: invalid sender\\\");\\r\\n _claim(_claimData, _msgSender());\\r\\n }\\r\\n\\r\\n function _claim(\\r\\n NFTClaimData calldata _claimData,\\r\\n address payable _receiver\\r\\n ) internal {\\r\\n address tokenAddress = _claimData.tokenAddress;\\r\\n uint256 tokenId = _claimData.tokenId;\\r\\n\\r\\n bytes32 transactionDataHash = getTransactionDataHash(\\r\\n _claimData.to,\\r\\n _claimData.from,\\r\\n tokenId,\\r\\n tokenAddress,\\r\\n _claimData.blockHash,\\r\\n _claimData.transactionHash,\\r\\n _claimData.logIndex\\r\\n );\\r\\n require(\\r\\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\\r\\n \\\"NFTBridge: Wrong txDataHash\\\"\\r\\n );\\r\\n require(!claimed[transactionDataHash], \\\"NFTBridge: Already claimed\\\");\\r\\n\\r\\n claimed[transactionDataHash] = true;\\r\\n bool isClaimBeingRequestedInMainChain = isAddressFromCrossedOriginalToken[tokenAddress];\\r\\n if (isClaimBeingRequestedInMainChain) {\\r\\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\\r\\n } else {\\r\\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[tokenAddress];\\r\\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\\r\\n }\\r\\n\\r\\n emit ClaimedNFTToken(\\r\\n _claimData.transactionHash,\\r\\n tokenAddress,\\r\\n _claimData.to,\\r\\n _claimData.from,\\r\\n _claimData.tokenId,\\r\\n _claimData.blockHash,\\r\\n _claimData.logIndex,\\r\\n _receiver\\r\\n );\\r\\n }\\r\\n\\r\\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\\r\\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\\\"creator()\\\"));\\r\\n if (success) {\\r\\n return abi.decode(data, (address));\\r\\n }\\r\\n\\r\\n return IERC721(tokenAddress).ownerOf(tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * ERC-20 tokens approve and transferFrom pattern\\r\\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\\r\\n */\\r\\n function receiveTokensTo(\\r\\n address tokenAddress,\\r\\n address to,\\r\\n uint256 tokenId\\r\\n ) public payable override {\\r\\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\\r\\n\\r\\n address payable sender = _msgSender();\\r\\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\\r\\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\\r\\n\\r\\n crossTokens(tokenAddress, to, tokenCreator, \\\"\\\", tokenId);\\r\\n\\r\\n if (fixedFee > 0) {\\r\\n require(msg.value >= fixedFee, \\\"NFTBridge: value is smaller than fixed fee\\\");\\r\\n\\r\\n // Send the payment to the MultiSig of the Federation\\r\\n federation.transfer(fixedFee);\\r\\n if (msg.value > fixedFee) { // refund of unused value\\r\\n sender.transfer(msg.value.sub(fixedFee));\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n function crossTokens(\\r\\n address tokenAddress,\\r\\n address to,\\r\\n address tokenCreator,\\r\\n bytes memory userData,\\r\\n uint256 tokenId\\r\\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\\r\\n isAddressFromCrossedOriginalToken[tokenAddress] = true;\\r\\n\\r\\n IERC721Enumerable enumerable = IERC721Enumerable(tokenAddress);\\r\\n IERC721Metadata metadataIERC = IERC721Metadata(tokenAddress);\\r\\n string memory tokenURI = metadataIERC.tokenURI(tokenId);\\r\\n\\r\\n address originalTokenAddress = tokenAddress;\\r\\n if (originalTokenAddressBySideTokenAddress[tokenAddress] != NULL_ADDRESS) {\\r\\n originalTokenAddress = originalTokenAddressBySideTokenAddress[tokenAddress];\\r\\n ERC721Burnable(tokenAddress).burn(tokenId);\\r\\n }\\r\\n\\r\\n emit Cross(\\r\\n originalTokenAddress,\\r\\n _msgSender(),\\r\\n to,\\r\\n tokenCreator,\\r\\n userData,\\r\\n enumerable.totalSupply(),\\r\\n tokenId,\\r\\n tokenURI\\r\\n );\\r\\n }\\r\\n\\r\\n function getTransactionDataHash(\\r\\n address _to,\\r\\n address _from,\\r\\n uint256 _tokenId,\\r\\n address _tokenAddress,\\r\\n bytes32 _blockHash,\\r\\n bytes32 _transactionHash,\\r\\n uint32 _logIndex\\r\\n ) public pure override returns (bytes32) {\\r\\n return keccak256(\\r\\n abi.encodePacked(\\r\\n _blockHash,\\r\\n _transactionHash,\\r\\n _to,\\r\\n _from,\\r\\n _tokenId,\\r\\n _tokenAddress,\\r\\n _logIndex\\r\\n )\\r\\n );\\r\\n }\\r\\n\\r\\n function setFixedFee(uint256 amount) external onlyOwner {\\r\\n fixedFee = amount;\\r\\n emit FixedFeeNFTChanged(fixedFee);\\r\\n }\\r\\n\\r\\n function getFixedFee() external view override returns (uint256) {\\r\\n return fixedFee;\\r\\n }\\r\\n\\r\\n function changeFederation(address payable newFederation) external onlyOwner {\\r\\n require(newFederation != NULL_ADDRESS, \\\"NFTBridge: Federation is empty\\\");\\r\\n federation = newFederation;\\r\\n emit FederationChanged(federation);\\r\\n }\\r\\n\\r\\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\\r\\n require(newAllowTokens != NULL_ADDRESS, \\\"NFTBridge: AllowTokens is empty\\\");\\r\\n allowTokens = IAllowTokens(newAllowTokens);\\r\\n emit AllowTokensChanged(newAllowTokens);\\r\\n }\\r\\n\\r\\n function getFederation() external view returns (address) {\\r\\n return federation;\\r\\n }\\r\\n\\r\\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\\r\\n require(\\r\\n newSideNFTTokenFactory != NULL_ADDRESS,\\r\\n \\\"NFTBridge: empty SideTokenFactory\\\"\\r\\n );\\r\\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\\r\\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\\r\\n }\\r\\n\\r\\n function setUpgrading(bool _isUpgrading) external onlyOwner {\\r\\n isUpgrading = _isUpgrading;\\r\\n emit Upgrading(isUpgrading);\\r\\n }\\r\\n\\r\\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\\r\\n return transactionDataHashes[transactionHash] != bytes32(0);\\r\\n }\\r\\n\\r\\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\\r\\n return claimed[transactionDataHashes[transactionHash]];\\r\\n }\\r\\n\\r\\n /**\\r\\n * Always returns `IERC721Receiver.onERC721Received.selector`.\\r\\n */\\r\\n function onERC721Received(\\r\\n address,\\r\\n address,\\r\\n uint256,\\r\\n bytes memory\\r\\n ) public virtual override returns (bytes4) {\\r\\n return this.onERC721Received.selector;\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0x1d5e192990a4660c02e48e52be750cbca20966baa95cb036f0d6c7512da0eacf\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/access/Roles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @title Roles\\r\\n * @dev Library for managing addresses assigned to a Role.\\r\\n */\\r\\nlibrary Roles {\\r\\n struct Role {\\r\\n mapping (address => bool) bearer;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Give an account access to this role.\\r\\n */\\r\\n function add(Role storage role, address account) internal {\\r\\n require(!has(role, account), \\\"Roles: account already has role\\\");\\r\\n role.bearer[account] = true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Remove an account's access to this role.\\r\\n */\\r\\n function remove(Role storage role, address account) internal {\\r\\n require(has(role, account), \\\"Roles: account doesn't have role\\\");\\r\\n role.bearer[account] = false;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Check if an account has this role.\\r\\n * @return bool\\r\\n */\\r\\n function has(Role storage role, address account) internal view returns (bool) {\\r\\n require(account != address(0), \\\"Roles: account is the zero address\\\");\\r\\n return role.bearer[account];\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x51be0ac4cc78172ee6ee886a4779e6b8f289420541d28be81f3c427c5118c298\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC165.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Implementation of the {IERC165} interface.\\r\\n *\\r\\n * Contracts may inherit from this and call {_registerInterface} to declare\\r\\n * their support of an interface.\\r\\n */\\r\\nabstract contract ERC165 is IERC165 {\\r\\n /*\\r\\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\\r\\n\\r\\n /**\\r\\n * @dev Mapping of interface ids to whether or not it's supported.\\r\\n */\\r\\n mapping(bytes4 => bool) private _supportedInterfaces;\\r\\n\\r\\n constructor () {\\r\\n // Derived contracts need only register support for their own interfaces,\\r\\n // we register support for ERC165 itself here\\r\\n _registerInterface(_INTERFACE_ID_ERC165);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC165-supportsInterface}.\\r\\n *\\r\\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\\r\\n */\\r\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\r\\n return _supportedInterfaces[interfaceId];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Registers the contract as an implementer of the interface defined by\\r\\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\\r\\n * registering its interface id is not required.\\r\\n *\\r\\n * See {IERC165-supportsInterface}.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\\r\\n */\\r\\n function _registerInterface(bytes4 interfaceId) internal virtual {\\r\\n require(interfaceId != 0xffffffff, \\\"ERC165: invalid interface id\\\");\\r\\n _supportedInterfaces[interfaceId] = true;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x5415f8c63658ee08e6284e6f270b2490331aea0c375b6451c4c9ed14a805a336\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC165 standard, as defined in the\\r\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\r\\n *\\r\\n * Implementers can declare support of contract interfaces, which can then be\\r\\n * queried by others ({ERC165Checker}).\\r\\n *\\r\\n * For an implementation, see {ERC165}.\\r\\n */\\r\\ninterface IERC165 {\\r\\n /**\\r\\n * @dev Returns true if this contract implements the interface defined by\\r\\n * `interfaceId`. See the corresponding\\r\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\r\\n * to learn more about how these ids are created.\\r\\n *\\r\\n * This function call must use less than 30 000 gas.\\r\\n */\\r\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\r\\n}\\r\\n\",\"keccak256\":\"0xd5da4ccf6a22475f021130a32aaad92daf6eecce9258cb7a8a5c48d109607767\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC1820Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\r\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\r\\n * implementers for interfaces in this registry, as well as query support.\\r\\n *\\r\\n * Implementers may be shared by multiple accounts, and can also implement more\\r\\n * than a single interface for each account. Contracts can implement interfaces\\r\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\r\\n * contract.\\r\\n *\\r\\n * {IERC165} interfaces can also be queried via the registry.\\r\\n *\\r\\n * For an in-depth explanation and source code analysis, see the EIP text.\\r\\n */\\r\\ninterface IERC1820Registry {\\r\\n /**\\r\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\r\\n * account is able to set interface implementers for it.\\r\\n *\\r\\n * By default, each account is its own manager. Passing a value of `0x0` in\\r\\n * `newManager` will reset the manager to this initial state.\\r\\n *\\r\\n * Emits a {ManagerChanged} event.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the caller must be the current manager for `account`.\\r\\n */\\r\\n function setManager(address account, address newManager) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the manager for `account`.\\r\\n *\\r\\n * See {setManager}.\\r\\n */\\r\\n function getManager(address account) external view returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Sets the `implementer` contract as `account`'s implementer for\\r\\n * `interfaceHash`.\\r\\n *\\r\\n * `account` being the zero address is an alias for the caller's address.\\r\\n * The zero address can also be used in `implementer` to remove an old one.\\r\\n *\\r\\n * See {interfaceHash} to learn how these are created.\\r\\n *\\r\\n * Emits an {InterfaceImplementerSet} event.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the caller must be the current manager for `_account`.\\r\\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\r\\n * end in 28 zeroes).\\r\\n * - `_implementer` must implement {IERC1820Implementer} and return true when\\r\\n * queried for support, unless `implementer` is the caller. See\\r\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\r\\n */\\r\\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\\r\\n * implementer is registered, returns the zero address.\\r\\n *\\r\\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\r\\n * zeroes), `_account` will be queried for support of it.\\r\\n *\\r\\n * `account` being the zero address is an alias for the caller's address.\\r\\n */\\r\\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\r\\n * corresponding\\r\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\r\\n */\\r\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\r\\n\\r\\n /**\\r\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\r\\n * @param account Address of the contract for which to update the cache.\\r\\n * @param interfaceId ERC165 interface for which to update the cache.\\r\\n */\\r\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\r\\n\\r\\n /**\\r\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\r\\n * If the result is not cached a direct lookup on the contract address is performed.\\r\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\r\\n * {updateERC165Cache} with the contract address.\\r\\n * @param account Address of the contract to check.\\r\\n * @param interfaceId ERC165 interface to check.\\r\\n * @return True if `account` implements `interfaceId`, false otherwise.\\r\\n */\\r\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\\r\\n * @param account Address of the contract to check.\\r\\n * @param interfaceId ERC165 interface to check.\\r\\n * @return True if `account` implements `interfaceId`, false otherwise.\\r\\n */\\r\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\r\\n\\r\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\r\\n\\r\\n event ManagerChanged(address indexed account, address indexed newManager);\\r\\n}\\r\\n\",\"keccak256\":\"0x0c607a83a8f5ec2f214bc754ffb59428d90978e122108fcd91ba193d5fc78018\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\r\\n * checks.\\r\\n *\\r\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\r\\n * in bugs, because programmers usually assume that an overflow raises an\\r\\n * error, which is the standard behavior in high level programming languages.\\r\\n * `SafeMath` restores this intuition by reverting the transaction when an\\r\\n * operation overflows.\\r\\n *\\r\\n * Using this library instead of the unchecked operations eliminates an entire\\r\\n * class of bugs, so it's recommended to use it always.\\r\\n */\\r\\nlibrary SafeMath {\\r\\n /**\\r\\n * @dev Returns the addition of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `+` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Addition cannot overflow.\\r\\n */\\r\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n uint256 c = a + b;\\r\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n */\\r\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b <= a, errorMessage);\\r\\n uint256 c = a - b;\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `*` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Multiplication cannot overflow.\\r\\n */\\r\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\r\\n // benefit is lost if 'b' is also tested.\\r\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\r\\n if (a == 0) {\\r\\n return 0;\\r\\n }\\r\\n\\r\\n uint256 c = a * b;\\r\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n // Solidity only automatically asserts when dividing by 0\\r\\n require(b > 0, errorMessage);\\r\\n uint256 c = a / b;\\r\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts with custom message when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b != 0, errorMessage);\\r\\n return a % b;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x29ffa7ff59806a3add585615cc102b70b43049587dcc73649f77b427f35b009d\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\r\\n * the optional functions; to access them see {ERC20Detailed}.\\r\\n */\\r\\ninterface IERC20 {\\r\\n /**\\r\\n * @dev Returns the amount of tokens in existence.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens owned by `account`.\\r\\n */\\r\\n function balanceOf(address account) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transfer(address recipient, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Returns the remaining number of tokens that `spender` will be\\r\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\r\\n * zero by default.\\r\\n *\\r\\n * This value changes when {approve} or {transferFrom} are called.\\r\\n */\\r\\n function allowance(address owner, address spender) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\r\\n * that someone may use both the old and the new allowance by unfortunate\\r\\n * transaction ordering. One possible solution to mitigate this race\\r\\n * condition is to first reduce the spender's allowance to 0 and set the\\r\\n * desired value afterwards:\\r\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\r\\n *\\r\\n * Emits an {Approval} event.\\r\\n */\\r\\n function approve(address spender, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\r\\n * allowance mechanism. `amount` is then deducted from the caller's\\r\\n * allowance.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\r\\n * another (`to`).\\r\\n *\\r\\n * Note that `value` may be zero.\\r\\n */\\r\\n event Transfer(address indexed from, address indexed to, uint256 value);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\r\\n * a call to {approve}. `value` is the new allowance.\\r\\n */\\r\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\r\\n}\\r\\n\",\"keccak256\":\"0x7531f90b8a5a04fd225fb07a30e0792068438a7c82127a22db870c1849460dfc\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./IERC20.sol\\\";\\r\\nimport \\\"../../math/SafeMath.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title SafeERC20\\r\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\r\\n * contract returns false). Tokens that return no value (and instead revert or\\r\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\r\\n * successful.\\r\\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\\r\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\r\\n */\\r\\nlibrary SafeERC20 {\\r\\n using SafeMath for uint256;\\r\\n using Address for address;\\r\\n\\r\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\r\\n }\\r\\n\\r\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\r\\n }\\r\\n\\r\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\r\\n // safeApprove should only be called when setting an initial allowance,\\r\\n // or when resetting it to zero. To increase and decrease it, use\\r\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\r\\n // solhint-disable-next-line max-line-length\\r\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\r\\n \\\"SafeERC20: approve non-zero to non-zero allowance\\\"\\r\\n );\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\r\\n }\\r\\n\\r\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\r\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\r\\n }\\r\\n\\r\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\r\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\r\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\r\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\r\\n * @param token The token targeted by the call.\\r\\n * @param data The call data (encoded using abi.encode or one of its variants).\\r\\n */\\r\\n function callOptionalReturn(IERC20 token, bytes memory data) private {\\r\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\r\\n // we're implementing it ourselves.\\r\\n\\r\\n // A Solidity high level call has three parts:\\r\\n // 1. The target address is checked to verify it contains contract code\\r\\n // 2. The call itself is made, and success asserted\\r\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\r\\n // solhint-disable-next-line max-line-length\\r\\n require(address(token).isContract(), \\\"SafeERC20: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = address(token).call(data);\\r\\n require(success, \\\"SafeERC20: low-level call failed\\\");\\r\\n\\r\\n if (returndata.length > 0) { // Return data is optional\\r\\n // solhint-disable-next-line max-line-length\\r\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x393fa2aef898c565ba8c8816ac0e2d0e31865d2866e4807f39f1a8cef95f5a81\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"./IERC721.sol\\\";\\r\\nimport \\\"./IERC721Metadata.sol\\\";\\r\\nimport \\\"./IERC721Enumerable.sol\\\";\\r\\nimport \\\"./IERC721Receiver.sol\\\";\\r\\nimport \\\"../../introspection/ERC165.sol\\\";\\r\\nimport \\\"../../math/SafeMath.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\nimport \\\"../../utils/EnumerableSet.sol\\\";\\r\\nimport \\\"../../utils/EnumerableMap.sol\\\";\\r\\nimport \\\"../../utils/Strings.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC721 Non-Fungible Token Standard basic implementation\\r\\n * @dev see https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\\r\\n using SafeMath for uint256;\\r\\n using Address for address;\\r\\n using EnumerableSet for EnumerableSet.UintSet;\\r\\n using EnumerableMap for EnumerableMap.UintToAddressMap;\\r\\n using Strings for uint256;\\r\\n\\r\\n // Equals to `bytes4(keccak256(\\\"onERC721Received(address,address,uint256,bytes)\\\"))`\\r\\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\\r\\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\\r\\n\\r\\n // Mapping from holder address to their (enumerable) set of owned tokens\\r\\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\\r\\n\\r\\n // Enumerable mapping from token ids to their owners\\r\\n EnumerableMap.UintToAddressMap private _tokenOwners;\\r\\n\\r\\n // Mapping from token ID to approved address\\r\\n mapping (uint256 => address) private _tokenApprovals;\\r\\n\\r\\n // Mapping from owner to operator approvals\\r\\n mapping (address => mapping (address => bool)) private _operatorApprovals;\\r\\n\\r\\n // Token name\\r\\n string private _name;\\r\\n\\r\\n // Token symbol\\r\\n string private _symbol;\\r\\n\\r\\n // Optional mapping for token URIs\\r\\n mapping (uint256 => string) private _tokenURIs;\\r\\n\\r\\n // Base URI\\r\\n string private _baseURI;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\\r\\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\\r\\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\\r\\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\\r\\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\\r\\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\\r\\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\\r\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\\r\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\\r\\n *\\r\\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\\r\\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('name()')) == 0x06fdde03\\r\\n * bytes4(keccak256('symbol()')) == 0x95d89b41\\r\\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\\r\\n *\\r\\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\\r\\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\\r\\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\\r\\n *\\r\\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\r\\n */\\r\\n constructor (string memory name_, string memory symbol_) {\\r\\n _name = name_;\\r\\n _symbol = symbol_;\\r\\n\\r\\n // register the supported interfaces to conform to ERC721 via ERC165\\r\\n _registerInterface(_INTERFACE_ID_ERC721);\\r\\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\\r\\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-balanceOf}.\\r\\n */\\r\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\r\\n require(owner != address(0), \\\"ERC721: balance query for the zero address\\\");\\r\\n return _holderTokens[owner].length();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-ownerOf}.\\r\\n */\\r\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\r\\n return _tokenOwners.get(tokenId, \\\"ERC721: owner query for nonexistent token\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-name}.\\r\\n */\\r\\n function name() public view virtual override returns (string memory) {\\r\\n return _name;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-symbol}.\\r\\n */\\r\\n function symbol() public view virtual override returns (string memory) {\\r\\n return _symbol;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-tokenURI}.\\r\\n */\\r\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\r\\n require(_exists(tokenId), \\\"ERC721Metadata: URI query for nonexistent token\\\");\\r\\n\\r\\n string memory _tokenURI = _tokenURIs[tokenId];\\r\\n string memory base = baseURI();\\r\\n\\r\\n // If there is no base URI, return the token URI.\\r\\n if (bytes(base).length == 0) {\\r\\n return _tokenURI;\\r\\n }\\r\\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\\r\\n if (bytes(_tokenURI).length > 0) {\\r\\n return string(abi.encodePacked(base, _tokenURI));\\r\\n }\\r\\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\\r\\n return string(abi.encodePacked(base, tokenId.toString()));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the base URI set via {_setBaseURI}. This will be\\r\\n * automatically added as a prefix in {tokenURI} to each token's URI, or\\r\\n * to the token ID if no specific URI is set for that token ID.\\r\\n */\\r\\n function baseURI() public view virtual returns (string memory) {\\r\\n return _baseURI;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\r\\n */\\r\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\r\\n return _holderTokens[owner].at(index);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-totalSupply}.\\r\\n */\\r\\n function totalSupply() public view virtual override returns (uint256) {\\r\\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\\r\\n return _tokenOwners.length();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\r\\n */\\r\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\r\\n (uint256 tokenId, ) = _tokenOwners.at(index);\\r\\n return tokenId;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-approve}.\\r\\n */\\r\\n function approve(address to, uint256 tokenId) public virtual override {\\r\\n address owner = ERC721.ownerOf(tokenId);\\r\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\r\\n\\r\\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\\r\\n \\\"ERC721: approve caller is not owner nor approved for all\\\"\\r\\n );\\r\\n\\r\\n _approve(to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-getApproved}.\\r\\n */\\r\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\r\\n require(_exists(tokenId), \\\"ERC721: approved query for nonexistent token\\\");\\r\\n\\r\\n return _tokenApprovals[tokenId];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-setApprovalForAll}.\\r\\n */\\r\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\r\\n require(operator != _msgSender(), \\\"ERC721: approve to caller\\\");\\r\\n\\r\\n _operatorApprovals[_msgSender()][operator] = approved;\\r\\n emit ApprovalForAll(_msgSender(), operator, approved);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-isApprovedForAll}.\\r\\n */\\r\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\r\\n return _operatorApprovals[owner][operator];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-transferFrom}.\\r\\n */\\r\\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\\r\\n //solhint-disable-next-line max-line-length\\r\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\r\\n\\r\\n _transfer(from, to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-safeTransferFrom}.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\\r\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-safeTransferFrom}.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\\r\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\r\\n _safeTransfer(from, to, tokenId, _data);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\r\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\r\\n *\\r\\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\\r\\n *\\r\\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\r\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\\r\\n _transfer(from, to, tokenId);\\r\\n require(_checkOnERC721Received(from, to, tokenId, _data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns whether `tokenId` exists.\\r\\n *\\r\\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\r\\n *\\r\\n * Tokens start existing when they are minted (`_mint`),\\r\\n * and stop existing when they are burned (`_burn`).\\r\\n */\\r\\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\\r\\n return _tokenOwners.contains(tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\r\\n require(_exists(tokenId), \\\"ERC721: operator query for nonexistent token\\\");\\r\\n address owner = ERC721.ownerOf(tokenId);\\r\\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\r\\n *\\r\\n * Requirements:\\r\\n d*\\r\\n * - `tokenId` must not exist.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\r\\n _safeMint(to, tokenId, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\r\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\r\\n */\\r\\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\\r\\n _mint(to, tokenId);\\r\\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Mints `tokenId` and transfers it to `to`.\\r\\n *\\r\\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must not exist.\\r\\n * - `to` cannot be the zero address.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _mint(address to, uint256 tokenId) internal virtual {\\r\\n require(to != address(0), \\\"ERC721: mint to the zero address\\\");\\r\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\r\\n\\r\\n _beforeTokenTransfer(address(0), to, tokenId);\\r\\n\\r\\n _holderTokens[to].add(tokenId);\\r\\n\\r\\n _tokenOwners.set(tokenId, to);\\r\\n\\r\\n emit Transfer(address(0), to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Destroys `tokenId`.\\r\\n * The approval is cleared when the token is burned.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _burn(uint256 tokenId) internal virtual {\\r\\n address owner = ERC721.ownerOf(tokenId); // internal owner\\r\\n\\r\\n _beforeTokenTransfer(owner, address(0), tokenId);\\r\\n\\r\\n // Clear approvals\\r\\n _approve(address(0), tokenId);\\r\\n\\r\\n // Clear metadata (if any)\\r\\n if (bytes(_tokenURIs[tokenId]).length != 0) {\\r\\n delete _tokenURIs[tokenId];\\r\\n }\\r\\n\\r\\n _holderTokens[owner].remove(tokenId);\\r\\n\\r\\n _tokenOwners.remove(tokenId);\\r\\n\\r\\n emit Transfer(owner, address(0), tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers `tokenId` from `from` to `to`.\\r\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must be owned by `from`.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\\r\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer of token that is not own\\\"); // internal owner\\r\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\r\\n\\r\\n _beforeTokenTransfer(from, to, tokenId);\\r\\n\\r\\n // Clear approvals from the previous owner\\r\\n _approve(address(0), tokenId);\\r\\n\\r\\n _holderTokens[from].remove(tokenId);\\r\\n _holderTokens[to].add(tokenId);\\r\\n\\r\\n _tokenOwners.set(tokenId, to);\\r\\n\\r\\n emit Transfer(from, to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\\r\\n require(_exists(tokenId), \\\"ERC721Metadata: URI set of nonexistent token\\\");\\r\\n _tokenURIs[tokenId] = _tokenURI;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Internal function to set the base URI for all token IDs. It is\\r\\n * automatically added as a prefix to the value returned in {tokenURI},\\r\\n * or to the token ID if {tokenURI} is empty.\\r\\n */\\r\\n function _setBaseURI(string memory baseURI_) internal virtual {\\r\\n _baseURI = baseURI_;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\r\\n * The call is not executed if the target address is not a contract.\\r\\n *\\r\\n * @param from address representing the previous owner of the given token ID\\r\\n * @param to target address that will receive the tokens\\r\\n * @param tokenId uint256 ID of the token to be transferred\\r\\n * @param _data bytes optional data to send along with the call\\r\\n * @return bool whether the call correctly returned the expected magic value\\r\\n */\\r\\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\\r\\n private returns (bool)\\r\\n {\\r\\n if (!to.isContract()) {\\r\\n return true;\\r\\n }\\r\\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\\r\\n IERC721Receiver(to).onERC721Received.selector,\\r\\n _msgSender(),\\r\\n from,\\r\\n tokenId,\\r\\n _data\\r\\n ), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n bytes4 retval = abi.decode(returndata, (bytes4));\\r\\n return (retval == _ERC721_RECEIVED);\\r\\n }\\r\\n\\r\\n function _approve(address to, uint256 tokenId) private {\\r\\n _tokenApprovals[tokenId] = to;\\r\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Hook that is called before any token transfer. This includes minting\\r\\n * and burning.\\r\\n *\\r\\n * Calling conditions:\\r\\n *\\r\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\r\\n * transferred to `to`.\\r\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\r\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n *\\r\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\r\\n */\\r\\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\\r\\n}\\r\\n\",\"keccak256\":\"0x4180eedc31f632ef146dd07583840a9688de44bdb9e7fe2425c448fd57496004\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"./ERC721.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC721 Burnable Token\\r\\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\\r\\n */\\r\\nabstract contract ERC721Burnable is Context, ERC721 {\\r\\n /**\\r\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - The caller must own `tokenId` or be an approved operator.\\r\\n */\\r\\n function burn(uint256 tokenId) public virtual {\\r\\n //solhint-disable-next-line max-line-length\\r\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721Burnable: caller is not owner nor approved\\\");\\r\\n _burn(tokenId);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x699ce4b0903e16b958d6a008703c24be7d11a7d3223e5e9ab9523a8f81687f13\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../../introspection/IERC165.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Required interface of an ERC721 compliant contract.\\r\\n */\\r\\ninterface IERC721 is IERC165 {\\r\\n /**\\r\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\r\\n */\\r\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\r\\n */\\r\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\r\\n */\\r\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of tokens in ``owner``'s account.\\r\\n */\\r\\n function balanceOf(address owner) external view returns (uint256 balance);\\r\\n\\r\\n /**\\r\\n * @dev Returns the owner of the `tokenId` token.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\r\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Transfers `tokenId` token from `from` to `to`.\\r\\n *\\r\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must be owned by `from`.\\r\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transferFrom(address from, address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\r\\n * The approval is cleared when the token is transferred.\\r\\n *\\r\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - The caller must own the token or be an approved operator.\\r\\n * - `tokenId` must exist.\\r\\n *\\r\\n * Emits an {Approval} event.\\r\\n */\\r\\n function approve(address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the account approved for `tokenId` token.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function getApproved(uint256 tokenId) external view returns (address operator);\\r\\n\\r\\n /**\\r\\n * @dev Approve or remove `operator` as an operator for the caller.\\r\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - The `operator` cannot be the caller.\\r\\n *\\r\\n * Emits an {ApprovalForAll} event.\\r\\n */\\r\\n function setApprovalForAll(address operator, bool _approved) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\r\\n *\\r\\n * See {setApprovalForAll}\\r\\n */\\r\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\r\\n}\\r\\n\",\"keccak256\":\"0xd3c22060e78ce52f5cb41b3ab9b29bb5582aa4a58015e878116251cba658324c\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC721.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\r\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ninterface IERC721Enumerable is IERC721 {\\r\\n\\r\\n /**\\r\\n * @dev Returns the total amount of tokens stored by the contract.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\r\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\r\\n */\\r\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\r\\n * Use along with {totalSupply} to enumerate all tokens.\\r\\n */\\r\\n function tokenByIndex(uint256 index) external view returns (uint256);\\r\\n}\\r\\n\",\"keccak256\":\"0x5539b1567797a57e7a135dcc446fdbb02b1ae2b450799274db88a47dea81e6fa\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC721.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\r\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ninterface IERC721Metadata is IERC721 {\\r\\n\\r\\n /**\\r\\n * @dev Returns the token collection name.\\r\\n */\\r\\n function name() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the token collection symbol.\\r\\n */\\r\\n function symbol() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\r\\n */\\r\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\r\\n}\\r\\n\",\"keccak256\":\"0xe92ae6f0b94fce8480d16a24faa8835926cd5fc074a4d418de94aaddbdecf49d\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @title ERC721 token receiver interface\\r\\n * @dev Interface for any contract that wants to support safeTransfers\\r\\n * from ERC721 asset contracts.\\r\\n */\\r\\ninterface IERC721Receiver {\\r\\n /**\\r\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\r\\n * by `operator` from `from`, this function is called.\\r\\n *\\r\\n * It must return its Solidity selector to confirm the token transfer.\\r\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\r\\n *\\r\\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\\r\\n */\\r\\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\\r\\n}\\r\\n\",\"keccak256\":\"0x515410f905897b0d658f1746064cc2a94d52a1bc625fab215dccb7fb5ead50f7\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @title Initializable\\r\\n *\\r\\n * @dev Helper contract to support initializer functions. To use it, replace\\r\\n * the constructor with a function that has the `initializer` modifier.\\r\\n * WARNING: Unlike constructors, initializer functions must be manually\\r\\n * invoked. This applies both to deploying an Initializable contract, as well\\r\\n * as extending an Initializable contract via inheritance.\\r\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\r\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\r\\n * because this is not dealt with automatically as with constructors.\\r\\n */\\r\\ncontract Initializable {\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract has been initialized.\\r\\n */\\r\\n bool private initialized;\\r\\n\\r\\n /**\\r\\n * @dev Indicates that the contract is in the process of being initialized.\\r\\n */\\r\\n bool private initializing;\\r\\n\\r\\n /**\\r\\n * @dev Modifier to use in the initializer function of a contract.\\r\\n */\\r\\n modifier initializer() {\\r\\n require(initializing || !initialized, \\\"Contract instance is already initialized\\\");\\r\\n\\r\\n bool isTopLevelCall = !initializing;\\r\\n if (isTopLevelCall) {\\r\\n initializing = true;\\r\\n initialized = true;\\r\\n }\\r\\n\\r\\n _;\\r\\n\\r\\n if (isTopLevelCall) {\\r\\n initializing = false;\\r\\n }\\r\\n }\\r\\n\\r\\n // Reserved storage space to allow for layout changes in the future.\\r\\n uint256[50] private ______gap;\\r\\n}\",\"keccak256\":\"0xc1f4d917648f0e17ba6a023a168173ad6163f3120e24d1c97ae294430e42eaf3\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../../GSN/Context.sol\\\";\\r\\nimport \\\"../../../access/Roles.sol\\\";\\r\\n\\r\\ncontract UpgradablePauserRole is Initializable, Context {\\r\\n using Roles for Roles.Role;\\r\\n\\r\\n event PauserAdded(address indexed account);\\r\\n event PauserRemoved(address indexed account);\\r\\n\\r\\n Roles.Role private _pausers;\\r\\n\\r\\n function __PauserRol_init(address sender) public initializer {\\r\\n if (!isPauser(sender)) {\\r\\n _addPauser(sender);\\r\\n }\\r\\n }\\r\\n\\r\\n modifier onlyPauser() {\\r\\n require(isPauser(_msgSender()), \\\"PauserRole: caller doesn't have the role\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function isPauser(address account) public view returns (bool) {\\r\\n return _pausers.has(account);\\r\\n }\\r\\n\\r\\n function addPauser(address account) public onlyPauser {\\r\\n _addPauser(account);\\r\\n }\\r\\n\\r\\n function renouncePauser() public {\\r\\n _removePauser(_msgSender());\\r\\n }\\r\\n\\r\\n function _addPauser(address account) internal {\\r\\n _pausers.add(account);\\r\\n emit PauserAdded(account);\\r\\n }\\r\\n\\r\\n function _removePauser(address account) internal {\\r\\n _pausers.remove(account);\\r\\n emit PauserRemoved(account);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x175465830c1ec77cab5ebdcfaeca43c79d33f3becded5332ed6136adac3f99eb\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"../access/roles/UpgradablePauserRole.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Contract module which allows children to implement an emergency stop\\r\\n * mechanism that can be triggered by an authorized account.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the\\r\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\r\\n * the functions of your contract. Note that they will not be pausable by\\r\\n * simply including this module, only once the modifiers are put in place.\\r\\n */\\r\\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\\r\\n /**\\r\\n * @dev Emitted when the pause is triggered by a pauser (`account`).\\r\\n */\\r\\n event Paused(address account);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the pause is lifted by a pauser (`account`).\\r\\n */\\r\\n event Unpaused(address account);\\r\\n\\r\\n bool private _paused;\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\\r\\n * to the deployer.\\r\\n */\\r\\n function __Pausable_init(address sender) public initializer {\\r\\n UpgradablePauserRole.__PauserRol_init(sender);\\r\\n\\r\\n _paused = false;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the contract is paused, and false otherwise.\\r\\n */\\r\\n function paused() public view returns (bool) {\\r\\n return _paused;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Modifier to make a function callable only when the contract is not paused.\\r\\n */\\r\\n modifier whenNotPaused() {\\r\\n require(!_paused, \\\"Pausable: paused\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Modifier to make a function callable only when the contract is paused.\\r\\n */\\r\\n modifier whenPaused() {\\r\\n require(_paused, \\\"Pausable: not paused\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Called by a pauser to pause, triggers stopped state.\\r\\n */\\r\\n function pause() public onlyPauser whenNotPaused {\\r\\n _paused = true;\\r\\n emit Paused(_msgSender());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Called by a pauser to unpause, returns to normal state.\\r\\n */\\r\\n function unpause() public onlyPauser whenPaused {\\r\\n _paused = false;\\r\\n emit Unpaused(_msgSender());\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x0837df4a389f73b7210b97b1b64ba8f9cc842367b473f8fc856c4e892f212ac4\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Contract module which provides a basic access control mechanism, where\\r\\n * there is an account (an owner) that can be granted exclusive access to\\r\\n * specific functions.\\r\\n *\\r\\n * This module is used through inheritance. It will make available the modifier\\r\\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\\r\\n * the owner.\\r\\n */\\r\\ncontract UpgradableOwnable is Initializable, Context {\\r\\n address private _owner;\\r\\n\\r\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract setting the deployer as the initial owner.\\r\\n */\\r\\n function initialize(address sender) public initializer {\\r\\n _owner = sender;\\r\\n emit OwnershipTransferred(address(0), _owner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the address of the current owner.\\r\\n */\\r\\n function owner() public view returns (address) {\\r\\n return _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Throws if called by any account other than the owner.\\r\\n */\\r\\n modifier onlyOwner() {\\r\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the caller is the current owner.\\r\\n */\\r\\n function isOwner() public view returns (bool) {\\r\\n return _msgSender() == _owner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Leaves the contract without owner. It will not be possible to call\\r\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\r\\n *\\r\\n * > Note: Renouncing ownership will leave the contract without an owner,\\r\\n * thereby removing any functionality that is only available to the owner.\\r\\n */\\r\\n function renounceOwnership() public onlyOwner {\\r\\n emit OwnershipTransferred(_owner, address(0));\\r\\n _owner = address(0);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n * Can only be called by the current owner.\\r\\n */\\r\\n function transferOwnership(address newOwner) public onlyOwner {\\r\\n _transferOwnership(newOwner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\r\\n */\\r\\n function _transferOwnership(address newOwner) internal {\\r\\n require(newOwner != address(0), \\\"Ownable: new owner is zero address\\\");\\r\\n emit OwnershipTransferred(_owner, newOwner);\\r\\n _owner = newOwner;\\r\\n }\\r\\n\\r\\n}\\r\\n\",\"keccak256\":\"0xea920007e371a3300245b5885f72cecc472c4780818365f0025fae65a767273d\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../Initializable.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title Helps contracts guard against reentrancy attacks.\\r\\n * @author Remco Bloemen , Eenae \\r\\n * @dev If you mark a function `nonReentrant`, you should also\\r\\n * mark it `external`.\\r\\n */\\r\\ncontract ReentrancyGuard is Initializable {\\r\\n /// @dev counter to allow mutex lock with only one SSTORE operation\\r\\n uint256 private _guardCounter;\\r\\n\\r\\n function initialize() public initializer {\\r\\n // The counter starts at one to prevent changing it from zero to a non-zero\\r\\n // value, which is a more expensive operation.\\r\\n _guardCounter = 1;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\r\\n * Calling a `nonReentrant` function from another `nonReentrant`\\r\\n * function is not supported. It is possible to prevent this from happening\\r\\n * by making the `nonReentrant` function external, and make it call a\\r\\n * `private` function that does the actual work.\\r\\n */\\r\\n modifier nonReentrant() {\\r\\n _guardCounter += 1;\\r\\n uint256 localCounter = _guardCounter;\\r\\n _;\\r\\n require(localCounter == _guardCounter, \\\"ReentrancyGuard: no reentrant allowed\\\");\\r\\n }\\r\\n}\",\"keccak256\":\"0x67a8148c8357409eac291fc0954ca7a2d023b0534294be95f34eba0b15d748a5\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/EnumerableMap.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Library for managing an enumerable variant of Solidity's\\r\\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\\r\\n * type.\\r\\n *\\r\\n * Maps have the following properties:\\r\\n *\\r\\n * - Entries are added, removed, and checked for existence in constant time\\r\\n * (O(1)).\\r\\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\\r\\n *\\r\\n * ```\\r\\n * contract Example {\\r\\n * // Add the library methods\\r\\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\\r\\n *\\r\\n * // Declare a set state variable\\r\\n * EnumerableMap.UintToAddressMap private myMap;\\r\\n * }\\r\\n * ```\\r\\n *\\r\\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\\r\\n * supported.\\r\\n */\\r\\nlibrary EnumerableMap {\\r\\n // To implement this library for multiple types with as little code\\r\\n // repetition as possible, we write it in terms of a generic Map type with\\r\\n // bytes32 keys and values.\\r\\n // The Map implementation uses private functions, and user-facing\\r\\n // implementations (such as Uint256ToAddressMap) are just wrappers around\\r\\n // the underlying Map.\\r\\n // This means that we can only create new EnumerableMaps for types that fit\\r\\n // in bytes32.\\r\\n\\r\\n struct MapEntry {\\r\\n bytes32 _key;\\r\\n bytes32 _value;\\r\\n }\\r\\n\\r\\n struct Map {\\r\\n // Storage of map keys and values\\r\\n MapEntry[] _entries;\\r\\n\\r\\n // Position of the entry defined by a key in the `entries` array, plus 1\\r\\n // because index 0 means a key is not in the map.\\r\\n mapping (bytes32 => uint256) _indexes;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Adds a key-value pair to a map, or updates the value for an existing\\r\\n * key. O(1).\\r\\n *\\r\\n * Returns true if the key was added to the map, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\\r\\n // We read and store the key's index to prevent multiple reads from the same storage slot\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n\\r\\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\\r\\n map._entries.push(MapEntry({ _key: key, _value: value }));\\r\\n // The entry is stored at length-1, but we add 1 to all indexes\\r\\n // and use 0 as a sentinel value\\r\\n map._indexes[key] = map._entries.length;\\r\\n return true;\\r\\n } else {\\r\\n map._entries[keyIndex - 1]._value = value;\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a key-value pair from a map. O(1).\\r\\n *\\r\\n * Returns true if the key was removed from the map, that is if it was present.\\r\\n */\\r\\n function _remove(Map storage map, bytes32 key) private returns (bool) {\\r\\n // We read and store the key's index to prevent multiple reads from the same storage slot\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n\\r\\n if (keyIndex != 0) { // Equivalent to contains(map, key)\\r\\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\\r\\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\\r\\n // This modifies the order of the array, as noted in {at}.\\r\\n\\r\\n uint256 toDeleteIndex = keyIndex - 1;\\r\\n uint256 lastIndex = map._entries.length - 1;\\r\\n\\r\\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\\r\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\r\\n\\r\\n MapEntry storage lastEntry = map._entries[lastIndex];\\r\\n\\r\\n // Move the last entry to the index where the entry to delete is\\r\\n map._entries[toDeleteIndex] = lastEntry;\\r\\n // Update the index for the moved entry\\r\\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\\r\\n\\r\\n // Delete the slot where the moved entry was stored\\r\\n map._entries.pop();\\r\\n\\r\\n // Delete the index for the deleted slot\\r\\n delete map._indexes[key];\\r\\n\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the key is in the map. O(1).\\r\\n */\\r\\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\\r\\n return map._indexes[key] != 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of key-value pairs in the map. O(1).\\r\\n */\\r\\n function _length(Map storage map) private view returns (uint256) {\\r\\n return map._entries.length;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of entries inside the\\r\\n * array, and it may change when more entries are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\\r\\n require(map._entries.length > index, \\\"EnumerableMap: index out of bounds\\\");\\r\\n\\r\\n MapEntry storage entry = map._entries[index];\\r\\n return (entry._key, entry._value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Tries to returns the value associated with `key`. O(1).\\r\\n * Does not revert if `key` is not in the map.\\r\\n */\\r\\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\\r\\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value associated with `key`. O(1).\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `key` must be in the map.\\r\\n */\\r\\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n require(keyIndex != 0, \\\"EnumerableMap: nonexistent key\\\"); // Equivalent to contains(map, key)\\r\\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\\r\\n *\\r\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\r\\n * message unnecessarily. For custom revert reasons use {_tryGet}.\\r\\n */\\r\\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\\r\\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\\r\\n }\\r\\n\\r\\n // UintToAddressMap\\r\\n\\r\\n struct UintToAddressMap {\\r\\n Map _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Adds a key-value pair to a map, or updates the value for an existing\\r\\n * key. O(1).\\r\\n *\\r\\n * Returns true if the key was added to the map, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\\r\\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the key was removed from the map, that is if it was present.\\r\\n */\\r\\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\\r\\n return _remove(map._inner, bytes32(key));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the key is in the map. O(1).\\r\\n */\\r\\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\\r\\n return _contains(map._inner, bytes32(key));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of elements in the map. O(1).\\r\\n */\\r\\n function length(UintToAddressMap storage map) internal view returns (uint256) {\\r\\n return _length(map._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the element stored at position `index` in the set. O(1).\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\\r\\n (bytes32 key, bytes32 value) = _at(map._inner, index);\\r\\n return (uint256(key), address(uint160(uint256(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Tries to returns the value associated with `key`. O(1).\\r\\n * Does not revert if `key` is not in the map.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\\r\\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\\r\\n return (success, address(uint160(uint256(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value associated with `key`. O(1).\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `key` must be in the map.\\r\\n */\\r\\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\\r\\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\\r\\n *\\r\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\r\\n * message unnecessarily. For custom revert reasons use {tryGet}.\\r\\n */\\r\\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\\r\\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x5538ae23826bfaa205dc16a24a50f18feaae576a1c46ddea7086bbbd4c13d84e\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Library for managing\\r\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\r\\n * types.\\r\\n *\\r\\n * Sets have the following properties:\\r\\n *\\r\\n * - Elements are added, removed, and checked for existence in constant time\\r\\n * (O(1)).\\r\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\r\\n *\\r\\n * ```\\r\\n * contract Example {\\r\\n * // Add the library methods\\r\\n * using EnumerableSet for EnumerableSet.AddressSet;\\r\\n *\\r\\n * // Declare a set state variable\\r\\n * EnumerableSet.AddressSet private mySet;\\r\\n * }\\r\\n * ```\\r\\n *\\r\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\r\\n * and `uint256` (`UintSet`) are supported.\\r\\n */\\r\\nlibrary EnumerableSet {\\r\\n // To implement this library for multiple types with as little code\\r\\n // repetition as possible, we write it in terms of a generic Set type with\\r\\n // bytes32 values.\\r\\n // The Set implementation uses private functions, and user-facing\\r\\n // implementations (such as AddressSet) are just wrappers around the\\r\\n // underlying Set.\\r\\n // This means that we can only create new EnumerableSets for types that fit\\r\\n // in bytes32.\\r\\n\\r\\n struct Set {\\r\\n // Storage of set values\\r\\n bytes32[] _values;\\r\\n\\r\\n // Position of the value in the `values` array, plus 1 because index 0\\r\\n // means a value is not in the set.\\r\\n mapping (bytes32 => uint256) _indexes;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\r\\n if (!_contains(set, value)) {\\r\\n set._values.push(value);\\r\\n // The value is stored at length-1, but we add 1 to all indexes\\r\\n // and use 0 as a sentinel value\\r\\n set._indexes[value] = set._values.length;\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\r\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\r\\n uint256 valueIndex = set._indexes[value];\\r\\n\\r\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\r\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\r\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\r\\n // This modifies the order of the array, as noted in {at}.\\r\\n\\r\\n uint256 toDeleteIndex = valueIndex - 1;\\r\\n uint256 lastIndex = set._values.length - 1;\\r\\n\\r\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\r\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\r\\n\\r\\n bytes32 lastvalue = set._values[lastIndex];\\r\\n\\r\\n // Move the last value to the index where the value to delete is\\r\\n set._values[toDeleteIndex] = lastvalue;\\r\\n // Update the index for the moved value\\r\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\r\\n\\r\\n // Delete the slot where the moved value was stored\\r\\n set._values.pop();\\r\\n\\r\\n // Delete the index for the deleted slot\\r\\n delete set._indexes[value];\\r\\n\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\r\\n return set._indexes[value] != 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values on the set. O(1).\\r\\n */\\r\\n function _length(Set storage set) private view returns (uint256) {\\r\\n return set._values.length;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\r\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\r\\n return set._values[index];\\r\\n }\\r\\n\\r\\n // Bytes32Set\\r\\n\\r\\n struct Bytes32Set {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\r\\n return _add(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\r\\n return _remove(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\r\\n return _contains(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values in the set. O(1).\\r\\n */\\r\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\r\\n return _at(set._inner, index);\\r\\n }\\r\\n\\r\\n // AddressSet\\r\\n\\r\\n struct AddressSet {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(AddressSet storage set, address value) internal returns (bool) {\\r\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\r\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\r\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values in the set. O(1).\\r\\n */\\r\\n function length(AddressSet storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\r\\n return address(uint160(uint256(_at(set._inner, index))));\\r\\n }\\r\\n\\r\\n\\r\\n // UintSet\\r\\n\\r\\n struct UintSet {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\r\\n return _add(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\r\\n return _remove(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\r\\n return _contains(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values on the set. O(1).\\r\\n */\\r\\n function length(UintSet storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\r\\n return uint256(_at(set._inner, index));\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x4c3f4a13b8f0c2b911044b85d3db13396e772cb9b79f7fb16ec8d41ca5fc7321\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev String operations.\\r\\n */\\r\\nlibrary Strings {\\r\\n /**\\r\\n * @dev Converts a `uint256` to its ASCII `string` representation.\\r\\n */\\r\\n function toString(uint256 value) internal pure returns (string memory) {\\r\\n // Inspired by OraclizeAPI's implementation - MIT licence\\r\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\r\\n\\r\\n if (value == 0) {\\r\\n return \\\"0\\\";\\r\\n }\\r\\n uint256 temp = value;\\r\\n uint256 digits;\\r\\n while (temp != 0) {\\r\\n digits++;\\r\\n temp /= 10;\\r\\n }\\r\\n bytes memory buffer = new bytes(digits);\\r\\n uint256 index = digits - 1;\\r\\n temp = value;\\r\\n while (temp != 0) {\\r\\n buffer[index--] = bytes1(uint8(48 + temp % 10));\\r\\n temp /= 10;\\r\\n }\\r\\n return string(buffer);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x0f1313d4fbca3b365d39200fc056b6db57b957b53dabb06d6fff3566fb8caa29\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50612f91806100206000396000f3fe6080604052600436106102515760003560e01c806382dc1ec411610139578063c4d66de8116100b6578063ea2170911161007a578063ea21709114610686578063eb16136f1461069b578063ed99f4c6146106bb578063f1409028146106d0578063f2fde38b146106f0578063fa0caa161461071057610251565b8063c4d66de8146105e6578063cc3c0f0614610606578063ce5f8bf214610626578063d220d30a14610646578063da6770371461066657610251565b8063a53d6e6e116100fd578063a53d6e6e14610567578063a9e4eff21461057c578063b79472621461059c578063b86f60d2146105b1578063c33c8c61146105c657610251565b806382dc1ec4146104db5780638456cb59146104fb5780638da5cb5b146105105780638f32d59b14610532578063916dc59d1461054757610251565b806342cdb2c6116101d2578063664761091161019657806366476109146104495780636a863191146104695780636ef8d66d14610489578063715018a61461049e5780637813bea2146104b35780638129fc1c146104c657610251565b806342cdb2c6146103bd57806346fbf68e146103dd57806354fd4d50146103fd57806359a8a8671461041f5780635c975abb1461043457610251565b80632f3cca4e116102195780632f3cca4e146103285780632fb3b3611461034857806337de81061461036857806337e76109146103885780633f4ba83a146103a857610251565b806307c8f7b0146102565780630b2292a614610278578063150b7a02146102ae5780631b68e6e6146102db5780631c7e6efb146102fb575b600080fd5b34801561026257600080fd5b506102766102713660046124d8565b610730565b005b34801561028457600080fd5b506102986102933660046124f8565b6107b9565b6040516102a59190612836565b60405180910390f35b3480156102ba57600080fd5b506102ce6102c936600461235c565b6107cb565b6040516102a5919061283f565b3480156102e757600080fd5b506102766102f636600461257a565b6107db565b34801561030757600080fd5b5061031b61031636600461216d565b610836565b6040516102a5919061282b565b34801561033457600080fd5b5061027661034336600461216d565b61084b565b34801561035457600080fd5b5061027661036336600461221b565b6108d4565b34801561037457600080fd5b506102766103833660046124f8565b610a3e565b34801561039457600080fd5b5061031b6103a33660046124f8565b610a97565b3480156103b457600080fd5b50610276610abc565b3480156103c957600080fd5b506102766103d836600461216d565b610b4f565b3480156103e957600080fd5b5061031b6103f836600461216d565b610be4565b34801561040957600080fd5b50610412610bf7565b6040516102a591906128b2565b34801561042b57600080fd5b50610412610c13565b34801561044057600080fd5b5061031b610ca1565b34801561045557600080fd5b5061027661046436600461257a565b610caa565b34801561047557600080fd5b506102766104843660046121a5565b610cbb565b34801561049557600080fd5b50610276610f0a565b3480156104aa57600080fd5b50610276610f1c565b6102766104c13660046122b4565b610f90565b3480156104d257600080fd5b506102766110eb565b3480156104e757600080fd5b506102766104f636600461216d565b611164565b34801561050757600080fd5b50610276611194565b34801561051c57600080fd5b50610525611214565b6040516102a59190612707565b34801561053e57600080fd5b5061031b611228565b34801561055357600080fd5b5061027661056236600461216d565b611253565b34801561057357600080fd5b506105256112e8565b34801561058857600080fd5b506102986105973660046122f4565b6112f7565b3480156105a857600080fd5b5061031b611339565b3480156105bd57600080fd5b50610525611349565b3480156105d257600080fd5b506102766105e13660046123d9565b611358565b3480156105f257600080fd5b5061027661060136600461216d565b61151f565b34801561061257600080fd5b5061031b6106213660046124f8565b6115ea565b34801561063257600080fd5b5061052561064136600461216d565b6115ff565b34801561065257600080fd5b506105256106613660046124ad565b61161a565b34801561067257600080fd5b5061031b6106813660046124f8565b61174d565b34801561069257600080fd5b50610525611761565b3480156106a757600080fd5b506102766106b636600461216d565b611770565b3480156106c757600080fd5b506102986117fb565b3480156106dc57600080fd5b506105256106eb36600461216d565b611801565b3480156106fc57600080fd5b5061027661070b36600461216d565b61181c565b34801561071c57600080fd5b5061027661072b36600461216d565b611849565b610738611228565b61075d5760405162461bcd60e51b815260040161075490612c16565b60405180910390fd5b603e805460ff60a01b1916600160a01b831515810291909117918290556040517f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad9926107ae9260ff9104169061282b565b60405180910390a150565b603f6020526000908152604090205481565b630a85bd0160e11b949350505050565b6107eb604082016020830161216d565b6001600160a01b03166107fc6118e4565b6001600160a01b0316146108225760405162461bcd60e51b81526004016107549061296f565b6108338161082e6118e4565b6118e8565b50565b603b6020526000908152604090205460ff1681565b600054610100900460ff1680610864575060005460ff16155b6108805760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff161580156108ab576000805460ff1961ff0019909116610100171660011790555b6108b482611770565b6034805460ff1916905580156108d0576000805461ff00191690555b5050565b600054610100900460ff16806108ed575060005460ff16155b6109095760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff16158015610934576000805460ff1961ff0019909116610100171660011790555b61093d8661151f565b6109468661084b565b8151610959906038906020850190612033565b50603d80546001600160a01b038087166001600160a01b031992831617909255603e805486841690831617905560368054928816929091169190911790556040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d906109f29030907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b9082906004016127d2565b600060405180830381600087803b158015610a0c57600080fd5b505af1158015610a20573d6000803e3d6000fd5b505050508015610a36576000805461ff00191690555b505050505050565b610a46611228565b610a625760405162461bcd60e51b815260040161075490612c16565b60378190556040517f5eebc59df2662862db7d6ef529ff1a264721bd7c26550f39c89a685382668f4e906107ae908390612836565b6000818152603f60209081526040808320548352603c90915290205460ff165b919050565b610ac76103f86118e4565b610ae35760405162461bcd60e51b815260040161075490612acb565b60345460ff16610b055760405162461bcd60e51b81526004016107549061290a565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610b386118e4565b604051610b459190612707565b60405180910390a1565b610b57611228565b610b735760405162461bcd60e51b815260040161075490612c16565b6001600160a01b038116610b995760405162461bcd60e51b815260040161075490612e8f565b603e80546001600160a01b0319166001600160a01b0383161790556040517f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e3183692521625906107ae908390612707565b6000610bf1603383611b47565b92915050565b604080518082019091526002815261763160f01b602082015290565b6038805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610c995780601f10610c6e57610100808354040283529160200191610c99565b820191906000526020600020905b815481529060010190602001808311610c7c57829003601f168201915b505050505081565b60345460ff1690565b6108338161082e602082018261216d565b60345460ff1615610cde5760405162461bcd60e51b815260040161075490612b57565b60358054600101908190556036546001600160a01b0316610cfd6118e4565b6001600160a01b031614610d235760405162461bcd60e51b815260040161075490612bdf565b6001600160a01b0388166000908152603b602052604090205460ff1680610d6357506001600160a01b038881166000908152603960205260409020541615155b610d7f5760405162461bcd60e51b815260040161075490612cfb565b6001600160a01b038616610da55760405162461bcd60e51b815260040161075490612db3565b6001600160a01b038716610dcb5760405162461bcd60e51b815260040161075490612b81565b83610de85760405162461bcd60e51b815260040161075490612e16565b82610e055760405162461bcd60e51b815260040161075490612baf565b6000838152603f602052604090205415610e315760405162461bcd60e51b815260040161075490612d32565b6000610e428789888c8989896112f7565b6000818152603c602052604090205490915060ff1615610e745760405162461bcd60e51b815260040161075490612cc4565b80603f600086815260200190815260200160002081905550866001600160a01b0316896001600160a01b0316857f68c55835fbe7c27942e2ff7632542cf70ee33ba41b292bff9cb6183e3db7e63b8b8a8a89604051610ed69493929190612758565b60405180910390a4506035548114610f005760405162461bcd60e51b8152600401610754906128c5565b5050505050505050565b610f1a610f156118e4565b611b8f565b565b610f24611228565b610f405760405162461bcd60e51b815260040161075490612c16565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b6000610f9c848361161a565b90506000610fa86118e4565b6040516323b872dd60e01b81529091506001600160a01b038616906323b872dd90610fdb9084903090889060040161271b565b600060405180830381600087803b158015610ff557600080fd5b505af1158015611009573d6000803e3d6000fd5b505050506110298585846040518060200160405280600081525087611bd1565b603754156110e4576037543410156110535760405162461bcd60e51b815260040161075490612d69565b6036546037546040516001600160a01b039092169181156108fc0291906000818181858888f1935050505015801561108f573d6000803e3d6000fd5b506037543411156110e457806001600160a01b03166108fc6110bc60375434611e5b90919063ffffffff16565b6040518115909202916000818181858888f19350505050158015610a36573d6000803e3d6000fd5b5050505050565b600054610100900460ff1680611104575060005460ff16155b6111205760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff1615801561114b576000805460ff1961ff0019909116610100171660011790555b60016035558015610833576000805461ff001916905550565b61116f6103f86118e4565b61118b5760405162461bcd60e51b815260040161075490612acb565b61083381611ea4565b61119f6103f86118e4565b6111bb5760405162461bcd60e51b815260040161075490612acb565b60345460ff16156111de5760405162461bcd60e51b815260040161075490612b57565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610b386118e4565b60345461010090046001600160a01b031690565b60345460009061010090046001600160a01b03166112446118e4565b6001600160a01b031614905090565b61125b611228565b6112775760405162461bcd60e51b815260040161075490612c16565b6001600160a01b03811661129d5760405162461bcd60e51b815260040161075490612ddf565b603d80546001600160a01b0319166001600160a01b0383161790556040517f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e3906107ae908390612707565b603d546001600160a01b031681565b6000838389898989876040516020016113169796959493929190612619565b604051602081830303815290604052805190602001209050979650505050505050565b603e54600160a01b900460ff1681565b603e546001600160a01b031681565b611360611228565b61137c5760405162461bcd60e51b815260040161075490612c16565b6001600160a01b0389166113a25760405162461bcd60e51b8152600401610754906129a6565b6001600160a01b03808a166000908152603960205260409020541680156113db5760405162461bcd60e51b815260040161075490612b13565b600060388a8a6040516020016113f39392919061268e565b60408051601f1981840301815290829052603e54634423ac3360e11b83529092506001600160a01b03169063884758669061143e908b908b9086908c908c908c908c90600401612854565b602060405180830381600087803b15801561145857600080fd5b505af115801561146c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114909190612189565b6001600160a01b03808d16600081815260396020908152604080832080549587166001600160a01b03199687168117909155808452603a909252918290208054909416831790935551929450917f622ea91961d2c1c42b6f59a73d152d990066165d59f27d922ce6d1f59650638c9061150a9085906128b2565b60405180910390a35050505050505050505050565b600054610100900460ff1680611538575060005460ff16155b6115545760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff1615801561157f576000805460ff1961ff0019909116610100171660011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a380156108d0576000805461ff00191690555050565b603c6020526000908152604090205460ff1681565b603a602052600090815260409020546001600160a01b031681565b60408051600481526024810182526020810180516001600160e01b03166302d05d3f60e01b1790529051600091829182916001600160a01b038716916116609190612672565b600060405180830381855afa9150503d806000811461169b576040519150601f19603f3d011682016040523d82523d6000602084013e6116a0565b606091505b509150915081156116c857808060200190518101906116bf9190612189565b92505050610bf1565b6040516331a9108f60e11b81526001600160a01b03861690636352211e906116f4908790600401612836565b60206040518083038186803b15801561170c57600080fd5b505afa158015611720573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117449190612189565b95945050505050565b6000908152603f6020526040902054151590565b6036546001600160a01b031690565b600054610100900460ff1680611789575060005460ff16155b6117a55760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff161580156117d0576000805460ff1961ff0019909116610100171660011790555b6117d982610be4565b6117e6576117e682611ea4565b80156108d0576000805461ff00191690555050565b60375490565b6039602052600090815260409020546001600160a01b031681565b611824611228565b6118405760405162461bcd60e51b815260040161075490612c16565b61083381611ee6565b611851611228565b61186d5760405162461bcd60e51b815260040161075490612c16565b6001600160a01b0381166118935760405162461bcd60e51b815260040161075490612c8d565b603680546001600160a01b0319166001600160a01b0383811691909117918290556040517f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb926107ae921690612707565b3390565b60006118fa608084016060850161216d565b90506040830135600061193f611913602087018761216d565b611923604088016020890161216d565b848660808a013560a08b013561059760e08d0160c08e016125a9565b60a08601356000908152603f602052604090205490915081146119745760405162461bcd60e51b8152600401610754906129ec565b6000818152603c602052604090205460ff16156119a35760405162461bcd60e51b815260040161075490612cc4565b6000818152603c60209081526040808320805460ff191660011790556001600160a01b0386168352603b90915290205460ff168015611a4357604051632142170760e11b81526001600160a01b038516906342842e0e90611a0c9030908990889060040161271b565b600060405180830381600087803b158015611a2657600080fd5b505af1158015611a3a573d6000803e3d6000fd5b50505050611aba565b6001600160a01b03808516600090815260396020526040908190205490516340c10f1960e01b815291169081906340c10f1990611a86908990889060040161273f565b600060405180830381600087803b158015611aa057600080fd5b505af1158015611ab4573d6000803e3d6000fd5b50505050505b611ac7602087018761216d565b6001600160a01b0390811690851660a08801357f8738727192721a6f1909e42e987fa3faf27386067521caf12f11c5dc4013c2ac611b0b60408b0160208c0161216d565b60408b013560808c0135611b2560e08e0160c08f016125a9565b8c604051611b379594939291906127f5565b60405180910390a4505050505050565b60006001600160a01b038216611b6f5760405162461bcd60e51b815260040161075490612c4b565b506001600160a01b03166000908152602091909152604090205460ff1690565b611b9a603382611f73565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b603e54600160a01b900460ff1615611bfb5760405162461bcd60e51b815260040161075490612a23565b60345460ff1615611c1e5760405162461bcd60e51b815260040161075490612b57565b603580546001908101918290556001600160a01b0387166000818152603b6020526040808220805460ff1916909417909355915163c87b56dd60e01b815288928392909163c87b56dd90611c76908890600401612836565b60006040518083038186803b158015611c8e57600080fd5b505afa158015611ca2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611cca9190810190612510565b6001600160a01b03808b166000908152603a60205260409020549192508a911615611d6257506001600160a01b03808a166000818152603a602052604090819020549051630852cd8d60e31b81529216916342966c6890611d2f908990600401612836565b600060405180830381600087803b158015611d4957600080fd5b505af1158015611d5d573d6000803e3d6000fd5b505050505b886001600160a01b0316611d746118e4565b6001600160a01b0316826001600160a01b03167f8586062302f52eda0114687cd36998f16298ea820e0a6f8878bbbfefebc09e9f8b8b896001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611de357600080fd5b505afa158015611df7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1b9190612591565b8c89604051611e2e959493929190612784565b60405180910390a4505050506035548114610a365760405162461bcd60e51b8152600401610754906128c5565b6000611e9d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611fbb565b9392505050565b611eaf603382611fe7565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6001600160a01b038116611f0c5760405162461bcd60e51b815260040161075490612e4d565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b611f7d8282611b47565b611f995760405162461bcd60e51b815260040161075490612a4e565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b60008184841115611fdf5760405162461bcd60e51b815260040161075491906128b2565b505050900390565b611ff18282611b47565b1561200e5760405162461bcd60e51b815260040161075490612938565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261206957600085556120af565b82601f1061208257805160ff19168380011785556120af565b828001600101855582156120af579182015b828111156120af578251825591602001919060010190612094565b506120bb9291506120bf565b5090565b5b808211156120bb57600081556001016120c0565b60006120e76120e284612ef4565b612ed0565b90508281528383830111156120fb57600080fd5b828260208301376000602084830101529392505050565b60008083601f840112612123578182fd5b50813567ffffffffffffffff81111561213a578182fd5b60208301915083602082850101111561215257600080fd5b9250929050565b803563ffffffff81168114610ab757600080fd5b60006020828403121561217e578081fd5b8135611e9d81612f46565b60006020828403121561219a578081fd5b8151611e9d81612f46565b600080600080600080600060e0888a0312156121bf578283fd5b87356121ca81612f46565b965060208801356121da81612f46565b955060408801356121ea81612f46565b9450606088013593506080880135925060a0880135915061220d60c08901612159565b905092959891949750929550565b600080600080600060a08688031215612232578081fd5b853561223d81612f46565b9450602086013561224d81612f46565b9350604086013561225d81612f46565b9250606086013561226d81612f46565b9150608086013567ffffffffffffffff811115612288578182fd5b8601601f81018813612298578182fd5b6122a7888235602084016120d4565b9150509295509295909350565b6000806000606084860312156122c8578283fd5b83356122d381612f46565b925060208401356122e381612f46565b929592945050506040919091013590565b600080600080600080600060e0888a03121561230e578081fd5b873561231981612f46565b9650602088013561232981612f46565b955060408801359450606088013561234081612f46565b93506080880135925060a0880135915061220d60c08901612159565b60008060008060808587031215612371578182fd5b843561237c81612f46565b9350602085013561238c81612f46565b925060408501359150606085013567ffffffffffffffff8111156123ae578182fd5b8501601f810187136123be578182fd5b6123cd878235602084016120d4565b91505092959194509250565b600080600080600080600080600060a08a8c0312156123f6578283fd5b893561240181612f46565b985060208a013567ffffffffffffffff8082111561241d578485fd5b6124298d838e01612112565b909a50985060408c0135915080821115612441578485fd5b61244d8d838e01612112565b909850965060608c0135915080821115612465578485fd5b6124718d838e01612112565b909650945060808c0135915080821115612489578384fd5b506124968c828d01612112565b915080935050809150509295985092959850929598565b600080604083850312156124bf578182fd5b82356124ca81612f46565b946020939093013593505050565b6000602082840312156124e9578081fd5b81358015158114611e9d578182fd5b600060208284031215612509578081fd5b5035919050565b600060208284031215612521578081fd5b815167ffffffffffffffff811115612537578182fd5b8201601f81018413612547578182fd5b80516125556120e282612ef4565b818152856020838501011115612569578384fd5b611744826020830160208601612f16565b600060e0828403121561258b578081fd5b50919050565b6000602082840312156125a2578081fd5b5051919050565b6000602082840312156125ba578081fd5b611e9d82612159565b600081518084526125db816020860160208601612f16565b601f01601f19169290920160200192915050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b9687526020870195909552606093841b6bffffffffffffffffffffffff19908116604088015292841b83166054870152606886019190915290911b16608883015260e01b6001600160e01b031916609c82015260a00190565b60008251612684818460208701612f16565b9190910192915050565b60008085546001808216600081146126ad57600181146126c4576126f3565b60ff198316865260028304607f16860193506126f3565b600283048986526020808720875b838110156126eb5781548a8201529085019082016126d2565b505050860193505b505050838582379092019182525092915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039490941684526020840192909252604083015263ffffffff16606082015260800190565b6001600160a01b038616815260a0602082018190526000906127a8908301876125c3565b85604084015284606084015282810360808401526127c681856125c3565b98975050505050505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b6001600160a01b0395861681526020810194909452604084019290925263ffffffff166060830152909116608082015260a00190565b901515815260200190565b90815260200190565b6001600160e01b031991909116815260200190565b60006080825261286860808301898b6125ef565b828103602084015261287a81896125c3565b9050828103604084015261288f8187896125ef565b905082810360608401526128a48185876125ef565b9a9950505050505050505050565b600060208252611e9d60208301846125c3565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b6020808252601f908201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604082015260600190565b60208082526019908201527f4e46544272696467653a20696e76616c69642073656e64657200000000000000604082015260600190565b60208082526026908201527f4e46544272696467653a204e756c6c206f726967696e616c20746f6b656e206160408201526564647265737360d01b606082015260800190565b6020808252601b908201527f4e46544272696467653a2057726f6e6720747844617461486173680000000000604082015260600190565b6020808252601190820152704272696467653a20557067726164696e6760781b604082015260600190565b6020808252818101527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c65604082015260600190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b60208082526024908201527f4e46544272696467653a205369646520746f6b656e20616c72656164792065786040820152636973747360e01b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252601490820152734e46544272696467653a204e756c6c2046726f6d60601b604082015260600190565b60208082526016908201527509c8ca884e4d2c8ceca74409cead8d840a8f090c2e6d60531b604082015260600190565b60208082526019908201527f4e46544272696467653a204e6f742046656465726174696f6e00000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526022908201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601e908201527f4e46544272696467653a2046656465726174696f6e20697320656d7074790000604082015260600190565b6020808252601a908201527f4e46544272696467653a20416c726561647920636c61696d6564000000000000604082015260600190565b60208082526018908201527f4e46544272696467653a20556e6b6e6f776e20746f6b656e0000000000000000604082015260600190565b6020808252601b908201527f4e46544272696467653a20416c72656164792061636365707465640000000000604082015260600190565b6020808252602a908201527f4e46544272696467653a2076616c756520697320736d616c6c6572207468616e6040820152692066697865642066656560b01b606082015260800190565b6020808252601290820152714e46544272696467653a204e756c6c20546f60701b604082015260600190565b6020808252601f908201527f4e46544272696467653a20416c6c6f77546f6b656e7320697320656d70747900604082015260600190565b60208082526019908201527f4e46544272696467653a204e756c6c20426c6f636b4861736800000000000000604082015260600190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526021908201527f4e46544272696467653a20656d7074792053696465546f6b656e466163746f726040820152607960f81b606082015260800190565b60405181810167ffffffffffffffff81118282101715612eec57fe5b604052919050565b600067ffffffffffffffff821115612f0857fe5b50601f01601f191660200190565b60005b83811015612f31578181015183820152602001612f19565b83811115612f40576000848401525b50505050565b6001600160a01b038116811461083357600080fdfea2646970667358221220c2db86366b65f97c4730018c60c95ed2c68e7f2ccd8332c152047ef6d532db2764736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106102515760003560e01c806382dc1ec411610139578063c4d66de8116100b6578063ea2170911161007a578063ea21709114610686578063eb16136f1461069b578063ed99f4c6146106bb578063f1409028146106d0578063f2fde38b146106f0578063fa0caa161461071057610251565b8063c4d66de8146105e6578063cc3c0f0614610606578063ce5f8bf214610626578063d220d30a14610646578063da6770371461066657610251565b8063a53d6e6e116100fd578063a53d6e6e14610567578063a9e4eff21461057c578063b79472621461059c578063b86f60d2146105b1578063c33c8c61146105c657610251565b806382dc1ec4146104db5780638456cb59146104fb5780638da5cb5b146105105780638f32d59b14610532578063916dc59d1461054757610251565b806342cdb2c6116101d2578063664761091161019657806366476109146104495780636a863191146104695780636ef8d66d14610489578063715018a61461049e5780637813bea2146104b35780638129fc1c146104c657610251565b806342cdb2c6146103bd57806346fbf68e146103dd57806354fd4d50146103fd57806359a8a8671461041f5780635c975abb1461043457610251565b80632f3cca4e116102195780632f3cca4e146103285780632fb3b3611461034857806337de81061461036857806337e76109146103885780633f4ba83a146103a857610251565b806307c8f7b0146102565780630b2292a614610278578063150b7a02146102ae5780631b68e6e6146102db5780631c7e6efb146102fb575b600080fd5b34801561026257600080fd5b506102766102713660046124d8565b610730565b005b34801561028457600080fd5b506102986102933660046124f8565b6107b9565b6040516102a59190612836565b60405180910390f35b3480156102ba57600080fd5b506102ce6102c936600461235c565b6107cb565b6040516102a5919061283f565b3480156102e757600080fd5b506102766102f636600461257a565b6107db565b34801561030757600080fd5b5061031b61031636600461216d565b610836565b6040516102a5919061282b565b34801561033457600080fd5b5061027661034336600461216d565b61084b565b34801561035457600080fd5b5061027661036336600461221b565b6108d4565b34801561037457600080fd5b506102766103833660046124f8565b610a3e565b34801561039457600080fd5b5061031b6103a33660046124f8565b610a97565b3480156103b457600080fd5b50610276610abc565b3480156103c957600080fd5b506102766103d836600461216d565b610b4f565b3480156103e957600080fd5b5061031b6103f836600461216d565b610be4565b34801561040957600080fd5b50610412610bf7565b6040516102a591906128b2565b34801561042b57600080fd5b50610412610c13565b34801561044057600080fd5b5061031b610ca1565b34801561045557600080fd5b5061027661046436600461257a565b610caa565b34801561047557600080fd5b506102766104843660046121a5565b610cbb565b34801561049557600080fd5b50610276610f0a565b3480156104aa57600080fd5b50610276610f1c565b6102766104c13660046122b4565b610f90565b3480156104d257600080fd5b506102766110eb565b3480156104e757600080fd5b506102766104f636600461216d565b611164565b34801561050757600080fd5b50610276611194565b34801561051c57600080fd5b50610525611214565b6040516102a59190612707565b34801561053e57600080fd5b5061031b611228565b34801561055357600080fd5b5061027661056236600461216d565b611253565b34801561057357600080fd5b506105256112e8565b34801561058857600080fd5b506102986105973660046122f4565b6112f7565b3480156105a857600080fd5b5061031b611339565b3480156105bd57600080fd5b50610525611349565b3480156105d257600080fd5b506102766105e13660046123d9565b611358565b3480156105f257600080fd5b5061027661060136600461216d565b61151f565b34801561061257600080fd5b5061031b6106213660046124f8565b6115ea565b34801561063257600080fd5b5061052561064136600461216d565b6115ff565b34801561065257600080fd5b506105256106613660046124ad565b61161a565b34801561067257600080fd5b5061031b6106813660046124f8565b61174d565b34801561069257600080fd5b50610525611761565b3480156106a757600080fd5b506102766106b636600461216d565b611770565b3480156106c757600080fd5b506102986117fb565b3480156106dc57600080fd5b506105256106eb36600461216d565b611801565b3480156106fc57600080fd5b5061027661070b36600461216d565b61181c565b34801561071c57600080fd5b5061027661072b36600461216d565b611849565b610738611228565b61075d5760405162461bcd60e51b815260040161075490612c16565b60405180910390fd5b603e805460ff60a01b1916600160a01b831515810291909117918290556040517f983e436223c000a441c2443b394ca5fb4669a513fe86dc1dd44494047b514ad9926107ae9260ff9104169061282b565b60405180910390a150565b603f6020526000908152604090205481565b630a85bd0160e11b949350505050565b6107eb604082016020830161216d565b6001600160a01b03166107fc6118e4565b6001600160a01b0316146108225760405162461bcd60e51b81526004016107549061296f565b6108338161082e6118e4565b6118e8565b50565b603b6020526000908152604090205460ff1681565b600054610100900460ff1680610864575060005460ff16155b6108805760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff161580156108ab576000805460ff1961ff0019909116610100171660011790555b6108b482611770565b6034805460ff1916905580156108d0576000805461ff00191690555b5050565b600054610100900460ff16806108ed575060005460ff16155b6109095760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff16158015610934576000805460ff1961ff0019909116610100171660011790555b61093d8661151f565b6109468661084b565b8151610959906038906020850190612033565b50603d80546001600160a01b038087166001600160a01b031992831617909255603e805486841690831617905560368054928816929091169190911790556040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d906109f29030907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b9082906004016127d2565b600060405180830381600087803b158015610a0c57600080fd5b505af1158015610a20573d6000803e3d6000fd5b505050508015610a36576000805461ff00191690555b505050505050565b610a46611228565b610a625760405162461bcd60e51b815260040161075490612c16565b60378190556040517f5eebc59df2662862db7d6ef529ff1a264721bd7c26550f39c89a685382668f4e906107ae908390612836565b6000818152603f60209081526040808320548352603c90915290205460ff165b919050565b610ac76103f86118e4565b610ae35760405162461bcd60e51b815260040161075490612acb565b60345460ff16610b055760405162461bcd60e51b81526004016107549061290a565b6034805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610b386118e4565b604051610b459190612707565b60405180910390a1565b610b57611228565b610b735760405162461bcd60e51b815260040161075490612c16565b6001600160a01b038116610b995760405162461bcd60e51b815260040161075490612e8f565b603e80546001600160a01b0319166001600160a01b0383161790556040517f619936bc6e3618d0b8dc69bcc70134fe9d88f9967f3a8b8304e3183692521625906107ae908390612707565b6000610bf1603383611b47565b92915050565b604080518082019091526002815261763160f01b602082015290565b6038805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610c995780601f10610c6e57610100808354040283529160200191610c99565b820191906000526020600020905b815481529060010190602001808311610c7c57829003601f168201915b505050505081565b60345460ff1690565b6108338161082e602082018261216d565b60345460ff1615610cde5760405162461bcd60e51b815260040161075490612b57565b60358054600101908190556036546001600160a01b0316610cfd6118e4565b6001600160a01b031614610d235760405162461bcd60e51b815260040161075490612bdf565b6001600160a01b0388166000908152603b602052604090205460ff1680610d6357506001600160a01b038881166000908152603960205260409020541615155b610d7f5760405162461bcd60e51b815260040161075490612cfb565b6001600160a01b038616610da55760405162461bcd60e51b815260040161075490612db3565b6001600160a01b038716610dcb5760405162461bcd60e51b815260040161075490612b81565b83610de85760405162461bcd60e51b815260040161075490612e16565b82610e055760405162461bcd60e51b815260040161075490612baf565b6000838152603f602052604090205415610e315760405162461bcd60e51b815260040161075490612d32565b6000610e428789888c8989896112f7565b6000818152603c602052604090205490915060ff1615610e745760405162461bcd60e51b815260040161075490612cc4565b80603f600086815260200190815260200160002081905550866001600160a01b0316896001600160a01b0316857f68c55835fbe7c27942e2ff7632542cf70ee33ba41b292bff9cb6183e3db7e63b8b8a8a89604051610ed69493929190612758565b60405180910390a4506035548114610f005760405162461bcd60e51b8152600401610754906128c5565b5050505050505050565b610f1a610f156118e4565b611b8f565b565b610f24611228565b610f405760405162461bcd60e51b815260040161075490612c16565b60345460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360348054610100600160a81b0319169055565b6000610f9c848361161a565b90506000610fa86118e4565b6040516323b872dd60e01b81529091506001600160a01b038616906323b872dd90610fdb9084903090889060040161271b565b600060405180830381600087803b158015610ff557600080fd5b505af1158015611009573d6000803e3d6000fd5b505050506110298585846040518060200160405280600081525087611bd1565b603754156110e4576037543410156110535760405162461bcd60e51b815260040161075490612d69565b6036546037546040516001600160a01b039092169181156108fc0291906000818181858888f1935050505015801561108f573d6000803e3d6000fd5b506037543411156110e457806001600160a01b03166108fc6110bc60375434611e5b90919063ffffffff16565b6040518115909202916000818181858888f19350505050158015610a36573d6000803e3d6000fd5b5050505050565b600054610100900460ff1680611104575060005460ff16155b6111205760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff1615801561114b576000805460ff1961ff0019909116610100171660011790555b60016035558015610833576000805461ff001916905550565b61116f6103f86118e4565b61118b5760405162461bcd60e51b815260040161075490612acb565b61083381611ea4565b61119f6103f86118e4565b6111bb5760405162461bcd60e51b815260040161075490612acb565b60345460ff16156111de5760405162461bcd60e51b815260040161075490612b57565b6034805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610b386118e4565b60345461010090046001600160a01b031690565b60345460009061010090046001600160a01b03166112446118e4565b6001600160a01b031614905090565b61125b611228565b6112775760405162461bcd60e51b815260040161075490612c16565b6001600160a01b03811661129d5760405162461bcd60e51b815260040161075490612ddf565b603d80546001600160a01b0319166001600160a01b0383161790556040517f5f2c1fe803fd576d8af05ea156011cc9cc8c025bda24c1e85772fc05a0b3f1e3906107ae908390612707565b603d546001600160a01b031681565b6000838389898989876040516020016113169796959493929190612619565b604051602081830303815290604052805190602001209050979650505050505050565b603e54600160a01b900460ff1681565b603e546001600160a01b031681565b611360611228565b61137c5760405162461bcd60e51b815260040161075490612c16565b6001600160a01b0389166113a25760405162461bcd60e51b8152600401610754906129a6565b6001600160a01b03808a166000908152603960205260409020541680156113db5760405162461bcd60e51b815260040161075490612b13565b600060388a8a6040516020016113f39392919061268e565b60408051601f1981840301815290829052603e54634423ac3360e11b83529092506001600160a01b03169063884758669061143e908b908b9086908c908c908c908c90600401612854565b602060405180830381600087803b15801561145857600080fd5b505af115801561146c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114909190612189565b6001600160a01b03808d16600081815260396020908152604080832080549587166001600160a01b03199687168117909155808452603a909252918290208054909416831790935551929450917f622ea91961d2c1c42b6f59a73d152d990066165d59f27d922ce6d1f59650638c9061150a9085906128b2565b60405180910390a35050505050505050505050565b600054610100900460ff1680611538575060005460ff16155b6115545760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff1615801561157f576000805460ff1961ff0019909116610100171660011790555b60348054610100600160a81b0319166101006001600160a01b0385811682029290921792839055604051920416906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a380156108d0576000805461ff00191690555050565b603c6020526000908152604090205460ff1681565b603a602052600090815260409020546001600160a01b031681565b60408051600481526024810182526020810180516001600160e01b03166302d05d3f60e01b1790529051600091829182916001600160a01b038716916116609190612672565b600060405180830381855afa9150503d806000811461169b576040519150601f19603f3d011682016040523d82523d6000602084013e6116a0565b606091505b509150915081156116c857808060200190518101906116bf9190612189565b92505050610bf1565b6040516331a9108f60e11b81526001600160a01b03861690636352211e906116f4908790600401612836565b60206040518083038186803b15801561170c57600080fd5b505afa158015611720573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117449190612189565b95945050505050565b6000908152603f6020526040902054151590565b6036546001600160a01b031690565b600054610100900460ff1680611789575060005460ff16155b6117a55760405162461bcd60e51b815260040161075490612a83565b600054610100900460ff161580156117d0576000805460ff1961ff0019909116610100171660011790555b6117d982610be4565b6117e6576117e682611ea4565b80156108d0576000805461ff00191690555050565b60375490565b6039602052600090815260409020546001600160a01b031681565b611824611228565b6118405760405162461bcd60e51b815260040161075490612c16565b61083381611ee6565b611851611228565b61186d5760405162461bcd60e51b815260040161075490612c16565b6001600160a01b0381166118935760405162461bcd60e51b815260040161075490612c8d565b603680546001600160a01b0319166001600160a01b0383811691909117918290556040517f4a41a4d11aaf0c0c9e4311ac1d68b2b0134556da594779a2a35b0ddf7cd1eafb926107ae921690612707565b3390565b60006118fa608084016060850161216d565b90506040830135600061193f611913602087018761216d565b611923604088016020890161216d565b848660808a013560a08b013561059760e08d0160c08e016125a9565b60a08601356000908152603f602052604090205490915081146119745760405162461bcd60e51b8152600401610754906129ec565b6000818152603c602052604090205460ff16156119a35760405162461bcd60e51b815260040161075490612cc4565b6000818152603c60209081526040808320805460ff191660011790556001600160a01b0386168352603b90915290205460ff168015611a4357604051632142170760e11b81526001600160a01b038516906342842e0e90611a0c9030908990889060040161271b565b600060405180830381600087803b158015611a2657600080fd5b505af1158015611a3a573d6000803e3d6000fd5b50505050611aba565b6001600160a01b03808516600090815260396020526040908190205490516340c10f1960e01b815291169081906340c10f1990611a86908990889060040161273f565b600060405180830381600087803b158015611aa057600080fd5b505af1158015611ab4573d6000803e3d6000fd5b50505050505b611ac7602087018761216d565b6001600160a01b0390811690851660a08801357f8738727192721a6f1909e42e987fa3faf27386067521caf12f11c5dc4013c2ac611b0b60408b0160208c0161216d565b60408b013560808c0135611b2560e08e0160c08f016125a9565b8c604051611b379594939291906127f5565b60405180910390a4505050505050565b60006001600160a01b038216611b6f5760405162461bcd60e51b815260040161075490612c4b565b506001600160a01b03166000908152602091909152604090205460ff1690565b611b9a603382611f73565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b603e54600160a01b900460ff1615611bfb5760405162461bcd60e51b815260040161075490612a23565b60345460ff1615611c1e5760405162461bcd60e51b815260040161075490612b57565b603580546001908101918290556001600160a01b0387166000818152603b6020526040808220805460ff1916909417909355915163c87b56dd60e01b815288928392909163c87b56dd90611c76908890600401612836565b60006040518083038186803b158015611c8e57600080fd5b505afa158015611ca2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611cca9190810190612510565b6001600160a01b03808b166000908152603a60205260409020549192508a911615611d6257506001600160a01b03808a166000818152603a602052604090819020549051630852cd8d60e31b81529216916342966c6890611d2f908990600401612836565b600060405180830381600087803b158015611d4957600080fd5b505af1158015611d5d573d6000803e3d6000fd5b505050505b886001600160a01b0316611d746118e4565b6001600160a01b0316826001600160a01b03167f8586062302f52eda0114687cd36998f16298ea820e0a6f8878bbbfefebc09e9f8b8b896001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611de357600080fd5b505afa158015611df7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1b9190612591565b8c89604051611e2e959493929190612784565b60405180910390a4505050506035548114610a365760405162461bcd60e51b8152600401610754906128c5565b6000611e9d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611fbb565b9392505050565b611eaf603382611fe7565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6001600160a01b038116611f0c5760405162461bcd60e51b815260040161075490612e4d565b6034546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b611f7d8282611b47565b611f995760405162461bcd60e51b815260040161075490612a4e565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b60008184841115611fdf5760405162461bcd60e51b815260040161075491906128b2565b505050900390565b611ff18282611b47565b1561200e5760405162461bcd60e51b815260040161075490612938565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261206957600085556120af565b82601f1061208257805160ff19168380011785556120af565b828001600101855582156120af579182015b828111156120af578251825591602001919060010190612094565b506120bb9291506120bf565b5090565b5b808211156120bb57600081556001016120c0565b60006120e76120e284612ef4565b612ed0565b90508281528383830111156120fb57600080fd5b828260208301376000602084830101529392505050565b60008083601f840112612123578182fd5b50813567ffffffffffffffff81111561213a578182fd5b60208301915083602082850101111561215257600080fd5b9250929050565b803563ffffffff81168114610ab757600080fd5b60006020828403121561217e578081fd5b8135611e9d81612f46565b60006020828403121561219a578081fd5b8151611e9d81612f46565b600080600080600080600060e0888a0312156121bf578283fd5b87356121ca81612f46565b965060208801356121da81612f46565b955060408801356121ea81612f46565b9450606088013593506080880135925060a0880135915061220d60c08901612159565b905092959891949750929550565b600080600080600060a08688031215612232578081fd5b853561223d81612f46565b9450602086013561224d81612f46565b9350604086013561225d81612f46565b9250606086013561226d81612f46565b9150608086013567ffffffffffffffff811115612288578182fd5b8601601f81018813612298578182fd5b6122a7888235602084016120d4565b9150509295509295909350565b6000806000606084860312156122c8578283fd5b83356122d381612f46565b925060208401356122e381612f46565b929592945050506040919091013590565b600080600080600080600060e0888a03121561230e578081fd5b873561231981612f46565b9650602088013561232981612f46565b955060408801359450606088013561234081612f46565b93506080880135925060a0880135915061220d60c08901612159565b60008060008060808587031215612371578182fd5b843561237c81612f46565b9350602085013561238c81612f46565b925060408501359150606085013567ffffffffffffffff8111156123ae578182fd5b8501601f810187136123be578182fd5b6123cd878235602084016120d4565b91505092959194509250565b600080600080600080600080600060a08a8c0312156123f6578283fd5b893561240181612f46565b985060208a013567ffffffffffffffff8082111561241d578485fd5b6124298d838e01612112565b909a50985060408c0135915080821115612441578485fd5b61244d8d838e01612112565b909850965060608c0135915080821115612465578485fd5b6124718d838e01612112565b909650945060808c0135915080821115612489578384fd5b506124968c828d01612112565b915080935050809150509295985092959850929598565b600080604083850312156124bf578182fd5b82356124ca81612f46565b946020939093013593505050565b6000602082840312156124e9578081fd5b81358015158114611e9d578182fd5b600060208284031215612509578081fd5b5035919050565b600060208284031215612521578081fd5b815167ffffffffffffffff811115612537578182fd5b8201601f81018413612547578182fd5b80516125556120e282612ef4565b818152856020838501011115612569578384fd5b611744826020830160208601612f16565b600060e0828403121561258b578081fd5b50919050565b6000602082840312156125a2578081fd5b5051919050565b6000602082840312156125ba578081fd5b611e9d82612159565b600081518084526125db816020860160208601612f16565b601f01601f19169290920160200192915050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b9687526020870195909552606093841b6bffffffffffffffffffffffff19908116604088015292841b83166054870152606886019190915290911b16608883015260e01b6001600160e01b031916609c82015260a00190565b60008251612684818460208701612f16565b9190910192915050565b60008085546001808216600081146126ad57600181146126c4576126f3565b60ff198316865260028304607f16860193506126f3565b600283048986526020808720875b838110156126eb5781548a8201529085019082016126d2565b505050860193505b505050838582379092019182525092915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039490941684526020840192909252604083015263ffffffff16606082015260800190565b6001600160a01b038616815260a0602082018190526000906127a8908301876125c3565b85604084015284606084015282810360808401526127c681856125c3565b98975050505050505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b6001600160a01b0395861681526020810194909452604084019290925263ffffffff166060830152909116608082015260a00190565b901515815260200190565b90815260200190565b6001600160e01b031991909116815260200190565b60006080825261286860808301898b6125ef565b828103602084015261287a81896125c3565b9050828103604084015261288f8187896125ef565b905082810360608401526128a48185876125ef565b9a9950505050505050505050565b600060208252611e9d60208301846125c3565b60208082526025908201527f5265656e7472616e637947756172643a206e6f207265656e7472616e7420616c6040820152641b1bddd95960da1b606082015260800190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b6020808252601f908201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604082015260600190565b60208082526019908201527f4e46544272696467653a20696e76616c69642073656e64657200000000000000604082015260600190565b60208082526026908201527f4e46544272696467653a204e756c6c206f726967696e616c20746f6b656e206160408201526564647265737360d01b606082015260800190565b6020808252601b908201527f4e46544272696467653a2057726f6e6720747844617461486173680000000000604082015260600190565b6020808252601190820152704272696467653a20557067726164696e6760781b604082015260600190565b6020808252818101527f526f6c65733a206163636f756e7420646f65736e2774206861766520726f6c65604082015260600190565b60208082526028908201527f436f6e747261637420696e7374616e636520697320616c726561647920696e696040820152671d1a585b1a5e995960c21b606082015260800190565b60208082526028908201527f506175736572526f6c653a2063616c6c657220646f65736e277420686176652060408201526774686520726f6c6560c01b606082015260800190565b60208082526024908201527f4e46544272696467653a205369646520746f6b656e20616c72656164792065786040820152636973747360e01b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252601490820152734e46544272696467653a204e756c6c2046726f6d60601b604082015260600190565b60208082526016908201527509c8ca884e4d2c8ceca74409cead8d840a8f090c2e6d60531b604082015260600190565b60208082526019908201527f4e46544272696467653a204e6f742046656465726174696f6e00000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526022908201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601e908201527f4e46544272696467653a2046656465726174696f6e20697320656d7074790000604082015260600190565b6020808252601a908201527f4e46544272696467653a20416c726561647920636c61696d6564000000000000604082015260600190565b60208082526018908201527f4e46544272696467653a20556e6b6e6f776e20746f6b656e0000000000000000604082015260600190565b6020808252601b908201527f4e46544272696467653a20416c72656164792061636365707465640000000000604082015260600190565b6020808252602a908201527f4e46544272696467653a2076616c756520697320736d616c6c6572207468616e6040820152692066697865642066656560b01b606082015260800190565b6020808252601290820152714e46544272696467653a204e756c6c20546f60701b604082015260600190565b6020808252601f908201527f4e46544272696467653a20416c6c6f77546f6b656e7320697320656d70747900604082015260600190565b60208082526019908201527f4e46544272696467653a204e756c6c20426c6f636b4861736800000000000000604082015260600190565b60208082526022908201527f4f776e61626c653a206e6577206f776e6572206973207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526021908201527f4e46544272696467653a20656d7074792053696465546f6b656e466163746f726040820152607960f81b606082015260800190565b60405181810167ffffffffffffffff81118282101715612eec57fe5b604052919050565b600067ffffffffffffffff821115612f0857fe5b50601f01601f191660200190565b60005b83811015612f31578181015183820152602001612f19565b83811115612f40576000848401525b50505050565b6001600160a01b038116811461083357600080fdfea2646970667358221220c2db86366b65f97c4730018c60c95ed2c68e7f2ccd8332c152047ef6d532db2764736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "__Pausable_init(address)": {
+ "details": "Initializes the contract in unpaused state. Assigns the Pauser role to the deployer."
+ },
+ "initialize(address)": {
+ "details": "Initializes the contract setting the deployer as the initial owner."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "pause()": {
+ "details": "Called by a pauser to pause, triggers stopped state."
+ },
+ "paused()": {
+ "details": "Returns true if the contract is paused, and false otherwise."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. > Note: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "unpause()": {
+ "details": "Called by a pauser to unpause, returns to normal state."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "claim((address,address,uint256,address,bytes32,bytes32,uint32))": {
+ "notice": "Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data"
+ },
+ "onERC721Received(address,address,uint256,bytes)": {
+ "notice": "Always returns `IERC721Receiver.onERC721Received.selector`."
+ },
+ "receiveTokensTo(address,address,uint256)": {
+ "notice": "ERC-20 tokens approve and transferFrom pattern See https://eips.ethereum.org/EIPS/eip-20#transferfrom"
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 15789,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15792,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool"
+ },
+ {
+ "astId": 15832,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "______gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage"
+ },
+ {
+ "astId": 15856,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "_pausers",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_struct(Role)10133_storage"
+ },
+ {
+ "astId": 15978,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "_paused",
+ "offset": 0,
+ "slot": "52",
+ "type": "t_bool"
+ },
+ {
+ "astId": 16076,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "_owner",
+ "offset": 1,
+ "slot": "52",
+ "type": "t_address"
+ },
+ {
+ "astId": 16790,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "_guardCounter",
+ "offset": 0,
+ "slot": "53",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 8062,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "federation",
+ "offset": 0,
+ "slot": "54",
+ "type": "t_address_payable"
+ },
+ {
+ "astId": 8064,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "fixedFee",
+ "offset": 0,
+ "slot": "55",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 8066,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "symbolPrefix",
+ "offset": 0,
+ "slot": "56",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 8070,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "sideTokenAddressByOriginalTokenAddress",
+ "offset": 0,
+ "slot": "57",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 8074,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "originalTokenAddressBySideTokenAddress",
+ "offset": 0,
+ "slot": "58",
+ "type": "t_mapping(t_address,t_address)"
+ },
+ {
+ "astId": 8078,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "isAddressFromCrossedOriginalToken",
+ "offset": 0,
+ "slot": "59",
+ "type": "t_mapping(t_address,t_bool)"
+ },
+ {
+ "astId": 8082,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "claimed",
+ "offset": 0,
+ "slot": "60",
+ "type": "t_mapping(t_bytes32,t_bool)"
+ },
+ {
+ "astId": 8084,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "allowTokens",
+ "offset": 0,
+ "slot": "61",
+ "type": "t_contract(IAllowTokens)7210"
+ },
+ {
+ "astId": 8086,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "sideTokenFactory",
+ "offset": 0,
+ "slot": "62",
+ "type": "t_contract(ISideNFTTokenFactory)7998"
+ },
+ {
+ "astId": 8088,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "isUpgrading",
+ "offset": 20,
+ "slot": "62",
+ "type": "t_bool"
+ },
+ {
+ "astId": 8092,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "transactionDataHashes",
+ "offset": 0,
+ "slot": "63",
+ "type": "t_mapping(t_bytes32,t_bytes32)"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_address_payable": {
+ "encoding": "inplace",
+ "label": "address payable",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_uint256)50_storage": {
+ "base": "t_uint256",
+ "encoding": "inplace",
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes32": {
+ "encoding": "inplace",
+ "label": "bytes32",
+ "numberOfBytes": "32"
+ },
+ "t_contract(IAllowTokens)7210": {
+ "encoding": "inplace",
+ "label": "contract IAllowTokens",
+ "numberOfBytes": "20"
+ },
+ "t_contract(ISideNFTTokenFactory)7998": {
+ "encoding": "inplace",
+ "label": "contract ISideNFTTokenFactory",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_address)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => address)",
+ "numberOfBytes": "32",
+ "value": "t_address"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bool)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bool)",
+ "numberOfBytes": "32",
+ "value": "t_bool"
+ },
+ "t_mapping(t_bytes32,t_bytes32)": {
+ "encoding": "mapping",
+ "key": "t_bytes32",
+ "label": "mapping(bytes32 => bytes32)",
+ "numberOfBytes": "32",
+ "value": "t_bytes32"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)10133_storage": {
+ "encoding": "inplace",
+ "label": "struct Roles.Role",
+ "members": [
+ {
+ "astId": 10132,
+ "contract": "contracts/nftbridge/NFTBridge.sol:NFTBridge",
+ "label": "bearer",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_address,t_bool)"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/NftBridgeProxy.json b/bridge/deployments/rsktestnetrinkeby/NftBridgeProxy.json
new file mode 100644
index 000000000..ee53078c9
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/NftBridgeProxy.json
@@ -0,0 +1,248 @@
+{
+ "address": "0xD28f2EEB1a242462149542BDF90C4CC99271fa70",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_logic",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "previousAdmin",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "AdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "inputs": [],
+ "name": "admin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "admin_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "implementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "implementation_",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xc7ee097b71ec087d0826f4be5a6fe11557dea10387237002905a15b956e63c10",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0xD28f2EEB1a242462149542BDF90C4CC99271fa70",
+ "transactionIndex": 0,
+ "gasUsed": "910413",
+ "logsBloom": "0x00000000020000000000041000008000000000000000000000800000000000001000000000000000000000000000002000000000000000000000000000000000000000000080000000000000000000000001000000000000000000000000000000000000020000000000000000040800000010004020000000000000020000400000021000000000000000000000000000000000000000000000000000000000000200000000000000000000000000020000000000000000200801000000000000000000000000000000000000000100000000000000000002000000000020000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x30c751547acb31394f15ee94eb793a233964458d7f06e6f1c8056a0f39af3c71",
+ "transactionHash": "0xc7ee097b71ec087d0826f4be5a6fe11557dea10387237002905a15b956e63c10",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170981,
+ "transactionHash": "0xc7ee097b71ec087d0826f4be5a6fe11557dea10387237002905a15b956e63c10",
+ "address": "0xD28f2EEB1a242462149542BDF90C4CC99271fa70",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x00000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x30c751547acb31394f15ee94eb793a233964458d7f06e6f1c8056a0f39af3c71"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170981,
+ "transactionHash": "0xc7ee097b71ec087d0826f4be5a6fe11557dea10387237002905a15b956e63c10",
+ "address": "0xD28f2EEB1a242462149542BDF90C4CC99271fa70",
+ "topics": [
+ "0x6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f8",
+ "0x00000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a"
+ ],
+ "data": "0x",
+ "logIndex": 1,
+ "blockHash": "0x30c751547acb31394f15ee94eb793a233964458d7f06e6f1c8056a0f39af3c71"
+ },
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170981,
+ "transactionHash": "0xc7ee097b71ec087d0826f4be5a6fe11557dea10387237002905a15b956e63c10",
+ "address": "0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24",
+ "topics": [
+ "0x93baa6efbd2244243bfee6ce4cfdd1d04fc4c0e9a786abd3a41313bd352db153",
+ "0x000000000000000000000000d28f2eeb1a242462149542bdf90c4cc99271fa70",
+ "0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b",
+ "0x000000000000000000000000d28f2eeb1a242462149542bdf90c4cc99271fa70"
+ ],
+ "data": "0x",
+ "logIndex": 2,
+ "blockHash": "0x30c751547acb31394f15ee94eb793a233964458d7f06e6f1c8056a0f39af3c71"
+ }
+ ],
+ "blockNumber": 2170981,
+ "cumulativeGasUsed": "910413",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [
+ "0xdc8E3000ED0aCAC926A37ead0f0B0F675182AC3b",
+ "0x8C35e166d2Dea7a8A28aaeA11AD7933cDae4b0aB",
+ "0x2fb3b36100000000000000000000000088f6b2bc66f4c31a3669b9b1359524abf79cfc4a000000000000000000000000bc7a3f163b2fe1d6810a942417922f09f1fe82ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b0c885518b38d8a83ff6e83e2aec6506fbedc8500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000047252696e00000000000000000000000000000000000000000000000000000000"
+ ],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"stateVariables\":{\"_ADMIN_SLOT\":{\"details\":\"Storage slot with the admin of the contract. This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is validated in the constructor.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\r\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\r\\n * be specified by overriding the virtual {_implementation} function.\\r\\n *\\r\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\r\\n * different contract through the {_delegate} function.\\r\\n *\\r\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\r\\n */\\r\\nabstract contract Proxy {\\r\\n /**\\r\\n * @dev Delegates the current call to `implementation`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _delegate(address implementation) internal virtual {\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n // Copy msg.data. We take full control of memory in this inline assembly\\r\\n // block because it will not return to Solidity code. We overwrite the\\r\\n // Solidity scratch pad at memory position 0.\\r\\n calldatacopy(0, 0, calldatasize())\\r\\n\\r\\n // Call the implementation.\\r\\n // out and outsize are 0 because we don't know the size yet.\\r\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\r\\n\\r\\n // Copy the returned data.\\r\\n returndatacopy(0, 0, returndatasize())\\r\\n\\r\\n switch result\\r\\n // delegatecall returns 0 on error.\\r\\n case 0 { revert(0, returndatasize()) }\\r\\n default { return(0, returndatasize()) }\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\r\\n * and {_fallback} should delegate.\\r\\n */\\r\\n function _implementation() internal view virtual returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\r\\n *\\r\\n * This function does not return to its internall call site, it will return directly to the external caller.\\r\\n */\\r\\n function _fallback() internal virtual {\\r\\n _beforeFallback();\\r\\n _delegate(_implementation());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\r\\n * function in the contract matches the call data.\\r\\n */\\r\\n fallback () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\r\\n * is empty.\\r\\n */\\r\\n receive () external payable virtual {\\r\\n _fallback();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\r\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\r\\n *\\r\\n * If overriden should call `super._beforeFallback()`.\\r\\n */\\r\\n function _beforeFallback() internal virtual {\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x6374180266624d2291abb230bdf0d364858fa164844f5d2d83ad5325852390c9\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./UpgradeableProxy.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\r\\n *\\r\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\r\\n * clashing], which can potentially be used in an attack, this contract uses the\\r\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\r\\n * things that go hand in hand:\\r\\n *\\r\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\r\\n * that call matches one of the admin functions exposed by the proxy itself.\\r\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\r\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\r\\n * \\\"admin cannot fallback to proxy target\\\".\\r\\n *\\r\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\r\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\r\\n * to sudden errors when trying to call a function from the proxy implementation.\\r\\n *\\r\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\r\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\r\\n */\\r\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\r\\n /**\\r\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\r\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\r\\n */\\r\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\r\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\r\\n _setAdmin(admin_);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the admin account has changed.\\r\\n */\\r\\n event AdminChanged(address previousAdmin, address newAdmin);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the admin of the contract.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\r\\n\\r\\n /**\\r\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\r\\n */\\r\\n modifier ifAdmin() {\\r\\n if (msg.sender == _admin()) {\\r\\n _;\\r\\n } else {\\r\\n _fallback();\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\r\\n */\\r\\n function admin() external ifAdmin returns (address admin_) {\\r\\n admin_ = _admin();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\r\\n *\\r\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\r\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\r\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\r\\n */\\r\\n function implementation() external ifAdmin returns (address implementation_) {\\r\\n implementation_ = _implementation();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Changes the admin of the proxy.\\r\\n *\\r\\n * Emits an {AdminChanged} event.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\r\\n */\\r\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\r\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\r\\n emit AdminChanged(_admin(), newAdmin);\\r\\n _setAdmin(newAdmin);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\r\\n */\\r\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\r\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\r\\n * proxied contract.\\r\\n *\\r\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\r\\n */\\r\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\r\\n _upgradeTo(newImplementation);\\r\\n Address.functionDelegateCall(newImplementation, data);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the current admin.\\r\\n */\\r\\n function _admin() internal view virtual returns (address adm) {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n adm := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 admin slot.\\r\\n */\\r\\n function _setAdmin(address newAdmin) private {\\r\\n bytes32 slot = _ADMIN_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newAdmin)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\r\\n */\\r\\n function _beforeFallback() internal virtual override {\\r\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\r\\n super._beforeFallback();\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x7496c2c54dd8e648d6999687cf759521e6ab229d0d8ddb4db62f3b51dbe68811\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./Proxy.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\r\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\r\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\r\\n * implementation behind the proxy.\\r\\n *\\r\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\r\\n * {TransparentUpgradeableProxy}.\\r\\n */\\r\\ncontract UpgradeableProxy is Proxy {\\r\\n /**\\r\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\r\\n *\\r\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\r\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\r\\n */\\r\\n constructor(address _logic, bytes memory _data) payable {\\r\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\r\\n _setImplementation(_logic);\\r\\n if(_data.length > 0) {\\r\\n Address.functionDelegateCall(_logic, _data);\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the implementation is upgraded.\\r\\n */\\r\\n event Upgraded(address indexed implementation);\\r\\n\\r\\n /**\\r\\n * @dev Storage slot with the address of the current implementation.\\r\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\r\\n * validated in the constructor.\\r\\n */\\r\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\r\\n\\r\\n /**\\r\\n * @dev Returns the current implementation address.\\r\\n */\\r\\n function _implementation() internal view virtual override returns (address impl) {\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n impl := sload(slot)\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Upgrades the proxy to a new implementation.\\r\\n *\\r\\n * Emits an {Upgraded} event.\\r\\n */\\r\\n function _upgradeTo(address newImplementation) internal virtual {\\r\\n _setImplementation(newImplementation);\\r\\n emit Upgraded(newImplementation);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Stores a new address in the EIP1967 implementation slot.\\r\\n */\\r\\n function _setImplementation(address newImplementation) private {\\r\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\r\\n\\r\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n sstore(slot, newImplementation)\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x4d3fcb8487e53abb8658817c4b90038b24d81d0a32d989f03b54d4cfab929f62\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405260405162000c9f38038062000c9f83398101604081905262000026916200022e565b8281620000338262000071565b8051156200005457620000528282620000d360201b620002ca1760201c565b505b506200005d9050565b620000688262000102565b5050506200041d565b62000087816200012660201b620002f61760201c565b620000af5760405162461bcd60e51b8152600401620000a69062000347565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6060620000fb838360405180606001604052806027815260200162000c786027913962000130565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b803b15155b919050565b60606200013d8462000126565b6200015c5760405162461bcd60e51b8152600401620000a690620003a4565b600080856001600160a01b031685604051620001799190620002f4565b600060405180830381855af49150503d8060008114620001b6576040519150601f19603f3d011682016040523d82523d6000602084013e620001bb565b606091505b509092509050620001ce828286620001d8565b9695505050505050565b60608315620001e9575081620000fb565b825115620001fa5782518084602001fd5b8160405162461bcd60e51b8152600401620000a6919062000312565b80516001600160a01b03811681146200012b57600080fd5b60008060006060848603121562000243578283fd5b6200024e8462000216565b92506200025e6020850162000216565b60408501519092506001600160401b03808211156200027b578283fd5b818601915086601f8301126200028f578283fd5b8151818111156200029c57fe5b604051601f8201601f191681016020018381118282101715620002bb57fe5b604052818152838201602001891015620002d3578485fd5b620002e6826020830160208701620003ea565b809450505050509250925092565b6000825162000308818460208701620003ea565b9190910192915050565b600060208252825180602084015262000333816040850160208701620003ea565b601f01601f19169190910160400192915050565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e746160408201527f74696f6e206973206e6f74206120636f6e747261637400000000000000000000606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60005b8381101562000407578181015183820152602001620003ed565b8381111562000417576000848401525b50505050565b61084b806200042d6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209ba77a19de177ea34b608207423a21765cca1077e9d39a414a7175e09fb147e464736f6c63430007060033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564",
+ "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c3578063f851a440146100e35761005d565b3661005d5761005b6100f8565b005b61005b6100f8565b34801561007157600080fd5b5061005b610080366004610548565b610112565b61005b610093366004610562565b61014c565b3480156100a457600080fd5b506100ad6101c9565b6040516100ba91906105fc565b60405180910390f35b3480156100cf57600080fd5b5061005b6100de366004610548565b610206565b3480156100ef57600080fd5b506100ad61029f565b610100610300565b61011061010b610341565b610366565b565b61011a61038a565b6001600160a01b0316336001600160a01b031614156101415761013c816103af565b610149565b6101496100f8565b50565b61015461038a565b6001600160a01b0316336001600160a01b031614156101bc57610176836103af565b6101b68383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ca92505050565b506101c4565b6101c46100f8565b505050565b60006101d361038a565b6001600160a01b0316336001600160a01b031614156101fb576101f4610341565b9050610203565b6102036100f8565b90565b61020e61038a565b6001600160a01b0316336001600160a01b03161415610141576001600160a01b0381166102565760405162461bcd60e51b815260040161024d9061065d565b60405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61027f61038a565b8260405161028e929190610610565b60405180910390a161013c816103ef565b60006102a961038a565b6001600160a01b0316336001600160a01b031614156101fb576101f461038a565b60606102ef83836040518060600160405280602781526020016107ef60279139610413565b9392505050565b803b15155b919050565b61030861038a565b6001600160a01b0316336001600160a01b031614156103395760405162461bcd60e51b815260040161024d90610756565b610110610110565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015610385573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103b8816104af565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b606061041e846102f6565b61043a5760405162461bcd60e51b815260040161024d90610710565b600080856001600160a01b03168560405161045591906105e0565b600060405180830381855af49150503d8060008114610490576040519150601f19603f3d011682016040523d82523d6000602084013e610495565b606091505b50915091506104a58282866104f8565b9695505050505050565b6104b8816102f6565b6104d45760405162461bcd60e51b815260040161024d906106ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b606083156105075750816102ef565b8251156105175782518084602001fd5b8160405162461bcd60e51b815260040161024d919061062a565b80356001600160a01b03811681146102fb57600080fd5b600060208284031215610559578081fd5b6102ef82610531565b600080600060408486031215610576578182fd5b61057f84610531565b9250602084013567ffffffffffffffff8082111561059b578384fd5b818601915086601f8301126105ae578384fd5b8135818111156105bc578485fd5b8760208285010111156105cd578485fd5b6020830194508093505050509250925092565b600082516105f28184602087016107be565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006020825282518060208401526106498160408501602087016107be565b601f01601f19169190910160400192915050565b6020808252603a908201527f5472616e73706172656e745570677261646561626c6550726f78793a206e657760408201527f2061646d696e20697320746865207a65726f2061646472657373000000000000606082015260800190565b60208082526036908201527f5570677261646561626c6550726f78793a206e657720696d706c656d656e74616040820152751d1a5bdb881a5cc81b9bdd08184818dbdb9d1c9858dd60521b606082015260800190565b60208082526026908201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6040820152651b9d1c9858dd60d21b606082015260800190565b60208082526042908201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60408201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606082015261195d60f21b608082015260a00190565b60005b838110156107d95781810151838201526020016107c1565b838111156107e8576000848401525b5050505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209ba77a19de177ea34b608207423a21765cca1077e9d39a414a7175e09fb147e464736f6c63430007060033",
+ "devdoc": {
+ "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.",
+ "events": {
+ "AdminChanged(address,address)": {
+ "details": "Emitted when the admin account has changed."
+ }
+ },
+ "kind": "dev",
+ "methods": {
+ "admin()": {
+ "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`"
+ },
+ "changeAdmin(address)": {
+ "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}."
+ },
+ "constructor": {
+ "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}."
+ },
+ "implementation()": {
+ "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`"
+ },
+ "upgradeTo(address)": {
+ "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}."
+ },
+ "upgradeToAndCall(address,bytes)": {
+ "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}."
+ }
+ },
+ "stateVariables": {
+ "_ADMIN_SLOT": {
+ "details": "Storage slot with the admin of the contract. This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/ProxyAdmin.json b/bridge/deployments/rsktestnetrinkeby/ProxyAdmin.json
new file mode 100644
index 000000000..fe5dd077d
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/ProxyAdmin.json
@@ -0,0 +1,261 @@
+{
+ "address": "0x8c35e166d2dea7a8a28aaea11ad7933cdae4b0ab",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "newAdmin",
+ "type": "address"
+ }
+ ],
+ "name": "changeProxyAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ }
+ ],
+ "name": "getProxyAdmin",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ }
+ ],
+ "name": "getProxyImplementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isOwner",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgrade",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract TransparentUpgradeableProxy",
+ "name": "proxy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0xccb5efec2a755bdacf9df4f51f512e23701a31e89a59c11fc6bb0f6134c34a2d",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0x826e131ADF0fFc77308540966d757B466fa72FFd",
+ "transactionIndex": 0,
+ "gasUsed": "601344",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000100000000000000020000020000000000000800000000000000000000000000000000400000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000020000000000000200000000000000000000000000000000000040000000000000000",
+ "blockHash": "0x23d2689ca13007d1c676dd0836055c3198c867cd10fc217c7808e956e6004304",
+ "transactionHash": "0xccb5efec2a755bdacf9df4f51f512e23701a31e89a59c11fc6bb0f6134c34a2d",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2152171,
+ "transactionHash": "0xccb5efec2a755bdacf9df4f51f512e23701a31e89a59c11fc6bb0f6134c34a2d",
+ "address": "0x826e131ADF0fFc77308540966d757B466fa72FFd",
+ "topics": [
+ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x000000000000000000000000eac27e59f8a71613137e9c5d475d05c7d4d198e8"
+ ],
+ "data": "0x",
+ "logIndex": 0,
+ "blockHash": "0x23d2689ca13007d1c676dd0836055c3198c867cd10fc217c7808e956e6004304"
+ }
+ ],
+ "blockNumber": 2152171,
+ "cumulativeGasUsed": "601344",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\",\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"details\":\"Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`.\"},\"getProxyAdmin(address)\":{\"details\":\"Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"getProxyImplementation(address)\":{\"details\":\"Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"isOwner()\":{\"details\":\"Returns true if the caller is the current owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"details\":\"Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`.\"},\"upgradeAndCall(address,address,bytes)\":{\"details\":\"Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol\":\"ProxyAdmin\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n\\n function _msgSender() internal view returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xbc43be9319c563253600d0a1d7106572c9bfc1fbb623d133a1edfb7e60c845c4\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../GSN/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () {\\n _owner = _msgSender();\\n emit OwnershipTransferred(address(0), _owner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(isOwner(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the caller is the current owner.\\n */\\n function isOwner() public view returns (bool) {\\n return _msgSender() == _owner;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n */\\n function _transferOwnership(address newOwner) internal {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x82fe89d36187df48c5e24e6ca1cf0566f4b0c0a3bd8da835ab64100e28d21b62\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0x590a4d952d39a99972cbcb691b472c5d58af9ae8fd142355ad26200affdd2a51\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"../../ownership/Ownable.sol\\\";\\nimport \\\"./TransparentUpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\\n */\\ncontract ProxyAdmin is Ownable {\\n\\n /**\\n * @dev Returns the current implementation of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"implementation()\\\")) == 0x5c60da1b\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"5c60da1b\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Returns the current admin of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"admin()\\\")) == 0xf851a440\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"f851a440\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Changes the admin of `proxy` to `newAdmin`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the current admin of `proxy`.\\n */\\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\\n proxy.changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\\n proxy.upgradeTo(implementation);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\\n }\\n}\\n\",\"keccak256\":\"0x808ad1c30093ccfc011509c642615a9bad84d0e1eced5327fe50d3ec145a9899\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(admin_);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\\n _upgradeTo(newImplementation);\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x0d5202a38732881d576fe3831605fe2633e1bc9f981ebea9c3a368af027e0b71\",\"license\":\"MIT\"},\"contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n *\\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n Address.functionDelegateCall(_logic, _data);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal virtual {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x53b00bc48bd4eac1e100195c494267c0ca082bd91ac3018e2ee6155fbcbbb14f\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc67d0428addcf1cbef937166a7b8f28d4e1d6ecf0eaaff683501d25e8593dc28\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50610019610066565b600080546001600160a01b0319166001600160a01b03928316178082556040519216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a361006a565b3390565b61079e806100796000396000f3fe6080604052600436106100865760003560e01c80638f32d59b116100595780638f32d59b1461010d5780639623609d1461012f57806399a88ec414610142578063f2fde38b14610162578063f3b7dead1461018257610086565b8063204e1c7a1461008b578063715018a6146100c15780637eff275e146100d85780638da5cb5b146100f8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610503565b6101a2565b6040516100b89190610656565b60405180910390f35b3480156100cd57600080fd5b506100d6610228565b005b3480156100e457600080fd5b506100d66100f3366004610542565b61029f565b34801561010457600080fd5b506100ab610325565b34801561011957600080fd5b50610122610334565b6040516100b891906106cd565b6100d661013d36600461057a565b610358565b34801561014e57600080fd5b506100d661015d366004610542565b6103e3565b34801561016e57600080fd5b506100d661017d366004610503565b610433565b34801561018e57600080fd5b506100ab61019d366004610503565b610463565b6000806000836001600160a01b03166040516101bd90610636565b600060405180830381855afa9150503d80600081146101f8576040519150601f19603f3d011682016040523d82523d6000602084013e6101fd565b606091505b50915091508161020c57600080fd5b808060200190518101906102209190610526565b949350505050565b610230610334565b6102555760405162461bcd60e51b815260040161024c9061071e565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6102a7610334565b6102c35760405162461bcd60e51b815260040161024c9061071e565b6040516308f2839760e41b81526001600160a01b03831690638f283970906102ef908490600401610656565b600060405180830381600087803b15801561030957600080fd5b505af115801561031d573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031690565b600080546001600160a01b031661034961047e565b6001600160a01b031614905090565b610360610334565b61037c5760405162461bcd60e51b815260040161024c9061071e565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906103ac908690869060040161066a565b6000604051808303818588803b1580156103c557600080fd5b505af11580156103d9573d6000803e3d6000fd5b5050505050505050565b6103eb610334565b6104075760405162461bcd60e51b815260040161024c9061071e565b604051631b2ce7f360e11b81526001600160a01b03831690633659cfe6906102ef908490600401610656565b61043b610334565b6104575760405162461bcd60e51b815260040161024c9061071e565b61046081610482565b50565b6000806000836001600160a01b03166040516101bd90610646565b3390565b6001600160a01b0381166104a85760405162461bcd60e51b815260040161024c906106d8565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600060208284031215610514578081fd5b813561051f81610753565b9392505050565b600060208284031215610537578081fd5b815161051f81610753565b60008060408385031215610554578081fd5b823561055f81610753565b9150602083013561056f81610753565b809150509250929050565b60008060006060848603121561058e578081fd5b833561059981610753565b92506020848101356105aa81610753565b9250604085013567ffffffffffffffff808211156105c6578384fd5b818701915087601f8301126105d9578384fd5b8135818111156105e557fe5b604051601f8201601f191681018501838111828210171561060257fe5b60405281815283820185018a1015610618578586fd5b81858501868301378585838301015280955050505050509250925092565b635c60da1b60e01b815260040190565b6303e1469160e61b815260040190565b6001600160a01b0391909116815260200190565b600060018060a01b038416825260206040818401528351806040850152825b818110156106a557858101830151858201606001528201610689565b818111156106b65783606083870101525b50601f01601f191692909201606001949350505050565b901515815260200190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6001600160a01b038116811461046057600080fdfea2646970667358221220142b10fc4fdd881bdff70408546e1b1005f22944adc6b0a0da6becaf7c2b47a164736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106100865760003560e01c80638f32d59b116100595780638f32d59b1461010d5780639623609d1461012f57806399a88ec414610142578063f2fde38b14610162578063f3b7dead1461018257610086565b8063204e1c7a1461008b578063715018a6146100c15780637eff275e146100d85780638da5cb5b146100f8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610503565b6101a2565b6040516100b89190610656565b60405180910390f35b3480156100cd57600080fd5b506100d6610228565b005b3480156100e457600080fd5b506100d66100f3366004610542565b61029f565b34801561010457600080fd5b506100ab610325565b34801561011957600080fd5b50610122610334565b6040516100b891906106cd565b6100d661013d36600461057a565b610358565b34801561014e57600080fd5b506100d661015d366004610542565b6103e3565b34801561016e57600080fd5b506100d661017d366004610503565b610433565b34801561018e57600080fd5b506100ab61019d366004610503565b610463565b6000806000836001600160a01b03166040516101bd90610636565b600060405180830381855afa9150503d80600081146101f8576040519150601f19603f3d011682016040523d82523d6000602084013e6101fd565b606091505b50915091508161020c57600080fd5b808060200190518101906102209190610526565b949350505050565b610230610334565b6102555760405162461bcd60e51b815260040161024c9061071e565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6102a7610334565b6102c35760405162461bcd60e51b815260040161024c9061071e565b6040516308f2839760e41b81526001600160a01b03831690638f283970906102ef908490600401610656565b600060405180830381600087803b15801561030957600080fd5b505af115801561031d573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031690565b600080546001600160a01b031661034961047e565b6001600160a01b031614905090565b610360610334565b61037c5760405162461bcd60e51b815260040161024c9061071e565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906103ac908690869060040161066a565b6000604051808303818588803b1580156103c557600080fd5b505af11580156103d9573d6000803e3d6000fd5b5050505050505050565b6103eb610334565b6104075760405162461bcd60e51b815260040161024c9061071e565b604051631b2ce7f360e11b81526001600160a01b03831690633659cfe6906102ef908490600401610656565b61043b610334565b6104575760405162461bcd60e51b815260040161024c9061071e565b61046081610482565b50565b6000806000836001600160a01b03166040516101bd90610646565b3390565b6001600160a01b0381166104a85760405162461bcd60e51b815260040161024c906106d8565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600060208284031215610514578081fd5b813561051f81610753565b9392505050565b600060208284031215610537578081fd5b815161051f81610753565b60008060408385031215610554578081fd5b823561055f81610753565b9150602083013561056f81610753565b809150509250929050565b60008060006060848603121561058e578081fd5b833561059981610753565b92506020848101356105aa81610753565b9250604085013567ffffffffffffffff808211156105c6578384fd5b818701915087601f8301126105d9578384fd5b8135818111156105e557fe5b604051601f8201601f191681018501838111828210171561060257fe5b60405281815283820185018a1015610618578586fd5b81858501868301378585838301015280955050505050509250925092565b635c60da1b60e01b815260040190565b6303e1469160e61b815260040190565b6001600160a01b0391909116815260200190565b600060018060a01b038416825260206040818401528351806040850152825b818110156106a557858101830151858201606001528201610689565b818111156106b65783606083870101525b50601f01601f191692909201606001949350505050565b901515815260200190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6001600160a01b038116811461046057600080fdfea2646970667358221220142b10fc4fdd881bdff70408546e1b1005f22944adc6b0a0da6becaf7c2b47a164736f6c63430007060033",
+ "devdoc": {
+ "details": "This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.",
+ "kind": "dev",
+ "methods": {
+ "changeProxyAdmin(address,address)": {
+ "details": "Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`."
+ },
+ "getProxyAdmin(address)": {
+ "details": "Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "getProxyImplementation(address)": {
+ "details": "Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "isOwner()": {
+ "details": "Returns true if the caller is the current owner."
+ },
+ "owner()": {
+ "details": "Returns the address of the current owner."
+ },
+ "renounceOwnership()": {
+ "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
+ },
+ "transferOwnership(address)": {
+ "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
+ },
+ "upgrade(address,address)": {
+ "details": "Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`."
+ },
+ "upgradeAndCall(address,address,bytes)": {
+ "details": "Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`."
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 10887,
+ "contract": "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol:ProxyAdmin",
+ "label": "_owner",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/SideNFTTokenFactory.json b/bridge/deployments/rsktestnetrinkeby/SideNFTTokenFactory.json
new file mode 100644
index 000000000..be34586ab
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/SideNFTTokenFactory.json
@@ -0,0 +1,184 @@
+{
+ "address": "0x5b0c885518B38d8A83fF6E83E2AEc6506fbeDc85",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sideTokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "baseURI",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "contractURI",
+ "type": "string"
+ }
+ ],
+ "name": "SideNFTTokenCreated",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "baseURI",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "contractURI",
+ "type": "string"
+ }
+ ],
+ "name": "createSideNFTToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x1b1f8eb006ba9241982029b1fe2df893581a7076e96ac418d0efdeace4271be6",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eAb56FB80b53f3137422189E940EeFe31b",
+ "contractAddress": "0x5b0c885518B38d8A83fF6E83E2AEc6506fbeDc85",
+ "transactionIndex": 0,
+ "gasUsed": "2834703",
+ "logsBloom": "0x00000000000000000000000000000000000000000000200000000000000000200000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000",
+ "blockHash": "0x5272ded42aa6d8c4d312455c08ee8bd7e31c688b66910f1a9181a94916166529",
+ "transactionHash": "0x1b1f8eb006ba9241982029b1fe2df893581a7076e96ac418d0efdeace4271be6",
+ "logs": [
+ {
+ "transactionIndex": 0,
+ "blockNumber": 2170978,
+ "transactionHash": "0x1b1f8eb006ba9241982029b1fe2df893581a7076e96ac418d0efdeace4271be6",
+ "address": "0x5b0c885518B38d8A83fF6E83E2AEc6506fbeDc85",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ],
+ "data": "0x0000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b",
+ "logIndex": 0,
+ "blockHash": "0x5272ded42aa6d8c4d312455c08ee8bd7e31c688b66910f1a9181a94916166529"
+ }
+ ],
+ "blockNumber": 2170978,
+ "cumulativeGasUsed": "2834703",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sideTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"baseURI\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"contractURI\",\"type\":\"string\"}],\"name\":\"SideNFTTokenCreated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"baseURI\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"contractURI\",\"type\":\"string\"}],\"name\":\"createSideNFTToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/nftbridge/SideNFTTokenFactory.sol\":\"SideNFTTokenFactory\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/nftbridge/ISideNFTToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideNFTToken {\\r\\n function mint(address account, uint256 tokenId) external;\\r\\n}\",\"keccak256\":\"0xcedb55e825518cb74679fa8a249cc36f5621d3787075cfaf483729e44cd605d3\",\"license\":\"MIT\"},\"contracts/nftbridge/ISideNFTTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideNFTTokenFactory {\\r\\n\\r\\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\\r\\n string calldata contractURI) external returns(address);\\r\\n\\r\\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\\r\\n}\",\"keccak256\":\"0x94993f1c48d9cc1e806d04fc5468566c5314f992705729024c4f9bcdd1eeb99f\",\"license\":\"MIT\"},\"contracts/nftbridge/SideNFTToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"./ISideNFTToken.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC721/ERC721.sol\\\";\\r\\nimport \\\"../zeppelin/token/ERC721/ERC721Burnable.sol\\\";\\r\\n\\r\\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\\r\\n address public minter;\\r\\n string private _contractURI;\\r\\n\\r\\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\\r\\n require(_minter != address(0), \\\"SideToken: Empty Minter\\\");\\r\\n minter = _minter;\\r\\n _setBaseURI(_baseURI);\\r\\n _setContractURI(contractURI_);\\r\\n }\\r\\n\\r\\n function _setContractURI(string memory contractURI_) internal {\\r\\n _contractURI = contractURI_;\\r\\n }\\r\\n\\r\\n function contractURI() public view returns (string memory) {\\r\\n return _contractURI;\\r\\n }\\r\\n\\r\\n modifier onlyMinter() {\\r\\n require(_msgSender() == minter, \\\"SideToken: Caller is not the minter\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function mint(address account, uint256 tokenId) external onlyMinter override {\\r\\n _mint(account, tokenId);\\r\\n }\\r\\n}\",\"keccak256\":\"0x83256170d784726faef65af12824e6c60d296b1360e5b949bc65dd674233ee95\",\"license\":\"MIT\"},\"contracts/nftbridge/SideNFTTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../zeppelin/ownership/Secondary.sol\\\";\\r\\nimport \\\"./ISideNFTTokenFactory.sol\\\";\\r\\nimport \\\"./SideNFTToken.sol\\\";\\r\\n\\r\\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\\r\\n\\r\\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\\r\\n string calldata contractURI) external onlyPrimary override returns(address) {\\r\\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\\r\\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\\r\\n return sideTokenAddress;\\r\\n }\\r\\n}\",\"keccak256\":\"0x69b402f7f4a3c074dcb2756e6def4f60a0c6d090e28d28d2ec5e158144fbf0ad\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC165.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Implementation of the {IERC165} interface.\\r\\n *\\r\\n * Contracts may inherit from this and call {_registerInterface} to declare\\r\\n * their support of an interface.\\r\\n */\\r\\nabstract contract ERC165 is IERC165 {\\r\\n /*\\r\\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\\r\\n\\r\\n /**\\r\\n * @dev Mapping of interface ids to whether or not it's supported.\\r\\n */\\r\\n mapping(bytes4 => bool) private _supportedInterfaces;\\r\\n\\r\\n constructor () {\\r\\n // Derived contracts need only register support for their own interfaces,\\r\\n // we register support for ERC165 itself here\\r\\n _registerInterface(_INTERFACE_ID_ERC165);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC165-supportsInterface}.\\r\\n *\\r\\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\\r\\n */\\r\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\r\\n return _supportedInterfaces[interfaceId];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Registers the contract as an implementer of the interface defined by\\r\\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\\r\\n * registering its interface id is not required.\\r\\n *\\r\\n * See {IERC165-supportsInterface}.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\\r\\n */\\r\\n function _registerInterface(bytes4 interfaceId) internal virtual {\\r\\n require(interfaceId != 0xffffffff, \\\"ERC165: invalid interface id\\\");\\r\\n _supportedInterfaces[interfaceId] = true;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x5415f8c63658ee08e6284e6f270b2490331aea0c375b6451c4c9ed14a805a336\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC165 standard, as defined in the\\r\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\r\\n *\\r\\n * Implementers can declare support of contract interfaces, which can then be\\r\\n * queried by others ({ERC165Checker}).\\r\\n *\\r\\n * For an implementation, see {ERC165}.\\r\\n */\\r\\ninterface IERC165 {\\r\\n /**\\r\\n * @dev Returns true if this contract implements the interface defined by\\r\\n * `interfaceId`. See the corresponding\\r\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\r\\n * to learn more about how these ids are created.\\r\\n *\\r\\n * This function call must use less than 30 000 gas.\\r\\n */\\r\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\r\\n}\\r\\n\",\"keccak256\":\"0xd5da4ccf6a22475f021130a32aaad92daf6eecce9258cb7a8a5c48d109607767\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\r\\n * checks.\\r\\n *\\r\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\r\\n * in bugs, because programmers usually assume that an overflow raises an\\r\\n * error, which is the standard behavior in high level programming languages.\\r\\n * `SafeMath` restores this intuition by reverting the transaction when an\\r\\n * operation overflows.\\r\\n *\\r\\n * Using this library instead of the unchecked operations eliminates an entire\\r\\n * class of bugs, so it's recommended to use it always.\\r\\n */\\r\\nlibrary SafeMath {\\r\\n /**\\r\\n * @dev Returns the addition of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `+` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Addition cannot overflow.\\r\\n */\\r\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n uint256 c = a + b;\\r\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n */\\r\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b <= a, errorMessage);\\r\\n uint256 c = a - b;\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `*` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Multiplication cannot overflow.\\r\\n */\\r\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\r\\n // benefit is lost if 'b' is also tested.\\r\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\r\\n if (a == 0) {\\r\\n return 0;\\r\\n }\\r\\n\\r\\n uint256 c = a * b;\\r\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n // Solidity only automatically asserts when dividing by 0\\r\\n require(b > 0, errorMessage);\\r\\n uint256 c = a / b;\\r\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts with custom message when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b != 0, errorMessage);\\r\\n return a % b;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x29ffa7ff59806a3add585615cc102b70b43049587dcc73649f77b427f35b009d\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Secondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../GSN/Context.sol\\\";\\r\\n/**\\r\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\r\\n */\\r\\nabstract contract Secondary is Context {\\r\\n address private _primary;\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the primary contract changes.\\r\\n */\\r\\n event PrimaryTransferred(\\r\\n address recipient\\r\\n );\\r\\n\\r\\n /**\\r\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\r\\n */\\r\\n constructor () {\\r\\n _primary = _msgSender();\\r\\n emit PrimaryTransferred(_primary);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Reverts if called from any account other than the primary.\\r\\n */\\r\\n modifier onlyPrimary() {\\r\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @return the address of the primary.\\r\\n */\\r\\n function primary() public view returns (address) {\\r\\n return _primary;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers contract to a new primary.\\r\\n * @param recipient The address of new primary.\\r\\n */\\r\\n function transferPrimary(address recipient) public onlyPrimary {\\r\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\r\\n _primary = recipient;\\r\\n emit PrimaryTransferred(_primary);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x9138d9f1c2d4b2b9d6fd72ceb5ef461ffcd2c26ade7b15a5ee86456ecda089ca\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"./IERC721.sol\\\";\\r\\nimport \\\"./IERC721Metadata.sol\\\";\\r\\nimport \\\"./IERC721Enumerable.sol\\\";\\r\\nimport \\\"./IERC721Receiver.sol\\\";\\r\\nimport \\\"../../introspection/ERC165.sol\\\";\\r\\nimport \\\"../../math/SafeMath.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\nimport \\\"../../utils/EnumerableSet.sol\\\";\\r\\nimport \\\"../../utils/EnumerableMap.sol\\\";\\r\\nimport \\\"../../utils/Strings.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC721 Non-Fungible Token Standard basic implementation\\r\\n * @dev see https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\\r\\n using SafeMath for uint256;\\r\\n using Address for address;\\r\\n using EnumerableSet for EnumerableSet.UintSet;\\r\\n using EnumerableMap for EnumerableMap.UintToAddressMap;\\r\\n using Strings for uint256;\\r\\n\\r\\n // Equals to `bytes4(keccak256(\\\"onERC721Received(address,address,uint256,bytes)\\\"))`\\r\\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\\r\\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\\r\\n\\r\\n // Mapping from holder address to their (enumerable) set of owned tokens\\r\\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\\r\\n\\r\\n // Enumerable mapping from token ids to their owners\\r\\n EnumerableMap.UintToAddressMap private _tokenOwners;\\r\\n\\r\\n // Mapping from token ID to approved address\\r\\n mapping (uint256 => address) private _tokenApprovals;\\r\\n\\r\\n // Mapping from owner to operator approvals\\r\\n mapping (address => mapping (address => bool)) private _operatorApprovals;\\r\\n\\r\\n // Token name\\r\\n string private _name;\\r\\n\\r\\n // Token symbol\\r\\n string private _symbol;\\r\\n\\r\\n // Optional mapping for token URIs\\r\\n mapping (uint256 => string) private _tokenURIs;\\r\\n\\r\\n // Base URI\\r\\n string private _baseURI;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\\r\\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\\r\\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\\r\\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\\r\\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\\r\\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\\r\\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\\r\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\\r\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\\r\\n *\\r\\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\\r\\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('name()')) == 0x06fdde03\\r\\n * bytes4(keccak256('symbol()')) == 0x95d89b41\\r\\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\\r\\n *\\r\\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\\r\\n\\r\\n /*\\r\\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\\r\\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\\r\\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\\r\\n *\\r\\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\\r\\n */\\r\\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\\r\\n\\r\\n /**\\r\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\r\\n */\\r\\n constructor (string memory name_, string memory symbol_) {\\r\\n _name = name_;\\r\\n _symbol = symbol_;\\r\\n\\r\\n // register the supported interfaces to conform to ERC721 via ERC165\\r\\n _registerInterface(_INTERFACE_ID_ERC721);\\r\\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\\r\\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-balanceOf}.\\r\\n */\\r\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\r\\n require(owner != address(0), \\\"ERC721: balance query for the zero address\\\");\\r\\n return _holderTokens[owner].length();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-ownerOf}.\\r\\n */\\r\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\r\\n return _tokenOwners.get(tokenId, \\\"ERC721: owner query for nonexistent token\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-name}.\\r\\n */\\r\\n function name() public view virtual override returns (string memory) {\\r\\n return _name;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-symbol}.\\r\\n */\\r\\n function symbol() public view virtual override returns (string memory) {\\r\\n return _symbol;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Metadata-tokenURI}.\\r\\n */\\r\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\r\\n require(_exists(tokenId), \\\"ERC721Metadata: URI query for nonexistent token\\\");\\r\\n\\r\\n string memory _tokenURI = _tokenURIs[tokenId];\\r\\n string memory base = baseURI();\\r\\n\\r\\n // If there is no base URI, return the token URI.\\r\\n if (bytes(base).length == 0) {\\r\\n return _tokenURI;\\r\\n }\\r\\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\\r\\n if (bytes(_tokenURI).length > 0) {\\r\\n return string(abi.encodePacked(base, _tokenURI));\\r\\n }\\r\\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\\r\\n return string(abi.encodePacked(base, tokenId.toString()));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the base URI set via {_setBaseURI}. This will be\\r\\n * automatically added as a prefix in {tokenURI} to each token's URI, or\\r\\n * to the token ID if no specific URI is set for that token ID.\\r\\n */\\r\\n function baseURI() public view virtual returns (string memory) {\\r\\n return _baseURI;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\r\\n */\\r\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\r\\n return _holderTokens[owner].at(index);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-totalSupply}.\\r\\n */\\r\\n function totalSupply() public view virtual override returns (uint256) {\\r\\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\\r\\n return _tokenOwners.length();\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\r\\n */\\r\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\r\\n (uint256 tokenId, ) = _tokenOwners.at(index);\\r\\n return tokenId;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-approve}.\\r\\n */\\r\\n function approve(address to, uint256 tokenId) public virtual override {\\r\\n address owner = ERC721.ownerOf(tokenId);\\r\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\r\\n\\r\\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\\r\\n \\\"ERC721: approve caller is not owner nor approved for all\\\"\\r\\n );\\r\\n\\r\\n _approve(to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-getApproved}.\\r\\n */\\r\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\r\\n require(_exists(tokenId), \\\"ERC721: approved query for nonexistent token\\\");\\r\\n\\r\\n return _tokenApprovals[tokenId];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-setApprovalForAll}.\\r\\n */\\r\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\r\\n require(operator != _msgSender(), \\\"ERC721: approve to caller\\\");\\r\\n\\r\\n _operatorApprovals[_msgSender()][operator] = approved;\\r\\n emit ApprovalForAll(_msgSender(), operator, approved);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-isApprovedForAll}.\\r\\n */\\r\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\r\\n return _operatorApprovals[owner][operator];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-transferFrom}.\\r\\n */\\r\\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\\r\\n //solhint-disable-next-line max-line-length\\r\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\r\\n\\r\\n _transfer(from, to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-safeTransferFrom}.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\\r\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC721-safeTransferFrom}.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\\r\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\r\\n _safeTransfer(from, to, tokenId, _data);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\r\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\r\\n *\\r\\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\\r\\n *\\r\\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\r\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\\r\\n _transfer(from, to, tokenId);\\r\\n require(_checkOnERC721Received(from, to, tokenId, _data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns whether `tokenId` exists.\\r\\n *\\r\\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\r\\n *\\r\\n * Tokens start existing when they are minted (`_mint`),\\r\\n * and stop existing when they are burned (`_burn`).\\r\\n */\\r\\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\\r\\n return _tokenOwners.contains(tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\r\\n require(_exists(tokenId), \\\"ERC721: operator query for nonexistent token\\\");\\r\\n address owner = ERC721.ownerOf(tokenId);\\r\\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\r\\n *\\r\\n * Requirements:\\r\\n d*\\r\\n * - `tokenId` must not exist.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\r\\n _safeMint(to, tokenId, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\r\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\r\\n */\\r\\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\\r\\n _mint(to, tokenId);\\r\\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Mints `tokenId` and transfers it to `to`.\\r\\n *\\r\\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must not exist.\\r\\n * - `to` cannot be the zero address.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _mint(address to, uint256 tokenId) internal virtual {\\r\\n require(to != address(0), \\\"ERC721: mint to the zero address\\\");\\r\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\r\\n\\r\\n _beforeTokenTransfer(address(0), to, tokenId);\\r\\n\\r\\n _holderTokens[to].add(tokenId);\\r\\n\\r\\n _tokenOwners.set(tokenId, to);\\r\\n\\r\\n emit Transfer(address(0), to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Destroys `tokenId`.\\r\\n * The approval is cleared when the token is burned.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _burn(uint256 tokenId) internal virtual {\\r\\n address owner = ERC721.ownerOf(tokenId); // internal owner\\r\\n\\r\\n _beforeTokenTransfer(owner, address(0), tokenId);\\r\\n\\r\\n // Clear approvals\\r\\n _approve(address(0), tokenId);\\r\\n\\r\\n // Clear metadata (if any)\\r\\n if (bytes(_tokenURIs[tokenId]).length != 0) {\\r\\n delete _tokenURIs[tokenId];\\r\\n }\\r\\n\\r\\n _holderTokens[owner].remove(tokenId);\\r\\n\\r\\n _tokenOwners.remove(tokenId);\\r\\n\\r\\n emit Transfer(owner, address(0), tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers `tokenId` from `from` to `to`.\\r\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must be owned by `from`.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\\r\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer of token that is not own\\\"); // internal owner\\r\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\r\\n\\r\\n _beforeTokenTransfer(from, to, tokenId);\\r\\n\\r\\n // Clear approvals from the previous owner\\r\\n _approve(address(0), tokenId);\\r\\n\\r\\n _holderTokens[from].remove(tokenId);\\r\\n _holderTokens[to].add(tokenId);\\r\\n\\r\\n _tokenOwners.set(tokenId, to);\\r\\n\\r\\n emit Transfer(from, to, tokenId);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\\r\\n require(_exists(tokenId), \\\"ERC721Metadata: URI set of nonexistent token\\\");\\r\\n _tokenURIs[tokenId] = _tokenURI;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Internal function to set the base URI for all token IDs. It is\\r\\n * automatically added as a prefix to the value returned in {tokenURI},\\r\\n * or to the token ID if {tokenURI} is empty.\\r\\n */\\r\\n function _setBaseURI(string memory baseURI_) internal virtual {\\r\\n _baseURI = baseURI_;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\r\\n * The call is not executed if the target address is not a contract.\\r\\n *\\r\\n * @param from address representing the previous owner of the given token ID\\r\\n * @param to target address that will receive the tokens\\r\\n * @param tokenId uint256 ID of the token to be transferred\\r\\n * @param _data bytes optional data to send along with the call\\r\\n * @return bool whether the call correctly returned the expected magic value\\r\\n */\\r\\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\\r\\n private returns (bool)\\r\\n {\\r\\n if (!to.isContract()) {\\r\\n return true;\\r\\n }\\r\\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\\r\\n IERC721Receiver(to).onERC721Received.selector,\\r\\n _msgSender(),\\r\\n from,\\r\\n tokenId,\\r\\n _data\\r\\n ), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\r\\n bytes4 retval = abi.decode(returndata, (bytes4));\\r\\n return (retval == _ERC721_RECEIVED);\\r\\n }\\r\\n\\r\\n function _approve(address to, uint256 tokenId) private {\\r\\n _tokenApprovals[tokenId] = to;\\r\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Hook that is called before any token transfer. This includes minting\\r\\n * and burning.\\r\\n *\\r\\n * Calling conditions:\\r\\n *\\r\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\r\\n * transferred to `to`.\\r\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\r\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n *\\r\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\r\\n */\\r\\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\\r\\n}\\r\\n\",\"keccak256\":\"0x4180eedc31f632ef146dd07583840a9688de44bdb9e7fe2425c448fd57496004\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"./ERC721.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC721 Burnable Token\\r\\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\\r\\n */\\r\\nabstract contract ERC721Burnable is Context, ERC721 {\\r\\n /**\\r\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - The caller must own `tokenId` or be an approved operator.\\r\\n */\\r\\n function burn(uint256 tokenId) public virtual {\\r\\n //solhint-disable-next-line max-line-length\\r\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721Burnable: caller is not owner nor approved\\\");\\r\\n _burn(tokenId);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x699ce4b0903e16b958d6a008703c24be7d11a7d3223e5e9ab9523a8f81687f13\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"../../introspection/IERC165.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Required interface of an ERC721 compliant contract.\\r\\n */\\r\\ninterface IERC721 is IERC165 {\\r\\n /**\\r\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\r\\n */\\r\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\r\\n */\\r\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\r\\n */\\r\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of tokens in ``owner``'s account.\\r\\n */\\r\\n function balanceOf(address owner) external view returns (uint256 balance);\\r\\n\\r\\n /**\\r\\n * @dev Returns the owner of the `tokenId` token.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\r\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Transfers `tokenId` token from `from` to `to`.\\r\\n *\\r\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must be owned by `from`.\\r\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transferFrom(address from, address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\r\\n * The approval is cleared when the token is transferred.\\r\\n *\\r\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - The caller must own the token or be an approved operator.\\r\\n * - `tokenId` must exist.\\r\\n *\\r\\n * Emits an {Approval} event.\\r\\n */\\r\\n function approve(address to, uint256 tokenId) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the account approved for `tokenId` token.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `tokenId` must exist.\\r\\n */\\r\\n function getApproved(uint256 tokenId) external view returns (address operator);\\r\\n\\r\\n /**\\r\\n * @dev Approve or remove `operator` as an operator for the caller.\\r\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - The `operator` cannot be the caller.\\r\\n *\\r\\n * Emits an {ApprovalForAll} event.\\r\\n */\\r\\n function setApprovalForAll(address operator, bool _approved) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\r\\n *\\r\\n * See {setApprovalForAll}\\r\\n */\\r\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `from` cannot be the zero address.\\r\\n * - `to` cannot be the zero address.\\r\\n * - `tokenId` token must exist and be owned by `from`.\\r\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\r\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\r\\n}\\r\\n\",\"keccak256\":\"0xd3c22060e78ce52f5cb41b3ab9b29bb5582aa4a58015e878116251cba658324c\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC721.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\r\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ninterface IERC721Enumerable is IERC721 {\\r\\n\\r\\n /**\\r\\n * @dev Returns the total amount of tokens stored by the contract.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\r\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\r\\n */\\r\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\\r\\n\\r\\n /**\\r\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\r\\n * Use along with {totalSupply} to enumerate all tokens.\\r\\n */\\r\\n function tokenByIndex(uint256 index) external view returns (uint256);\\r\\n}\\r\\n\",\"keccak256\":\"0x5539b1567797a57e7a135dcc446fdbb02b1ae2b450799274db88a47dea81e6fa\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\nimport \\\"./IERC721.sol\\\";\\r\\n\\r\\n/**\\r\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\r\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\r\\n */\\r\\ninterface IERC721Metadata is IERC721 {\\r\\n\\r\\n /**\\r\\n * @dev Returns the token collection name.\\r\\n */\\r\\n function name() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the token collection symbol.\\r\\n */\\r\\n function symbol() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\r\\n */\\r\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\r\\n}\\r\\n\",\"keccak256\":\"0xe92ae6f0b94fce8480d16a24faa8835926cd5fc074a4d418de94aaddbdecf49d\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @title ERC721 token receiver interface\\r\\n * @dev Interface for any contract that wants to support safeTransfers\\r\\n * from ERC721 asset contracts.\\r\\n */\\r\\ninterface IERC721Receiver {\\r\\n /**\\r\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\r\\n * by `operator` from `from`, this function is called.\\r\\n *\\r\\n * It must return its Solidity selector to confirm the token transfer.\\r\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\r\\n *\\r\\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\\r\\n */\\r\\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\\r\\n}\\r\\n\",\"keccak256\":\"0x515410f905897b0d658f1746064cc2a94d52a1bc625fab215dccb7fb5ead50f7\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/EnumerableMap.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Library for managing an enumerable variant of Solidity's\\r\\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\\r\\n * type.\\r\\n *\\r\\n * Maps have the following properties:\\r\\n *\\r\\n * - Entries are added, removed, and checked for existence in constant time\\r\\n * (O(1)).\\r\\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\\r\\n *\\r\\n * ```\\r\\n * contract Example {\\r\\n * // Add the library methods\\r\\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\\r\\n *\\r\\n * // Declare a set state variable\\r\\n * EnumerableMap.UintToAddressMap private myMap;\\r\\n * }\\r\\n * ```\\r\\n *\\r\\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\\r\\n * supported.\\r\\n */\\r\\nlibrary EnumerableMap {\\r\\n // To implement this library for multiple types with as little code\\r\\n // repetition as possible, we write it in terms of a generic Map type with\\r\\n // bytes32 keys and values.\\r\\n // The Map implementation uses private functions, and user-facing\\r\\n // implementations (such as Uint256ToAddressMap) are just wrappers around\\r\\n // the underlying Map.\\r\\n // This means that we can only create new EnumerableMaps for types that fit\\r\\n // in bytes32.\\r\\n\\r\\n struct MapEntry {\\r\\n bytes32 _key;\\r\\n bytes32 _value;\\r\\n }\\r\\n\\r\\n struct Map {\\r\\n // Storage of map keys and values\\r\\n MapEntry[] _entries;\\r\\n\\r\\n // Position of the entry defined by a key in the `entries` array, plus 1\\r\\n // because index 0 means a key is not in the map.\\r\\n mapping (bytes32 => uint256) _indexes;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Adds a key-value pair to a map, or updates the value for an existing\\r\\n * key. O(1).\\r\\n *\\r\\n * Returns true if the key was added to the map, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\\r\\n // We read and store the key's index to prevent multiple reads from the same storage slot\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n\\r\\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\\r\\n map._entries.push(MapEntry({ _key: key, _value: value }));\\r\\n // The entry is stored at length-1, but we add 1 to all indexes\\r\\n // and use 0 as a sentinel value\\r\\n map._indexes[key] = map._entries.length;\\r\\n return true;\\r\\n } else {\\r\\n map._entries[keyIndex - 1]._value = value;\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a key-value pair from a map. O(1).\\r\\n *\\r\\n * Returns true if the key was removed from the map, that is if it was present.\\r\\n */\\r\\n function _remove(Map storage map, bytes32 key) private returns (bool) {\\r\\n // We read and store the key's index to prevent multiple reads from the same storage slot\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n\\r\\n if (keyIndex != 0) { // Equivalent to contains(map, key)\\r\\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\\r\\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\\r\\n // This modifies the order of the array, as noted in {at}.\\r\\n\\r\\n uint256 toDeleteIndex = keyIndex - 1;\\r\\n uint256 lastIndex = map._entries.length - 1;\\r\\n\\r\\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\\r\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\r\\n\\r\\n MapEntry storage lastEntry = map._entries[lastIndex];\\r\\n\\r\\n // Move the last entry to the index where the entry to delete is\\r\\n map._entries[toDeleteIndex] = lastEntry;\\r\\n // Update the index for the moved entry\\r\\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\\r\\n\\r\\n // Delete the slot where the moved entry was stored\\r\\n map._entries.pop();\\r\\n\\r\\n // Delete the index for the deleted slot\\r\\n delete map._indexes[key];\\r\\n\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the key is in the map. O(1).\\r\\n */\\r\\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\\r\\n return map._indexes[key] != 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of key-value pairs in the map. O(1).\\r\\n */\\r\\n function _length(Map storage map) private view returns (uint256) {\\r\\n return map._entries.length;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of entries inside the\\r\\n * array, and it may change when more entries are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\\r\\n require(map._entries.length > index, \\\"EnumerableMap: index out of bounds\\\");\\r\\n\\r\\n MapEntry storage entry = map._entries[index];\\r\\n return (entry._key, entry._value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Tries to returns the value associated with `key`. O(1).\\r\\n * Does not revert if `key` is not in the map.\\r\\n */\\r\\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\\r\\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value associated with `key`. O(1).\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `key` must be in the map.\\r\\n */\\r\\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n require(keyIndex != 0, \\\"EnumerableMap: nonexistent key\\\"); // Equivalent to contains(map, key)\\r\\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\\r\\n *\\r\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\r\\n * message unnecessarily. For custom revert reasons use {_tryGet}.\\r\\n */\\r\\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\\r\\n uint256 keyIndex = map._indexes[key];\\r\\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\\r\\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\\r\\n }\\r\\n\\r\\n // UintToAddressMap\\r\\n\\r\\n struct UintToAddressMap {\\r\\n Map _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Adds a key-value pair to a map, or updates the value for an existing\\r\\n * key. O(1).\\r\\n *\\r\\n * Returns true if the key was added to the map, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\\r\\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the key was removed from the map, that is if it was present.\\r\\n */\\r\\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\\r\\n return _remove(map._inner, bytes32(key));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the key is in the map. O(1).\\r\\n */\\r\\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\\r\\n return _contains(map._inner, bytes32(key));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of elements in the map. O(1).\\r\\n */\\r\\n function length(UintToAddressMap storage map) internal view returns (uint256) {\\r\\n return _length(map._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the element stored at position `index` in the set. O(1).\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\\r\\n (bytes32 key, bytes32 value) = _at(map._inner, index);\\r\\n return (uint256(key), address(uint160(uint256(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Tries to returns the value associated with `key`. O(1).\\r\\n * Does not revert if `key` is not in the map.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\\r\\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\\r\\n return (success, address(uint160(uint256(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value associated with `key`. O(1).\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `key` must be in the map.\\r\\n */\\r\\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\\r\\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\\r\\n *\\r\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\r\\n * message unnecessarily. For custom revert reasons use {tryGet}.\\r\\n */\\r\\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\\r\\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x5538ae23826bfaa205dc16a24a50f18feaae576a1c46ddea7086bbbd4c13d84e\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev Library for managing\\r\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\r\\n * types.\\r\\n *\\r\\n * Sets have the following properties:\\r\\n *\\r\\n * - Elements are added, removed, and checked for existence in constant time\\r\\n * (O(1)).\\r\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\r\\n *\\r\\n * ```\\r\\n * contract Example {\\r\\n * // Add the library methods\\r\\n * using EnumerableSet for EnumerableSet.AddressSet;\\r\\n *\\r\\n * // Declare a set state variable\\r\\n * EnumerableSet.AddressSet private mySet;\\r\\n * }\\r\\n * ```\\r\\n *\\r\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\r\\n * and `uint256` (`UintSet`) are supported.\\r\\n */\\r\\nlibrary EnumerableSet {\\r\\n // To implement this library for multiple types with as little code\\r\\n // repetition as possible, we write it in terms of a generic Set type with\\r\\n // bytes32 values.\\r\\n // The Set implementation uses private functions, and user-facing\\r\\n // implementations (such as AddressSet) are just wrappers around the\\r\\n // underlying Set.\\r\\n // This means that we can only create new EnumerableSets for types that fit\\r\\n // in bytes32.\\r\\n\\r\\n struct Set {\\r\\n // Storage of set values\\r\\n bytes32[] _values;\\r\\n\\r\\n // Position of the value in the `values` array, plus 1 because index 0\\r\\n // means a value is not in the set.\\r\\n mapping (bytes32 => uint256) _indexes;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\r\\n if (!_contains(set, value)) {\\r\\n set._values.push(value);\\r\\n // The value is stored at length-1, but we add 1 to all indexes\\r\\n // and use 0 as a sentinel value\\r\\n set._indexes[value] = set._values.length;\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\r\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\r\\n uint256 valueIndex = set._indexes[value];\\r\\n\\r\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\r\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\r\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\r\\n // This modifies the order of the array, as noted in {at}.\\r\\n\\r\\n uint256 toDeleteIndex = valueIndex - 1;\\r\\n uint256 lastIndex = set._values.length - 1;\\r\\n\\r\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\r\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\r\\n\\r\\n bytes32 lastvalue = set._values[lastIndex];\\r\\n\\r\\n // Move the last value to the index where the value to delete is\\r\\n set._values[toDeleteIndex] = lastvalue;\\r\\n // Update the index for the moved value\\r\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\r\\n\\r\\n // Delete the slot where the moved value was stored\\r\\n set._values.pop();\\r\\n\\r\\n // Delete the index for the deleted slot\\r\\n delete set._indexes[value];\\r\\n\\r\\n return true;\\r\\n } else {\\r\\n return false;\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\r\\n return set._indexes[value] != 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values on the set. O(1).\\r\\n */\\r\\n function _length(Set storage set) private view returns (uint256) {\\r\\n return set._values.length;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\r\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\r\\n return set._values[index];\\r\\n }\\r\\n\\r\\n // Bytes32Set\\r\\n\\r\\n struct Bytes32Set {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\r\\n return _add(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\r\\n return _remove(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\r\\n return _contains(set._inner, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values in the set. O(1).\\r\\n */\\r\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\r\\n return _at(set._inner, index);\\r\\n }\\r\\n\\r\\n // AddressSet\\r\\n\\r\\n struct AddressSet {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(AddressSet storage set, address value) internal returns (bool) {\\r\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\r\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\r\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values in the set. O(1).\\r\\n */\\r\\n function length(AddressSet storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\r\\n return address(uint160(uint256(_at(set._inner, index))));\\r\\n }\\r\\n\\r\\n\\r\\n // UintSet\\r\\n\\r\\n struct UintSet {\\r\\n Set _inner;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Add a value to a set. O(1).\\r\\n *\\r\\n * Returns true if the value was added to the set, that is if it was not\\r\\n * already present.\\r\\n */\\r\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\r\\n return _add(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Removes a value from a set. O(1).\\r\\n *\\r\\n * Returns true if the value was removed from the set, that is if it was\\r\\n * present.\\r\\n */\\r\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\r\\n return _remove(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns true if the value is in the set. O(1).\\r\\n */\\r\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\r\\n return _contains(set._inner, bytes32(value));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the number of values on the set. O(1).\\r\\n */\\r\\n function length(UintSet storage set) internal view returns (uint256) {\\r\\n return _length(set._inner);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the value stored at position `index` in the set. O(1).\\r\\n *\\r\\n * Note that there are no guarantees on the ordering of values inside the\\r\\n * array, and it may change when more values are added or removed.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `index` must be strictly less than {length}.\\r\\n */\\r\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\r\\n return uint256(_at(set._inner, index));\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x4c3f4a13b8f0c2b911044b85d3db13396e772cb9b79f7fb16ec8d41ca5fc7321\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\n\\r\\n/**\\r\\n * @dev String operations.\\r\\n */\\r\\nlibrary Strings {\\r\\n /**\\r\\n * @dev Converts a `uint256` to its ASCII `string` representation.\\r\\n */\\r\\n function toString(uint256 value) internal pure returns (string memory) {\\r\\n // Inspired by OraclizeAPI's implementation - MIT licence\\r\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\r\\n\\r\\n if (value == 0) {\\r\\n return \\\"0\\\";\\r\\n }\\r\\n uint256 temp = value;\\r\\n uint256 digits;\\r\\n while (temp != 0) {\\r\\n digits++;\\r\\n temp /= 10;\\r\\n }\\r\\n bytes memory buffer = new bytes(digits);\\r\\n uint256 index = digits - 1;\\r\\n temp = value;\\r\\n while (temp != 0) {\\r\\n buffer[index--] = bytes1(uint8(48 + temp % 10));\\r\\n temp /= 10;\\r\\n }\\r\\n return string(buffer);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x0f1313d4fbca3b365d39200fc056b6db57b957b53dabb06d6fff3566fb8caa29\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50610019610074565b600080546001600160a01b0319166001600160a01b0392831617908190556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610067921690610078565b60405180910390a161008c565b3390565b6001600160a01b0391909116815260200190565b61286d8061009b6000396000f3fe60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b578063884758661462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002c7565b6200009d565b005b6200007b62000075366004620002f7565b6200016c565b6040516200008a9190620003ed565b60405180910390f35b6200007b6200025c565b6000546001600160a01b0316620000b36200026b565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000512565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc90620004c8565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d99262000161921690620003ed565b60405180910390a150565b600080546001600160a01b0316620001836200026b565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000512565b600089898989620001bc6200025c565b8a8a8a8a604051620001ce906200026f565b620001e29998979695949392919062000401565b604051809103906000f080158015620001ff573d6000803e3d6000fd5b509050806001600160a01b03167f3d0677e9be6c322795ce7407a961a98bb2822f9ed8a66c3c11d2ac9bab6d401a898989898989604051620002479695949392919062000479565b60405180910390a29998505050505050505050565b6000546001600160a01b031690565b3390565b6122d9806200055f83390190565b60008083601f8401126200028f578182fd5b50813567ffffffffffffffff811115620002a7578182fd5b602083019150836020828501011115620002c057600080fd5b9250929050565b600060208284031215620002d9578081fd5b81356001600160a01b0381168114620002f0578182fd5b9392505050565b6000806000806000806000806080898b03121562000313578384fd5b883567ffffffffffffffff808211156200032b578586fd5b620003398c838d016200027d565b909a50985060208b013591508082111562000352578586fd5b620003608c838d016200027d565b909850965060408b013591508082111562000379578586fd5b620003878c838d016200027d565b909650945060608b0135915080821115620003a0578384fd5b50620003af8b828c016200027d565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060a082526200041760a083018b8d620003c3565b82810360208401526200042c818a8c620003c3565b6001600160a01b03891660408501528381036060850152905062000452818789620003c3565b9050828103608084015262000469818587620003c3565b9c9b505050505050505050505050565b6000606082526200048f60608301888a620003c3565b8281036020840152620004a4818789620003c3565b90508281036040840152620004bb818587620003c3565b9998505050505050505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b50604051620022d9380380620022d983398101604081905262000034916200030f565b8484620000486301ffc9a760e01b6200011a565b81516200005d906006906020850190620001c8565b50805162000073906007906020840190620001c8565b50620000866380ac58cd60e01b6200011a565b62000098635b5e139f60e01b6200011a565b620000aa63780e9d6360e01b6200011a565b50506001600160a01b038316620000de5760405162461bcd60e51b8152600401620000d590620003e4565b60405180910390fd5b600a80546001600160a01b0319166001600160a01b03851617905562000104826200019f565b6200010f81620001b8565b50505050506200041b565b6001600160e01b031980821614156200017a576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b8051620001b4906009906020840190620001c8565b5050565b8051620001b490600b9060208401905b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200020057600085556200024b565b82601f106200021b57805160ff19168380011785556200024b565b828001600101855582156200024b579182015b828111156200024b5782518255916020019190600101906200022e565b50620002599291506200025d565b5090565b5b808211156200025957600081556001016200025e565b600082601f83011262000285578081fd5b81516001600160401b03808211156200029a57fe5b6040516020601f8401601f1916820181018381118382101715620002ba57fe5b6040528382528584018101871015620002d1578485fd5b8492505b83831015620002f45785830181015182840182015291820191620002d5565b838311156200030557848185840101525b5095945050505050565b600080600080600060a0868803121562000327578081fd5b85516001600160401b03808211156200033e578283fd5b6200034c89838a0162000274565b9650602088015191508082111562000362578283fd5b6200037089838a0162000274565b604089015190965091506001600160a01b03821682146200038f578283fd5b606088015191945080821115620003a4578283fd5b620003b289838a0162000274565b93506080880151915080821115620003c8578283fd5b50620003d78882890162000274565b9150509295509295909350565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b611eae806200042b6000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806342966c68116100b857806395d89b411161007c57806395d89b411461026c578063a22cb46514610274578063b88d4fde14610287578063c87b56dd1461029a578063e8a3d485146102ad578063e985e9c5146102b557610137565b806342966c68146102185780634f6ccce71461022b5780636352211e1461023e5780636c0360eb1461025157806370a082311461025957610137565b806318160ddd116100ff57806318160ddd146101b757806323b872dd146101cc5780632f745c59146101df57806340c10f19146101f257806342842e0e1461020557610137565b806301ffc9a71461013c57806306fdde0314610165578063075461721461017a578063081812fc1461018f578063095ea7b3146101a2575b600080fd5b61014f61014a366004611ac4565b6102c8565b60405161015c9190611b34565b60405180910390f35b61016d6102eb565b60405161015c9190611b3f565b610182610381565b60405161015c9190611b20565b61018261019d366004611aec565b610390565b6101b56101b0366004611a9b565b6103f2565b005b6101bf6104c8565b60405161015c9190611bec565b6101b56101da366004611966565b6104d9565b6101bf6101ed366004611a9b565b610530565b6101b5610200366004611a9b565b61055b565b6101b5610213366004611966565b6105ac565b6101b5610226366004611aec565b6105c7565b6101bf610239366004611aec565b610619565b61018261024c366004611aec565b61062f565b61016d610657565b6101bf61026736600461191a565b6106b8565b61016d610720565b6101b5610282366004611a61565b610781565b6101b56102953660046119a1565b610886565b61016d6102a8366004611aec565b6108e4565b61016d610b65565b61014f6102c3366004611934565b610bc6565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b820191906000526020600020905b81548152906001019060200180831161035a57829003601f168201915b5050505050905090565b600a546001600160a01b031681565b600061039b82610bf4565b6103d65760405162461bcd60e51b815260040180806020018281038252602c815260200180611d73602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006103fd8261062f565b9050806001600160a01b0316836001600160a01b031614156104505760405162461bcd60e51b8152600401808060200182810382526021815260200180611df76021913960400191505060405180910390fd5b806001600160a01b0316610462610c01565b6001600160a01b0316148061047e575061047e816102c3610c01565b6104b95760405162461bcd60e51b8152600401808060200182810382526038815260200180611cc66038913960400191505060405180910390fd5b6104c38383610c05565b505050565b60006104d46002610c73565b905090565b6104ea6104e4610c01565b82610c7e565b6105255760405162461bcd60e51b8152600401808060200182810382526031815260200180611e186031913960400191505060405180910390fd5b6104c3838383610d22565b6001600160a01b03821660009081526001602052604081206105529083610e6e565b90505b92915050565b600a546001600160a01b031661056f610c01565b6001600160a01b03161461059e5760405162461bcd60e51b815260040161059590611b72565b60405180910390fd5b6105a88282610e7a565b5050565b6104c383838360405180602001604052806000815250610886565b6105d26104e4610c01565b61060d5760405162461bcd60e51b8152600401808060200182810382526030815260200180611e496030913960400191505060405180910390fd5b61061681610fa8565b50565b600080610627600284611075565b509392505050565b600061055582604051806060016040528060298152602001611d286029913960029190611091565b60098054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b60006001600160a01b0382166106ff5760405162461bcd60e51b815260040180806020018281038252602a815260200180611cfe602a913960400191505060405180910390fd5b6001600160a01b038216600090815260016020526040902061055590610c73565b60078054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b610789610c01565b6001600160a01b0316826001600160a01b031614156107ef576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b80600560006107fc610c01565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610840610c01565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b610897610891610c01565b83610c7e565b6108d25760405162461bcd60e51b8152600401808060200182810382526031815260200180611e186031913960400191505060405180910390fd5b6108de848484846110a8565b50505050565b60606108ef82610bf4565b61092a5760405162461bcd60e51b815260040180806020018281038252602f815260200180611dc8602f913960400191505060405180910390fd5b60008281526008602090815260408083208054825160026001831615610100026000190190921691909104601f8101859004850282018501909352828152929091908301828280156109bd5780601f10610992576101008083540402835291602001916109bd565b820191906000526020600020905b8154815290600101906020018083116109a057829003601f168201915b5050505050905060006109ce610657565b90508051600014156109e2575090506102e6565b815115610aa35780826040516020018083805190602001908083835b60208310610a1d5780518252601f1990920191602091820191016109fe565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610a655780518252601f199092019160209182019101610a46565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052925050506102e6565b80610aad856110fa565b6040516020018083805190602001908083835b60208310610adf5780518252601f199092019160209182019101610ac0565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610b275780518252601f199092019160209182019101610b08565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b600b8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006105556002836111d5565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610c3a8261062f565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610555826111e1565b6000610c8982610bf4565b610cc45760405162461bcd60e51b815260040180806020018281038252602c815260200180611c9a602c913960400191505060405180910390fd5b6000610ccf8361062f565b9050806001600160a01b0316846001600160a01b03161480610d0a5750836001600160a01b0316610cff84610390565b6001600160a01b0316145b80610d1a5750610d1a8185610bc6565b949350505050565b826001600160a01b0316610d358261062f565b6001600160a01b031614610d7a5760405162461bcd60e51b8152600401808060200182810382526029815260200180611d9f6029913960400191505060405180910390fd5b6001600160a01b038216610dbf5760405162461bcd60e51b8152600401808060200182810382526024815260200180611c766024913960400191505060405180910390fd5b610dca8383836104c3565b610dd5600082610c05565b6001600160a01b0383166000908152600160205260409020610df790826111e5565b506001600160a01b0382166000908152600160205260409020610e1a90826111f1565b50610e27600282846111fd565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006105528383611213565b6001600160a01b038216610ed5576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b610ede81610bf4565b15610f30576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b610f3c600083836104c3565b6001600160a01b0382166000908152600160205260409020610f5e90826111f1565b50610f6b600282846111fd565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000610fb38261062f565b9050610fc1816000846104c3565b610fcc600083610c05565b600082815260086020526040902054600260001961010060018416150201909116041561100a57600082815260086020526040812061100a916118ab565b6001600160a01b038116600090815260016020526040902061102c90836111e5565b50611038600283611277565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60008080806110848686611283565b9097909650945050505050565b600061109e8484846112fe565b90505b9392505050565b6110b3848484610d22565b6110bf848484846113c8565b6108de5760405162461bcd60e51b8152600401808060200182810382526032815260200180611c446032913960400191505060405180910390fd5b60608161111f57506040805180820190915260018152600360fc1b60208201526102e6565b8160005b811561113757600101600a82049150611123565b60008167ffffffffffffffff8111801561115057600080fd5b506040519080825280601f01601f19166020018201604052801561117b576020820181803683370190505b50859350905060001982015b83156111cc57600a840660300160f81b828280600190039350815181106111aa57fe5b60200101906001600160f81b031916908160001a905350600a84049350611187565b50949350505050565b60006105528383611530565b5490565b60006105528383611548565b6000610552838361160e565b600061109e84846001600160a01b038516611658565b815460009082106112555760405162461bcd60e51b8152600401808060200182810382526022815260200180611c226022913960400191505060405180910390fd5b82600001828154811061126457fe5b9060005260206000200154905092915050565b600061055283836116ef565b8154600090819083106112c75760405162461bcd60e51b8152600401808060200182810382526022815260200180611d516022913960400191505060405180910390fd5b60008460000184815481106112d857fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816113995760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561135e578181015183820152602001611346565b50505050905090810190601f16801561138b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508460000160018203815481106113ac57fe5b9060005260206000209060020201600101549150509392505050565b60006113dc846001600160a01b03166117c3565b6113e857506001610d1a565b60006114f6630a85bd0160e11b6113fd610c01565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561146457818101518382015260200161144c565b50505050905090810190601f1680156114915780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001611c44603291396001600160a01b03881691906117c9565b9050600081806020019051602081101561150f57600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60009081526001919091016020526040902054151590565b60008181526001830160205260408120548015611604578354600019808301919081019060009087908390811061157b57fe5b906000526020600020015490508087600001848154811061159857fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806115c857fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610555565b6000915050610555565b600061161a8383611530565b61165057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610555565b506000610555565b6000828152600184016020526040812054806116bd5750506040805180820182528381526020808201848152865460018181018955600089815284812095516002909302909501918255915190820155865486845281880190925292909120556110a1565b828560000160018303815481106116d057fe5b90600052602060002090600202016001018190555060009150506110a1565b60008181526001830160205260408120548015611604578354600019808301919081019060009087908390811061172257fe5b906000526020600020906002020190508087600001848154811061174257fe5b60009182526020808320845460029093020191825560019384015491840191909155835482528983019052604090209084019055865487908061178157fe5b60008281526020808220600260001990940193840201828155600190810183905592909355888152898201909252604082209190915594506105559350505050565b3b151590565b606061109e8484600085856117dd856117c3565b6117f95760405162461bcd60e51b815260040161059590611bb5565b600080866001600160a01b031685876040516118159190611b04565b60006040518083038185875af1925050503d8060008114611852576040519150601f19603f3d011682016040523d82523d6000602084013e611857565b606091505b5091509150611867828286611872565b979650505050505050565b606083156118815750816110a1565b8251156118915782518084602001fd5b8160405162461bcd60e51b81526004016105959190611b3f565b50805460018160011615610100020316600290046000825580601f106118d15750610616565b601f01602090049060005260206000209081019061061691905b808211156118ff57600081556001016118eb565b5090565b80356001600160a01b03811681146102e657600080fd5b60006020828403121561192b578081fd5b61055282611903565b60008060408385031215611946578081fd5b61194f83611903565b915061195d60208401611903565b90509250929050565b60008060006060848603121561197a578081fd5b61198384611903565b925061199160208501611903565b9150604084013590509250925092565b600080600080608085870312156119b6578081fd5b6119bf85611903565b935060206119ce818701611903565b935060408601359250606086013567ffffffffffffffff808211156119f1578384fd5b818801915088601f830112611a04578384fd5b813581811115611a1057fe5b604051601f8201601f1916810185018381118282101715611a2d57fe5b60405281815283820185018b1015611a43578586fd5b81858501868301379081019093019390935250939692955090935050565b60008060408385031215611a73578182fd5b611a7c83611903565b915060208301358015158114611a90578182fd5b809150509250929050565b60008060408385031215611aad578182fd5b611ab683611903565b946020939093013593505050565b600060208284031215611ad5578081fd5b81356001600160e01b0319811681146110a1578182fd5b600060208284031215611afd578081fd5b5035919050565b60008251611b16818460208701611bf5565b9190910192915050565b6001600160a01b0391909116815260200190565b901515815260200190565b6000602082528251806020840152611b5e816040850160208701611bf5565b601f01601f19169190910160400192915050565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b90815260200190565b60005b83811015611c10578181015183820152602001611bf8565b838111156108de575050600091015256fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665644552433732314275726e61626c653a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a26469706673582212205307f2282cc3339095cc0f4126ed0dad47c6f8ccf92f08d8924edffb57bc62f264736f6c63430007060033a264697066735822122003345c4b244dad413e4ec6ea2b273db60207e29a100d6c2a37386abca0146aac64736f6c63430007060033",
+ "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b578063884758661462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002c7565b6200009d565b005b6200007b62000075366004620002f7565b6200016c565b6040516200008a9190620003ed565b60405180910390f35b6200007b6200025c565b6000546001600160a01b0316620000b36200026b565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000512565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc90620004c8565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d99262000161921690620003ed565b60405180910390a150565b600080546001600160a01b0316620001836200026b565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000512565b600089898989620001bc6200025c565b8a8a8a8a604051620001ce906200026f565b620001e29998979695949392919062000401565b604051809103906000f080158015620001ff573d6000803e3d6000fd5b509050806001600160a01b03167f3d0677e9be6c322795ce7407a961a98bb2822f9ed8a66c3c11d2ac9bab6d401a898989898989604051620002479695949392919062000479565b60405180910390a29998505050505050505050565b6000546001600160a01b031690565b3390565b6122d9806200055f83390190565b60008083601f8401126200028f578182fd5b50813567ffffffffffffffff811115620002a7578182fd5b602083019150836020828501011115620002c057600080fd5b9250929050565b600060208284031215620002d9578081fd5b81356001600160a01b0381168114620002f0578182fd5b9392505050565b6000806000806000806000806080898b03121562000313578384fd5b883567ffffffffffffffff808211156200032b578586fd5b620003398c838d016200027d565b909a50985060208b013591508082111562000352578586fd5b620003608c838d016200027d565b909850965060408b013591508082111562000379578586fd5b620003878c838d016200027d565b909650945060608b0135915080821115620003a0578384fd5b50620003af8b828c016200027d565b999c989b5096995094979396929594505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060a082526200041760a083018b8d620003c3565b82810360208401526200042c818a8c620003c3565b6001600160a01b03891660408501528381036060850152905062000452818789620003c3565b9050828103608084015262000469818587620003c3565b9c9b505050505050505050505050565b6000606082526200048f60608301888a620003c3565b8281036020840152620004a4818789620003c3565b90508281036040840152620004bb818587620003c3565b9998505050505050505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b50604051620022d9380380620022d983398101604081905262000034916200030f565b8484620000486301ffc9a760e01b6200011a565b81516200005d906006906020850190620001c8565b50805162000073906007906020840190620001c8565b50620000866380ac58cd60e01b6200011a565b62000098635b5e139f60e01b6200011a565b620000aa63780e9d6360e01b6200011a565b50506001600160a01b038316620000de5760405162461bcd60e51b8152600401620000d590620003e4565b60405180910390fd5b600a80546001600160a01b0319166001600160a01b03851617905562000104826200019f565b6200010f81620001b8565b50505050506200041b565b6001600160e01b031980821614156200017a576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b8051620001b4906009906020840190620001c8565b5050565b8051620001b490600b9060208401905b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200020057600085556200024b565b82601f106200021b57805160ff19168380011785556200024b565b828001600101855582156200024b579182015b828111156200024b5782518255916020019190600101906200022e565b50620002599291506200025d565b5090565b5b808211156200025957600081556001016200025e565b600082601f83011262000285578081fd5b81516001600160401b03808211156200029a57fe5b6040516020601f8401601f1916820181018381118382101715620002ba57fe5b6040528382528584018101871015620002d1578485fd5b8492505b83831015620002f45785830181015182840182015291820191620002d5565b838311156200030557848185840101525b5095945050505050565b600080600080600060a0868803121562000327578081fd5b85516001600160401b03808211156200033e578283fd5b6200034c89838a0162000274565b9650602088015191508082111562000362578283fd5b6200037089838a0162000274565b604089015190965091506001600160a01b03821682146200038f578283fd5b606088015191945080821115620003a4578283fd5b620003b289838a0162000274565b93506080880151915080821115620003c8578283fd5b50620003d78882890162000274565b9150509295509295909350565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b611eae806200042b6000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806342966c68116100b857806395d89b411161007c57806395d89b411461026c578063a22cb46514610274578063b88d4fde14610287578063c87b56dd1461029a578063e8a3d485146102ad578063e985e9c5146102b557610137565b806342966c68146102185780634f6ccce71461022b5780636352211e1461023e5780636c0360eb1461025157806370a082311461025957610137565b806318160ddd116100ff57806318160ddd146101b757806323b872dd146101cc5780632f745c59146101df57806340c10f19146101f257806342842e0e1461020557610137565b806301ffc9a71461013c57806306fdde0314610165578063075461721461017a578063081812fc1461018f578063095ea7b3146101a2575b600080fd5b61014f61014a366004611ac4565b6102c8565b60405161015c9190611b34565b60405180910390f35b61016d6102eb565b60405161015c9190611b3f565b610182610381565b60405161015c9190611b20565b61018261019d366004611aec565b610390565b6101b56101b0366004611a9b565b6103f2565b005b6101bf6104c8565b60405161015c9190611bec565b6101b56101da366004611966565b6104d9565b6101bf6101ed366004611a9b565b610530565b6101b5610200366004611a9b565b61055b565b6101b5610213366004611966565b6105ac565b6101b5610226366004611aec565b6105c7565b6101bf610239366004611aec565b610619565b61018261024c366004611aec565b61062f565b61016d610657565b6101bf61026736600461191a565b6106b8565b61016d610720565b6101b5610282366004611a61565b610781565b6101b56102953660046119a1565b610886565b61016d6102a8366004611aec565b6108e4565b61016d610b65565b61014f6102c3366004611934565b610bc6565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b820191906000526020600020905b81548152906001019060200180831161035a57829003601f168201915b5050505050905090565b600a546001600160a01b031681565b600061039b82610bf4565b6103d65760405162461bcd60e51b815260040180806020018281038252602c815260200180611d73602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006103fd8261062f565b9050806001600160a01b0316836001600160a01b031614156104505760405162461bcd60e51b8152600401808060200182810382526021815260200180611df76021913960400191505060405180910390fd5b806001600160a01b0316610462610c01565b6001600160a01b0316148061047e575061047e816102c3610c01565b6104b95760405162461bcd60e51b8152600401808060200182810382526038815260200180611cc66038913960400191505060405180910390fd5b6104c38383610c05565b505050565b60006104d46002610c73565b905090565b6104ea6104e4610c01565b82610c7e565b6105255760405162461bcd60e51b8152600401808060200182810382526031815260200180611e186031913960400191505060405180910390fd5b6104c3838383610d22565b6001600160a01b03821660009081526001602052604081206105529083610e6e565b90505b92915050565b600a546001600160a01b031661056f610c01565b6001600160a01b03161461059e5760405162461bcd60e51b815260040161059590611b72565b60405180910390fd5b6105a88282610e7a565b5050565b6104c383838360405180602001604052806000815250610886565b6105d26104e4610c01565b61060d5760405162461bcd60e51b8152600401808060200182810382526030815260200180611e496030913960400191505060405180910390fd5b61061681610fa8565b50565b600080610627600284611075565b509392505050565b600061055582604051806060016040528060298152602001611d286029913960029190611091565b60098054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b60006001600160a01b0382166106ff5760405162461bcd60e51b815260040180806020018281038252602a815260200180611cfe602a913960400191505060405180910390fd5b6001600160a01b038216600090815260016020526040902061055590610c73565b60078054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b610789610c01565b6001600160a01b0316826001600160a01b031614156107ef576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b80600560006107fc610c01565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610840610c01565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b610897610891610c01565b83610c7e565b6108d25760405162461bcd60e51b8152600401808060200182810382526031815260200180611e186031913960400191505060405180910390fd5b6108de848484846110a8565b50505050565b60606108ef82610bf4565b61092a5760405162461bcd60e51b815260040180806020018281038252602f815260200180611dc8602f913960400191505060405180910390fd5b60008281526008602090815260408083208054825160026001831615610100026000190190921691909104601f8101859004850282018501909352828152929091908301828280156109bd5780601f10610992576101008083540402835291602001916109bd565b820191906000526020600020905b8154815290600101906020018083116109a057829003601f168201915b5050505050905060006109ce610657565b90508051600014156109e2575090506102e6565b815115610aa35780826040516020018083805190602001908083835b60208310610a1d5780518252601f1990920191602091820191016109fe565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610a655780518252601f199092019160209182019101610a46565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052925050506102e6565b80610aad856110fa565b6040516020018083805190602001908083835b60208310610adf5780518252601f199092019160209182019101610ac0565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610b275780518252601f199092019160209182019101610b08565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b600b8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103775780601f1061034c57610100808354040283529160200191610377565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006105556002836111d5565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610c3a8261062f565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610555826111e1565b6000610c8982610bf4565b610cc45760405162461bcd60e51b815260040180806020018281038252602c815260200180611c9a602c913960400191505060405180910390fd5b6000610ccf8361062f565b9050806001600160a01b0316846001600160a01b03161480610d0a5750836001600160a01b0316610cff84610390565b6001600160a01b0316145b80610d1a5750610d1a8185610bc6565b949350505050565b826001600160a01b0316610d358261062f565b6001600160a01b031614610d7a5760405162461bcd60e51b8152600401808060200182810382526029815260200180611d9f6029913960400191505060405180910390fd5b6001600160a01b038216610dbf5760405162461bcd60e51b8152600401808060200182810382526024815260200180611c766024913960400191505060405180910390fd5b610dca8383836104c3565b610dd5600082610c05565b6001600160a01b0383166000908152600160205260409020610df790826111e5565b506001600160a01b0382166000908152600160205260409020610e1a90826111f1565b50610e27600282846111fd565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006105528383611213565b6001600160a01b038216610ed5576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b610ede81610bf4565b15610f30576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b610f3c600083836104c3565b6001600160a01b0382166000908152600160205260409020610f5e90826111f1565b50610f6b600282846111fd565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000610fb38261062f565b9050610fc1816000846104c3565b610fcc600083610c05565b600082815260086020526040902054600260001961010060018416150201909116041561100a57600082815260086020526040812061100a916118ab565b6001600160a01b038116600090815260016020526040902061102c90836111e5565b50611038600283611277565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60008080806110848686611283565b9097909650945050505050565b600061109e8484846112fe565b90505b9392505050565b6110b3848484610d22565b6110bf848484846113c8565b6108de5760405162461bcd60e51b8152600401808060200182810382526032815260200180611c446032913960400191505060405180910390fd5b60608161111f57506040805180820190915260018152600360fc1b60208201526102e6565b8160005b811561113757600101600a82049150611123565b60008167ffffffffffffffff8111801561115057600080fd5b506040519080825280601f01601f19166020018201604052801561117b576020820181803683370190505b50859350905060001982015b83156111cc57600a840660300160f81b828280600190039350815181106111aa57fe5b60200101906001600160f81b031916908160001a905350600a84049350611187565b50949350505050565b60006105528383611530565b5490565b60006105528383611548565b6000610552838361160e565b600061109e84846001600160a01b038516611658565b815460009082106112555760405162461bcd60e51b8152600401808060200182810382526022815260200180611c226022913960400191505060405180910390fd5b82600001828154811061126457fe5b9060005260206000200154905092915050565b600061055283836116ef565b8154600090819083106112c75760405162461bcd60e51b8152600401808060200182810382526022815260200180611d516022913960400191505060405180910390fd5b60008460000184815481106112d857fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816113995760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561135e578181015183820152602001611346565b50505050905090810190601f16801561138b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508460000160018203815481106113ac57fe5b9060005260206000209060020201600101549150509392505050565b60006113dc846001600160a01b03166117c3565b6113e857506001610d1a565b60006114f6630a85bd0160e11b6113fd610c01565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561146457818101518382015260200161144c565b50505050905090810190601f1680156114915780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001611c44603291396001600160a01b03881691906117c9565b9050600081806020019051602081101561150f57600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60009081526001919091016020526040902054151590565b60008181526001830160205260408120548015611604578354600019808301919081019060009087908390811061157b57fe5b906000526020600020015490508087600001848154811061159857fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806115c857fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610555565b6000915050610555565b600061161a8383611530565b61165057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610555565b506000610555565b6000828152600184016020526040812054806116bd5750506040805180820182528381526020808201848152865460018181018955600089815284812095516002909302909501918255915190820155865486845281880190925292909120556110a1565b828560000160018303815481106116d057fe5b90600052602060002090600202016001018190555060009150506110a1565b60008181526001830160205260408120548015611604578354600019808301919081019060009087908390811061172257fe5b906000526020600020906002020190508087600001848154811061174257fe5b60009182526020808320845460029093020191825560019384015491840191909155835482528983019052604090209084019055865487908061178157fe5b60008281526020808220600260001990940193840201828155600190810183905592909355888152898201909252604082209190915594506105559350505050565b3b151590565b606061109e8484600085856117dd856117c3565b6117f95760405162461bcd60e51b815260040161059590611bb5565b600080866001600160a01b031685876040516118159190611b04565b60006040518083038185875af1925050503d8060008114611852576040519150601f19603f3d011682016040523d82523d6000602084013e611857565b606091505b5091509150611867828286611872565b979650505050505050565b606083156118815750816110a1565b8251156118915782518084602001fd5b8160405162461bcd60e51b81526004016105959190611b3f565b50805460018160011615610100020316600290046000825580601f106118d15750610616565b601f01602090049060005260206000209081019061061691905b808211156118ff57600081556001016118eb565b5090565b80356001600160a01b03811681146102e657600080fd5b60006020828403121561192b578081fd5b61055282611903565b60008060408385031215611946578081fd5b61194f83611903565b915061195d60208401611903565b90509250929050565b60008060006060848603121561197a578081fd5b61198384611903565b925061199160208501611903565b9150604084013590509250925092565b600080600080608085870312156119b6578081fd5b6119bf85611903565b935060206119ce818701611903565b935060408601359250606086013567ffffffffffffffff808211156119f1578384fd5b818801915088601f830112611a04578384fd5b813581811115611a1057fe5b604051601f8201601f1916810185018381118282101715611a2d57fe5b60405281815283820185018b1015611a43578586fd5b81858501868301379081019093019390935250939692955090935050565b60008060408385031215611a73578182fd5b611a7c83611903565b915060208301358015158114611a90578182fd5b809150509250929050565b60008060408385031215611aad578182fd5b611ab683611903565b946020939093013593505050565b600060208284031215611ad5578081fd5b81356001600160e01b0319811681146110a1578182fd5b600060208284031215611afd578081fd5b5035919050565b60008251611b16818460208701611bf5565b9190910192915050565b6001600160a01b0391909116815260200190565b901515815260200190565b6000602082528251806020840152611b5e816040850160208701611bf5565b601f01601f19169190910160400192915050565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b90815260200190565b60005b83811015611c10578181015183820152602001611bf8565b838111156108de575050600091015256fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665644552433732314275726e61626c653a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a26469706673582212205307f2282cc3339095cc0f4126ed0dad47c6f8ccf92f08d8924edffb57bc62f264736f6c63430007060033a264697066735822122003345c4b244dad413e4ec6ea2b273db60207e29a100d6c2a37386abca0146aac64736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 11018,
+ "contract": "contracts/nftbridge/SideNFTTokenFactory.sol:SideNFTTokenFactory",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/SideTokenFactory.json b/bridge/deployments/rsktestnetrinkeby/SideTokenFactory.json
new file mode 100644
index 000000000..4f6b6d7f5
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/SideTokenFactory.json
@@ -0,0 +1,172 @@
+{
+ "address": "0x500f602f60b6d223f50aac3750625ec771ed3c57",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "PrimaryTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sideToken",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "SideTokenCreated",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "granularity",
+ "type": "uint256"
+ }
+ ],
+ "name": "createSideToken",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "primary",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "recipient",
+ "type": "address"
+ }
+ ],
+ "name": "transferPrimary",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "transactionHash": "0x13b2796ad985be30d048292a4fa8370ee69193e1591361c5cb18f7b29d2b831d",
+ "receipt": {
+ "to": null,
+ "from": "0x2b3058eab56fb80b53f3137422189e940eefe31b",
+ "contractAddress": "0x500f602f60b6d223f50aac3750625ec771ed3c57",
+ "transactionIndex": "0x0",
+ "gasUsed": "0x307330",
+ "logsBloom": "0x00000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000100000",
+ "blockHash": "0xaaed3faa171e255d8e62473b51609cdb8d669db936369494fe11d54920fb5ef2",
+ "transactionHash": "0x13b2796ad985be30d048292a4fa8370ee69193e1591361c5cb18f7b29d2b831d",
+ "logs": [
+ {
+ "logIndex": "0x0",
+ "blockNumber": "0x211fc6",
+ "blockHash": "0xaaed3faa171e255d8e62473b51609cdb8d669db936369494fe11d54920fb5ef2",
+ "transactionHash": "0x13b2796ad985be30d048292a4fa8370ee69193e1591361c5cb18f7b29d2b831d",
+ "transactionIndex": "0x0",
+ "address": "0x500f602f60b6d223f50aac3750625ec771ed3c57",
+ "data": "0x0000000000000000000000002b3058eab56fb80b53f3137422189e940eefe31b",
+ "topics": [
+ "0x4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9"
+ ]
+ }
+ ],
+ "blockNumber": "0x211fc6",
+ "cumulativeGasUsed": "0x307330",
+ "status": "0x1"
+ },
+ "args": [],
+ "solcInputHash": "f57b3a626f709a0447a665aac92698b7",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"PrimaryTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sideToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"granularity\",\"type\":\"uint256\"}],\"name\":\"SideTokenCreated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"granularity\",\"type\":\"uint256\"}],\"name\":\"createSideToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"primary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferPrimary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"primary()\":{\"returns\":{\"_0\":\"the address of the primary.\"}},\"transferPrimary(address)\":{\"details\":\"Transfers contract to a new primary.\",\"params\":{\"recipient\":\"The address of new primary.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/SideTokenFactory/SideTokenFactory.sol\":\"SideTokenFactory\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/SideToken/SideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../zeppelin/token/ERC777/ERC777.sol\\\";\\r\\nimport \\\"../interface/IERC677Receiver.sol\\\";\\r\\nimport \\\"../interface/ISideToken.sol\\\";\\r\\nimport \\\"../lib/LibEIP712.sol\\\";\\r\\n\\r\\ncontract SideToken is ISideToken, ERC777 {\\r\\n using Address for address;\\r\\n using SafeMath for uint256;\\r\\n\\r\\n address public minter;\\r\\n uint256 private _granularity;\\r\\n\\r\\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\\r\\n bytes32 public domainSeparator;\\r\\n // keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\r\\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\\r\\n mapping(address => uint) public nonces;\\r\\n\\r\\n // ERC677 Transfer Event\\r\\n event Transfer(address,address,uint256,bytes);\\r\\n\\r\\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\\r\\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\\r\\n require(_minterAddr != address(0), \\\"SideToken: Empty Minter\\\");\\r\\n require(_newGranularity >= 1, \\\"SideToken: Granularity < 1\\\");\\r\\n minter = _minterAddr;\\r\\n _granularity = _newGranularity;\\r\\n\\r\\n uint chainId;\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n chainId := chainid()\\r\\n }\\r\\n domainSeparator = LibEIP712.hashEIP712Domain(\\r\\n name(),\\r\\n \\\"1\\\",\\r\\n chainId,\\r\\n address(this)\\r\\n );\\r\\n }\\r\\n\\r\\n modifier onlyMinter() {\\r\\n require(_msgSender() == minter, \\\"SideToken: Caller is not the minter\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n function mint(\\r\\n address account,\\r\\n uint256 amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata operatorData\\r\\n )\\r\\n external onlyMinter override\\r\\n {\\r\\n _mint(_msgSender(), account, amount, userData, operatorData);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\\r\\n * @param recipient The address to transfer to.\\r\\n * @param amount The amount to be transferred.\\r\\n * @param data The extra data to be passed to the receiving contract.\\r\\n */\\r\\n function transferAndCall(address recipient, uint amount, bytes calldata data)\\r\\n external returns (bool success)\\r\\n {\\r\\n address from = _msgSender();\\r\\n\\r\\n _send(from, from, recipient, amount, data, \\\"\\\", false);\\r\\n emit Transfer(from, recipient, amount, data);\\r\\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\\r\\n return true;\\r\\n }\\r\\n\\r\\n function granularity() public view override returns (uint256) {\\r\\n return _granularity;\\r\\n }\\r\\n\\r\\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\\r\\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\\r\\n require(deadline >= block.timestamp, \\\"SideToken: EXPIRED\\\"); // solhint-disable-line not-rely-on-time\\r\\n bytes32 digest = LibEIP712.hashEIP712Message(\\r\\n domainSeparator,\\r\\n keccak256(\\r\\n abi.encode(\\r\\n PERMIT_TYPEHASH,\\r\\n owner,\\r\\n spender,\\r\\n value,\\r\\n nonces[owner]++,\\r\\n deadline\\r\\n )\\r\\n )\\r\\n );\\r\\n address recoveredAddress = ecrecover(digest, v, r, s);\\r\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"SideToken: INVALID_SIGNATURE\\\");\\r\\n _approve(owner, spender, value);\\r\\n }\\r\\n\\r\\n}\",\"keccak256\":\"0x8dc386892a6c2db9d5cda50f159054df2309b4031abd43505a8ff0082a0e8b6a\",\"license\":\"MIT\"},\"contracts/SideTokenFactory/SideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../zeppelin/ownership/Secondary.sol\\\";\\r\\nimport \\\"../interface/ISideTokenFactory.sol\\\";\\r\\nimport \\\"../SideToken/SideToken.sol\\\";\\r\\n\\r\\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\\r\\n\\r\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\\r\\n external onlyPrimary override returns(address) {\\r\\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\\r\\n emit SideTokenCreated(sideToken, symbol, granularity);\\r\\n return sideToken;\\r\\n }\\r\\n}\",\"keccak256\":\"0x1c1fed2932047fa8e68041b33e0f0dc2d461e4e99c74d02da9a4714b4441bbe0\",\"license\":\"MIT\"},\"contracts/interface/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface IERC677Receiver {\\r\\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\\r\\n}\",\"keccak256\":\"0x37338df5bea5204995bca492b0f421fc2ea3e11bafa54b1e6080fd5ed6824a43\",\"license\":\"MIT\"},\"contracts/interface/ISideToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideToken {\\r\\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\\r\\n}\",\"keccak256\":\"0x22b96c1de44cc83f38f93cb0bebac0d090b88e1d951373eefdceb2b4284d6ffa\",\"license\":\"MIT\"},\"contracts/interface/ISideTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\ninterface ISideTokenFactory {\\r\\n\\r\\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\\r\\n\\r\\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\\r\\n}\",\"keccak256\":\"0xbac49cc8df91c7aae47037ac9b3956615399bc6fa01d2a49764a7e6e48085b14\",\"license\":\"MIT\"},\"contracts/lib/LibEIP712.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\\r\\nlibrary LibEIP712 {\\r\\n\\r\\n // Hash of the EIP712 Domain Separator Schema\\r\\n // keccak256(abi.encodePacked(\\r\\n // \\\"EIP712Domain(\\\",\\r\\n // \\\"string name,\\\",\\r\\n // \\\"string version,\\\",\\r\\n // \\\"uint256 chainId,\\\",\\r\\n // \\\"address verifyingContract\\\",\\r\\n // \\\")\\\"\\r\\n // ))\\r\\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\\r\\n\\r\\n /// @dev Calculates a EIP712 domain separator.\\r\\n /// @param name The EIP712 domain name.\\r\\n /// @param version The EIP712 domain version.\\r\\n /// @param verifyingContract The EIP712 verifying contract.\\r\\n /// @return result EIP712 domain separator.\\r\\n function hashEIP712Domain(\\r\\n string memory name,\\r\\n string memory version,\\r\\n uint256 chainId,\\r\\n address verifyingContract\\r\\n )\\r\\n internal\\r\\n pure\\r\\n returns (bytes32 result)\\r\\n {\\r\\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\\r\\n\\r\\n // Assembly for more efficient computing:\\r\\n // keccak256(abi.encodePacked(\\r\\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\\r\\n // keccak256(bytes(name)),\\r\\n // keccak256(bytes(version)),\\r\\n // chainId,\\r\\n // uint256(verifyingContract)\\r\\n // ))\\r\\n\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n // Calculate hashes of dynamic data\\r\\n let nameHash := keccak256(add(name, 32), mload(name))\\r\\n let versionHash := keccak256(add(version, 32), mload(version))\\r\\n\\r\\n // Load free memory pointer\\r\\n let memPtr := mload(64)\\r\\n\\r\\n // Store params in memory\\r\\n mstore(memPtr, schemaHash)\\r\\n mstore(add(memPtr, 32), nameHash)\\r\\n mstore(add(memPtr, 64), versionHash)\\r\\n mstore(add(memPtr, 96), chainId)\\r\\n mstore(add(memPtr, 128), verifyingContract)\\r\\n\\r\\n // Compute hash\\r\\n result := keccak256(memPtr, 160)\\r\\n }\\r\\n return result;\\r\\n }\\r\\n\\r\\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\\r\\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\\r\\n /// with getDomainHash().\\r\\n /// @param hashStruct The EIP712 hash struct.\\r\\n /// @return result EIP712 hash applied to the given EIP712 Domain.\\r\\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\\r\\n internal\\r\\n pure\\r\\n returns (bytes32 result)\\r\\n {\\r\\n // Assembly for more efficient computing:\\r\\n // keccak256(abi.encodePacked(\\r\\n // EIP191_HEADER,\\r\\n // EIP712_DOMAIN_HASH,\\r\\n // hashStruct\\r\\n // ));\\r\\n\\r\\n // solium-disable-next-line security/no-inline-assembly\\r\\n assembly {\\r\\n // Load free memory pointer\\r\\n let memPtr := mload(64)\\r\\n\\r\\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\\r\\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\\r\\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\\r\\n\\r\\n // Compute hash\\r\\n result := keccak256(memPtr, 66)\\r\\n }\\r\\n return result;\\r\\n }\\r\\n}\",\"keccak256\":\"0xfcfcf60905df9a2644e372c9e76b8cc7a5034c5c4d6d9f44b1ffb56244551237\",\"license\":\"MIT\"},\"contracts/zeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/*\\r\\n * @dev Provides information about the current execution context, including the\\r\\n * sender of the transaction and its data. While these are generally available\\r\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\r\\n * manner, since when dealing with GSN meta-transactions the account sending and\\r\\n * paying for execution may not be the actual sender (as far as an application\\r\\n * is concerned).\\r\\n *\\r\\n * This contract is only required for intermediate, library-like contracts.\\r\\n */\\r\\nabstract contract Context {\\r\\n\\r\\n function _msgSender() internal view returns (address payable) {\\r\\n return msg.sender;\\r\\n }\\r\\n\\r\\n function _msgData() internal view returns (bytes memory) {\\r\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\r\\n return msg.data;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xff38f9ba6027ec9133e123cb63f4c77fb89b2569cd3a1825c7f693f496c67a78\",\"license\":\"MIT\"},\"contracts/zeppelin/introspection/IERC1820Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\r\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\r\\n * implementers for interfaces in this registry, as well as query support.\\r\\n *\\r\\n * Implementers may be shared by multiple accounts, and can also implement more\\r\\n * than a single interface for each account. Contracts can implement interfaces\\r\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\r\\n * contract.\\r\\n *\\r\\n * {IERC165} interfaces can also be queried via the registry.\\r\\n *\\r\\n * For an in-depth explanation and source code analysis, see the EIP text.\\r\\n */\\r\\ninterface IERC1820Registry {\\r\\n /**\\r\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\r\\n * account is able to set interface implementers for it.\\r\\n *\\r\\n * By default, each account is its own manager. Passing a value of `0x0` in\\r\\n * `newManager` will reset the manager to this initial state.\\r\\n *\\r\\n * Emits a {ManagerChanged} event.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the caller must be the current manager for `account`.\\r\\n */\\r\\n function setManager(address account, address newManager) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the manager for `account`.\\r\\n *\\r\\n * See {setManager}.\\r\\n */\\r\\n function getManager(address account) external view returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Sets the `implementer` contract as `account`'s implementer for\\r\\n * `interfaceHash`.\\r\\n *\\r\\n * `account` being the zero address is an alias for the caller's address.\\r\\n * The zero address can also be used in `implementer` to remove an old one.\\r\\n *\\r\\n * See {interfaceHash} to learn how these are created.\\r\\n *\\r\\n * Emits an {InterfaceImplementerSet} event.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the caller must be the current manager for `_account`.\\r\\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\r\\n * end in 28 zeroes).\\r\\n * - `_implementer` must implement {IERC1820Implementer} and return true when\\r\\n * queried for support, unless `implementer` is the caller. See\\r\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\r\\n */\\r\\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\\r\\n * implementer is registered, returns the zero address.\\r\\n *\\r\\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\r\\n * zeroes), `_account` will be queried for support of it.\\r\\n *\\r\\n * `account` being the zero address is an alias for the caller's address.\\r\\n */\\r\\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\\r\\n\\r\\n /**\\r\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\r\\n * corresponding\\r\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\r\\n */\\r\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\r\\n\\r\\n /**\\r\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\r\\n * @param account Address of the contract for which to update the cache.\\r\\n * @param interfaceId ERC165 interface for which to update the cache.\\r\\n */\\r\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\r\\n\\r\\n /**\\r\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\r\\n * If the result is not cached a direct lookup on the contract address is performed.\\r\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\r\\n * {updateERC165Cache} with the contract address.\\r\\n * @param account Address of the contract to check.\\r\\n * @param interfaceId ERC165 interface to check.\\r\\n * @return True if `account` implements `interfaceId`, false otherwise.\\r\\n */\\r\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\\r\\n * @param account Address of the contract to check.\\r\\n * @param interfaceId ERC165 interface to check.\\r\\n * @return True if `account` implements `interfaceId`, false otherwise.\\r\\n */\\r\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\r\\n\\r\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\r\\n\\r\\n event ManagerChanged(address indexed account, address indexed newManager);\\r\\n}\\r\\n\",\"keccak256\":\"0x0c607a83a8f5ec2f214bc754ffb59428d90978e122108fcd91ba193d5fc78018\",\"license\":\"MIT\"},\"contracts/zeppelin/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\r\\n * checks.\\r\\n *\\r\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\r\\n * in bugs, because programmers usually assume that an overflow raises an\\r\\n * error, which is the standard behavior in high level programming languages.\\r\\n * `SafeMath` restores this intuition by reverting the transaction when an\\r\\n * operation overflows.\\r\\n *\\r\\n * Using this library instead of the unchecked operations eliminates an entire\\r\\n * class of bugs, so it's recommended to use it always.\\r\\n */\\r\\nlibrary SafeMath {\\r\\n /**\\r\\n * @dev Returns the addition of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `+` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Addition cannot overflow.\\r\\n */\\r\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n uint256 c = a + b;\\r\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n */\\r\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\r\\n * overflow (when the result is negative).\\r\\n *\\r\\n * Counterpart to Solidity's `-` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Subtraction cannot overflow.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b <= a, errorMessage);\\r\\n uint256 c = a - b;\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\r\\n * overflow.\\r\\n *\\r\\n * Counterpart to Solidity's `*` operator.\\r\\n *\\r\\n * Requirements:\\r\\n * - Multiplication cannot overflow.\\r\\n */\\r\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\r\\n // benefit is lost if 'b' is also tested.\\r\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\r\\n if (a == 0) {\\r\\n return 0;\\r\\n }\\r\\n\\r\\n uint256 c = a * b;\\r\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\r\\n * division by zero. The result is rounded towards zero.\\r\\n *\\r\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\r\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\r\\n * uses an invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n // Solidity only automatically asserts when dividing by 0\\r\\n require(b > 0, errorMessage);\\r\\n uint256 c = a / b;\\r\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\r\\n\\r\\n return c;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n */\\r\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\r\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\r\\n * Reverts with custom message when dividing by zero.\\r\\n *\\r\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\r\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\r\\n * invalid opcode to revert (consuming all remaining gas).\\r\\n *\\r\\n * Requirements:\\r\\n * - The divisor cannot be zero.\\r\\n *\\r\\n * _Available since v2.4.0._\\r\\n */\\r\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\r\\n require(b != 0, errorMessage);\\r\\n return a % b;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x29ffa7ff59806a3add585615cc102b70b43049587dcc73649f77b427f35b009d\",\"license\":\"MIT\"},\"contracts/zeppelin/ownership/Secondary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../GSN/Context.sol\\\";\\r\\n/**\\r\\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\\r\\n */\\r\\nabstract contract Secondary is Context {\\r\\n address private _primary;\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the primary contract changes.\\r\\n */\\r\\n event PrimaryTransferred(\\r\\n address recipient\\r\\n );\\r\\n\\r\\n /**\\r\\n * @dev Sets the primary account to the one that is creating the Secondary contract.\\r\\n */\\r\\n constructor () {\\r\\n _primary = _msgSender();\\r\\n emit PrimaryTransferred(_primary);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Reverts if called from any account other than the primary.\\r\\n */\\r\\n modifier onlyPrimary() {\\r\\n require(_msgSender() == _primary, \\\"Secondary: caller is not the primary account\\\");\\r\\n _;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @return the address of the primary.\\r\\n */\\r\\n function primary() public view returns (address) {\\r\\n return _primary;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Transfers contract to a new primary.\\r\\n * @param recipient The address of new primary.\\r\\n */\\r\\n function transferPrimary(address recipient) public onlyPrimary {\\r\\n require(recipient != address(0), \\\"Secondary: new primary is the zero address\\\");\\r\\n _primary = recipient;\\r\\n emit PrimaryTransferred(_primary);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x9138d9f1c2d4b2b9d6fd72ceb5ef461ffcd2c26ade7b15a5ee86456ecda089ca\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\r\\n * the optional functions; to access them see {ERC20Detailed}.\\r\\n */\\r\\ninterface IERC20 {\\r\\n /**\\r\\n * @dev Returns the amount of tokens in existence.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens owned by `account`.\\r\\n */\\r\\n function balanceOf(address account) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transfer(address recipient, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Returns the remaining number of tokens that `spender` will be\\r\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\r\\n * zero by default.\\r\\n *\\r\\n * This value changes when {approve} or {transferFrom} are called.\\r\\n */\\r\\n function allowance(address owner, address spender) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\r\\n * that someone may use both the old and the new allowance by unfortunate\\r\\n * transaction ordering. One possible solution to mitigate this race\\r\\n * condition is to first reduce the spender's allowance to 0 and set the\\r\\n * desired value afterwards:\\r\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\r\\n *\\r\\n * Emits an {Approval} event.\\r\\n */\\r\\n function approve(address spender, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\r\\n * allowance mechanism. `amount` is then deducted from the caller's\\r\\n * allowance.\\r\\n *\\r\\n * Returns a boolean value indicating whether the operation succeeded.\\r\\n *\\r\\n * Emits a {Transfer} event.\\r\\n */\\r\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\r\\n * another (`to`).\\r\\n *\\r\\n * Note that `value` may be zero.\\r\\n */\\r\\n event Transfer(address indexed from, address indexed to, uint256 value);\\r\\n\\r\\n /**\\r\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\r\\n * a call to {approve}. `value` is the new allowance.\\r\\n */\\r\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\r\\n}\\r\\n\",\"keccak256\":\"0x7531f90b8a5a04fd225fb07a30e0792068438a7c82127a22db870c1849460dfc\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/ERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\nimport \\\"../../GSN/Context.sol\\\";\\r\\nimport \\\"./IERC777.sol\\\";\\r\\nimport \\\"./IERC777Recipient.sol\\\";\\r\\nimport \\\"./IERC777Sender.sol\\\";\\r\\nimport \\\"../../token/ERC20/IERC20.sol\\\";\\r\\nimport \\\"../../math/SafeMath.sol\\\";\\r\\nimport \\\"../../utils/Address.sol\\\";\\r\\nimport \\\"../../introspection/IERC1820Registry.sol\\\";\\r\\n\\r\\n/**\\r\\n * @dev Implementation of the {IERC777} interface.\\r\\n *\\r\\n * This implementation is agnostic to the way tokens are created. This means\\r\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\r\\n *\\r\\n * Support for ERC20 is included in this contract, as specified by the EIP: both\\r\\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\\r\\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\\r\\n * movements.\\r\\n *\\r\\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\\r\\n * are no special restrictions in the amount of tokens that created, moved, or\\r\\n * destroyed. This makes integration with ERC20 applications seamless.\\r\\n */\\r\\ncontract ERC777 is Context, IERC777, IERC20 {\\r\\n using SafeMath for uint256;\\r\\n using Address for address;\\r\\n\\r\\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\r\\n\\r\\n mapping(address => uint256) private _balances;\\r\\n\\r\\n uint256 private _totalSupply;\\r\\n\\r\\n string private _name;\\r\\n string private _symbol;\\r\\n\\r\\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\\r\\n // See https://github.com/ethereum/solidity/issues/4024.\\r\\n\\r\\n // keccak256(\\\"ERC777TokensSender\\\")\\r\\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\\r\\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\\r\\n\\r\\n // keccak256(\\\"ERC777TokensRecipient\\\")\\r\\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\\r\\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\\r\\n\\r\\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\\r\\n address[] private _defaultOperatorsArray;\\r\\n\\r\\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\\r\\n mapping(address => bool) private _defaultOperators;\\r\\n\\r\\n // For each account, a mapping of its operators and revoked default operators.\\r\\n mapping(address => mapping(address => bool)) private _operators;\\r\\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\\r\\n\\r\\n // ERC20-allowances\\r\\n mapping (address => mapping (address => uint256)) private _allowances;\\r\\n\\r\\n /**\\r\\n * @dev `defaultOperators` may be an empty array.\\r\\n */\\r\\n constructor(\\r\\n string memory aName,\\r\\n string memory aSymbol,\\r\\n address[] memory theDefaultOperators\\r\\n ) {\\r\\n _name = aName;\\r\\n _symbol = aSymbol;\\r\\n\\r\\n _defaultOperatorsArray = theDefaultOperators;\\r\\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\\r\\n _defaultOperators[_defaultOperatorsArray[i]] = true;\\r\\n }\\r\\n\\r\\n // register interfaces\\r\\n _erc1820.setInterfaceImplementer(address(this), keccak256(\\\"ERC777Token\\\"), address(this));\\r\\n _erc1820.setInterfaceImplementer(address(this), keccak256(\\\"ERC20Token\\\"), address(this));\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-name}.\\r\\n */\\r\\n function name() public view override(IERC777) returns (string memory) {\\r\\n return _name;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-symbol}.\\r\\n */\\r\\n function symbol() public view override(IERC777) returns (string memory) {\\r\\n return _symbol;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {ERC20Detailed-decimals}.\\r\\n *\\r\\n * Always returns 18, as per the\\r\\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\\r\\n */\\r\\n function decimals() public pure override returns (uint8) {\\r\\n return 18;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-granularity}.\\r\\n *\\r\\n * This implementation always returns `1`.\\r\\n */\\r\\n function granularity() public view virtual override(IERC777) returns (uint256) {\\r\\n return 1;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-totalSupply}.\\r\\n */\\r\\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\\r\\n return _totalSupply;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\\r\\n */\\r\\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\\r\\n return _balances[tokenHolder];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-send}.\\r\\n *\\r\\n * Also emits a {Transfer} event for ERC20 compatibility.\\r\\n */\\r\\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\\r\\n _send(_msgSender(), _msgSender(), recipient, amount, data, \\\"\\\", true);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC20-transfer}.\\r\\n *\\r\\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\\r\\n * interface if it is a contract.\\r\\n *\\r\\n * Also emits a {Sent} event.\\r\\n */\\r\\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\\r\\n require(recipient != address(0), \\\"ERC777: transfer to zero address\\\");\\r\\n\\r\\n address from = _msgSender();\\r\\n\\r\\n _callTokensToSend(from, from, recipient, amount, \\\"\\\", \\\"\\\");\\r\\n\\r\\n _move(from, from, recipient, amount, \\\"\\\", \\\"\\\");\\r\\n\\r\\n _callTokensReceived(from, from, recipient, amount, \\\"\\\", \\\"\\\", false);\\r\\n\\r\\n return true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-burn}.\\r\\n *\\r\\n * Also emits a {Transfer} event for ERC20 compatibility.\\r\\n */\\r\\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\\r\\n _burn(_msgSender(), _msgSender(), amount, data, \\\"\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-isOperatorFor}.\\r\\n */\\r\\n function isOperatorFor(\\r\\n address operator,\\r\\n address tokenHolder\\r\\n ) public view override(IERC777) returns (bool) {\\r\\n return operator == tokenHolder ||\\r\\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\\r\\n _operators[tokenHolder][operator];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-authorizeOperator}.\\r\\n */\\r\\n function authorizeOperator(address operator) external override(IERC777) {\\r\\n require(_msgSender() != operator, \\\"ERC777: authorizing self as operator\\\");\\r\\n\\r\\n if (_defaultOperators[operator]) {\\r\\n delete _revokedDefaultOperators[_msgSender()][operator];\\r\\n } else {\\r\\n _operators[_msgSender()][operator] = true;\\r\\n }\\r\\n\\r\\n emit AuthorizedOperator(operator, _msgSender());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-revokeOperator}.\\r\\n */\\r\\n function revokeOperator(address operator) external override(IERC777) {\\r\\n require(operator != _msgSender(), \\\"ERC777: revoking self as operator\\\");\\r\\n\\r\\n if (_defaultOperators[operator]) {\\r\\n _revokedDefaultOperators[_msgSender()][operator] = true;\\r\\n } else {\\r\\n delete _operators[_msgSender()][operator];\\r\\n }\\r\\n\\r\\n emit RevokedOperator(operator, _msgSender());\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-defaultOperators}.\\r\\n */\\r\\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\\r\\n return _defaultOperatorsArray;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-operatorSend}.\\r\\n *\\r\\n * Emits {Sent} and {Transfer} events.\\r\\n */\\r\\n function operatorSend(\\r\\n address sender,\\r\\n address recipient,\\r\\n uint256 amount,\\r\\n bytes calldata data,\\r\\n bytes calldata operatorData\\r\\n )\\r\\n external override(IERC777)\\r\\n {\\r\\n require(isOperatorFor(_msgSender(), sender), \\\"ERC777: caller is not an operator\\\");\\r\\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC777-operatorBurn}.\\r\\n *\\r\\n * Emits {Burned} and {Transfer} events.\\r\\n */\\r\\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\\r\\n external override(IERC777) {\\r\\n require(isOperatorFor(_msgSender(), account), \\\"ERC777: caller is not an operator\\\");\\r\\n _burn(_msgSender(), account, amount, data, operatorData);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC20-allowance}.\\r\\n *\\r\\n * Note that operator and allowance concepts are orthogonal: operators may\\r\\n * not have allowance, and accounts with allowance may not be operators\\r\\n * themselves.\\r\\n */\\r\\n function allowance(address holder, address spender)\\r\\n public view override(IERC20) returns (uint256) {\\r\\n return _allowances[holder][spender];\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC20-approve}.\\r\\n *\\r\\n * Note that accounts cannot have allowance issued by their operators.\\r\\n */\\r\\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\\r\\n address holder = _msgSender();\\r\\n _approve(holder, spender, value);\\r\\n return true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev See {IERC20-transferFrom}.\\r\\n *\\r\\n * Note that operator and allowance concepts are orthogonal: operators cannot\\r\\n * call `transferFrom` (unless they have allowance), and accounts with\\r\\n * allowance cannot call `operatorSend` (unless they are operators).\\r\\n *\\r\\n * Emits {Sent}, {Transfer} and {Approval} events.\\r\\n */\\r\\n function transferFrom(address holder, address recipient, uint256 amount)\\r\\n external override(IERC20) returns (bool) {\\r\\n require(recipient != address(0), \\\"ERC777: transfer to zero address\\\");\\r\\n require(holder != address(0), \\\"ERC777: transfer from zero address\\\");\\r\\n\\r\\n address spender = _msgSender();\\r\\n\\r\\n _callTokensToSend(spender, holder, recipient, amount, \\\"\\\", \\\"\\\");\\r\\n\\r\\n _move(spender, holder, recipient, amount, \\\"\\\", \\\"\\\");\\r\\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \\\"ERC777: transfer amount exceeds allowance\\\"));\\r\\n\\r\\n _callTokensReceived(spender, holder, recipient, amount, \\\"\\\", \\\"\\\", false);\\r\\n\\r\\n return true;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\\r\\n * the total supply.\\r\\n *\\r\\n * If a send hook is registered for `account`, the corresponding function\\r\\n * will be called with `operator`, `data` and `operatorData`.\\r\\n *\\r\\n * See {IERC777Sender} and {IERC777Recipient}.\\r\\n *\\r\\n * Emits {Minted} and {Transfer} events.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `account` cannot be the zero address.\\r\\n * - if `account` is a contract, it must implement the {IERC777Recipient}\\r\\n * interface.\\r\\n */\\r\\n function _mint(\\r\\n address operator,\\r\\n address account,\\r\\n uint256 amount,\\r\\n bytes memory userData,\\r\\n bytes memory operatorData\\r\\n )\\r\\n internal\\r\\n {\\r\\n require(account != address(0), \\\"ERC777: mint to zero address\\\");\\r\\n\\r\\n // Update state variables\\r\\n _totalSupply = _totalSupply.add(amount);\\r\\n _balances[account] = _balances[account].add(amount);\\r\\n\\r\\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\\r\\n\\r\\n emit Minted(operator, account, amount, userData, operatorData);\\r\\n emit Transfer(address(0), account, amount);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Send tokens\\r\\n * @param operator address operator requesting the transfer\\r\\n * @param from address token holder address\\r\\n * @param to address recipient address\\r\\n * @param amount uint256 amount of tokens to transfer\\r\\n * @param userData bytes extra information provided by the token holder (if any)\\r\\n * @param operatorData bytes extra information provided by the operator (if any)\\r\\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\\r\\n */\\r\\n function _send(\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint256 amount,\\r\\n bytes memory userData,\\r\\n bytes memory operatorData,\\r\\n bool requireReceptionAck\\r\\n )\\r\\n internal\\r\\n {\\r\\n require(from != address(0), \\\"ERC777: send from zero address\\\");\\r\\n require(to != address(0), \\\"ERC777: send to zero address\\\");\\r\\n\\r\\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\\r\\n\\r\\n _move(operator, from, to, amount, userData, operatorData);\\r\\n\\r\\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Burn tokens\\r\\n * @param operator address operator requesting the operation\\r\\n * @param from address token holder address\\r\\n * @param amount uint256 amount of tokens to burn\\r\\n * @param data bytes extra information provided by the token holder\\r\\n * @param operatorData bytes extra information provided by the operator (if any)\\r\\n */\\r\\n function _burn(\\r\\n address operator,\\r\\n address from,\\r\\n uint256 amount,\\r\\n bytes memory data,\\r\\n bytes memory operatorData\\r\\n )\\r\\n internal\\r\\n {\\r\\n require(from != address(0), \\\"ERC777: burn from zero address\\\");\\r\\n\\r\\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\\r\\n\\r\\n // Update state variables\\r\\n _balances[from] = _balances[from].sub(amount, \\\"ERC777: burn amount exceeds balance\\\");\\r\\n _totalSupply = _totalSupply.sub(amount);\\r\\n\\r\\n emit Burned(operator, from, amount, data, operatorData);\\r\\n emit Transfer(from, address(0), amount);\\r\\n }\\r\\n\\r\\n function _move(\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint256 amount,\\r\\n bytes memory userData,\\r\\n bytes memory operatorData\\r\\n )\\r\\n internal\\r\\n {\\r\\n _balances[from] = _balances[from].sub(amount, \\\"ERC777: transfer amount exceeds balance\\\");\\r\\n _balances[to] = _balances[to].add(amount);\\r\\n\\r\\n emit Sent(operator, from, to, amount, userData, operatorData);\\r\\n emit Transfer(from, to, amount);\\r\\n }\\r\\n\\r\\n function _approve(address holder, address spender, uint256 value) internal {\\r\\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\\r\\n // currently unnecessary.\\r\\n //require(holder != address(0), \\\"ERC777: approve from the zero address\\\");\\r\\n require(spender != address(0), \\\"ERC777: approve to zero address\\\");\\r\\n\\r\\n _allowances[holder][spender] = value;\\r\\n emit Approval(holder, spender, value);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Call from.tokensToSend() if the interface is registered\\r\\n * @param operator address operator requesting the transfer\\r\\n * @param from address token holder address\\r\\n * @param to address recipient address\\r\\n * @param amount uint256 amount of tokens to transfer\\r\\n * @param userData bytes extra information provided by the token holder (if any)\\r\\n * @param operatorData bytes extra information provided by the operator (if any)\\r\\n */\\r\\n function _callTokensToSend(\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint256 amount,\\r\\n bytes memory userData,\\r\\n bytes memory operatorData\\r\\n )\\r\\n internal\\r\\n {\\r\\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\\r\\n if (implementer != address(0)) {\\r\\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\\r\\n }\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\\r\\n * tokensReceived() was not registered for the recipient\\r\\n * @param operator address operator requesting the transfer\\r\\n * @param from address token holder address\\r\\n * @param to address recipient address\\r\\n * @param amount uint256 amount of tokens to transfer\\r\\n * @param userData bytes extra information provided by the token holder (if any)\\r\\n * @param operatorData bytes extra information provided by the operator (if any)\\r\\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\\r\\n */\\r\\n function _callTokensReceived(\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint256 amount,\\r\\n bytes memory userData,\\r\\n bytes memory operatorData,\\r\\n bool requireReceptionAck\\r\\n )\\r\\n private\\r\\n {\\r\\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\\r\\n if (implementer != address(0)) {\\r\\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\\r\\n } else if (requireReceptionAck) {\\r\\n require(!to.isContract(), \\\"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\\\");\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xd113e66c8ecca27aa14ca2e6e7d0005220eb62d02f3f3b1e92930fd40797d5e4\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC777Token standard as defined in the EIP.\\r\\n *\\r\\n * This contract uses the\\r\\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\\r\\n * token holders and recipients react to token movements by using setting implementers\\r\\n * for the associated interfaces in said registry. See `IERC1820Registry` and\\r\\n * `ERC1820Implementer`.\\r\\n */\\r\\ninterface IERC777 {\\r\\n /**\\r\\n * @dev Returns the name of the token.\\r\\n */\\r\\n function name() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the symbol of the token, usually a shorter version of the\\r\\n * name.\\r\\n */\\r\\n function symbol() external view returns (string memory);\\r\\n\\r\\n /**\\r\\n * @dev Returns the smallest part of the token that is not divisible. This\\r\\n * means all token operations (creation, movement and destruction) must have\\r\\n * amounts that are a multiple of this number.\\r\\n *\\r\\n * For most token contracts, this value will equal 1.\\r\\n */\\r\\n function granularity() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens in existence.\\r\\n */\\r\\n function totalSupply() external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Returns the amount of tokens owned by an account (`owner`).\\r\\n */\\r\\n function balanceOf(address owner) external view returns (uint256);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\r\\n *\\r\\n * If send or receive hooks are registered for the caller and `recipient`,\\r\\n * the corresponding functions will be called with `data` and empty\\r\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\r\\n *\\r\\n * Emits a `Sent` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - the caller must have at least `amount` tokens.\\r\\n * - `recipient` cannot be the zero address.\\r\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\r\\n * interface.\\r\\n */\\r\\n function send(address recipient, uint256 amount, bytes calldata data) external;\\r\\n\\r\\n /**\\r\\n * @dev Destroys `amount` tokens from the caller's account, reducing the\\r\\n * total supply.\\r\\n *\\r\\n * If a send hook is registered for the caller, the corresponding function\\r\\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\\r\\n *\\r\\n * Emits a `Burned` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - the caller must have at least `amount` tokens.\\r\\n */\\r\\n function burn(uint256 amount, bytes calldata data) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns true if an account is an operator of `tokenHolder`.\\r\\n * Operators can send and burn tokens on behalf of their owners. All\\r\\n * accounts are their own operator.\\r\\n *\\r\\n * See `operatorSend` and `operatorBurn`.\\r\\n */\\r\\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\\r\\n\\r\\n /**\\r\\n * @dev Make an account an operator of the caller.\\r\\n *\\r\\n * See `isOperatorFor`.\\r\\n *\\r\\n * Emits an `AuthorizedOperator` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `operator` cannot be calling address.\\r\\n */\\r\\n function authorizeOperator(address operator) external;\\r\\n\\r\\n /**\\r\\n * @dev Make an account an operator of the caller.\\r\\n *\\r\\n * See `isOperatorFor` and `defaultOperators`.\\r\\n *\\r\\n * Emits a `RevokedOperator` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `operator` cannot be calling address.\\r\\n */\\r\\n function revokeOperator(address operator) external;\\r\\n\\r\\n /**\\r\\n * @dev Returns the list of default operators. These accounts are operators\\r\\n * for all token holders, even if `authorizeOperator` was never called on\\r\\n * them.\\r\\n *\\r\\n * This list is immutable, but individual holders may revoke these via\\r\\n * `revokeOperator`, in which case `isOperatorFor` will return false.\\r\\n */\\r\\n function defaultOperators() external view returns (address[] memory);\\r\\n\\r\\n /**\\r\\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\\r\\n * be an operator of `sender`.\\r\\n *\\r\\n * If send or receive hooks are registered for `sender` and `recipient`,\\r\\n * the corresponding functions will be called with `data` and\\r\\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\\r\\n *\\r\\n * Emits a `Sent` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `sender` cannot be the zero address.\\r\\n * - `sender` must have at least `amount` tokens.\\r\\n * - the caller must be an operator for `sender`.\\r\\n * - `recipient` cannot be the zero address.\\r\\n * - if `recipient` is a contract, it must implement the `tokensReceived`\\r\\n * interface.\\r\\n */\\r\\n function operatorSend(\\r\\n address sender,\\r\\n address recipient,\\r\\n uint256 amount,\\r\\n bytes calldata data,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n\\r\\n /**\\r\\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\\r\\n * The caller must be an operator of `account`.\\r\\n *\\r\\n * If a send hook is registered for `account`, the corresponding function\\r\\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\\r\\n *\\r\\n * Emits a `Burned` event.\\r\\n *\\r\\n * Requirements\\r\\n *\\r\\n * - `account` cannot be the zero address.\\r\\n * - `account` must have at least `amount` tokens.\\r\\n * - the caller must be an operator for `account`.\\r\\n */\\r\\n function operatorBurn(\\r\\n address account,\\r\\n uint256 amount,\\r\\n bytes calldata data,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n\\r\\n event Sent(\\r\\n address indexed operator,\\r\\n address indexed from,\\r\\n address indexed to,\\r\\n uint256 amount,\\r\\n bytes data,\\r\\n bytes operatorData\\r\\n );\\r\\n\\r\\n function decimals() external returns (uint8);\\r\\n\\r\\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\\r\\n\\r\\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\\r\\n\\r\\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\\r\\n\\r\\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\\r\\n}\\r\\n\",\"keccak256\":\"0xf9947f4f7572e74766fcb4de1d58c6c26cd31379fd5d4b885cdbdf14a16dbe94\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\r\\n *\\r\\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\\r\\n * contract implement this interface (contract holders can be their own\\r\\n * implementer) and registering it on the\\r\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\r\\n *\\r\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\r\\n */\\r\\ninterface IERC777Recipient {\\r\\n /**\\r\\n * @dev Called by an `IERC777` token contract whenever tokens are being\\r\\n * moved or created into a registered account (`to`). The type of operation\\r\\n * is conveyed by `from` being the zero address or not.\\r\\n *\\r\\n * This call occurs _after_ the token contract's state is updated, so\\r\\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\\r\\n *\\r\\n * This function may revert to prevent the operation from being executed.\\r\\n */\\r\\n function tokensReceived(\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n}\\r\\n\",\"keccak256\":\"0x1f43e427174c60bacb510e63053626e5b24d825333e9921bb7c1ea673b1c6e1e\",\"license\":\"MIT\"},\"contracts/zeppelin/token/ERC777/IERC777Sender.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\\r\\n *\\r\\n * `IERC777` Token holders can be notified of operations performed on their\\r\\n * tokens by having a contract implement this interface (contract holders can be\\r\\n * their own implementer) and registering it on the\\r\\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\\r\\n *\\r\\n * See `IERC1820Registry` and `ERC1820Implementer`.\\r\\n */\\r\\ninterface IERC777Sender {\\r\\n /**\\r\\n * @dev Called by an `IERC777` token contract whenever a registered holder's\\r\\n * (`from`) tokens are about to be moved or destroyed. The type of operation\\r\\n * is conveyed by `to` being the zero address or not.\\r\\n *\\r\\n * This call occurs _before_ the token contract's state is updated, so\\r\\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\\r\\n *\\r\\n * This function may revert to prevent the operation from being executed.\\r\\n */\\r\\n function tokensToSend(\\r\\n address operator,\\r\\n address from,\\r\\n address to,\\r\\n uint amount,\\r\\n bytes calldata userData,\\r\\n bytes calldata operatorData\\r\\n ) external;\\r\\n}\\r\\n\",\"keccak256\":\"0x6a963a46297ee065e14820a02556dee14da60684657d302387e31c50b0dff374\",\"license\":\"MIT\"},\"contracts/zeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity ^0.7.0;\\r\\npragma abicoder v2;\\r\\n\\r\\n/**\\r\\n * @dev Collection of functions related to the address type\\r\\n */\\r\\nlibrary Address {\\r\\n /**\\r\\n * @dev Returns true if `account` is a contract.\\r\\n *\\r\\n * [IMPORTANT]\\r\\n * ====\\r\\n * It is unsafe to assume that an address for which this function returns\\r\\n * false is an externally-owned account (EOA) and not a contract.\\r\\n *\\r\\n * Among others, `isContract` will return false for the following\\r\\n * types of addresses:\\r\\n *\\r\\n * - an externally-owned account\\r\\n * - a contract in construction\\r\\n * - an address where a contract will be created\\r\\n * - an address where a contract lived, but was destroyed\\r\\n * ====\\r\\n */\\r\\n function isContract(address account) internal view returns (bool) {\\r\\n // This method relies on extcodesize, which returns 0 for contracts in\\r\\n // construction, since the code is only stored at the end of the\\r\\n // constructor execution.\\r\\n\\r\\n uint256 size;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly { size := extcodesize(account) }\\r\\n return size > 0;\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\r\\n * `recipient`, forwarding all available gas and reverting on errors.\\r\\n *\\r\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\r\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\r\\n * imposed by `transfer`, making them unable to receive funds via\\r\\n * `transfer`. {sendValue} removes this limitation.\\r\\n *\\r\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\r\\n *\\r\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\r\\n * taken to not create reentrancy vulnerabilities. Consider using\\r\\n * {ReentrancyGuard} or the\\r\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\r\\n */\\r\\n function sendValue(address payable recipient, uint256 amount) internal {\\r\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\r\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\r\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Performs a Solidity function call using a low level `call`. A\\r\\n * plain`call` is an unsafe replacement for a function call: use this\\r\\n * function instead.\\r\\n *\\r\\n * If `target` reverts with a revert reason, it is bubbled up by this\\r\\n * function (like regular Solidity function calls).\\r\\n *\\r\\n * Returns the raw returned data. To convert to the expected return value,\\r\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - `target` must be a contract.\\r\\n * - calling `target` with `data` must not revert.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\r\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, 0, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but also transferring `value` wei to `target`.\\r\\n *\\r\\n * Requirements:\\r\\n *\\r\\n * - the calling contract must have an ETH balance of at least `value`.\\r\\n * - the called Solidity function must be `payable`.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\r\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\r\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\r\\n *\\r\\n * _Available since v3.1._\\r\\n */\\r\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\r\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\r\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a static call.\\r\\n *\\r\\n * _Available since v3.3._\\r\\n */\\r\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.staticcall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\r\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\r\\n }\\r\\n\\r\\n /**\\r\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\r\\n * but performing a delegate call.\\r\\n *\\r\\n * _Available since v3.4._\\r\\n */\\r\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\r\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\r\\n\\r\\n // solhint-disable-next-line avoid-low-level-calls\\r\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\r\\n return _verifyCallResult(success, returndata, errorMessage);\\r\\n }\\r\\n\\r\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\r\\n if (success) {\\r\\n return returndata;\\r\\n } else {\\r\\n // Look for revert reason and bubble it up if present\\r\\n if (returndata.length > 0) {\\r\\n // The easiest way to bubble the revert reason is using memory via assembly\\r\\n\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n let returndata_size := mload(returndata)\\r\\n revert(add(32, returndata), returndata_size)\\r\\n }\\r\\n } else {\\r\\n revert(errorMessage);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe5e6562dbec24dff773a844145d3cf3de12505b6b9f8d6ac5259f291c731c1ff\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50610019610074565b600080546001600160a01b0319166001600160a01b0392831617908190556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992610067921690610078565b60405180910390a161008c565b3390565b6001600160a01b0391909116815260200190565b612d628061009b6000396000f3fe60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b57806326d9e9631462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002b8565b6200009d565b005b6200007b62000075366004620002e8565b6200016c565b6040516200008a91906200038a565b60405180910390f35b6200007b6200024d565b6000546001600160a01b0316620000b36200025c565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000458565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc906200040e565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992620001619216906200038a565b60405180910390a150565b600080546001600160a01b0316620001836200025c565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000458565b600086868686620001bc6200024d565b87604051620001cb9062000260565b620001dc969594939291906200039e565b604051809103906000f080158015620001f9573d6000803e3d6000fd5b509050806001600160a01b03167ff57d2ded8330a4affd2fa52378069be534fe22288536537d1a1cfc06151845078686866040516200023b93929190620003e8565b60405180910390a29695505050505050565b6000546001600160a01b031690565b3390565b61288880620004a583390190565b60008083601f84011262000280578182fd5b50813567ffffffffffffffff81111562000298578182fd5b602083019150836020828501011115620002b157600080fd5b9250929050565b600060208284031215620002ca578081fd5b81356001600160a01b0381168114620002e1578182fd5b9392505050565b60008060008060006060868803121562000300578081fd5b853567ffffffffffffffff8082111562000318578283fd5b6200032689838a016200026e565b909750955060208801359150808211156200033f578283fd5b506200034e888289016200026e565b96999598509660400135949350505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060808252620003b460808301888a62000360565b8281036020840152620003c981878962000360565b6001600160a01b03959095166040840152505060600152949350505050565b600060408252620003fe60408301858762000360565b9050826020830152949350505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b506040516200288838038062002888833981016040819052620000349162000561565b60408051600081526020808201909252855186928692916200005d9160029190860190620003c2565b50815162000073906003906020850190620003c2565b5080516200008990600490602084019062000457565b5060005b600454811015620000e95760016005600060048481548110620000ac57fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff19169115159190911790556001016200008d565b506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90620001479030907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054908290600401620005f0565b600060405180830381600087803b1580156200016257600080fd5b505af115801562000177573d6000803e3d6000fd5b50506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad2492506329965a1d9150620001d89030907faea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a908290600401620005f0565b600060405180830381600087803b158015620001f357600080fd5b505af115801562000208573d6000803e3d6000fd5b50505050506001600160a01b038416151591506200024590505760405162461bcd60e51b81526004016200023c9062000613565b60405180910390fd5b6001811015620002695760405162461bcd60e51b81526004016200023c906200064a565b600980546001600160a01b0319166001600160a01b038416179055600a81905546620002c562000298620002d4565b604051806040016040528060018152602001603160f81b81525083306200036b60201b62000fa41760201c565b600b5550620006819350505050565b60028054604080516020601f6000196101006001871615020190941685900493840181900481028201810190925282815260609390929091830182828015620003615780601f10620003355761010080835404028352916020019162000361565b820191906000526020600020905b8154815290600101906020018083116200034357829003601f168201915b5050505050905090565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620003fa576000855562000445565b82601f106200041557805160ff191683800117855562000445565b8280016001018555821562000445579182015b828111156200044557825182559160200191906001019062000428565b5062000453929150620004af565b5090565b82805482825590600052602060002090810192821562000445579160200282015b828111156200044557825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000478565b5b80821115620004535760008155600101620004b0565b600082601f830112620004d7578081fd5b81516001600160401b0380821115620004ec57fe5b6040516020601f8401601f19168201810183811183821017156200050c57fe5b604052838252858401810187101562000523578485fd5b8492505b8383101562000546578583018101518284018201529182019162000527565b838311156200055757848185840101525b5095945050505050565b6000806000806080858703121562000577578384fd5b84516001600160401b03808211156200058e578586fd5b6200059c88838901620004c6565b95506020870151915080821115620005b2578485fd5b50620005c187828801620004c6565b604087015190945090506001600160a01b0381168114620005e0578283fd5b6060959095015193969295505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b6020808252601a908201527f53696465546f6b656e3a204772616e756c6172697479203c2031000000000000604082015260600190565b6121f780620006916000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80637ecebe00116100de578063d95b637111610097578063f698da2511610071578063f698da2514610308578063fad8b32a14610310578063fc673c4f14610323578063fe9d93031461033657610173565b8063d95b6371146102cf578063dcdc7dd0146102e2578063dd62ed3e146102f557610173565b80637ecebe0014610268578063959b8c3f1461027b57806395d89b411461028e5780639bd9bbc614610296578063a9059cbb146102a9578063d505accf146102bc57610173565b806330adf81f1161013057806330adf81f14610208578063313ce567146102105780634000aea014610225578063556f0dc71461023857806362ad1b831461024057806370a082311461025557610173565b806306e485381461017857806306fdde031461019657806307546172146101ab578063095ea7b3146101c057806318160ddd146101e057806323b872dd146101f5575b600080fd5b610180610349565b60405161018d9190611c97565b60405180910390f35b61019e6103ab565b60405161018d9190611d4a565b6101b3610435565b60405161018d9190611b9f565b6101d36101ce3660046119d2565b610444565b60405161018d9190611ce4565b6101e8610466565b60405161018d9190611cef565b6101d3610203366004611881565b61046c565b6101e86105b4565b6102186105d8565b60405161018d9190612128565b6101d36102333660046119fd565b6105dd565b6101e86106eb565b61025361024e3660046118c1565b6106f1565b005b6101e8610263366004611811565b6107a8565b6101e8610276366004611811565b6107c3565b610253610289366004611811565b6107d5565b61019e610902565b6102536102a43660046119fd565b610963565b6101d36102b73660046119d2565b6109cb565b6102536102ca36600461195d565b610a85565b6101d36102dd366004611849565b610bd8565b6102536102f0366004611a57565b610c7a565b6101e8610303366004611849565b610d39565b6101e8610d64565b61025361031e366004611811565b610d6a565b610253610331366004611a57565b610e97565b610253610344366004611ae0565b610f41565b606060048054806020026020016040519081016040528092919081815260200182805480156103a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610383575b5050505050905090565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b820191906000526020600020905b81548152906001019060200180831161041757509395945050505050565b6009546001600160a01b031681565b60008061044f610ffb565b905061045c818585610fff565b5060019392505050565b60015490565b60006001600160a01b03831661049d5760405162461bcd60e51b815260040161049490611e50565b60405180910390fd5b6001600160a01b0384166104c35760405162461bcd60e51b815260040161049490612043565b60006104cd610ffb565b90506104fb81868686604051806020016040528060008152506040518060200160405280600081525061108d565b6105278186868660405180602001604052806000815250604051806020016040528060008152506111bb565b61057b858261057686604051806060016040528060298152602001612176602991396001600160a01b03808c166000908152600860209081526040808320938b168352929052205491906112db565b610fff565b6105a98186868660405180602001604052806000815250604051806020016040528060008152506000611307565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601290565b6000806105e8610ffb565b905061063c8182888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060408051602081019091528181529350915061146e9050565b7fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c168187878787604051610673959493929190611c0d565b60405180910390a1604051635260769b60e11b81526001600160a01b0387169063a4c0ed36906106ad908490899089908990600401611c65565b600060405180830381600087803b1580156106c757600080fd5b505af11580156106db573d6000803e3d6000fd5b5060019998505050505050505050565b600a5490565b6107026106fc610ffb565b88610bd8565b61071e5760405162461bcd60e51b815260040161049490612085565b61079f610729610ffb565b88888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a91508990819084018382808284376000920191909152506001925061146e915050565b50505050505050565b6001600160a01b031660009081526020819052604090205490565b600c6020526000908152604090205481565b806001600160a01b03166107e7610ffb565b6001600160a01b0316141561080e5760405162461bcd60e51b815260040161049490611dcb565b6001600160a01b03811660009081526005602052604090205460ff1615610871576007600061083b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690556108b8565b60016006600061087f610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b6108c0610ffb565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b6109c561096e610ffb565b610976610ffb565b868686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604080516020810190915290815292506001915061146e9050565b50505050565b60006001600160a01b0383166109f35760405162461bcd60e51b815260040161049490611e50565b60006109fd610ffb565b9050610a2b81828686604051806020016040528060008152506040518060200160405280600081525061108d565b610a578182868660405180602001604052806000815250604051806020016040528060008152506111bb565b61045c8182868660405180602001604052806000815250604051806020016040528060008152506000611307565b42841015610aa55760405162461bcd60e51b815260040161049490611fa9565b600b546001600160a01b0388166000908152600c6020908152604080832080546001810190915590519293610b27939092610b0c927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928e928e928e9290918e9101611cf8565b604051602081830303815290604052805190602001206114e5565b9050600060018286868660405160008152602001604052604051610b4e9493929190611d2c565b6020604051602081039080840390855afa158015610b70573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610ba65750886001600160a01b0316816001600160a01b0316145b610bc25760405162461bcd60e51b815260040161049490611f2f565b610bcd898989610fff565b505050505050505050565b6000816001600160a01b0316836001600160a01b03161480610c4357506001600160a01b03831660009081526005602052604090205460ff168015610c4357506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b80610c7357506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b6009546001600160a01b0316610c8e610ffb565b6001600160a01b031614610cb45760405162461bcd60e51b815260040161049490611f66565b610d31610cbf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061150492505050565b505050505050565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b600b5481565b610d72610ffb565b6001600160a01b0316816001600160a01b03161415610da35760405162461bcd60e51b815260040161049490611e0f565b6001600160a01b03811660009081526005602052604090205460ff1615610e0f57600160076000610dd2610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055610e4d565b60066000610e1b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b610e55610ffb565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b610ea8610ea2610ffb565b87610bd8565b610ec45760405162461bcd60e51b815260040161049490612085565b610d31610ecf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061162c92505050565b610f9f610f4c610ffb565b610f54610ffb565b8585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805160208101909152908152925061162c915050565b505050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b3390565b6001600160a01b0382166110255760405162461bcd60e51b8152600401610494906120c6565b6001600160a01b0380841660008181526008602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611080908590611cef565b60405180910390a3505050565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906110e99089907f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89590600401611c4c565b60206040518083038186803b15801561110157600080fd5b505afa158015611115573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611139919061182d565b90506001600160a01b0381161561079f57604051633ad5cbc160e11b81526001600160a01b038216906375ab978290611180908a908a908a908a908a908a90600401611bb3565b600060405180830381600087803b15801561119a57600080fd5b505af11580156111ae573d6000803e3d6000fd5b5050505050505050505050565b6111f88360405180606001604052806027815260200161214f602791396001600160a01b03881660009081526020819052604090205491906112db565b6001600160a01b038087166000908152602081905260408082209390935590861681522054611227908461175d565b6001600160a01b0380861660008181526020819052604090819020939093559151878216918916907f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc8261467798790611280908890889088906120fd565b60405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516112cb9190611cef565b60405180910390a3505050505050565b600081848411156112ff5760405162461bcd60e51b81526004016104949190611d4a565b505050900390565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906113639089907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b90600401611c4c565b60206040518083038186803b15801561137b57600080fd5b505afa15801561138f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b3919061182d565b90506001600160a01b0381161561142f576040516223de2960e01b81526001600160a01b038216906223de29906113f8908b908b908b908b908b908b90600401611bb3565b600060405180830381600087803b15801561141257600080fd5b505af1158015611426573d6000803e3d6000fd5b50505050611464565b811561146457611447866001600160a01b0316611782565b156114645760405162461bcd60e51b815260040161049490611ebc565b5050505050505050565b6001600160a01b0386166114945760405162461bcd60e51b815260040161049490611fd5565b6001600160a01b0385166114ba5760405162461bcd60e51b81526004016104949061200c565b6114c887878787878761108d565b6114d68787878787876111bb565b61079f87878787878787611307565b60405161190160f01b8152600281019290925260228201526042902090565b6001600160a01b03841661152a5760405162461bcd60e51b815260040161049490611e85565b600154611537908461175d565b6001556001600160a01b03841660009081526020819052604090205461155d908461175d565b6001600160a01b03851660009081526020819052604081209190915561158a908690868686866001611307565b836001600160a01b0316856001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d8585856040516115d1939291906120fd565b60405180910390a3836001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b60405180910390a35050505050565b6001600160a01b0384166116525760405162461bcd60e51b815260040161049490611d94565b6116618585600086868661108d565b61169e8360405180606001604052806023815260200161219f602391396001600160a01b03871660009081526020819052604090205491906112db565b6001600160a01b0385166000908152602081905260409020556001546116c49084611788565b600181905550836001600160a01b0316856001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098858585604051611711939291906120fd565b60405180910390a360006001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b600082820183811015610c735760405162461bcd60e51b815260040161049490611d5d565b3b151590565b6000610c7383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506112db565b60008083601f8401126117db578182fd5b50813567ffffffffffffffff8111156117f2578182fd5b60208301915083602082850101111561180a57600080fd5b9250929050565b600060208284031215611822578081fd5b8135610c7381612136565b60006020828403121561183e578081fd5b8151610c7381612136565b6000806040838503121561185b578081fd5b823561186681612136565b9150602083013561187681612136565b809150509250929050565b600080600060608486031215611895578081fd5b83356118a081612136565b925060208401356118b081612136565b929592945050506040919091013590565b600080600080600080600060a0888a0312156118db578283fd5b87356118e681612136565b965060208801356118f681612136565b955060408801359450606088013567ffffffffffffffff80821115611919578485fd5b6119258b838c016117ca565b909650945060808a013591508082111561193d578384fd5b5061194a8a828b016117ca565b989b979a50959850939692959293505050565b600080600080600080600060e0888a031215611977578283fd5b873561198281612136565b9650602088013561199281612136565b95506040880135945060608801359350608088013560ff811681146119b5578384fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156119e4578182fd5b82356119ef81612136565b946020939093013593505050565b60008060008060608587031215611a12578384fd5b8435611a1d81612136565b935060208501359250604085013567ffffffffffffffff811115611a3f578283fd5b611a4b878288016117ca565b95989497509550505050565b60008060008060008060808789031215611a6f578182fd5b8635611a7a81612136565b955060208701359450604087013567ffffffffffffffff80821115611a9d578384fd5b611aa98a838b016117ca565b90965094506060890135915080821115611ac1578384fd5b50611ace89828a016117ca565b979a9699509497509295939492505050565b600080600060408486031215611af4578283fd5b83359250602084013567ffffffffffffffff811115611b11578283fd5b611b1d868287016117ca565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b81811015611b7957602081850181015186830182015201611b5d565b81811115611b8a5782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0387811682528681166020830152851660408201526060810184905260c060808201819052600090611bee90830185611b54565b82810360a0840152611c008185611b54565b9998505050505050505050565b6001600160a01b0386811682528516602082015260408101849052608060608201819052600090611c419083018486611b2a565b979650505050505050565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038616825284602083015260606040830152611c8d606083018486611b2a565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611cd85783516001600160a01b031683529284019291840191600101611cb3565b50909695505050505050565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610c736020830184611b54565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f4552433737373a206275726e2066726f6d207a65726f20616464726573730000604082015260600190565b60208082526024908201527f4552433737373a20617574686f72697a696e672073656c66206173206f70657260408201526330ba37b960e11b606082015260800190565b60208082526021908201527f4552433737373a207265766f6b696e672073656c66206173206f70657261746f6040820152603960f91b606082015260800190565b6020808252818101527f4552433737373a207472616e7366657220746f207a65726f2061646472657373604082015260600190565b6020808252601c908201527f4552433737373a206d696e7420746f207a65726f206164647265737300000000604082015260600190565b6020808252604d908201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460408201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60608201526c1ad95b9cd49958da5c1a595b9d609a1b608082015260a00190565b6020808252601c908201527f53696465546f6b656e3a20494e56414c49445f5349474e415455524500000000604082015260600190565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b60208082526012908201527114da5919551bdad95b8e881156141254915160721b604082015260600190565b6020808252601e908201527f4552433737373a2073656e642066726f6d207a65726f20616464726573730000604082015260600190565b6020808252601c908201527f4552433737373a2073656e6420746f207a65726f206164647265737300000000604082015260600190565b60208082526022908201527f4552433737373a207472616e736665722066726f6d207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526021908201527f4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f6040820152603960f91b606082015260800190565b6020808252601f908201527f4552433737373a20617070726f766520746f207a65726f206164647265737300604082015260600190565b6000848252606060208301526121166060830185611b54565b8281036040840152611c8d8185611b54565b60ff91909116815260200190565b6001600160a01b038116811461214b57600080fd5b5056fe4552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a206275726e20616d6f756e7420657863656564732062616c616e6365a2646970667358221220e50313b8f4599486bdf7f8664f20e7ac280c8c35bbfd6cde681392ecbb37f14d64736f6c63430007060033a26469706673582212208c32c0735adbbf4ac7cf06584e89be0c8b8a258182daeed841b15ec41b72036764736f6c63430007060033",
+ "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000465760003560e01c80632348238c146200004b57806326d9e9631462000064578063c6dbdf611462000093575b600080fd5b620000626200005c366004620002b8565b6200009d565b005b6200007b62000075366004620002e8565b6200016c565b6040516200008a91906200038a565b60405180910390f35b6200007b6200024d565b6000546001600160a01b0316620000b36200025c565b6001600160a01b031614620000e55760405162461bcd60e51b8152600401620000dc9062000458565b60405180910390fd5b6001600160a01b0381166200010e5760405162461bcd60e51b8152600401620000dc906200040e565b600080546001600160a01b0319166001600160a01b0383811691909117918290556040517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d992620001619216906200038a565b60405180910390a150565b600080546001600160a01b0316620001836200025c565b6001600160a01b031614620001ac5760405162461bcd60e51b8152600401620000dc9062000458565b600086868686620001bc6200024d565b87604051620001cb9062000260565b620001dc969594939291906200039e565b604051809103906000f080158015620001f9573d6000803e3d6000fd5b509050806001600160a01b03167ff57d2ded8330a4affd2fa52378069be534fe22288536537d1a1cfc06151845078686866040516200023b93929190620003e8565b60405180910390a29695505050505050565b6000546001600160a01b031690565b3390565b61288880620004a583390190565b60008083601f84011262000280578182fd5b50813567ffffffffffffffff81111562000298578182fd5b602083019150836020828501011115620002b157600080fd5b9250929050565b600060208284031215620002ca578081fd5b81356001600160a01b0381168114620002e1578182fd5b9392505050565b60008060008060006060868803121562000300578081fd5b853567ffffffffffffffff8082111562000318578283fd5b6200032689838a016200026e565b909750955060208801359150808211156200033f578283fd5b506200034e888289016200026e565b96999598509660400135949350505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6001600160a01b0391909116815260200190565b600060808252620003b460808301888a62000360565b8281036020840152620003c981878962000360565b6001600160a01b03959095166040840152505060600152949350505050565b600060408252620003fe60408301858762000360565b9050826020830152949350505050565b6020808252602a908201527f5365636f6e646172793a206e6577207072696d61727920697320746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602c908201527f5365636f6e646172793a2063616c6c6572206973206e6f74207468652070726960408201526b1b585c9e481858d8dbdd5b9d60a21b60608201526080019056fe60806040523480156200001157600080fd5b506040516200288838038062002888833981016040819052620000349162000561565b60408051600081526020808201909252855186928692916200005d9160029190860190620003c2565b50815162000073906003906020850190620003c2565b5080516200008990600490602084019062000457565b5060005b600454811015620000e95760016005600060048481548110620000ac57fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff19169115159190911790556001016200008d565b506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90620001479030907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054908290600401620005f0565b600060405180830381600087803b1580156200016257600080fd5b505af115801562000177573d6000803e3d6000fd5b50506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad2492506329965a1d9150620001d89030907faea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a908290600401620005f0565b600060405180830381600087803b158015620001f357600080fd5b505af115801562000208573d6000803e3d6000fd5b50505050506001600160a01b038416151591506200024590505760405162461bcd60e51b81526004016200023c9062000613565b60405180910390fd5b6001811015620002695760405162461bcd60e51b81526004016200023c906200064a565b600980546001600160a01b0319166001600160a01b038416179055600a81905546620002c562000298620002d4565b604051806040016040528060018152602001603160f81b81525083306200036b60201b62000fa41760201c565b600b5550620006819350505050565b60028054604080516020601f6000196101006001871615020190941685900493840181900481028201810190925282815260609390929091830182828015620003615780601f10620003355761010080835404028352916020019162000361565b820191906000526020600020905b8154815290600101906020018083116200034357829003601f168201915b5050505050905090565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620003fa576000855562000445565b82601f106200041557805160ff191683800117855562000445565b8280016001018555821562000445579182015b828111156200044557825182559160200191906001019062000428565b5062000453929150620004af565b5090565b82805482825590600052602060002090810192821562000445579160200282015b828111156200044557825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000478565b5b80821115620004535760008155600101620004b0565b600082601f830112620004d7578081fd5b81516001600160401b0380821115620004ec57fe5b6040516020601f8401601f19168201810183811183821017156200050c57fe5b604052838252858401810187101562000523578485fd5b8492505b8383101562000546578583018101518284018201529182019162000527565b838311156200055757848185840101525b5095945050505050565b6000806000806080858703121562000577578384fd5b84516001600160401b03808211156200058e578586fd5b6200059c88838901620004c6565b95506020870151915080821115620005b2578485fd5b50620005c187828801620004c6565b604087015190945090506001600160a01b0381168114620005e0578283fd5b6060959095015193969295505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b60208082526017908201527f53696465546f6b656e3a20456d707479204d696e746572000000000000000000604082015260600190565b6020808252601a908201527f53696465546f6b656e3a204772616e756c6172697479203c2031000000000000604082015260600190565b6121f780620006916000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80637ecebe00116100de578063d95b637111610097578063f698da2511610071578063f698da2514610308578063fad8b32a14610310578063fc673c4f14610323578063fe9d93031461033657610173565b8063d95b6371146102cf578063dcdc7dd0146102e2578063dd62ed3e146102f557610173565b80637ecebe0014610268578063959b8c3f1461027b57806395d89b411461028e5780639bd9bbc614610296578063a9059cbb146102a9578063d505accf146102bc57610173565b806330adf81f1161013057806330adf81f14610208578063313ce567146102105780634000aea014610225578063556f0dc71461023857806362ad1b831461024057806370a082311461025557610173565b806306e485381461017857806306fdde031461019657806307546172146101ab578063095ea7b3146101c057806318160ddd146101e057806323b872dd146101f5575b600080fd5b610180610349565b60405161018d9190611c97565b60405180910390f35b61019e6103ab565b60405161018d9190611d4a565b6101b3610435565b60405161018d9190611b9f565b6101d36101ce3660046119d2565b610444565b60405161018d9190611ce4565b6101e8610466565b60405161018d9190611cef565b6101d3610203366004611881565b61046c565b6101e86105b4565b6102186105d8565b60405161018d9190612128565b6101d36102333660046119fd565b6105dd565b6101e86106eb565b61025361024e3660046118c1565b6106f1565b005b6101e8610263366004611811565b6107a8565b6101e8610276366004611811565b6107c3565b610253610289366004611811565b6107d5565b61019e610902565b6102536102a43660046119fd565b610963565b6101d36102b73660046119d2565b6109cb565b6102536102ca36600461195d565b610a85565b6101d36102dd366004611849565b610bd8565b6102536102f0366004611a57565b610c7a565b6101e8610303366004611849565b610d39565b6101e8610d64565b61025361031e366004611811565b610d6a565b610253610331366004611a57565b610e97565b610253610344366004611ae0565b610f41565b606060048054806020026020016040519081016040528092919081815260200182805480156103a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610383575b5050505050905090565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b820191906000526020600020905b81548152906001019060200180831161041757509395945050505050565b6009546001600160a01b031681565b60008061044f610ffb565b905061045c818585610fff565b5060019392505050565b60015490565b60006001600160a01b03831661049d5760405162461bcd60e51b815260040161049490611e50565b60405180910390fd5b6001600160a01b0384166104c35760405162461bcd60e51b815260040161049490612043565b60006104cd610ffb565b90506104fb81868686604051806020016040528060008152506040518060200160405280600081525061108d565b6105278186868660405180602001604052806000815250604051806020016040528060008152506111bb565b61057b858261057686604051806060016040528060298152602001612176602991396001600160a01b03808c166000908152600860209081526040808320938b168352929052205491906112db565b610fff565b6105a98186868660405180602001604052806000815250604051806020016040528060008152506000611307565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601290565b6000806105e8610ffb565b905061063c8182888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060408051602081019091528181529350915061146e9050565b7fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c168187878787604051610673959493929190611c0d565b60405180910390a1604051635260769b60e11b81526001600160a01b0387169063a4c0ed36906106ad908490899089908990600401611c65565b600060405180830381600087803b1580156106c757600080fd5b505af11580156106db573d6000803e3d6000fd5b5060019998505050505050505050565b600a5490565b6107026106fc610ffb565b88610bd8565b61071e5760405162461bcd60e51b815260040161049490612085565b61079f610729610ffb565b88888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a91508990819084018382808284376000920191909152506001925061146e915050565b50505050505050565b6001600160a01b031660009081526020819052604090205490565b600c6020526000908152604090205481565b806001600160a01b03166107e7610ffb565b6001600160a01b0316141561080e5760405162461bcd60e51b815260040161049490611dcb565b6001600160a01b03811660009081526005602052604090205460ff1615610871576007600061083b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690556108b8565b60016006600061087f610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b6108c0610ffb565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103a15780601f10610409576101008083540402835291602001916103a1565b6109c561096e610ffb565b610976610ffb565b868686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604080516020810190915290815292506001915061146e9050565b50505050565b60006001600160a01b0383166109f35760405162461bcd60e51b815260040161049490611e50565b60006109fd610ffb565b9050610a2b81828686604051806020016040528060008152506040518060200160405280600081525061108d565b610a578182868660405180602001604052806000815250604051806020016040528060008152506111bb565b61045c8182868660405180602001604052806000815250604051806020016040528060008152506000611307565b42841015610aa55760405162461bcd60e51b815260040161049490611fa9565b600b546001600160a01b0388166000908152600c6020908152604080832080546001810190915590519293610b27939092610b0c927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928e928e928e9290918e9101611cf8565b604051602081830303815290604052805190602001206114e5565b9050600060018286868660405160008152602001604052604051610b4e9493929190611d2c565b6020604051602081039080840390855afa158015610b70573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610ba65750886001600160a01b0316816001600160a01b0316145b610bc25760405162461bcd60e51b815260040161049490611f2f565b610bcd898989610fff565b505050505050505050565b6000816001600160a01b0316836001600160a01b03161480610c4357506001600160a01b03831660009081526005602052604090205460ff168015610c4357506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b80610c7357506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b6009546001600160a01b0316610c8e610ffb565b6001600160a01b031614610cb45760405162461bcd60e51b815260040161049490611f66565b610d31610cbf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061150492505050565b505050505050565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b600b5481565b610d72610ffb565b6001600160a01b0316816001600160a01b03161415610da35760405162461bcd60e51b815260040161049490611e0f565b6001600160a01b03811660009081526005602052604090205460ff1615610e0f57600160076000610dd2610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055610e4d565b60066000610e1b610ffb565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b610e55610ffb565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b610ea8610ea2610ffb565b87610bd8565b610ec45760405162461bcd60e51b815260040161049490612085565b610d31610ecf610ffb565b878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152925089915088908190840183828082843760009201919091525061162c92505050565b610f9f610f4c610ffb565b610f54610ffb565b8585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805160208101909152908152925061162c915050565b505050565b8351602094850120835193850193909320604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f815295860194909452928401929092526060830152608082015260a0902090565b3390565b6001600160a01b0382166110255760405162461bcd60e51b8152600401610494906120c6565b6001600160a01b0380841660008181526008602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611080908590611cef565b60405180910390a3505050565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906110e99089907f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89590600401611c4c565b60206040518083038186803b15801561110157600080fd5b505afa158015611115573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611139919061182d565b90506001600160a01b0381161561079f57604051633ad5cbc160e11b81526001600160a01b038216906375ab978290611180908a908a908a908a908a908a90600401611bb3565b600060405180830381600087803b15801561119a57600080fd5b505af11580156111ae573d6000803e3d6000fd5b5050505050505050505050565b6111f88360405180606001604052806027815260200161214f602791396001600160a01b03881660009081526020819052604090205491906112db565b6001600160a01b038087166000908152602081905260408082209390935590861681522054611227908461175d565b6001600160a01b0380861660008181526020819052604090819020939093559151878216918916907f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc8261467798790611280908890889088906120fd565b60405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516112cb9190611cef565b60405180910390a3505050505050565b600081848411156112ff5760405162461bcd60e51b81526004016104949190611d4a565b505050900390565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906113639089907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b90600401611c4c565b60206040518083038186803b15801561137b57600080fd5b505afa15801561138f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b3919061182d565b90506001600160a01b0381161561142f576040516223de2960e01b81526001600160a01b038216906223de29906113f8908b908b908b908b908b908b90600401611bb3565b600060405180830381600087803b15801561141257600080fd5b505af1158015611426573d6000803e3d6000fd5b50505050611464565b811561146457611447866001600160a01b0316611782565b156114645760405162461bcd60e51b815260040161049490611ebc565b5050505050505050565b6001600160a01b0386166114945760405162461bcd60e51b815260040161049490611fd5565b6001600160a01b0385166114ba5760405162461bcd60e51b81526004016104949061200c565b6114c887878787878761108d565b6114d68787878787876111bb565b61079f87878787878787611307565b60405161190160f01b8152600281019290925260228201526042902090565b6001600160a01b03841661152a5760405162461bcd60e51b815260040161049490611e85565b600154611537908461175d565b6001556001600160a01b03841660009081526020819052604090205461155d908461175d565b6001600160a01b03851660009081526020819052604081209190915561158a908690868686866001611307565b836001600160a01b0316856001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d8585856040516115d1939291906120fd565b60405180910390a3836001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b60405180910390a35050505050565b6001600160a01b0384166116525760405162461bcd60e51b815260040161049490611d94565b6116618585600086868661108d565b61169e8360405180606001604052806023815260200161219f602391396001600160a01b03871660009081526020819052604090205491906112db565b6001600160a01b0385166000908152602081905260409020556001546116c49084611788565b600181905550836001600160a01b0316856001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098858585604051611711939291906120fd565b60405180910390a360006001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161161d9190611cef565b600082820183811015610c735760405162461bcd60e51b815260040161049490611d5d565b3b151590565b6000610c7383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506112db565b60008083601f8401126117db578182fd5b50813567ffffffffffffffff8111156117f2578182fd5b60208301915083602082850101111561180a57600080fd5b9250929050565b600060208284031215611822578081fd5b8135610c7381612136565b60006020828403121561183e578081fd5b8151610c7381612136565b6000806040838503121561185b578081fd5b823561186681612136565b9150602083013561187681612136565b809150509250929050565b600080600060608486031215611895578081fd5b83356118a081612136565b925060208401356118b081612136565b929592945050506040919091013590565b600080600080600080600060a0888a0312156118db578283fd5b87356118e681612136565b965060208801356118f681612136565b955060408801359450606088013567ffffffffffffffff80821115611919578485fd5b6119258b838c016117ca565b909650945060808a013591508082111561193d578384fd5b5061194a8a828b016117ca565b989b979a50959850939692959293505050565b600080600080600080600060e0888a031215611977578283fd5b873561198281612136565b9650602088013561199281612136565b95506040880135945060608801359350608088013560ff811681146119b5578384fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156119e4578182fd5b82356119ef81612136565b946020939093013593505050565b60008060008060608587031215611a12578384fd5b8435611a1d81612136565b935060208501359250604085013567ffffffffffffffff811115611a3f578283fd5b611a4b878288016117ca565b95989497509550505050565b60008060008060008060808789031215611a6f578182fd5b8635611a7a81612136565b955060208701359450604087013567ffffffffffffffff80821115611a9d578384fd5b611aa98a838b016117ca565b90965094506060890135915080821115611ac1578384fd5b50611ace89828a016117ca565b979a9699509497509295939492505050565b600080600060408486031215611af4578283fd5b83359250602084013567ffffffffffffffff811115611b11578283fd5b611b1d868287016117ca565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b81811015611b7957602081850181015186830182015201611b5d565b81811115611b8a5782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0387811682528681166020830152851660408201526060810184905260c060808201819052600090611bee90830185611b54565b82810360a0840152611c008185611b54565b9998505050505050505050565b6001600160a01b0386811682528516602082015260408101849052608060608201819052600090611c419083018486611b2a565b979650505050505050565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038616825284602083015260606040830152611c8d606083018486611b2a565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611cd85783516001600160a01b031683529284019291840191600101611cb3565b50909695505050505050565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610c736020830184611b54565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f4552433737373a206275726e2066726f6d207a65726f20616464726573730000604082015260600190565b60208082526024908201527f4552433737373a20617574686f72697a696e672073656c66206173206f70657260408201526330ba37b960e11b606082015260800190565b60208082526021908201527f4552433737373a207265766f6b696e672073656c66206173206f70657261746f6040820152603960f91b606082015260800190565b6020808252818101527f4552433737373a207472616e7366657220746f207a65726f2061646472657373604082015260600190565b6020808252601c908201527f4552433737373a206d696e7420746f207a65726f206164647265737300000000604082015260600190565b6020808252604d908201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460408201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60608201526c1ad95b9cd49958da5c1a595b9d609a1b608082015260a00190565b6020808252601c908201527f53696465546f6b656e3a20494e56414c49445f5349474e415455524500000000604082015260600190565b60208082526023908201527f53696465546f6b656e3a2043616c6c6572206973206e6f7420746865206d696e6040820152623a32b960e91b606082015260800190565b60208082526012908201527114da5919551bdad95b8e881156141254915160721b604082015260600190565b6020808252601e908201527f4552433737373a2073656e642066726f6d207a65726f20616464726573730000604082015260600190565b6020808252601c908201527f4552433737373a2073656e6420746f207a65726f206164647265737300000000604082015260600190565b60208082526022908201527f4552433737373a207472616e736665722066726f6d207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526021908201527f4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f6040820152603960f91b606082015260800190565b6020808252601f908201527f4552433737373a20617070726f766520746f207a65726f206164647265737300604082015260600190565b6000848252606060208301526121166060830185611b54565b8281036040840152611c8d8185611b54565b60ff91909116815260200190565b6001600160a01b038116811461214b57600080fd5b5056fe4552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a206275726e20616d6f756e7420657863656564732062616c616e6365a2646970667358221220e50313b8f4599486bdf7f8664f20e7ac280c8c35bbfd6cde681392ecbb37f14d64736f6c63430007060033a26469706673582212208c32c0735adbbf4ac7cf06584e89be0c8b8a258182daeed841b15ec41b72036764736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "primary()": {
+ "returns": {
+ "_0": "the address of the primary."
+ }
+ },
+ "transferPrimary(address)": {
+ "details": "Transfers contract to a new primary.",
+ "params": {
+ "recipient": "The address of new primary."
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 11018,
+ "contract": "contracts/SideTokenFactory/SideTokenFactory.sol:SideTokenFactory",
+ "label": "_primary",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/WRBTC.json b/bridge/deployments/rsktestnetrinkeby/WRBTC.json
new file mode 100644
index 000000000..f78571e12
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/WRBTC.json
@@ -0,0 +1,400 @@
+{
+ "address": "0x09b6ca5e4496238a1f176aea6bb607db96c2286e",
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "guy",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposit",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "Withdrawal",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "guy",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "deposit",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "src",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "dst",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "wad",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdraw",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "transactionHash": "0xa55afc0a86fae3e78c22da4d796f54929788ac921ad83ef5ebf35902982c73ca",
+ "receipt": {
+ "to": null,
+ "from": "0xEAC27e59F8a71613137E9C5D475D05c7D4d198e8",
+ "contractAddress": "0xcAB50DA63928519b4dD58e3766D90B8E860982D9",
+ "transactionIndex": 0,
+ "gasUsed": "665718",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xdb8404801fc937df8ffbc62579c7ec91193ef9ac5d47401cb5a264ab3ce8090c",
+ "transactionHash": "0xa55afc0a86fae3e78c22da4d796f54929788ac921ad83ef5ebf35902982c73ca",
+ "logs": [],
+ "blockNumber": 2152326,
+ "cumulativeGasUsed": "665718",
+ "status": 1,
+ "byzantium": true
+ },
+ "args": [],
+ "solcInputHash": "c9c50994c7f4ed6c6a7c2f652aca7adb",
+ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/test/WRBTC.sol\":\"WRBTC\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interface/IWrapped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\ninterface IWrapped {\\n function balanceOf(address) external returns(uint);\\n\\n function deposit() external payable;\\n\\n function withdraw(uint wad) external;\\n\\n function totalSupply() external view returns (uint);\\n\\n function approve(address guy, uint wad) external returns (bool);\\n\\n function transfer(address dst, uint wad) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint wad)\\n external\\n returns (bool);\\n}\",\"keccak256\":\"0x2d8a99b6a030e37f01dba86db80e3bd29d1d01e592e399c8635df3fb636ec0d1\",\"license\":\"MIT\"},\"contracts/test/WRBTC.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../interface/IWrapped.sol\\\";\\n\\ncontract WRBTC is IWrapped {\\n string public name = \\\"Wrapped RBTC\\\";\\n string public symbol = \\\"WRBTC\\\";\\n uint8 public decimals = 18;\\n\\n event Approval(address indexed src, address indexed guy, uint wad);\\n event Transfer(address indexed src, address indexed dst, uint wad);\\n event Deposit(address indexed dst, uint wad);\\n event Withdrawal(address indexed src, uint wad);\\n\\n mapping (address => uint) override public balanceOf;\\n mapping (address => mapping (address => uint)) public allowance;\\n\\n receive () external payable {\\n deposit();\\n }\\n function deposit() override public payable {\\n balanceOf[msg.sender] += msg.value;\\n emit Deposit(msg.sender, msg.value);\\n }\\n function withdraw(uint wad) override public {\\n require(balanceOf[msg.sender] >= wad, \\\"WRBTC: Balance less than wad\\\");\\n balanceOf[msg.sender] -= wad;\\n msg.sender.transfer(wad);\\n emit Withdrawal(msg.sender, wad);\\n }\\n\\n function totalSupply() override public view returns (uint) {\\n return address(this).balance;\\n }\\n\\n function approve(address guy, uint wad) override public returns (bool) {\\n allowance[msg.sender][guy] = wad;\\n emit Approval(msg.sender, guy, wad);\\n return true;\\n }\\n\\n function transfer(address dst, uint wad) override public returns (bool) {\\n return transferFrom(msg.sender, dst, wad);\\n }\\n\\n function transferFrom(address src, address dst, uint wad)\\n override public\\n returns (bool)\\n {\\n require(balanceOf[src] >= wad, \\\"WRBTC: Balance less than wad\\\");\\n\\n if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\\n require(allowance[src][msg.sender] >= wad, \\\"WRBTC: Allowance less than wad\\\");\\n allowance[src][msg.sender] -= wad;\\n }\\n\\n balanceOf[src] -= wad;\\n balanceOf[dst] += wad;\\n\\n emit Transfer(src, dst, wad);\\n\\n return true;\\n }\\n}\",\"keccak256\":\"0xf664c159f6302a78c9e6393c00de0c2630dc3e830215dc467a03f17a533b6807\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x60c0604052600c60808190526b57726170706564205242544360a01b60a090815261002d916000919061007a565b5060408051808201909152600580825264575242544360d81b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b5061011b565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826100b057600085556100f6565b82601f106100c957805160ff19168380011785556100f6565b828001600101855582156100f6579182015b828111156100f65782518255916020019190600101906100db565b50610102929150610106565b5090565b5b808211156101025760008155600101610107565b6107d28061012a6000396000f3fe6080604052600436106100a05760003560e01c8063313ce56711610064578063313ce5671461021f57806370a082311461024a57806395d89b411461027d578063a9059cbb14610292578063d0e30db0146102cb578063dd62ed3e146102d3576100af565b806306fdde03146100b4578063095ea7b31461013e57806318160ddd1461018b57806323b872dd146101b25780632e1a7d4d146101f5576100af565b366100af576100ad61030e565b005b600080fd5b3480156100c057600080fd5b506100c961035d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101035781810151838201526020016100eb565b50505050905090810190601f1680156101305780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014a57600080fd5b506101776004803603604081101561016157600080fd5b506001600160a01b0381351690602001356103eb565b604080519115158252519081900360200190f35b34801561019757600080fd5b506101a0610451565b60408051918252519081900360200190f35b3480156101be57600080fd5b50610177600480360360608110156101d557600080fd5b506001600160a01b03813581169160208101359091169060400135610455565b34801561020157600080fd5b506100ad6004803603602081101561021857600080fd5b5035610619565b34801561022b57600080fd5b506102346106f6565b6040805160ff9092168252519081900360200190f35b34801561025657600080fd5b506101a06004803603602081101561026d57600080fd5b50356001600160a01b03166106ff565b34801561028957600080fd5b506100c9610711565b34801561029e57600080fd5b50610177600480360360408110156102b557600080fd5b506001600160a01b03813516906020013561076b565b6100ad61030e565b3480156102df57600080fd5b506101a0600480360360408110156102f657600080fd5b506001600160a01b038135811691602001351661077f565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b820191906000526020600020905b8154815290600101906020018083116103c657829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b6001600160a01b0383166000908152600360205260408120548211156104c2576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b6001600160a01b038416331480159061050057506001600160a01b038416600090815260046020908152604080832033845290915290205460001914155b156105a8576001600160a01b038416600090815260046020908152604080832033845290915290205482111561057d576040805162461bcd60e51b815260206004820152601e60248201527f57524254433a20416c6c6f77616e6365206c657373207468616e207761640000604482015290519081900360640190fd5b6001600160a01b03841660009081526004602090815260408083203384529091529020805483900390555b6001600160a01b03808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561067d576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106bc573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b6000610778338484610455565b9392505050565b60046020908152600092835260408084209091529082529020548156fea26469706673582212202d01111733e2aa80d67d08b8b3a53d89aabe0e468d80eba287b4a34d46db4ab564736f6c63430007060033",
+ "deployedBytecode": "0x6080604052600436106100a05760003560e01c8063313ce56711610064578063313ce5671461021f57806370a082311461024a57806395d89b411461027d578063a9059cbb14610292578063d0e30db0146102cb578063dd62ed3e146102d3576100af565b806306fdde03146100b4578063095ea7b31461013e57806318160ddd1461018b57806323b872dd146101b25780632e1a7d4d146101f5576100af565b366100af576100ad61030e565b005b600080fd5b3480156100c057600080fd5b506100c961035d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101035781810151838201526020016100eb565b50505050905090810190601f1680156101305780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014a57600080fd5b506101776004803603604081101561016157600080fd5b506001600160a01b0381351690602001356103eb565b604080519115158252519081900360200190f35b34801561019757600080fd5b506101a0610451565b60408051918252519081900360200190f35b3480156101be57600080fd5b50610177600480360360608110156101d557600080fd5b506001600160a01b03813581169160208101359091169060400135610455565b34801561020157600080fd5b506100ad6004803603602081101561021857600080fd5b5035610619565b34801561022b57600080fd5b506102346106f6565b6040805160ff9092168252519081900360200190f35b34801561025657600080fd5b506101a06004803603602081101561026d57600080fd5b50356001600160a01b03166106ff565b34801561028957600080fd5b506100c9610711565b34801561029e57600080fd5b50610177600480360360408110156102b557600080fd5b506001600160a01b03813516906020013561076b565b6100ad61030e565b3480156102df57600080fd5b506101a0600480360360408110156102f657600080fd5b506001600160a01b038135811691602001351661077f565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b820191906000526020600020905b8154815290600101906020018083116103c657829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b6001600160a01b0383166000908152600360205260408120548211156104c2576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b6001600160a01b038416331480159061050057506001600160a01b038416600090815260046020908152604080832033845290915290205460001914155b156105a8576001600160a01b038416600090815260046020908152604080832033845290915290205482111561057d576040805162461bcd60e51b815260206004820152601e60248201527f57524254433a20416c6c6f77616e6365206c657373207468616e207761640000604482015290519081900360640190fd5b6001600160a01b03841660009081526004602090815260408083203384529091529020805483900390555b6001600160a01b03808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561067d576040805162461bcd60e51b815260206004820152601c60248201527f57524254433a2042616c616e6365206c657373207468616e2077616400000000604482015290519081900360640190fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106bc573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103e35780601f106103b8576101008083540402835291602001916103e3565b6000610778338484610455565b9392505050565b60046020908152600092835260408084209091529082529020548156fea26469706673582212202d01111733e2aa80d67d08b8b3a53d89aabe0e468d80eba287b4a34d46db4ab564736f6c63430007060033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {},
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 9308,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "name",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 9311,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "symbol",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 9314,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "decimals",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint8"
+ },
+ {
+ "astId": 9347,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "balanceOf",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_mapping(t_address,t_uint256)"
+ },
+ {
+ "astId": 9353,
+ "contract": "contracts/test/WRBTC.sol:WRBTC",
+ "label": "allowance",
+ "offset": 0,
+ "slot": "4",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_uint256))": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": "t_mapping(t_address,t_uint256)"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_string_storage": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "encoding": "inplace",
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deployments/rsktestnetrinkeby/solcInputs/f57b3a626f709a0447a665aac92698b7.json b/bridge/deployments/rsktestnetrinkeby/solcInputs/f57b3a626f709a0447a665aac92698b7.json
new file mode 100644
index 000000000..de6b9b893
--- /dev/null
+++ b/bridge/deployments/rsktestnetrinkeby/solcInputs/f57b3a626f709a0447a665aac92698b7.json
@@ -0,0 +1,297 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/AllowTokens/AllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../zeppelin/math/SafeMath.sol\";\r\n// Upgradables\r\nimport \"../zeppelin/upgradable/Initializable.sol\";\r\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\r\nimport \"../zeppelin/upgradable/ownership/UpgradableSecondary.sol\";\r\n\r\nimport \"../interface/IAllowTokens.sol\";\r\n\r\ncontract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {\r\n using SafeMath for uint256;\r\n\r\n address constant private NULL_ADDRESS = address(0);\r\n uint256 constant public MAX_TYPES = 250;\r\n mapping (address => TokenInfo) public allowedTokens;\r\n mapping (uint256 => Limits) public typeLimits;\r\n uint256 public smallAmountConfirmations;\r\n uint256 public mediumAmountConfirmations;\r\n uint256 public largeAmountConfirmations;\r\n string[] public typeDescriptions;\r\n\r\n event SetToken(address indexed _tokenAddress, uint256 _typeId);\r\n event AllowedTokenRemoved(address indexed _tokenAddress);\r\n event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);\r\n event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);\r\n event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);\r\n event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);\r\n\r\n\r\n modifier notNull(address _address) {\r\n require(_address != NULL_ADDRESS, \"AllowTokens: Null Address\");\r\n _;\r\n }\r\n\r\n function initialize(\r\n address _manager,\r\n address _primary,\r\n uint256 _smallAmountConfirmations,\r\n uint256 _mediumAmountConfirmations,\r\n uint256 _largeAmountConfirmations,\r\n TypeInfo[] memory typesInfo) public initializer {\r\n UpgradableOwnable.initialize(_manager);\r\n UpgradableSecondary.__Secondary_init(_primary);\r\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\r\n for(uint i = 0; i < typesInfo.length; i = i + 1) {\r\n _addTokenType(typesInfo[i].description, typesInfo[i].limits);\r\n }\r\n }\r\n\r\n function version() override external pure returns (string memory) {\r\n return \"v1\";\r\n }\r\n\r\n function getInfoAndLimits(address token) override public view\r\n returns (TokenInfo memory info, Limits memory limit) {\r\n info = allowedTokens[token];\r\n limit = typeLimits[info.typeId];\r\n return (info, limit);\r\n }\r\n function calcMaxWithdraw(address token) override public view returns (uint256 maxWithdraw) {\r\n (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);\r\n return _calcMaxWithdraw(info, limits);\r\n }\r\n\r\n function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {\r\n // solium-disable-next-line security/no-block-members\r\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\r\n info.spentToday = 0;\r\n }\r\n if (limits.daily <= info.spentToday)\r\n return 0;\r\n maxWithdraw = limits.daily - info.spentToday;\r\n if(maxWithdraw > limits.max)\r\n maxWithdraw = limits.max;\r\n return maxWithdraw;\r\n }\r\n\r\n // solium-disable-next-line max-len\r\n function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {\r\n (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);\r\n require(isTokenAllowed(token), \"AllowTokens: Not whitelisted\");\r\n require(amount >= limit.min, \"AllowTokens: Lower than limit\");\r\n\r\n // solium-disable-next-line security/no-block-members\r\n if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\r\n // solium-disable-next-line security/no-block-members\r\n info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\r\n info.spentToday = 0;\r\n }\r\n uint maxWithdraw = _calcMaxWithdraw(info, limit);\r\n require(amount <= maxWithdraw, \"AllowTokens: Exceeded limit\");\r\n info.spentToday = info.spentToday.add(amount);\r\n allowedTokens[token] = info;\r\n\r\n emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);\r\n }\r\n\r\n function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {\r\n require(bytes(description).length > 0, \"AllowTokens: Empty description\");\r\n len = typeDescriptions.length;\r\n require(len + 1 <= MAX_TYPES, \"AllowTokens: Reached MAX_TYPES\");\r\n typeDescriptions.push(description);\r\n _setTypeLimits(len, limits);\r\n emit TokenTypeAdded(len, description);\r\n return len;\r\n }\r\n\r\n function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {\r\n return _addTokenType(description, limits);\r\n }\r\n\r\n function _setTypeLimits(uint256 typeId, Limits memory limits) private {\r\n require(typeId < typeDescriptions.length, \"AllowTokens: bigger than typeDescriptions\");\r\n require(limits.max >= limits.min, \"AllowTokens: maxTokens smaller than minTokens\");\r\n require(limits.daily >= limits.max, \"AllowTokens: dailyLimit smaller than maxTokens\");\r\n require(limits.mediumAmount > limits.min, \"AllowTokens: limits.mediumAmount smaller than min\");\r\n require(limits.largeAmount > limits.mediumAmount, \"AllowTokens: limits.largeAmount smaller than mediumAmount\");\r\n typeLimits[typeId] = limits;\r\n emit TypeLimitsChanged(typeId, limits);\r\n }\r\n\r\n function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {\r\n _setTypeLimits(typeId, limits);\r\n }\r\n\r\n function getTypesLimits() external view override returns(Limits[] memory limits) {\r\n limits = new Limits[](typeDescriptions.length);\r\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\r\n limits[i] = typeLimits[i];\r\n }\r\n return limits;\r\n }\r\n\r\n function getTypeDescriptionsLength() external view override returns(uint256) {\r\n return typeDescriptions.length;\r\n }\r\n\r\n function getTypeDescriptions() external view override returns(string[] memory descriptions) {\r\n descriptions = new string[](typeDescriptions.length);\r\n for (uint256 i = 0; i < typeDescriptions.length; i++) {\r\n descriptions[i] = typeDescriptions[i];\r\n }\r\n return descriptions;\r\n }\r\n\r\n function isTokenAllowed(address token) public view notNull(token) override returns (bool) {\r\n return allowedTokens[token].allowed;\r\n }\r\n\r\n function setToken(address token, uint256 typeId) override public notNull(token) {\r\n require(isOwner() || _msgSender() == primary(), \"AllowTokens: unauthorized sender\");\r\n require(typeId < typeDescriptions.length, \"AllowTokens: typeId does not exist\");\r\n TokenInfo memory info = allowedTokens[token];\r\n info.allowed = true;\r\n info.typeId = typeId;\r\n allowedTokens[token] = info;\r\n emit SetToken(token, typeId);\r\n }\r\n\r\n function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {\r\n require(tokensAndTypes.length > 0, \"AllowTokens: empty tokens\");\r\n for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {\r\n setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);\r\n }\r\n }\r\n\r\n function removeAllowedToken(address token) external notNull(token) onlyOwner {\r\n TokenInfo memory info = allowedTokens[token];\r\n require(info.allowed, \"AllowTokens: Not Allowed\");\r\n info.allowed = false;\r\n allowedTokens[token] = info;\r\n emit AllowedTokenRemoved(token);\r\n }\r\n\r\n function setConfirmations(\r\n uint256 _smallAmountConfirmations,\r\n uint256 _mediumAmountConfirmations,\r\n uint256 _largeAmountConfirmations) external onlyOwner {\r\n _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\r\n }\r\n\r\n function _setConfirmations(\r\n uint256 _smallAmountConfirmations,\r\n uint256 _mediumAmountConfirmations,\r\n uint256 _largeAmountConfirmations) private {\r\n require(_smallAmountConfirmations <= _mediumAmountConfirmations, \"AllowTokens: small bigger than medium confirmations\");\r\n require(_mediumAmountConfirmations <= _largeAmountConfirmations, \"AllowTokens: medium bigger than large confirmations\");\r\n smallAmountConfirmations = _smallAmountConfirmations;\r\n mediumAmountConfirmations = _mediumAmountConfirmations;\r\n largeAmountConfirmations = _largeAmountConfirmations;\r\n emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);\r\n }\r\n\r\n function getConfirmations() external view override\r\n returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount) {\r\n return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/zeppelin/math/SafeMath.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\r\n * checks.\r\n *\r\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\r\n * in bugs, because programmers usually assume that an overflow raises an\r\n * error, which is the standard behavior in high level programming languages.\r\n * `SafeMath` restores this intuition by reverting the transaction when an\r\n * operation overflows.\r\n *\r\n * Using this library instead of the unchecked operations eliminates an entire\r\n * class of bugs, so it's recommended to use it always.\r\n */\r\nlibrary SafeMath {\r\n /**\r\n * @dev Returns the addition of two unsigned integers, reverting on\r\n * overflow.\r\n *\r\n * Counterpart to Solidity's `+` operator.\r\n *\r\n * Requirements:\r\n * - Addition cannot overflow.\r\n */\r\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\r\n uint256 c = a + b;\r\n require(c >= a, \"SafeMath: addition overflow\");\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the subtraction of two unsigned integers, reverting on\r\n * overflow (when the result is negative).\r\n *\r\n * Counterpart to Solidity's `-` operator.\r\n *\r\n * Requirements:\r\n * - Subtraction cannot overflow.\r\n */\r\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\r\n return sub(a, b, \"SafeMath: subtraction overflow\");\r\n }\r\n\r\n /**\r\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\r\n * overflow (when the result is negative).\r\n *\r\n * Counterpart to Solidity's `-` operator.\r\n *\r\n * Requirements:\r\n * - Subtraction cannot overflow.\r\n *\r\n * _Available since v2.4.0._\r\n */\r\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\r\n require(b <= a, errorMessage);\r\n uint256 c = a - b;\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the multiplication of two unsigned integers, reverting on\r\n * overflow.\r\n *\r\n * Counterpart to Solidity's `*` operator.\r\n *\r\n * Requirements:\r\n * - Multiplication cannot overflow.\r\n */\r\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\r\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\r\n // benefit is lost if 'b' is also tested.\r\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\r\n if (a == 0) {\r\n return 0;\r\n }\r\n\r\n uint256 c = a * b;\r\n require(c / a == b, \"SafeMath: multiplication overflow\");\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the integer division of two unsigned integers. Reverts on\r\n * division by zero. The result is rounded towards zero.\r\n *\r\n * Counterpart to Solidity's `/` operator. Note: this function uses a\r\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\r\n * uses an invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n * - The divisor cannot be zero.\r\n */\r\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\r\n return div(a, b, \"SafeMath: division by zero\");\r\n }\r\n\r\n /**\r\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\r\n * division by zero. The result is rounded towards zero.\r\n *\r\n * Counterpart to Solidity's `/` operator. Note: this function uses a\r\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\r\n * uses an invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n * - The divisor cannot be zero.\r\n *\r\n * _Available since v2.4.0._\r\n */\r\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\r\n // Solidity only automatically asserts when dividing by 0\r\n require(b > 0, errorMessage);\r\n uint256 c = a / b;\r\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\r\n\r\n return c;\r\n }\r\n\r\n /**\r\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\r\n * Reverts when dividing by zero.\r\n *\r\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\r\n * opcode (which leaves remaining gas untouched) while Solidity uses an\r\n * invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n * - The divisor cannot be zero.\r\n */\r\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\r\n return mod(a, b, \"SafeMath: modulo by zero\");\r\n }\r\n\r\n /**\r\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\r\n * Reverts with custom message when dividing by zero.\r\n *\r\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\r\n * opcode (which leaves remaining gas untouched) while Solidity uses an\r\n * invalid opcode to revert (consuming all remaining gas).\r\n *\r\n * Requirements:\r\n * - The divisor cannot be zero.\r\n *\r\n * _Available since v2.4.0._\r\n */\r\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\r\n require(b != 0, errorMessage);\r\n return a % b;\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/upgradable/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @title Initializable\r\n *\r\n * @dev Helper contract to support initializer functions. To use it, replace\r\n * the constructor with a function that has the `initializer` modifier.\r\n * WARNING: Unlike constructors, initializer functions must be manually\r\n * invoked. This applies both to deploying an Initializable contract, as well\r\n * as extending an Initializable contract via inheritance.\r\n * WARNING: When used with inheritance, manual care must be taken to not invoke\r\n * a parent initializer twice, or ensure that all initializers are idempotent,\r\n * because this is not dealt with automatically as with constructors.\r\n */\r\ncontract Initializable {\r\n\r\n /**\r\n * @dev Indicates that the contract has been initialized.\r\n */\r\n bool private initialized;\r\n\r\n /**\r\n * @dev Indicates that the contract is in the process of being initialized.\r\n */\r\n bool private initializing;\r\n\r\n /**\r\n * @dev Modifier to use in the initializer function of a contract.\r\n */\r\n modifier initializer() {\r\n require(initializing || !initialized, \"Contract instance is already initialized\");\r\n\r\n bool isTopLevelCall = !initializing;\r\n if (isTopLevelCall) {\r\n initializing = true;\r\n initialized = true;\r\n }\r\n\r\n _;\r\n\r\n if (isTopLevelCall) {\r\n initializing = false;\r\n }\r\n }\r\n\r\n // Reserved storage space to allow for layout changes in the future.\r\n uint256[50] private ______gap;\r\n}"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../Initializable.sol\";\r\n\r\nimport \"../../GSN/Context.sol\";\r\n\r\n/**\r\n * @dev Contract module which provides a basic access control mechanism, where\r\n * there is an account (an owner) that can be granted exclusive access to\r\n * specific functions.\r\n *\r\n * This module is used through inheritance. It will make available the modifier\r\n * `onlyOwner`, which can be aplied to your functions to restrict their use to\r\n * the owner.\r\n */\r\ncontract UpgradableOwnable is Initializable, Context {\r\n address private _owner;\r\n\r\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\r\n\r\n /**\r\n * @dev Initializes the contract setting the deployer as the initial owner.\r\n */\r\n function initialize(address sender) public initializer {\r\n _owner = sender;\r\n emit OwnershipTransferred(address(0), _owner);\r\n }\r\n\r\n /**\r\n * @dev Returns the address of the current owner.\r\n */\r\n function owner() public view returns (address) {\r\n return _owner;\r\n }\r\n\r\n /**\r\n * @dev Throws if called by any account other than the owner.\r\n */\r\n modifier onlyOwner() {\r\n require(isOwner(), \"Ownable: caller is not the owner\");\r\n _;\r\n }\r\n\r\n /**\r\n * @dev Returns true if the caller is the current owner.\r\n */\r\n function isOwner() public view returns (bool) {\r\n return _msgSender() == _owner;\r\n }\r\n\r\n /**\r\n * @dev Leaves the contract without owner. It will not be possible to call\r\n * `onlyOwner` functions anymore. Can only be called by the current owner.\r\n *\r\n * > Note: Renouncing ownership will leave the contract without an owner,\r\n * thereby removing any functionality that is only available to the owner.\r\n */\r\n function renounceOwnership() public onlyOwner {\r\n emit OwnershipTransferred(_owner, address(0));\r\n _owner = address(0);\r\n }\r\n\r\n /**\r\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n * Can only be called by the current owner.\r\n */\r\n function transferOwnership(address newOwner) public onlyOwner {\r\n _transferOwnership(newOwner);\r\n }\r\n\r\n /**\r\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n */\r\n function _transferOwnership(address newOwner) internal {\r\n require(newOwner != address(0), \"Ownable: new owner is zero address\");\r\n emit OwnershipTransferred(_owner, newOwner);\r\n _owner = newOwner;\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../Initializable.sol\";\r\n\r\nimport \"../../GSN/Context.sol\";\r\n\r\n/**\r\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\r\n */\r\ncontract UpgradableSecondary is Initializable, Context {\r\n address private _primary;\r\n\r\n /**\r\n * @dev Emitted when the primary contract changes.\r\n */\r\n event PrimaryTransferred(\r\n address recipient\r\n );\r\n\r\n /**\r\n * @dev Sets the primary account to the one that is creating the Secondary contract.\r\n */\r\n function __Secondary_init(address sender) public initializer {\r\n _primary = sender;\r\n emit PrimaryTransferred(_primary);\r\n }\r\n\r\n /**\r\n * @dev Reverts if called from any account other than the primary.\r\n */\r\n modifier onlyPrimary() {\r\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\r\n _;\r\n }\r\n\r\n /**\r\n * @return the address of the primary.\r\n */\r\n function primary() public view returns (address) {\r\n return _primary;\r\n }\r\n\r\n /**\r\n * @dev Transfers contract to a new primary.\r\n * @param recipient The address of new primary.\r\n */\r\n function transferPrimary(address recipient) public onlyPrimary {\r\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\r\n _primary = recipient;\r\n emit PrimaryTransferred(recipient);\r\n }\r\n\r\n}"
+ },
+ "contracts/interface/IAllowTokens.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\ninterface IAllowTokens {\r\n\r\n struct Limits {\r\n uint256 min;\r\n uint256 max;\r\n uint256 daily;\r\n uint256 mediumAmount;\r\n uint256 largeAmount;\r\n }\r\n\r\n struct TokenInfo {\r\n bool allowed;\r\n uint256 typeId;\r\n uint256 spentToday;\r\n uint256 lastDay;\r\n }\r\n\r\n struct TypeInfo {\r\n string description;\r\n Limits limits;\r\n }\r\n\r\n struct TokensAndType {\r\n address token;\r\n uint256 typeId;\r\n }\r\n\r\n function version() external pure returns (string memory);\r\n\r\n function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);\r\n\r\n function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);\r\n\r\n function getTypesLimits() external view returns(Limits[] memory limits);\r\n\r\n function getTypeDescriptionsLength() external view returns(uint256);\r\n\r\n function getTypeDescriptions() external view returns(string[] memory descriptions);\r\n\r\n function setToken(address token, uint256 typeId) external;\r\n\r\n function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);\r\n\r\n function isTokenAllowed(address token) external view returns (bool);\r\n\r\n function updateTokenTransfer(address token, uint256 amount) external;\r\n}"
+ },
+ "contracts/zeppelin/GSN/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/*\r\n * @dev Provides information about the current execution context, including the\r\n * sender of the transaction and its data. While these are generally available\r\n * via msg.sender and msg.data, they should not be accessed in such a direct\r\n * manner, since when dealing with GSN meta-transactions the account sending and\r\n * paying for execution may not be the actual sender (as far as an application\r\n * is concerned).\r\n *\r\n * This contract is only required for intermediate, library-like contracts.\r\n */\r\nabstract contract Context {\r\n\r\n function _msgSender() internal view returns (address payable) {\r\n return msg.sender;\r\n }\r\n\r\n function _msgData() internal view returns (bytes memory) {\r\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\r\n return msg.data;\r\n }\r\n}\r\n"
+ },
+ "contracts/nftbridge/NFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n// Import base Initializable contract\r\nimport \"../zeppelin/upgradable/Initializable.sol\";\r\n// Import interface and library from OpenZeppelin contracts\r\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\r\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\r\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\r\n\r\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\r\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\r\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\r\nimport \"../zeppelin/token/ERC721/IERC721.sol\";\r\nimport \"../zeppelin/token/ERC721/IERC721Metadata.sol\";\r\nimport \"../zeppelin/token/ERC721/IERC721Enumerable.sol\";\r\nimport \"../zeppelin/token/ERC721/IERC721Receiver.sol\";\r\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\r\nimport \"../zeppelin/utils/Address.sol\";\r\nimport \"../zeppelin/math/SafeMath.sol\";\r\n\r\nimport \"../lib/LibEIP712.sol\";\r\nimport \"../lib/LibUtils.sol\";\r\n\r\nimport \"./INFTBridge.sol\";\r\nimport \"./ISideNFTToken.sol\";\r\nimport \"./ISideNFTTokenFactory.sol\";\r\nimport \"../interface/IAllowTokens.sol\";\r\nimport \"../interface/IWrapped.sol\";\r\n\r\n// solhint-disable-next-line max-states-count\r\ncontract NFTBridge is\r\n Initializable,\r\n INFTBridge,\r\n UpgradablePausable,\r\n UpgradableOwnable,\r\n ReentrancyGuard,\r\n IERC721Receiver {\r\n using SafeMath for uint256;\r\n using SafeERC20 for IERC20;\r\n using Address for address;\r\n\r\n address internal constant NULL_ADDRESS = address(0);\r\n bytes32 internal constant NULL_HASH = bytes32(0);\r\n IERC1820Registry internal constant ERC1820 =\r\n IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\r\n\r\n address payable internal federation;\r\n uint256 internal fixedFee;\r\n string public symbolPrefix;\r\n\r\n mapping(address => address) public sideTokenAddressByOriginalTokenAddress;\r\n mapping(address => address) public originalTokenAddressBySideTokenAddress;\r\n mapping(address => bool) public isAddressFromCrossedOriginalToken; // address => returns true if it's an original token address crossed previously (whether it comes from main or side chain)\r\n mapping(bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\r\n IAllowTokens public allowTokens;\r\n ISideNFTTokenFactory public sideTokenFactory;\r\n bool public isUpgrading;\r\n mapping(bytes32 => bytes32) public transactionDataHashes; // transactionHash => transactionDataHash\r\n\r\n event AllowTokensChanged(address _newAllowTokens);\r\n event FederationChanged(address _newFederation);\r\n event SideTokenFactoryChanged(address _newSideNFTTokenFactory);\r\n event Upgrading(bool _isUpgrading);\r\n\r\n function initialize(\r\n address _manager,\r\n address payable _federation,\r\n address _allowTokens,\r\n address _sideTokenFactory,\r\n string memory _symbolPrefix\r\n ) public initializer {\r\n UpgradableOwnable.initialize(_manager);\r\n UpgradablePausable.__Pausable_init(_manager);\r\n symbolPrefix = _symbolPrefix;\r\n allowTokens = IAllowTokens(_allowTokens);\r\n sideTokenFactory = ISideNFTTokenFactory(_sideTokenFactory);\r\n federation = _federation;\r\n ERC1820.setInterfaceImplementer(\r\n address(this),\r\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b,\r\n address(this)\r\n );\r\n }\r\n\r\n function version() external pure override returns (string memory) {\r\n return \"v1\";\r\n }\r\n\r\n modifier whenNotUpgrading() {\r\n require(!isUpgrading, \"Bridge: Upgrading\");\r\n _;\r\n }\r\n\r\n function acceptTransfer(\r\n address _tokenAddress,\r\n address payable _from,\r\n address payable _to,\r\n uint256 _tokenId,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n ) external whenNotPaused nonReentrant override {\r\n require(_msgSender() == federation, \"NFTBridge: Not Federation\");\r\n require(\r\n isAddressFromCrossedOriginalToken[_tokenAddress] ||\r\n sideTokenAddressByOriginalTokenAddress[_tokenAddress] != NULL_ADDRESS,\r\n \"NFTBridge: Unknown token\"\r\n );\r\n require(_to != NULL_ADDRESS, \"NFTBridge: Null To\");\r\n require(_from != NULL_ADDRESS, \"NFTBridge: Null From\");\r\n require(_blockHash != NULL_HASH, \"NFTBridge: Null BlockHash\");\r\n require(_transactionHash != NULL_HASH, \"NFTBridge: Null TxHash\");\r\n require(\r\n transactionDataHashes[_transactionHash] == bytes32(0),\r\n \"NFTBridge: Already accepted\"\r\n );\r\n\r\n bytes32 _transactionDataHash = getTransactionDataHash(\r\n _to,\r\n _from,\r\n _tokenId,\r\n _tokenAddress,\r\n _blockHash,\r\n _transactionHash,\r\n _logIndex\r\n );\r\n // Do not remove, claimed will also have transactions previously processed using older bridge versions\r\n require(!claimed[_transactionDataHash], \"NFTBridge: Already claimed\");\r\n\r\n transactionDataHashes[_transactionHash] = _transactionDataHash;\r\n// tokenAddressByTransactionHash[_transactionHash] = _tokenAddress;\r\n// senderAddresses[_transactionHash] = _from;\r\n\r\n emit AcceptedNFTCrossTransfer(\r\n _transactionHash,\r\n _tokenAddress,\r\n _to,\r\n _from,\r\n _tokenId,\r\n _blockHash,\r\n _logIndex\r\n );\r\n }\r\n\r\n function createSideNFTToken(\r\n address _originalTokenAddress,\r\n string calldata _originalTokenSymbol,\r\n string calldata _originalTokenName,\r\n string calldata _baseURI,\r\n string calldata _contractURI\r\n ) external onlyOwner {\r\n require(_originalTokenAddress != NULL_ADDRESS, \"NFTBridge: Null original token address\");\r\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[_originalTokenAddress];\r\n require(sideTokenAddress == NULL_ADDRESS, \"NFTBridge: Side token already exists\");\r\n string memory sideTokenSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\r\n\r\n // Create side token\r\n sideTokenAddress = sideTokenFactory.createSideNFTToken(_originalTokenName, sideTokenSymbol, _baseURI, _contractURI);\r\n\r\n sideTokenAddressByOriginalTokenAddress[_originalTokenAddress] = sideTokenAddress;\r\n originalTokenAddressBySideTokenAddress[sideTokenAddress] = _originalTokenAddress;\r\n emit NewSideNFTToken(sideTokenAddress, _originalTokenAddress, sideTokenSymbol);\r\n }\r\n\r\n function claim(NFTClaimData calldata _claimData) external override {\r\n _claim(_claimData, _claimData.to);\r\n }\r\n\r\n function claimFallback(NFTClaimData calldata _claimData) external override {\r\n require(_msgSender() == _claimData.from, \"NFTBridge: invalid sender\");\r\n _claim(_claimData, _msgSender());\r\n }\r\n\r\n function _claim(\r\n NFTClaimData calldata _claimData,\r\n address payable _receiver\r\n ) internal {\r\n address tokenAddress = _claimData.tokenAddress;\r\n uint256 tokenId = _claimData.tokenId;\r\n\r\n bytes32 transactionDataHash = getTransactionDataHash(\r\n _claimData.to,\r\n _claimData.from,\r\n tokenId,\r\n tokenAddress,\r\n _claimData.blockHash,\r\n _claimData.transactionHash,\r\n _claimData.logIndex\r\n );\r\n require(\r\n transactionDataHashes[_claimData.transactionHash] == transactionDataHash,\r\n \"NFTBridge: Wrong txDataHash\"\r\n );\r\n require(!claimed[transactionDataHash], \"NFTBridge: Already claimed\");\r\n\r\n claimed[transactionDataHash] = true;\r\n bool isClaimBeingRequestedInMainChain = isAddressFromCrossedOriginalToken[tokenAddress];\r\n if (isClaimBeingRequestedInMainChain) {\r\n IERC721(tokenAddress).safeTransferFrom(address(this), _receiver, tokenId);\r\n } else {\r\n address sideTokenAddress = sideTokenAddressByOriginalTokenAddress[tokenAddress];\r\n ISideNFTToken(sideTokenAddress).mint(_receiver, tokenId);\r\n }\r\n\r\n emit ClaimedNFTToken(\r\n _claimData.transactionHash,\r\n tokenAddress,\r\n _claimData.to,\r\n _claimData.from,\r\n _claimData.tokenId,\r\n _claimData.blockHash,\r\n _claimData.logIndex,\r\n _receiver\r\n );\r\n }\r\n\r\n function getTokenCreator(address tokenAddress, uint256 tokenId) public view returns (address) {\r\n (bool success, bytes memory data) = tokenAddress.staticcall(abi.encodeWithSignature(\"creator()\"));\r\n if (success) {\r\n return abi.decode(data, (address));\r\n }\r\n\r\n return IERC721(tokenAddress).ownerOf(tokenId);\r\n }\r\n\r\n /**\r\n * ERC-20 tokens approve and transferFrom pattern\r\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\r\n */\r\n function receiveTokensTo(\r\n address tokenAddress,\r\n address to,\r\n uint256 tokenId\r\n ) public payable override {\r\n address tokenCreator = getTokenCreator(tokenAddress, tokenId);\r\n\r\n address payable sender = _msgSender();\r\n // Transfer the tokens on IERC721, they should be already Approved for the bridge Address to use them\r\n IERC721(tokenAddress).transferFrom(sender, address(this), tokenId);\r\n\r\n crossTokens(tokenAddress, to, tokenCreator, \"\", tokenId);\r\n\r\n if (fixedFee > 0) {\r\n require(msg.value >= fixedFee, \"NFTBridge: value is smaller than fixed fee\");\r\n\r\n // Send the payment to the MultiSig of the Federation\r\n federation.transfer(fixedFee);\r\n if (msg.value > fixedFee) { // refund of unused value\r\n sender.transfer(msg.value.sub(fixedFee));\r\n }\r\n }\r\n }\r\n\r\n function crossTokens(\r\n address tokenAddress,\r\n address to,\r\n address tokenCreator,\r\n bytes memory userData,\r\n uint256 tokenId\r\n ) internal whenNotUpgrading whenNotPaused nonReentrant {\r\n isAddressFromCrossedOriginalToken[tokenAddress] = true;\r\n\r\n IERC721Enumerable enumerable = IERC721Enumerable(tokenAddress);\r\n IERC721Metadata metadataIERC = IERC721Metadata(tokenAddress);\r\n string memory tokenURI = metadataIERC.tokenURI(tokenId);\r\n\r\n address originalTokenAddress = tokenAddress;\r\n if (originalTokenAddressBySideTokenAddress[tokenAddress] != NULL_ADDRESS) {\r\n originalTokenAddress = originalTokenAddressBySideTokenAddress[tokenAddress];\r\n ERC721Burnable(tokenAddress).burn(tokenId);\r\n }\r\n\r\n emit Cross(\r\n originalTokenAddress,\r\n _msgSender(),\r\n to,\r\n tokenCreator,\r\n userData,\r\n enumerable.totalSupply(),\r\n tokenId,\r\n tokenURI\r\n );\r\n }\r\n\r\n function getTransactionDataHash(\r\n address _to,\r\n address _from,\r\n uint256 _tokenId,\r\n address _tokenAddress,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n ) public pure override returns (bytes32) {\r\n return keccak256(\r\n abi.encodePacked(\r\n _blockHash,\r\n _transactionHash,\r\n _to,\r\n _from,\r\n _tokenId,\r\n _tokenAddress,\r\n _logIndex\r\n )\r\n );\r\n }\r\n\r\n function setFixedFee(uint256 amount) external onlyOwner {\r\n fixedFee = amount;\r\n emit FixedFeeNFTChanged(fixedFee);\r\n }\r\n\r\n function getFixedFee() external view override returns (uint256) {\r\n return fixedFee;\r\n }\r\n\r\n function changeFederation(address payable newFederation) external onlyOwner {\r\n require(newFederation != NULL_ADDRESS, \"NFTBridge: Federation is empty\");\r\n federation = newFederation;\r\n emit FederationChanged(federation);\r\n }\r\n\r\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\r\n require(newAllowTokens != NULL_ADDRESS, \"NFTBridge: AllowTokens is empty\");\r\n allowTokens = IAllowTokens(newAllowTokens);\r\n emit AllowTokensChanged(newAllowTokens);\r\n }\r\n\r\n function getFederation() external view returns (address) {\r\n return federation;\r\n }\r\n\r\n function changeSideTokenFactory(address newSideNFTTokenFactory) external onlyOwner {\r\n require(\r\n newSideNFTTokenFactory != NULL_ADDRESS,\r\n \"NFTBridge: empty SideTokenFactory\"\r\n );\r\n sideTokenFactory = ISideNFTTokenFactory(newSideNFTTokenFactory);\r\n emit SideTokenFactoryChanged(newSideNFTTokenFactory);\r\n }\r\n\r\n function setUpgrading(bool _isUpgrading) external onlyOwner {\r\n isUpgrading = _isUpgrading;\r\n emit Upgrading(isUpgrading);\r\n }\r\n\r\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\r\n return transactionDataHashes[transactionHash] != bytes32(0);\r\n }\r\n\r\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\r\n return claimed[transactionDataHashes[transactionHash]];\r\n }\r\n\r\n /**\r\n * Always returns `IERC721Receiver.onERC721Received.selector`.\r\n */\r\n function onERC721Received(\r\n address,\r\n address,\r\n uint256,\r\n bytes memory\r\n ) public virtual override returns (bytes4) {\r\n return this.onERC721Received.selector;\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../Initializable.sol\";\r\n\r\n/**\r\n * @title Helps contracts guard against reentrancy attacks.\r\n * @author Remco Bloemen , Eenae \r\n * @dev If you mark a function `nonReentrant`, you should also\r\n * mark it `external`.\r\n */\r\ncontract ReentrancyGuard is Initializable {\r\n /// @dev counter to allow mutex lock with only one SSTORE operation\r\n uint256 private _guardCounter;\r\n\r\n function initialize() public initializer {\r\n // The counter starts at one to prevent changing it from zero to a non-zero\r\n // value, which is a more expensive operation.\r\n _guardCounter = 1;\r\n }\r\n\r\n /**\r\n * @dev Prevents a contract from calling itself, directly or indirectly.\r\n * Calling a `nonReentrant` function from another `nonReentrant`\r\n * function is not supported. It is possible to prevent this from happening\r\n * by making the `nonReentrant` function external, and make it call a\r\n * `private` function that does the actual work.\r\n */\r\n modifier nonReentrant() {\r\n _guardCounter += 1;\r\n uint256 localCounter = _guardCounter;\r\n _;\r\n require(localCounter == _guardCounter, \"ReentrancyGuard: no reentrant allowed\");\r\n }\r\n}"
+ },
+ "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../Initializable.sol\";\r\n\r\nimport \"../../GSN/Context.sol\";\r\nimport \"../access/roles/UpgradablePauserRole.sol\";\r\n\r\n/**\r\n * @dev Contract module which allows children to implement an emergency stop\r\n * mechanism that can be triggered by an authorized account.\r\n *\r\n * This module is used through inheritance. It will make available the\r\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\r\n * the functions of your contract. Note that they will not be pausable by\r\n * simply including this module, only once the modifiers are put in place.\r\n */\r\ncontract UpgradablePausable is Initializable, Context, UpgradablePauserRole {\r\n /**\r\n * @dev Emitted when the pause is triggered by a pauser (`account`).\r\n */\r\n event Paused(address account);\r\n\r\n /**\r\n * @dev Emitted when the pause is lifted by a pauser (`account`).\r\n */\r\n event Unpaused(address account);\r\n\r\n bool private _paused;\r\n\r\n /**\r\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\r\n * to the deployer.\r\n */\r\n function __Pausable_init(address sender) public initializer {\r\n UpgradablePauserRole.__PauserRol_init(sender);\r\n\r\n _paused = false;\r\n }\r\n\r\n /**\r\n * @dev Returns true if the contract is paused, and false otherwise.\r\n */\r\n function paused() public view returns (bool) {\r\n return _paused;\r\n }\r\n\r\n /**\r\n * @dev Modifier to make a function callable only when the contract is not paused.\r\n */\r\n modifier whenNotPaused() {\r\n require(!_paused, \"Pausable: paused\");\r\n _;\r\n }\r\n\r\n /**\r\n * @dev Modifier to make a function callable only when the contract is paused.\r\n */\r\n modifier whenPaused() {\r\n require(_paused, \"Pausable: not paused\");\r\n _;\r\n }\r\n\r\n /**\r\n * @dev Called by a pauser to pause, triggers stopped state.\r\n */\r\n function pause() public onlyPauser whenNotPaused {\r\n _paused = true;\r\n emit Paused(_msgSender());\r\n }\r\n\r\n /**\r\n * @dev Called by a pauser to unpause, returns to normal state.\r\n */\r\n function unpause() public onlyPauser whenPaused {\r\n _paused = false;\r\n emit Unpaused(_msgSender());\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/introspection/IERC1820Registry.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev Interface of the global ERC1820 Registry, as defined in the\r\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\r\n * implementers for interfaces in this registry, as well as query support.\r\n *\r\n * Implementers may be shared by multiple accounts, and can also implement more\r\n * than a single interface for each account. Contracts can implement interfaces\r\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\r\n * contract.\r\n *\r\n * {IERC165} interfaces can also be queried via the registry.\r\n *\r\n * For an in-depth explanation and source code analysis, see the EIP text.\r\n */\r\ninterface IERC1820Registry {\r\n /**\r\n * @dev Sets `newManager` as the manager for `account`. A manager of an\r\n * account is able to set interface implementers for it.\r\n *\r\n * By default, each account is its own manager. Passing a value of `0x0` in\r\n * `newManager` will reset the manager to this initial state.\r\n *\r\n * Emits a {ManagerChanged} event.\r\n *\r\n * Requirements:\r\n *\r\n * - the caller must be the current manager for `account`.\r\n */\r\n function setManager(address account, address newManager) external;\r\n\r\n /**\r\n * @dev Returns the manager for `account`.\r\n *\r\n * See {setManager}.\r\n */\r\n function getManager(address account) external view returns (address);\r\n\r\n /**\r\n * @dev Sets the `implementer` contract as `account`'s implementer for\r\n * `interfaceHash`.\r\n *\r\n * `account` being the zero address is an alias for the caller's address.\r\n * The zero address can also be used in `implementer` to remove an old one.\r\n *\r\n * See {interfaceHash} to learn how these are created.\r\n *\r\n * Emits an {InterfaceImplementerSet} event.\r\n *\r\n * Requirements:\r\n *\r\n * - the caller must be the current manager for `_account`.\r\n * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not\r\n * end in 28 zeroes).\r\n * - `_implementer` must implement {IERC1820Implementer} and return true when\r\n * queried for support, unless `implementer` is the caller. See\r\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\r\n */\r\n function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;\r\n\r\n /**\r\n * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such\r\n * implementer is registered, returns the zero address.\r\n *\r\n * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\r\n * zeroes), `_account` will be queried for support of it.\r\n *\r\n * `account` being the zero address is an alias for the caller's address.\r\n */\r\n function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);\r\n\r\n /**\r\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\r\n * corresponding\r\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\r\n */\r\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\r\n\r\n /**\r\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\r\n * @param account Address of the contract for which to update the cache.\r\n * @param interfaceId ERC165 interface for which to update the cache.\r\n */\r\n function updateERC165Cache(address account, bytes4 interfaceId) external;\r\n\r\n /**\r\n * @notice Checks whether a contract implements an ERC165 interface or not.\r\n * If the result is not cached a direct lookup on the contract address is performed.\r\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\r\n * {updateERC165Cache} with the contract address.\r\n * @param account Address of the contract to check.\r\n * @param interfaceId ERC165 interface to check.\r\n * @return True if `account` implements `interfaceId`, false otherwise.\r\n */\r\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\r\n\r\n /**\r\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\r\n * @param account Address of the contract to check.\r\n * @param interfaceId ERC165 interface to check.\r\n * @return True if `account` implements `interfaceId`, false otherwise.\r\n */\r\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\r\n\r\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\r\n\r\n event ManagerChanged(address indexed account, address indexed newManager);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\r\n * the optional functions; to access them see {ERC20Detailed}.\r\n */\r\ninterface IERC20 {\r\n /**\r\n * @dev Returns the amount of tokens in existence.\r\n */\r\n function totalSupply() external view returns (uint256);\r\n\r\n /**\r\n * @dev Returns the amount of tokens owned by `account`.\r\n */\r\n function balanceOf(address account) external view returns (uint256);\r\n\r\n /**\r\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\r\n *\r\n * Returns a boolean value indicating whether the operation succeeded.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function transfer(address recipient, uint256 amount) external returns (bool);\r\n\r\n /**\r\n * @dev Returns the remaining number of tokens that `spender` will be\r\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\r\n * zero by default.\r\n *\r\n * This value changes when {approve} or {transferFrom} are called.\r\n */\r\n function allowance(address owner, address spender) external view returns (uint256);\r\n\r\n /**\r\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\r\n *\r\n * Returns a boolean value indicating whether the operation succeeded.\r\n *\r\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\r\n * that someone may use both the old and the new allowance by unfortunate\r\n * transaction ordering. One possible solution to mitigate this race\r\n * condition is to first reduce the spender's allowance to 0 and set the\r\n * desired value afterwards:\r\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\r\n *\r\n * Emits an {Approval} event.\r\n */\r\n function approve(address spender, uint256 amount) external returns (bool);\r\n\r\n /**\r\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\r\n * allowance mechanism. `amount` is then deducted from the caller's\r\n * allowance.\r\n *\r\n * Returns a boolean value indicating whether the operation succeeded.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\r\n\r\n /**\r\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\r\n * another (`to`).\r\n *\r\n * Note that `value` may be zero.\r\n */\r\n event Transfer(address indexed from, address indexed to, uint256 value);\r\n\r\n /**\r\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\r\n * a call to {approve}. `value` is the new allowance.\r\n */\r\n event Approval(address indexed owner, address indexed spender, uint256 value);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC20/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"./IERC20.sol\";\r\nimport \"../../math/SafeMath.sol\";\r\nimport \"../../utils/Address.sol\";\r\n\r\n/**\r\n * @title SafeERC20\r\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\r\n * contract returns false). Tokens that return no value (and instead revert or\r\n * throw on failure) are also supported, non-reverting calls are assumed to be\r\n * successful.\r\n * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,\r\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\r\n */\r\nlibrary SafeERC20 {\r\n using SafeMath for uint256;\r\n using Address for address;\r\n\r\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\r\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\r\n }\r\n\r\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\r\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\r\n }\r\n\r\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\r\n // safeApprove should only be called when setting an initial allowance,\r\n // or when resetting it to zero. To increase and decrease it, use\r\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\r\n // solhint-disable-next-line max-line-length\r\n require((value == 0) || (token.allowance(address(this), spender) == 0),\r\n \"SafeERC20: approve non-zero to non-zero allowance\"\r\n );\r\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\r\n }\r\n\r\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\r\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\r\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\r\n }\r\n\r\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\r\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\r\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\r\n }\r\n\r\n /**\r\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\r\n * on the return value: the return value is optional (but if data is returned, it must not be false).\r\n * @param token The token targeted by the call.\r\n * @param data The call data (encoded using abi.encode or one of its variants).\r\n */\r\n function callOptionalReturn(IERC20 token, bytes memory data) private {\r\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\r\n // we're implementing it ourselves.\r\n\r\n // A Solidity high level call has three parts:\r\n // 1. The target address is checked to verify it contains contract code\r\n // 2. The call itself is made, and success asserted\r\n // 3. The return value is decoded, which in turn checks the size of the returned data.\r\n // solhint-disable-next-line max-line-length\r\n require(address(token).isContract(), \"SafeERC20: call to non-contract\");\r\n\r\n // solhint-disable-next-line avoid-low-level-calls\r\n (bool success, bytes memory returndata) = address(token).call(data);\r\n require(success, \"SafeERC20: low-level call failed\");\r\n\r\n if (returndata.length > 0) { // Return data is optional\r\n // solhint-disable-next-line max-line-length\r\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\r\n }\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../../introspection/IERC165.sol\";\r\n\r\n/**\r\n * @dev Required interface of an ERC721 compliant contract.\r\n */\r\ninterface IERC721 is IERC165 {\r\n /**\r\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\r\n */\r\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\r\n\r\n /**\r\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\r\n */\r\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\r\n\r\n /**\r\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\r\n */\r\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\r\n\r\n /**\r\n * @dev Returns the number of tokens in ``owner``'s account.\r\n */\r\n function balanceOf(address owner) external view returns (uint256 balance);\r\n\r\n /**\r\n * @dev Returns the owner of the `tokenId` token.\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must exist.\r\n */\r\n function ownerOf(uint256 tokenId) external view returns (address owner);\r\n\r\n /**\r\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\r\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must exist and be owned by `from`.\r\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\r\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\r\n\r\n /**\r\n * @dev Transfers `tokenId` token from `from` to `to`.\r\n *\r\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must be owned by `from`.\r\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function transferFrom(address from, address to, uint256 tokenId) external;\r\n\r\n /**\r\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\r\n * The approval is cleared when the token is transferred.\r\n *\r\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\r\n *\r\n * Requirements:\r\n *\r\n * - The caller must own the token or be an approved operator.\r\n * - `tokenId` must exist.\r\n *\r\n * Emits an {Approval} event.\r\n */\r\n function approve(address to, uint256 tokenId) external;\r\n\r\n /**\r\n * @dev Returns the account approved for `tokenId` token.\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must exist.\r\n */\r\n function getApproved(uint256 tokenId) external view returns (address operator);\r\n\r\n /**\r\n * @dev Approve or remove `operator` as an operator for the caller.\r\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\r\n *\r\n * Requirements:\r\n *\r\n * - The `operator` cannot be the caller.\r\n *\r\n * Emits an {ApprovalForAll} event.\r\n */\r\n function setApprovalForAll(address operator, bool _approved) external;\r\n\r\n /**\r\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\r\n *\r\n * See {setApprovalForAll}\r\n */\r\n function isApprovedForAll(address owner, address operator) external view returns (bool);\r\n\r\n /**\r\n * @dev Safely transfers `tokenId` token from `from` to `to`.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must exist and be owned by `from`.\r\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\r\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./IERC721.sol\";\r\n\r\n/**\r\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\r\n * @dev See https://eips.ethereum.org/EIPS/eip-721\r\n */\r\ninterface IERC721Metadata is IERC721 {\r\n\r\n /**\r\n * @dev Returns the token collection name.\r\n */\r\n function name() external view returns (string memory);\r\n\r\n /**\r\n * @dev Returns the token collection symbol.\r\n */\r\n function symbol() external view returns (string memory);\r\n\r\n /**\r\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\r\n */\r\n function tokenURI(uint256 tokenId) external view returns (string memory);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Enumerable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./IERC721.sol\";\r\n\r\n/**\r\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\r\n * @dev See https://eips.ethereum.org/EIPS/eip-721\r\n */\r\ninterface IERC721Enumerable is IERC721 {\r\n\r\n /**\r\n * @dev Returns the total amount of tokens stored by the contract.\r\n */\r\n function totalSupply() external view returns (uint256);\r\n\r\n /**\r\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\r\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\r\n */\r\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\r\n\r\n /**\r\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\r\n * Use along with {totalSupply} to enumerate all tokens.\r\n */\r\n function tokenByIndex(uint256 index) external view returns (uint256);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\n/**\r\n * @title ERC721 token receiver interface\r\n * @dev Interface for any contract that wants to support safeTransfers\r\n * from ERC721 asset contracts.\r\n */\r\ninterface IERC721Receiver {\r\n /**\r\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\r\n * by `operator` from `from`, this function is called.\r\n *\r\n * It must return its Solidity selector to confirm the token transfer.\r\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\r\n *\r\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\r\n */\r\n function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../../GSN/Context.sol\";\r\nimport \"./ERC721.sol\";\r\n\r\n/**\r\n * @title ERC721 Burnable Token\r\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\r\n */\r\nabstract contract ERC721Burnable is Context, ERC721 {\r\n /**\r\n * @dev Burns `tokenId`. See {ERC721-_burn}.\r\n *\r\n * Requirements:\r\n *\r\n * - The caller must own `tokenId` or be an approved operator.\r\n */\r\n function burn(uint256 tokenId) public virtual {\r\n //solhint-disable-next-line max-line-length\r\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\r\n _burn(tokenId);\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev Collection of functions related to the address type\r\n */\r\nlibrary Address {\r\n /**\r\n * @dev Returns true if `account` is a contract.\r\n *\r\n * [IMPORTANT]\r\n * ====\r\n * It is unsafe to assume that an address for which this function returns\r\n * false is an externally-owned account (EOA) and not a contract.\r\n *\r\n * Among others, `isContract` will return false for the following\r\n * types of addresses:\r\n *\r\n * - an externally-owned account\r\n * - a contract in construction\r\n * - an address where a contract will be created\r\n * - an address where a contract lived, but was destroyed\r\n * ====\r\n */\r\n function isContract(address account) internal view returns (bool) {\r\n // This method relies on extcodesize, which returns 0 for contracts in\r\n // construction, since the code is only stored at the end of the\r\n // constructor execution.\r\n\r\n uint256 size;\r\n // solhint-disable-next-line no-inline-assembly\r\n assembly { size := extcodesize(account) }\r\n return size > 0;\r\n }\r\n\r\n /**\r\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\r\n * `recipient`, forwarding all available gas and reverting on errors.\r\n *\r\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\r\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\r\n * imposed by `transfer`, making them unable to receive funds via\r\n * `transfer`. {sendValue} removes this limitation.\r\n *\r\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\r\n *\r\n * IMPORTANT: because control is transferred to `recipient`, care must be\r\n * taken to not create reentrancy vulnerabilities. Consider using\r\n * {ReentrancyGuard} or the\r\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\r\n */\r\n function sendValue(address payable recipient, uint256 amount) internal {\r\n require(address(this).balance >= amount, \"Address: insufficient balance\");\r\n\r\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\r\n (bool success, ) = recipient.call{ value: amount }(\"\");\r\n require(success, \"Address: unable to send value, recipient may have reverted\");\r\n }\r\n\r\n /**\r\n * @dev Performs a Solidity function call using a low level `call`. A\r\n * plain`call` is an unsafe replacement for a function call: use this\r\n * function instead.\r\n *\r\n * If `target` reverts with a revert reason, it is bubbled up by this\r\n * function (like regular Solidity function calls).\r\n *\r\n * Returns the raw returned data. To convert to the expected return value,\r\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\r\n *\r\n * Requirements:\r\n *\r\n * - `target` must be a contract.\r\n * - calling `target` with `data` must not revert.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\r\n return functionCall(target, data, \"Address: low-level call failed\");\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\r\n * `errorMessage` as a fallback revert reason when `target` reverts.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\r\n return functionCallWithValue(target, data, 0, errorMessage);\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\r\n * but also transferring `value` wei to `target`.\r\n *\r\n * Requirements:\r\n *\r\n * - the calling contract must have an ETH balance of at least `value`.\r\n * - the called Solidity function must be `payable`.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\r\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\r\n * with `errorMessage` as a fallback revert reason when `target` reverts.\r\n *\r\n * _Available since v3.1._\r\n */\r\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\r\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\r\n require(isContract(target), \"Address: call to non-contract\");\r\n\r\n // solhint-disable-next-line avoid-low-level-calls\r\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\r\n return _verifyCallResult(success, returndata, errorMessage);\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\r\n * but performing a static call.\r\n *\r\n * _Available since v3.3._\r\n */\r\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\r\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\r\n * but performing a static call.\r\n *\r\n * _Available since v3.3._\r\n */\r\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\r\n require(isContract(target), \"Address: static call to non-contract\");\r\n\r\n // solhint-disable-next-line avoid-low-level-calls\r\n (bool success, bytes memory returndata) = target.staticcall(data);\r\n return _verifyCallResult(success, returndata, errorMessage);\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\r\n * but performing a delegate call.\r\n *\r\n * _Available since v3.4._\r\n */\r\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\r\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\r\n * but performing a delegate call.\r\n *\r\n * _Available since v3.4._\r\n */\r\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\r\n require(isContract(target), \"Address: delegate call to non-contract\");\r\n\r\n // solhint-disable-next-line avoid-low-level-calls\r\n (bool success, bytes memory returndata) = target.delegatecall(data);\r\n return _verifyCallResult(success, returndata, errorMessage);\r\n }\r\n\r\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\r\n if (success) {\r\n return returndata;\r\n } else {\r\n // Look for revert reason and bubble it up if present\r\n if (returndata.length > 0) {\r\n // The easiest way to bubble the revert reason is using memory via assembly\r\n\r\n // solhint-disable-next-line no-inline-assembly\r\n assembly {\r\n let returndata_size := mload(returndata)\r\n revert(add(32, returndata), returndata_size)\r\n }\r\n } else {\r\n revert(errorMessage);\r\n }\r\n }\r\n }\r\n}\r\n"
+ },
+ "contracts/lib/LibEIP712.sol": {
+ "content": "//SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol\r\nlibrary LibEIP712 {\r\n\r\n // Hash of the EIP712 Domain Separator Schema\r\n // keccak256(abi.encodePacked(\r\n // \"EIP712Domain(\",\r\n // \"string name,\",\r\n // \"string version,\",\r\n // \"uint256 chainId,\",\r\n // \"address verifyingContract\",\r\n // \")\"\r\n // ))\r\n bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\r\n\r\n /// @dev Calculates a EIP712 domain separator.\r\n /// @param name The EIP712 domain name.\r\n /// @param version The EIP712 domain version.\r\n /// @param verifyingContract The EIP712 verifying contract.\r\n /// @return result EIP712 domain separator.\r\n function hashEIP712Domain(\r\n string memory name,\r\n string memory version,\r\n uint256 chainId,\r\n address verifyingContract\r\n )\r\n internal\r\n pure\r\n returns (bytes32 result)\r\n {\r\n bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\r\n\r\n // Assembly for more efficient computing:\r\n // keccak256(abi.encodePacked(\r\n // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\r\n // keccak256(bytes(name)),\r\n // keccak256(bytes(version)),\r\n // chainId,\r\n // uint256(verifyingContract)\r\n // ))\r\n\r\n // solium-disable-next-line security/no-inline-assembly\r\n assembly {\r\n // Calculate hashes of dynamic data\r\n let nameHash := keccak256(add(name, 32), mload(name))\r\n let versionHash := keccak256(add(version, 32), mload(version))\r\n\r\n // Load free memory pointer\r\n let memPtr := mload(64)\r\n\r\n // Store params in memory\r\n mstore(memPtr, schemaHash)\r\n mstore(add(memPtr, 32), nameHash)\r\n mstore(add(memPtr, 64), versionHash)\r\n mstore(add(memPtr, 96), chainId)\r\n mstore(add(memPtr, 128), verifyingContract)\r\n\r\n // Compute hash\r\n result := keccak256(memPtr, 160)\r\n }\r\n return result;\r\n }\r\n\r\n /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\r\n /// @param eip712DomainHash Hash of the domain domain separator data, computed\r\n /// with getDomainHash().\r\n /// @param hashStruct The EIP712 hash struct.\r\n /// @return result EIP712 hash applied to the given EIP712 Domain.\r\n function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\r\n internal\r\n pure\r\n returns (bytes32 result)\r\n {\r\n // Assembly for more efficient computing:\r\n // keccak256(abi.encodePacked(\r\n // EIP191_HEADER,\r\n // EIP712_DOMAIN_HASH,\r\n // hashStruct\r\n // ));\r\n\r\n // solium-disable-next-line security/no-inline-assembly\r\n assembly {\r\n // Load free memory pointer\r\n let memPtr := mload(64)\r\n\r\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\r\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\r\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\r\n\r\n // Compute hash\r\n result := keccak256(memPtr, 66)\r\n }\r\n return result;\r\n }\r\n}"
+ },
+ "contracts/lib/LibUtils.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nlibrary LibUtils {\r\n\r\n function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {\r\n require(decimals <= 18, \"LibUtils: Decimals not <= 18\");\r\n return uint256(10)**(18-decimals);\r\n }\r\n\r\n function getDecimals(address tokenToUse) internal view returns (uint8) {\r\n //support decimals as uint256 or uint8\r\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\r\n require(success, \"LibUtils: No decimals\");\r\n // uint: enc(X) is the big-endian encoding of X,\r\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\r\n return uint8(abi.decode(data, (uint256)));\r\n }\r\n\r\n function getGranularity(address tokenToUse) internal view returns (uint256) {\r\n //support granularity if ERC777\r\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"granularity()\"));\r\n require(success, \"LibUtils: No granularity\");\r\n\r\n return abi.decode(data, (uint256));\r\n }\r\n\r\n function bytesToAddress(bytes memory bys) internal pure returns (address addr) {\r\n // solium-disable-next-line security/no-inline-assembly\r\n assembly {\r\n addr := mload(add(bys,20))\r\n }\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/nftbridge/INFTBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\ninterface INFTBridge {\r\n struct NFTClaimData {\r\n address payable to;\r\n address from;\r\n uint256 tokenId;\r\n address tokenAddress;\r\n bytes32 blockHash;\r\n bytes32 transactionHash;\r\n uint32 logIndex;\r\n }\r\n\r\n function version() external pure returns (string memory);\r\n\r\n function getFixedFee() external view returns (uint256);\r\n\r\n function receiveTokensTo(\r\n address tokenAddress,\r\n address to,\r\n uint256 tokenId\r\n ) external payable;\r\n\r\n /**\r\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\r\n */\r\n function acceptTransfer(\r\n address _originalTokenAddress,\r\n address payable _from,\r\n address payable _to,\r\n uint256 _tokenId,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n ) external;\r\n\r\n /**\r\n * Claims the crossed transaction using the hash, this sends the token to the address specified in the claim data\r\n */\r\n function claim(NFTClaimData calldata _claimData) external;\r\n\r\n function claimFallback(NFTClaimData calldata _claimData) external;\r\n\r\n function getTransactionDataHash(\r\n address _to,\r\n address _from,\r\n uint256 _tokenId,\r\n address _tokenAddress,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n ) external returns (bytes32);\r\n\r\n event Cross(\r\n address indexed _originalTokenAddress,\r\n address indexed _from,\r\n address indexed _to,\r\n address _tokenCreator,\r\n bytes _userData,\r\n uint256 _totalSupply,\r\n uint256 _tokenId,\r\n string _tokenURI\r\n );\r\n event NewSideNFTToken(\r\n address indexed _newSideNFTTokenAddress,\r\n address indexed _originalTokenAddress,\r\n string _newSymbol\r\n );\r\n event AcceptedNFTCrossTransfer(\r\n bytes32 indexed _transactionHash,\r\n address indexed _originalTokenAddress,\r\n address indexed _to,\r\n address _from,\r\n uint256 _tokenId,\r\n bytes32 _blockHash,\r\n uint256 _logIndex\r\n );\r\n event FixedFeeNFTChanged(uint256 _amount);\r\n event ClaimedNFTToken(\r\n bytes32 indexed _transactionHash,\r\n address indexed _originalTokenAddress,\r\n address indexed _to,\r\n address _sender,\r\n uint256 _tokenId,\r\n bytes32 _blockHash,\r\n uint256 _logIndex,\r\n address _receiver\r\n );\r\n}\r\n"
+ },
+ "contracts/nftbridge/ISideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\ninterface ISideNFTToken {\r\n function mint(address account, uint256 tokenId) external;\r\n}"
+ },
+ "contracts/nftbridge/ISideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\ninterface ISideNFTTokenFactory {\r\n\r\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\r\n string calldata contractURI) external returns(address);\r\n\r\n event SideNFTTokenCreated(address indexed sideTokenAddress, string symbol, string baseURI, string contractURI);\r\n}"
+ },
+ "contracts/interface/IWrapped.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\ninterface IWrapped {\r\n function balanceOf(address) external returns(uint);\r\n\r\n function deposit() external payable;\r\n\r\n function withdraw(uint wad) external;\r\n\r\n function totalSupply() external view returns (uint);\r\n\r\n function approve(address guy, uint wad) external returns (bool);\r\n\r\n function transfer(address dst, uint wad) external returns (bool);\r\n\r\n function transferFrom(address src, address dst, uint wad)\r\n external\r\n returns (bool);\r\n}"
+ },
+ "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../../Initializable.sol\";\r\n\r\nimport \"../../../GSN/Context.sol\";\r\nimport \"../../../access/Roles.sol\";\r\n\r\ncontract UpgradablePauserRole is Initializable, Context {\r\n using Roles for Roles.Role;\r\n\r\n event PauserAdded(address indexed account);\r\n event PauserRemoved(address indexed account);\r\n\r\n Roles.Role private _pausers;\r\n\r\n function __PauserRol_init(address sender) public initializer {\r\n if (!isPauser(sender)) {\r\n _addPauser(sender);\r\n }\r\n }\r\n\r\n modifier onlyPauser() {\r\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\r\n _;\r\n }\r\n\r\n function isPauser(address account) public view returns (bool) {\r\n return _pausers.has(account);\r\n }\r\n\r\n function addPauser(address account) public onlyPauser {\r\n _addPauser(account);\r\n }\r\n\r\n function renouncePauser() public {\r\n _removePauser(_msgSender());\r\n }\r\n\r\n function _addPauser(address account) internal {\r\n _pausers.add(account);\r\n emit PauserAdded(account);\r\n }\r\n\r\n function _removePauser(address account) internal {\r\n _pausers.remove(account);\r\n emit PauserRemoved(account);\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/access/Roles.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @title Roles\r\n * @dev Library for managing addresses assigned to a Role.\r\n */\r\nlibrary Roles {\r\n struct Role {\r\n mapping (address => bool) bearer;\r\n }\r\n\r\n /**\r\n * @dev Give an account access to this role.\r\n */\r\n function add(Role storage role, address account) internal {\r\n require(!has(role, account), \"Roles: account already has role\");\r\n role.bearer[account] = true;\r\n }\r\n\r\n /**\r\n * @dev Remove an account's access to this role.\r\n */\r\n function remove(Role storage role, address account) internal {\r\n require(has(role, account), \"Roles: account doesn't have role\");\r\n role.bearer[account] = false;\r\n }\r\n\r\n /**\r\n * @dev Check if an account has this role.\r\n * @return bool\r\n */\r\n function has(Role storage role, address account) internal view returns (bool) {\r\n require(account != address(0), \"Roles: account is the zero address\");\r\n return role.bearer[account];\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\n/**\r\n * @dev Interface of the ERC165 standard, as defined in the\r\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\r\n *\r\n * Implementers can declare support of contract interfaces, which can then be\r\n * queried by others ({ERC165Checker}).\r\n *\r\n * For an implementation, see {ERC165}.\r\n */\r\ninterface IERC165 {\r\n /**\r\n * @dev Returns true if this contract implements the interface defined by\r\n * `interfaceId`. See the corresponding\r\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\r\n * to learn more about how these ids are created.\r\n *\r\n * This function call must use less than 30 000 gas.\r\n */\r\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../../GSN/Context.sol\";\r\nimport \"./IERC721.sol\";\r\nimport \"./IERC721Metadata.sol\";\r\nimport \"./IERC721Enumerable.sol\";\r\nimport \"./IERC721Receiver.sol\";\r\nimport \"../../introspection/ERC165.sol\";\r\nimport \"../../math/SafeMath.sol\";\r\nimport \"../../utils/Address.sol\";\r\nimport \"../../utils/EnumerableSet.sol\";\r\nimport \"../../utils/EnumerableMap.sol\";\r\nimport \"../../utils/Strings.sol\";\r\n\r\n/**\r\n * @title ERC721 Non-Fungible Token Standard basic implementation\r\n * @dev see https://eips.ethereum.org/EIPS/eip-721\r\n */\r\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\r\n using SafeMath for uint256;\r\n using Address for address;\r\n using EnumerableSet for EnumerableSet.UintSet;\r\n using EnumerableMap for EnumerableMap.UintToAddressMap;\r\n using Strings for uint256;\r\n\r\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\r\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\r\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\r\n\r\n // Mapping from holder address to their (enumerable) set of owned tokens\r\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\r\n\r\n // Enumerable mapping from token ids to their owners\r\n EnumerableMap.UintToAddressMap private _tokenOwners;\r\n\r\n // Mapping from token ID to approved address\r\n mapping (uint256 => address) private _tokenApprovals;\r\n\r\n // Mapping from owner to operator approvals\r\n mapping (address => mapping (address => bool)) private _operatorApprovals;\r\n\r\n // Token name\r\n string private _name;\r\n\r\n // Token symbol\r\n string private _symbol;\r\n\r\n // Optional mapping for token URIs\r\n mapping (uint256 => string) private _tokenURIs;\r\n\r\n // Base URI\r\n string private _baseURI;\r\n\r\n /*\r\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\r\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\r\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\r\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\r\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\r\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\r\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\r\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\r\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\r\n *\r\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\r\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\r\n */\r\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\r\n\r\n /*\r\n * bytes4(keccak256('name()')) == 0x06fdde03\r\n * bytes4(keccak256('symbol()')) == 0x95d89b41\r\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\r\n *\r\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\r\n */\r\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\r\n\r\n /*\r\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\r\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\r\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\r\n *\r\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\r\n */\r\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\r\n\r\n /**\r\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\r\n */\r\n constructor (string memory name_, string memory symbol_) {\r\n _name = name_;\r\n _symbol = symbol_;\r\n\r\n // register the supported interfaces to conform to ERC721 via ERC165\r\n _registerInterface(_INTERFACE_ID_ERC721);\r\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\r\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-balanceOf}.\r\n */\r\n function balanceOf(address owner) public view virtual override returns (uint256) {\r\n require(owner != address(0), \"ERC721: balance query for the zero address\");\r\n return _holderTokens[owner].length();\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-ownerOf}.\r\n */\r\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\r\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\r\n }\r\n\r\n /**\r\n * @dev See {IERC721Metadata-name}.\r\n */\r\n function name() public view virtual override returns (string memory) {\r\n return _name;\r\n }\r\n\r\n /**\r\n * @dev See {IERC721Metadata-symbol}.\r\n */\r\n function symbol() public view virtual override returns (string memory) {\r\n return _symbol;\r\n }\r\n\r\n /**\r\n * @dev See {IERC721Metadata-tokenURI}.\r\n */\r\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\r\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\r\n\r\n string memory _tokenURI = _tokenURIs[tokenId];\r\n string memory base = baseURI();\r\n\r\n // If there is no base URI, return the token URI.\r\n if (bytes(base).length == 0) {\r\n return _tokenURI;\r\n }\r\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\r\n if (bytes(_tokenURI).length > 0) {\r\n return string(abi.encodePacked(base, _tokenURI));\r\n }\r\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\r\n return string(abi.encodePacked(base, tokenId.toString()));\r\n }\r\n\r\n /**\r\n * @dev Returns the base URI set via {_setBaseURI}. This will be\r\n * automatically added as a prefix in {tokenURI} to each token's URI, or\r\n * to the token ID if no specific URI is set for that token ID.\r\n */\r\n function baseURI() public view virtual returns (string memory) {\r\n return _baseURI;\r\n }\r\n\r\n /**\r\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\r\n */\r\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\r\n return _holderTokens[owner].at(index);\r\n }\r\n\r\n /**\r\n * @dev See {IERC721Enumerable-totalSupply}.\r\n */\r\n function totalSupply() public view virtual override returns (uint256) {\r\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\r\n return _tokenOwners.length();\r\n }\r\n\r\n /**\r\n * @dev See {IERC721Enumerable-tokenByIndex}.\r\n */\r\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\r\n (uint256 tokenId, ) = _tokenOwners.at(index);\r\n return tokenId;\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-approve}.\r\n */\r\n function approve(address to, uint256 tokenId) public virtual override {\r\n address owner = ERC721.ownerOf(tokenId);\r\n require(to != owner, \"ERC721: approval to current owner\");\r\n\r\n require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\r\n \"ERC721: approve caller is not owner nor approved for all\"\r\n );\r\n\r\n _approve(to, tokenId);\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-getApproved}.\r\n */\r\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\r\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\r\n\r\n return _tokenApprovals[tokenId];\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-setApprovalForAll}.\r\n */\r\n function setApprovalForAll(address operator, bool approved) public virtual override {\r\n require(operator != _msgSender(), \"ERC721: approve to caller\");\r\n\r\n _operatorApprovals[_msgSender()][operator] = approved;\r\n emit ApprovalForAll(_msgSender(), operator, approved);\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-isApprovedForAll}.\r\n */\r\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\r\n return _operatorApprovals[owner][operator];\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-transferFrom}.\r\n */\r\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\r\n //solhint-disable-next-line max-line-length\r\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\r\n\r\n _transfer(from, to, tokenId);\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-safeTransferFrom}.\r\n */\r\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\r\n safeTransferFrom(from, to, tokenId, \"\");\r\n }\r\n\r\n /**\r\n * @dev See {IERC721-safeTransferFrom}.\r\n */\r\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\r\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\r\n _safeTransfer(from, to, tokenId, _data);\r\n }\r\n\r\n /**\r\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\r\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\r\n *\r\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\r\n *\r\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\r\n * implement alternative mechanisms to perform token transfer, such as signature-based.\r\n *\r\n * Requirements:\r\n *\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must exist and be owned by `from`.\r\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\r\n _transfer(from, to, tokenId);\r\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\r\n }\r\n\r\n /**\r\n * @dev Returns whether `tokenId` exists.\r\n *\r\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\r\n *\r\n * Tokens start existing when they are minted (`_mint`),\r\n * and stop existing when they are burned (`_burn`).\r\n */\r\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\r\n return _tokenOwners.contains(tokenId);\r\n }\r\n\r\n /**\r\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must exist.\r\n */\r\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\r\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\r\n address owner = ERC721.ownerOf(tokenId);\r\n return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\r\n }\r\n\r\n /**\r\n * @dev Safely mints `tokenId` and transfers it to `to`.\r\n *\r\n * Requirements:\r\n d*\r\n * - `tokenId` must not exist.\r\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function _safeMint(address to, uint256 tokenId) internal virtual {\r\n _safeMint(to, tokenId, \"\");\r\n }\r\n\r\n /**\r\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\r\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\r\n */\r\n function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\r\n _mint(to, tokenId);\r\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\r\n }\r\n\r\n /**\r\n * @dev Mints `tokenId` and transfers it to `to`.\r\n *\r\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must not exist.\r\n * - `to` cannot be the zero address.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function _mint(address to, uint256 tokenId) internal virtual {\r\n require(to != address(0), \"ERC721: mint to the zero address\");\r\n require(!_exists(tokenId), \"ERC721: token already minted\");\r\n\r\n _beforeTokenTransfer(address(0), to, tokenId);\r\n\r\n _holderTokens[to].add(tokenId);\r\n\r\n _tokenOwners.set(tokenId, to);\r\n\r\n emit Transfer(address(0), to, tokenId);\r\n }\r\n\r\n /**\r\n * @dev Destroys `tokenId`.\r\n * The approval is cleared when the token is burned.\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must exist.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function _burn(uint256 tokenId) internal virtual {\r\n address owner = ERC721.ownerOf(tokenId); // internal owner\r\n\r\n _beforeTokenTransfer(owner, address(0), tokenId);\r\n\r\n // Clear approvals\r\n _approve(address(0), tokenId);\r\n\r\n // Clear metadata (if any)\r\n if (bytes(_tokenURIs[tokenId]).length != 0) {\r\n delete _tokenURIs[tokenId];\r\n }\r\n\r\n _holderTokens[owner].remove(tokenId);\r\n\r\n _tokenOwners.remove(tokenId);\r\n\r\n emit Transfer(owner, address(0), tokenId);\r\n }\r\n\r\n /**\r\n * @dev Transfers `tokenId` from `from` to `to`.\r\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\r\n *\r\n * Requirements:\r\n *\r\n * - `to` cannot be the zero address.\r\n * - `tokenId` token must be owned by `from`.\r\n *\r\n * Emits a {Transfer} event.\r\n */\r\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\r\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\r\n require(to != address(0), \"ERC721: transfer to the zero address\");\r\n\r\n _beforeTokenTransfer(from, to, tokenId);\r\n\r\n // Clear approvals from the previous owner\r\n _approve(address(0), tokenId);\r\n\r\n _holderTokens[from].remove(tokenId);\r\n _holderTokens[to].add(tokenId);\r\n\r\n _tokenOwners.set(tokenId, to);\r\n\r\n emit Transfer(from, to, tokenId);\r\n }\r\n\r\n /**\r\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\r\n *\r\n * Requirements:\r\n *\r\n * - `tokenId` must exist.\r\n */\r\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\r\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\r\n _tokenURIs[tokenId] = _tokenURI;\r\n }\r\n\r\n /**\r\n * @dev Internal function to set the base URI for all token IDs. It is\r\n * automatically added as a prefix to the value returned in {tokenURI},\r\n * or to the token ID if {tokenURI} is empty.\r\n */\r\n function _setBaseURI(string memory baseURI_) internal virtual {\r\n _baseURI = baseURI_;\r\n }\r\n\r\n /**\r\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\r\n * The call is not executed if the target address is not a contract.\r\n *\r\n * @param from address representing the previous owner of the given token ID\r\n * @param to target address that will receive the tokens\r\n * @param tokenId uint256 ID of the token to be transferred\r\n * @param _data bytes optional data to send along with the call\r\n * @return bool whether the call correctly returned the expected magic value\r\n */\r\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\r\n private returns (bool)\r\n {\r\n if (!to.isContract()) {\r\n return true;\r\n }\r\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\r\n IERC721Receiver(to).onERC721Received.selector,\r\n _msgSender(),\r\n from,\r\n tokenId,\r\n _data\r\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\r\n bytes4 retval = abi.decode(returndata, (bytes4));\r\n return (retval == _ERC721_RECEIVED);\r\n }\r\n\r\n function _approve(address to, uint256 tokenId) private {\r\n _tokenApprovals[tokenId] = to;\r\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\r\n }\r\n\r\n /**\r\n * @dev Hook that is called before any token transfer. This includes minting\r\n * and burning.\r\n *\r\n * Calling conditions:\r\n *\r\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\r\n * transferred to `to`.\r\n * - When `from` is zero, `tokenId` will be minted for `to`.\r\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\r\n * - `from` cannot be the zero address.\r\n * - `to` cannot be the zero address.\r\n *\r\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\r\n */\r\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\r\n}\r\n"
+ },
+ "contracts/zeppelin/introspection/ERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./IERC165.sol\";\r\n\r\n/**\r\n * @dev Implementation of the {IERC165} interface.\r\n *\r\n * Contracts may inherit from this and call {_registerInterface} to declare\r\n * their support of an interface.\r\n */\r\nabstract contract ERC165 is IERC165 {\r\n /*\r\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\r\n */\r\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\r\n\r\n /**\r\n * @dev Mapping of interface ids to whether or not it's supported.\r\n */\r\n mapping(bytes4 => bool) private _supportedInterfaces;\r\n\r\n constructor () {\r\n // Derived contracts need only register support for their own interfaces,\r\n // we register support for ERC165 itself here\r\n _registerInterface(_INTERFACE_ID_ERC165);\r\n }\r\n\r\n /**\r\n * @dev See {IERC165-supportsInterface}.\r\n *\r\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\r\n */\r\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\r\n return _supportedInterfaces[interfaceId];\r\n }\r\n\r\n /**\r\n * @dev Registers the contract as an implementer of the interface defined by\r\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\r\n * registering its interface id is not required.\r\n *\r\n * See {IERC165-supportsInterface}.\r\n *\r\n * Requirements:\r\n *\r\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\r\n */\r\n function _registerInterface(bytes4 interfaceId) internal virtual {\r\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\r\n _supportedInterfaces[interfaceId] = true;\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/utils/EnumerableSet.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\n/**\r\n * @dev Library for managing\r\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\r\n * types.\r\n *\r\n * Sets have the following properties:\r\n *\r\n * - Elements are added, removed, and checked for existence in constant time\r\n * (O(1)).\r\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\r\n *\r\n * ```\r\n * contract Example {\r\n * // Add the library methods\r\n * using EnumerableSet for EnumerableSet.AddressSet;\r\n *\r\n * // Declare a set state variable\r\n * EnumerableSet.AddressSet private mySet;\r\n * }\r\n * ```\r\n *\r\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\r\n * and `uint256` (`UintSet`) are supported.\r\n */\r\nlibrary EnumerableSet {\r\n // To implement this library for multiple types with as little code\r\n // repetition as possible, we write it in terms of a generic Set type with\r\n // bytes32 values.\r\n // The Set implementation uses private functions, and user-facing\r\n // implementations (such as AddressSet) are just wrappers around the\r\n // underlying Set.\r\n // This means that we can only create new EnumerableSets for types that fit\r\n // in bytes32.\r\n\r\n struct Set {\r\n // Storage of set values\r\n bytes32[] _values;\r\n\r\n // Position of the value in the `values` array, plus 1 because index 0\r\n // means a value is not in the set.\r\n mapping (bytes32 => uint256) _indexes;\r\n }\r\n\r\n /**\r\n * @dev Add a value to a set. O(1).\r\n *\r\n * Returns true if the value was added to the set, that is if it was not\r\n * already present.\r\n */\r\n function _add(Set storage set, bytes32 value) private returns (bool) {\r\n if (!_contains(set, value)) {\r\n set._values.push(value);\r\n // The value is stored at length-1, but we add 1 to all indexes\r\n // and use 0 as a sentinel value\r\n set._indexes[value] = set._values.length;\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * @dev Removes a value from a set. O(1).\r\n *\r\n * Returns true if the value was removed from the set, that is if it was\r\n * present.\r\n */\r\n function _remove(Set storage set, bytes32 value) private returns (bool) {\r\n // We read and store the value's index to prevent multiple reads from the same storage slot\r\n uint256 valueIndex = set._indexes[value];\r\n\r\n if (valueIndex != 0) { // Equivalent to contains(set, value)\r\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\r\n // the array, and then remove the last element (sometimes called as 'swap and pop').\r\n // This modifies the order of the array, as noted in {at}.\r\n\r\n uint256 toDeleteIndex = valueIndex - 1;\r\n uint256 lastIndex = set._values.length - 1;\r\n\r\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\r\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\r\n\r\n bytes32 lastvalue = set._values[lastIndex];\r\n\r\n // Move the last value to the index where the value to delete is\r\n set._values[toDeleteIndex] = lastvalue;\r\n // Update the index for the moved value\r\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\r\n\r\n // Delete the slot where the moved value was stored\r\n set._values.pop();\r\n\r\n // Delete the index for the deleted slot\r\n delete set._indexes[value];\r\n\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * @dev Returns true if the value is in the set. O(1).\r\n */\r\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\r\n return set._indexes[value] != 0;\r\n }\r\n\r\n /**\r\n * @dev Returns the number of values on the set. O(1).\r\n */\r\n function _length(Set storage set) private view returns (uint256) {\r\n return set._values.length;\r\n }\r\n\r\n /**\r\n * @dev Returns the value stored at position `index` in the set. O(1).\r\n *\r\n * Note that there are no guarantees on the ordering of values inside the\r\n * array, and it may change when more values are added or removed.\r\n *\r\n * Requirements:\r\n *\r\n * - `index` must be strictly less than {length}.\r\n */\r\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\r\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\r\n return set._values[index];\r\n }\r\n\r\n // Bytes32Set\r\n\r\n struct Bytes32Set {\r\n Set _inner;\r\n }\r\n\r\n /**\r\n * @dev Add a value to a set. O(1).\r\n *\r\n * Returns true if the value was added to the set, that is if it was not\r\n * already present.\r\n */\r\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\r\n return _add(set._inner, value);\r\n }\r\n\r\n /**\r\n * @dev Removes a value from a set. O(1).\r\n *\r\n * Returns true if the value was removed from the set, that is if it was\r\n * present.\r\n */\r\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\r\n return _remove(set._inner, value);\r\n }\r\n\r\n /**\r\n * @dev Returns true if the value is in the set. O(1).\r\n */\r\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\r\n return _contains(set._inner, value);\r\n }\r\n\r\n /**\r\n * @dev Returns the number of values in the set. O(1).\r\n */\r\n function length(Bytes32Set storage set) internal view returns (uint256) {\r\n return _length(set._inner);\r\n }\r\n\r\n /**\r\n * @dev Returns the value stored at position `index` in the set. O(1).\r\n *\r\n * Note that there are no guarantees on the ordering of values inside the\r\n * array, and it may change when more values are added or removed.\r\n *\r\n * Requirements:\r\n *\r\n * - `index` must be strictly less than {length}.\r\n */\r\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\r\n return _at(set._inner, index);\r\n }\r\n\r\n // AddressSet\r\n\r\n struct AddressSet {\r\n Set _inner;\r\n }\r\n\r\n /**\r\n * @dev Add a value to a set. O(1).\r\n *\r\n * Returns true if the value was added to the set, that is if it was not\r\n * already present.\r\n */\r\n function add(AddressSet storage set, address value) internal returns (bool) {\r\n return _add(set._inner, bytes32(uint256(uint160(value))));\r\n }\r\n\r\n /**\r\n * @dev Removes a value from a set. O(1).\r\n *\r\n * Returns true if the value was removed from the set, that is if it was\r\n * present.\r\n */\r\n function remove(AddressSet storage set, address value) internal returns (bool) {\r\n return _remove(set._inner, bytes32(uint256(uint160(value))));\r\n }\r\n\r\n /**\r\n * @dev Returns true if the value is in the set. O(1).\r\n */\r\n function contains(AddressSet storage set, address value) internal view returns (bool) {\r\n return _contains(set._inner, bytes32(uint256(uint160(value))));\r\n }\r\n\r\n /**\r\n * @dev Returns the number of values in the set. O(1).\r\n */\r\n function length(AddressSet storage set) internal view returns (uint256) {\r\n return _length(set._inner);\r\n }\r\n\r\n /**\r\n * @dev Returns the value stored at position `index` in the set. O(1).\r\n *\r\n * Note that there are no guarantees on the ordering of values inside the\r\n * array, and it may change when more values are added or removed.\r\n *\r\n * Requirements:\r\n *\r\n * - `index` must be strictly less than {length}.\r\n */\r\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\r\n return address(uint160(uint256(_at(set._inner, index))));\r\n }\r\n\r\n\r\n // UintSet\r\n\r\n struct UintSet {\r\n Set _inner;\r\n }\r\n\r\n /**\r\n * @dev Add a value to a set. O(1).\r\n *\r\n * Returns true if the value was added to the set, that is if it was not\r\n * already present.\r\n */\r\n function add(UintSet storage set, uint256 value) internal returns (bool) {\r\n return _add(set._inner, bytes32(value));\r\n }\r\n\r\n /**\r\n * @dev Removes a value from a set. O(1).\r\n *\r\n * Returns true if the value was removed from the set, that is if it was\r\n * present.\r\n */\r\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\r\n return _remove(set._inner, bytes32(value));\r\n }\r\n\r\n /**\r\n * @dev Returns true if the value is in the set. O(1).\r\n */\r\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\r\n return _contains(set._inner, bytes32(value));\r\n }\r\n\r\n /**\r\n * @dev Returns the number of values on the set. O(1).\r\n */\r\n function length(UintSet storage set) internal view returns (uint256) {\r\n return _length(set._inner);\r\n }\r\n\r\n /**\r\n * @dev Returns the value stored at position `index` in the set. O(1).\r\n *\r\n * Note that there are no guarantees on the ordering of values inside the\r\n * array, and it may change when more values are added or removed.\r\n *\r\n * Requirements:\r\n *\r\n * - `index` must be strictly less than {length}.\r\n */\r\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\r\n return uint256(_at(set._inner, index));\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/utils/EnumerableMap.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\n/**\r\n * @dev Library for managing an enumerable variant of Solidity's\r\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\r\n * type.\r\n *\r\n * Maps have the following properties:\r\n *\r\n * - Entries are added, removed, and checked for existence in constant time\r\n * (O(1)).\r\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\r\n *\r\n * ```\r\n * contract Example {\r\n * // Add the library methods\r\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\r\n *\r\n * // Declare a set state variable\r\n * EnumerableMap.UintToAddressMap private myMap;\r\n * }\r\n * ```\r\n *\r\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\r\n * supported.\r\n */\r\nlibrary EnumerableMap {\r\n // To implement this library for multiple types with as little code\r\n // repetition as possible, we write it in terms of a generic Map type with\r\n // bytes32 keys and values.\r\n // The Map implementation uses private functions, and user-facing\r\n // implementations (such as Uint256ToAddressMap) are just wrappers around\r\n // the underlying Map.\r\n // This means that we can only create new EnumerableMaps for types that fit\r\n // in bytes32.\r\n\r\n struct MapEntry {\r\n bytes32 _key;\r\n bytes32 _value;\r\n }\r\n\r\n struct Map {\r\n // Storage of map keys and values\r\n MapEntry[] _entries;\r\n\r\n // Position of the entry defined by a key in the `entries` array, plus 1\r\n // because index 0 means a key is not in the map.\r\n mapping (bytes32 => uint256) _indexes;\r\n }\r\n\r\n /**\r\n * @dev Adds a key-value pair to a map, or updates the value for an existing\r\n * key. O(1).\r\n *\r\n * Returns true if the key was added to the map, that is if it was not\r\n * already present.\r\n */\r\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\r\n // We read and store the key's index to prevent multiple reads from the same storage slot\r\n uint256 keyIndex = map._indexes[key];\r\n\r\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\r\n map._entries.push(MapEntry({ _key: key, _value: value }));\r\n // The entry is stored at length-1, but we add 1 to all indexes\r\n // and use 0 as a sentinel value\r\n map._indexes[key] = map._entries.length;\r\n return true;\r\n } else {\r\n map._entries[keyIndex - 1]._value = value;\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * @dev Removes a key-value pair from a map. O(1).\r\n *\r\n * Returns true if the key was removed from the map, that is if it was present.\r\n */\r\n function _remove(Map storage map, bytes32 key) private returns (bool) {\r\n // We read and store the key's index to prevent multiple reads from the same storage slot\r\n uint256 keyIndex = map._indexes[key];\r\n\r\n if (keyIndex != 0) { // Equivalent to contains(map, key)\r\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\r\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\r\n // This modifies the order of the array, as noted in {at}.\r\n\r\n uint256 toDeleteIndex = keyIndex - 1;\r\n uint256 lastIndex = map._entries.length - 1;\r\n\r\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\r\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\r\n\r\n MapEntry storage lastEntry = map._entries[lastIndex];\r\n\r\n // Move the last entry to the index where the entry to delete is\r\n map._entries[toDeleteIndex] = lastEntry;\r\n // Update the index for the moved entry\r\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\r\n\r\n // Delete the slot where the moved entry was stored\r\n map._entries.pop();\r\n\r\n // Delete the index for the deleted slot\r\n delete map._indexes[key];\r\n\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * @dev Returns true if the key is in the map. O(1).\r\n */\r\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\r\n return map._indexes[key] != 0;\r\n }\r\n\r\n /**\r\n * @dev Returns the number of key-value pairs in the map. O(1).\r\n */\r\n function _length(Map storage map) private view returns (uint256) {\r\n return map._entries.length;\r\n }\r\n\r\n /**\r\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\r\n *\r\n * Note that there are no guarantees on the ordering of entries inside the\r\n * array, and it may change when more entries are added or removed.\r\n *\r\n * Requirements:\r\n *\r\n * - `index` must be strictly less than {length}.\r\n */\r\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\r\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\r\n\r\n MapEntry storage entry = map._entries[index];\r\n return (entry._key, entry._value);\r\n }\r\n\r\n /**\r\n * @dev Tries to returns the value associated with `key`. O(1).\r\n * Does not revert if `key` is not in the map.\r\n */\r\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\r\n uint256 keyIndex = map._indexes[key];\r\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\r\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\r\n }\r\n\r\n /**\r\n * @dev Returns the value associated with `key`. O(1).\r\n *\r\n * Requirements:\r\n *\r\n * - `key` must be in the map.\r\n */\r\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\r\n uint256 keyIndex = map._indexes[key];\r\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\r\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\r\n }\r\n\r\n /**\r\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\r\n *\r\n * CAUTION: This function is deprecated because it requires allocating memory for the error\r\n * message unnecessarily. For custom revert reasons use {_tryGet}.\r\n */\r\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\r\n uint256 keyIndex = map._indexes[key];\r\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\r\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\r\n }\r\n\r\n // UintToAddressMap\r\n\r\n struct UintToAddressMap {\r\n Map _inner;\r\n }\r\n\r\n /**\r\n * @dev Adds a key-value pair to a map, or updates the value for an existing\r\n * key. O(1).\r\n *\r\n * Returns true if the key was added to the map, that is if it was not\r\n * already present.\r\n */\r\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\r\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\r\n }\r\n\r\n /**\r\n * @dev Removes a value from a set. O(1).\r\n *\r\n * Returns true if the key was removed from the map, that is if it was present.\r\n */\r\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\r\n return _remove(map._inner, bytes32(key));\r\n }\r\n\r\n /**\r\n * @dev Returns true if the key is in the map. O(1).\r\n */\r\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\r\n return _contains(map._inner, bytes32(key));\r\n }\r\n\r\n /**\r\n * @dev Returns the number of elements in the map. O(1).\r\n */\r\n function length(UintToAddressMap storage map) internal view returns (uint256) {\r\n return _length(map._inner);\r\n }\r\n\r\n /**\r\n * @dev Returns the element stored at position `index` in the set. O(1).\r\n * Note that there are no guarantees on the ordering of values inside the\r\n * array, and it may change when more values are added or removed.\r\n *\r\n * Requirements:\r\n *\r\n * - `index` must be strictly less than {length}.\r\n */\r\n function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\r\n (bytes32 key, bytes32 value) = _at(map._inner, index);\r\n return (uint256(key), address(uint160(uint256(value))));\r\n }\r\n\r\n /**\r\n * @dev Tries to returns the value associated with `key`. O(1).\r\n * Does not revert if `key` is not in the map.\r\n *\r\n * _Available since v3.4._\r\n */\r\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\r\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\r\n return (success, address(uint160(uint256(value))));\r\n }\r\n\r\n /**\r\n * @dev Returns the value associated with `key`. O(1).\r\n *\r\n * Requirements:\r\n *\r\n * - `key` must be in the map.\r\n */\r\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\r\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\r\n }\r\n\r\n /**\r\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\r\n *\r\n * CAUTION: This function is deprecated because it requires allocating memory for the error\r\n * message unnecessarily. For custom revert reasons use {tryGet}.\r\n */\r\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\r\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\n/**\r\n * @dev String operations.\r\n */\r\nlibrary Strings {\r\n /**\r\n * @dev Converts a `uint256` to its ASCII `string` representation.\r\n */\r\n function toString(uint256 value) internal pure returns (string memory) {\r\n // Inspired by OraclizeAPI's implementation - MIT licence\r\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\r\n\r\n if (value == 0) {\r\n return \"0\";\r\n }\r\n uint256 temp = value;\r\n uint256 digits;\r\n while (temp != 0) {\r\n digits++;\r\n temp /= 10;\r\n }\r\n bytes memory buffer = new bytes(digits);\r\n uint256 index = digits - 1;\r\n temp = value;\r\n while (temp != 0) {\r\n buffer[index--] = bytes1(uint8(48 + temp % 10));\r\n temp /= 10;\r\n }\r\n return string(buffer);\r\n }\r\n}\r\n"
+ },
+ "contracts/test/WRBTC.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../interface/IWrapped.sol\";\r\n\r\ncontract WRBTC is IWrapped {\r\n string public name = \"Wrapped RBTC\";\r\n string public symbol = \"WRBTC\";\r\n uint8 public decimals = 18;\r\n\r\n event Approval(address indexed src, address indexed guy, uint wad);\r\n event Transfer(address indexed src, address indexed dst, uint wad);\r\n event Deposit(address indexed dst, uint wad);\r\n event Withdrawal(address indexed src, uint wad);\r\n\r\n mapping (address => uint) override public balanceOf;\r\n mapping (address => mapping (address => uint)) public allowance;\r\n\r\n receive () external payable {\r\n deposit();\r\n }\r\n function deposit() override public payable {\r\n balanceOf[msg.sender] += msg.value;\r\n emit Deposit(msg.sender, msg.value);\r\n }\r\n function withdraw(uint wad) override public {\r\n require(balanceOf[msg.sender] >= wad, \"WRBTC: Balance less than wad\");\r\n balanceOf[msg.sender] -= wad;\r\n msg.sender.transfer(wad);\r\n emit Withdrawal(msg.sender, wad);\r\n }\r\n\r\n function totalSupply() override public view returns (uint) {\r\n return address(this).balance;\r\n }\r\n\r\n function approve(address guy, uint wad) override public returns (bool) {\r\n allowance[msg.sender][guy] = wad;\r\n emit Approval(msg.sender, guy, wad);\r\n return true;\r\n }\r\n\r\n function transfer(address dst, uint wad) override public returns (bool) {\r\n return transferFrom(msg.sender, dst, wad);\r\n }\r\n\r\n function transferFrom(address src, address dst, uint wad)\r\n override public\r\n returns (bool)\r\n {\r\n require(balanceOf[src] >= wad, \"WRBTC: Balance less than wad\");\r\n\r\n if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\r\n require(allowance[src][msg.sender] >= wad, \"WRBTC: Allowance less than wad\");\r\n allowance[src][msg.sender] -= wad;\r\n }\r\n\r\n balanceOf[src] -= wad;\r\n balanceOf[dst] += wad;\r\n\r\n emit Transfer(src, dst, wad);\r\n\r\n return true;\r\n }\r\n}"
+ },
+ "contracts/Bridge/Bridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n// Import base Initializable contract\r\nimport \"../zeppelin/upgradable/Initializable.sol\";\r\n// Import interface and library from OpenZeppelin contracts\r\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\r\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\r\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\r\n\r\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\r\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\r\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\r\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\r\nimport \"../zeppelin/utils/Address.sol\";\r\nimport \"../zeppelin/math/SafeMath.sol\";\r\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\r\n\r\nimport \"../lib/LibEIP712.sol\";\r\nimport \"../lib/LibUtils.sol\";\r\n\r\nimport \"../interface/IBridge.sol\";\r\nimport \"../interface/ISideToken.sol\";\r\nimport \"../interface/ISideTokenFactory.sol\";\r\nimport \"../interface/IAllowTokens.sol\";\r\nimport \"../interface/IWrapped.sol\";\r\n\r\n// solhint-disable-next-line max-states-count\r\ncontract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\r\n using SafeMath for uint256;\r\n using SafeERC20 for IERC20;\r\n using Address for address;\r\n\r\n address constant internal NULL_ADDRESS = address(0);\r\n bytes32 constant internal NULL_HASH = bytes32(0);\r\n IERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\r\n\r\n address internal federation;\r\n uint256 internal feePercentage;\r\n string public symbolPrefix;\r\n // replaces uint256 internal _depprecatedLastDay;\r\n bytes32 public domainSeparator;\r\n uint256 internal _deprecatedSpentToday;\r\n\r\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\r\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\r\n mapping (address => bool) public knownTokens; // OriginalToken => true\r\n mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed\r\n IAllowTokens public allowTokens;\r\n ISideTokenFactory public sideTokenFactory;\r\n //Bridge_v1 variables\r\n bool public isUpgrading;\r\n // Percentage with up to 2 decimals\r\n uint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase\r\n //Bridge_v3 variables\r\n bytes32 constant internal _erc777Interface = keccak256(\"ERC777Token\"); // solhint-disable-line const-name-snakecase\r\n IWrapped public wrappedCurrency;\r\n mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash\r\n mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress\r\n mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress\r\n\r\n // keccak256(\"Claim(address to,uint256 amount,bytes32 transactionHash,address relayer,uint256 fee,uint256 nonce,uint256 deadline)\");\r\n bytes32 public constant CLAIM_TYPEHASH = 0xf18ceda3f6355f78c234feba066041a50f6557bfb600201e2a71a89e2dd80433;\r\n mapping(address => uint) public nonces;\r\n\r\n event AllowTokensChanged(address _newAllowTokens);\r\n event FederationChanged(address _newFederation);\r\n event SideTokenFactoryChanged(address _newSideTokenFactory);\r\n event Upgrading(bool _isUpgrading);\r\n event WrappedCurrencyChanged(address _wrappedCurrency);\r\n\r\n function initialize(\r\n address _manager,\r\n address _federation,\r\n address _allowTokens,\r\n address _sideTokenFactory,\r\n string memory _symbolPrefix\r\n ) public initializer {\r\n UpgradableOwnable.initialize(_manager);\r\n UpgradablePausable.__Pausable_init(_manager);\r\n symbolPrefix = _symbolPrefix;\r\n allowTokens = IAllowTokens(_allowTokens);\r\n sideTokenFactory = ISideTokenFactory(_sideTokenFactory);\r\n federation = _federation;\r\n //keccak256(\"ERC777TokensRecipient\")\r\n ERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\r\n initDomainSeparator();\r\n }\r\n\r\n receive () external payable {\r\n // The fallback function is needed to use WRBTC\r\n require(_msgSender() == address(wrappedCurrency), \"Bridge: not wrappedCurrency\");\r\n }\r\n\r\n function version() override external pure returns (string memory) {\r\n return \"v3\";\r\n }\r\n\r\n function initDomainSeparator() public {\r\n uint chainId;\r\n // solium-disable-next-line security/no-inline-assembly\r\n assembly {\r\n chainId := chainid()\r\n }\r\n domainSeparator = LibEIP712.hashEIP712Domain(\r\n \"RSK Token Bridge\",\r\n \"1\",\r\n chainId,\r\n address(this)\r\n );\r\n }\r\n\r\n modifier whenNotUpgrading() {\r\n require(!isUpgrading, \"Bridge: Upgrading\");\r\n _;\r\n }\r\n\r\n function acceptTransfer(\r\n address _originalTokenAddress,\r\n address payable _from,\r\n address payable _to,\r\n uint256 _amount,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n ) external whenNotPaused nonReentrant override {\r\n require(_msgSender() == federation, \"Bridge: Not Federation\");\r\n require(knownTokens[_originalTokenAddress] ||\r\n mappedTokens[_originalTokenAddress] != NULL_ADDRESS,\r\n \"Bridge: Unknown token\"\r\n );\r\n require(_to != NULL_ADDRESS, \"Bridge: Null To\");\r\n require(_amount > 0, \"Bridge: Amount 0\");\r\n require(_blockHash != NULL_HASH, \"Bridge: Null BlockHash\");\r\n require(_transactionHash != NULL_HASH, \"Bridge: Null TxHash\");\r\n require(transactionsDataHashes[_transactionHash] == bytes32(0), \"Bridge: Already accepted\");\r\n\r\n bytes32 _transactionDataHash = getTransactionDataHash(\r\n _to,\r\n _amount,\r\n _blockHash,\r\n _transactionHash,\r\n _logIndex\r\n );\r\n // Do not remove, claimed also has the previously processed using the older bridge version\r\n // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41\r\n require(!claimed[_transactionDataHash], \"Bridge: Already claimed\");\r\n\r\n transactionsDataHashes[_transactionHash] = _transactionDataHash;\r\n originalTokenAddresses[_transactionHash] = _originalTokenAddress;\r\n senderAddresses[_transactionHash] = _from;\r\n\r\n emit AcceptedCrossTransfer(\r\n _transactionHash,\r\n _originalTokenAddress,\r\n _to,\r\n _from,\r\n _amount,\r\n _blockHash,\r\n _logIndex\r\n );\r\n }\r\n\r\n\r\n function createSideToken(\r\n uint256 _typeId,\r\n address _originalTokenAddress,\r\n uint8 _originalTokenDecimals,\r\n string calldata _originalTokenSymbol,\r\n string calldata _originalTokenName\r\n ) external onlyOwner {\r\n require(_originalTokenAddress != NULL_ADDRESS, \"Bridge: Null token\");\r\n address sideToken = mappedTokens[_originalTokenAddress];\r\n require(sideToken == NULL_ADDRESS, \"Bridge: Already exists\");\r\n uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);\r\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, _originalTokenSymbol));\r\n\r\n // Create side token\r\n sideToken = sideTokenFactory.createSideToken(_originalTokenName, newSymbol, granularity);\r\n\r\n mappedTokens[_originalTokenAddress] = sideToken;\r\n originalTokens[sideToken] = _originalTokenAddress;\r\n allowTokens.setToken(sideToken, _typeId);\r\n\r\n emit NewSideToken(sideToken, _originalTokenAddress, newSymbol, granularity);\r\n }\r\n\r\n function claim(ClaimData calldata _claimData)\r\n external override returns (uint256 receivedAmount) {\r\n\r\n receivedAmount = _claim(\r\n _claimData,\r\n _claimData.to,\r\n payable(address(0)),\r\n 0\r\n );\r\n return receivedAmount;\r\n }\r\n\r\n function claimFallback(ClaimData calldata _claimData)\r\n external override returns (uint256 receivedAmount) {\r\n require(_msgSender() == senderAddresses[_claimData.transactionHash],\"Bridge: invalid sender\");\r\n receivedAmount = _claim(\r\n _claimData,\r\n _msgSender(),\r\n payable(address(0)),\r\n 0\r\n );\r\n return receivedAmount;\r\n }\r\n\r\n function getDigest(\r\n ClaimData memory _claimData,\r\n address payable _relayer,\r\n uint256 _fee,\r\n uint256 _deadline\r\n ) internal returns (bytes32) {\r\n return LibEIP712.hashEIP712Message(\r\n domainSeparator,\r\n keccak256(\r\n abi.encode(\r\n CLAIM_TYPEHASH,\r\n _claimData.to,\r\n _claimData.amount,\r\n _claimData.transactionHash,\r\n _relayer,\r\n _fee,\r\n nonces[_claimData.to]++,\r\n _deadline\r\n )\r\n )\r\n );\r\n }\r\n\r\n // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol\r\n function claimGasless(\r\n ClaimData calldata _claimData,\r\n address payable _relayer,\r\n uint256 _fee,\r\n uint256 _deadline,\r\n uint8 _v,\r\n bytes32 _r,\r\n bytes32 _s\r\n ) external override returns (uint256 receivedAmount) {\r\n require(_deadline >= block.timestamp, \"Bridge: EXPIRED\"); // solhint-disable-line not-rely-on-time\r\n\r\n bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);\r\n address recoveredAddress = ecrecover(digest, _v, _r, _s);\r\n require(_claimData.to != address(0) && recoveredAddress == _claimData.to, \"Bridge: INVALID_SIGNATURE\");\r\n\r\n receivedAmount = _claim(\r\n _claimData,\r\n _claimData.to,\r\n _relayer,\r\n _fee\r\n );\r\n return receivedAmount;\r\n }\r\n\r\n function _claim(\r\n ClaimData calldata _claimData,\r\n address payable _reciever,\r\n address payable _relayer,\r\n uint256 _fee\r\n ) internal nonReentrant returns (uint256 receivedAmount) {\r\n address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];\r\n require(originalTokenAddress != NULL_ADDRESS, \"Bridge: Tx not crossed\");\r\n\r\n bytes32 transactionDataHash = getTransactionDataHash(\r\n _claimData.to,\r\n _claimData.amount,\r\n _claimData.blockHash,\r\n _claimData.transactionHash,\r\n _claimData.logIndex\r\n );\r\n require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, \"Bridge: Wrong transactionDataHash\");\r\n require(!claimed[transactionDataHash], \"Bridge: Already claimed\");\r\n\r\n claimed[transactionDataHash] = true;\r\n if (knownTokens[originalTokenAddress]) {\r\n receivedAmount =_claimCrossBackToToken(\r\n originalTokenAddress,\r\n _reciever,\r\n _claimData.amount,\r\n _relayer,\r\n _fee\r\n );\r\n } else {\r\n receivedAmount =_claimCrossToSideToken(\r\n originalTokenAddress,\r\n _reciever,\r\n _claimData.amount,\r\n _relayer,\r\n _fee\r\n );\r\n }\r\n emit Claimed(\r\n _claimData.transactionHash,\r\n originalTokenAddress,\r\n _claimData.to,\r\n senderAddresses[_claimData.transactionHash],\r\n _claimData.amount,\r\n _claimData.blockHash,\r\n _claimData.logIndex,\r\n _reciever,\r\n _relayer,\r\n _fee\r\n );\r\n return receivedAmount;\r\n }\r\n\r\n function _claimCrossToSideToken(\r\n address _originalTokenAddress,\r\n address payable _receiver,\r\n uint256 _amount,\r\n address payable _relayer,\r\n uint256 _fee\r\n ) internal returns (uint256 receivedAmount) {\r\n address sideToken = mappedTokens[_originalTokenAddress];\r\n uint256 granularity = IERC777(sideToken).granularity();\r\n uint256 formattedAmount = _amount.mul(granularity);\r\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\r\n receivedAmount = formattedAmount - _fee;\r\n ISideToken(sideToken).mint(_receiver, receivedAmount, \"\", \"\");\r\n if(_fee > 0) {\r\n ISideToken(sideToken).mint(_relayer, _fee, \"\", \"relayer fee\");\r\n }\r\n return receivedAmount;\r\n }\r\n\r\n function _claimCrossBackToToken(\r\n address _originalTokenAddress,\r\n address payable _receiver,\r\n uint256 _amount,\r\n address payable _relayer,\r\n uint256 _fee\r\n ) internal returns (uint256 receivedAmount) {\r\n uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);\r\n //As side tokens are ERC777 they will always have 18 decimals\r\n uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));\r\n require(_fee <= formattedAmount, \"Bridge: fee too high\");\r\n receivedAmount = formattedAmount - _fee;\r\n if(address(wrappedCurrency) == _originalTokenAddress) {\r\n wrappedCurrency.withdraw(formattedAmount);\r\n _receiver.transfer(receivedAmount);\r\n if(_fee > 0) {\r\n _relayer.transfer(_fee);\r\n }\r\n } else {\r\n IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);\r\n if(_fee > 0) {\r\n IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);\r\n }\r\n }\r\n return receivedAmount;\r\n }\r\n\r\n /**\r\n * ERC-20 tokens approve and transferFrom pattern\r\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\r\n */\r\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) override public {\r\n address sender = _msgSender();\r\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\r\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\r\n crossTokens(tokenToUse, sender, to, amount, \"\");\r\n }\r\n\r\n /**\r\n * Use network currency and cross it.\r\n */\r\n function depositTo(address to) override external payable {\r\n address sender = _msgSender();\r\n require(address(wrappedCurrency) != NULL_ADDRESS, \"Bridge: wrappedCurrency empty\");\r\n wrappedCurrency.deposit{ value: msg.value }();\r\n crossTokens(address(wrappedCurrency), sender, to, msg.value, \"\");\r\n }\r\n\r\n /**\r\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\r\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\r\n */\r\n function tokensReceived (\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes calldata userData,\r\n bytes calldata\r\n ) external override(IBridge, IERC777Recipient){\r\n //Hook from ERC777address\r\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\r\n require(to == address(this), \"Bridge: Not to this address\");\r\n address tokenToUse = _msgSender();\r\n require(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, \"Bridge: Not ERC777 token\");\r\n require(userData.length != 0 || !from.isContract(), \"Bridge: Specify receiver address in data\");\r\n address receiver = userData.length == 0 ? from : LibUtils.bytesToAddress(userData);\r\n crossTokens(tokenToUse, from, receiver, amount, userData);\r\n }\r\n\r\n function crossTokens(address tokenToUse, address from, address to, uint256 amount, bytes memory userData)\r\n internal whenNotUpgrading whenNotPaused nonReentrant {\r\n knownTokens[tokenToUse] = true;\r\n uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);\r\n uint256 amountMinusFees = amount.sub(fee);\r\n uint8 decimals = LibUtils.getDecimals(tokenToUse);\r\n uint formattedAmount = amount;\r\n if(decimals != 18) {\r\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\r\n }\r\n // We consider the amount before fees converted to 18 decimals to check the limits\r\n // updateTokenTransfer revert if token not allowed\r\n allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);\r\n address originalTokenAddress = tokenToUse;\r\n if (originalTokens[tokenToUse] != NULL_ADDRESS) {\r\n //Side Token Crossing\r\n originalTokenAddress = originalTokens[tokenToUse];\r\n uint256 granularity = LibUtils.getGranularity(tokenToUse);\r\n uint256 modulo = amountMinusFees.mod(granularity);\r\n fee = fee.add(modulo);\r\n amountMinusFees = amountMinusFees.sub(modulo);\r\n IERC777(tokenToUse).burn(amountMinusFees, userData);\r\n }\r\n\r\n emit Cross(\r\n originalTokenAddress,\r\n from,\r\n to,\r\n amountMinusFees,\r\n userData\r\n );\r\n\r\n if (fee > 0) {\r\n //Send the payment to the MultiSig of the Federation\r\n IERC20(tokenToUse).safeTransfer(owner(), fee);\r\n }\r\n }\r\n\r\n function getTransactionDataHash(\r\n address _to,\r\n uint256 _amount,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n )\r\n public pure override returns(bytes32)\r\n {\r\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));\r\n }\r\n\r\n function setFeePercentage(uint amount) external onlyOwner {\r\n require(amount < (feePercentageDivider/10), \"Bridge: bigger than 10%\");\r\n feePercentage = amount;\r\n emit FeePercentageChanged(feePercentage);\r\n }\r\n\r\n function getFeePercentage() external view override returns(uint) {\r\n return feePercentage;\r\n }\r\n\r\n function changeFederation(address newFederation) external onlyOwner {\r\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\r\n federation = newFederation;\r\n emit FederationChanged(federation);\r\n }\r\n\r\n\r\n function changeAllowTokens(address newAllowTokens) external onlyOwner {\r\n require(newAllowTokens != NULL_ADDRESS, \"Bridge: AllowTokens is empty\");\r\n allowTokens = IAllowTokens(newAllowTokens);\r\n emit AllowTokensChanged(newAllowTokens);\r\n }\r\n\r\n function getFederation() external view returns(address) {\r\n return federation;\r\n }\r\n\r\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {\r\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\r\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\r\n emit SideTokenFactoryChanged(newSideTokenFactory);\r\n }\r\n\r\n function setUpgrading(bool _isUpgrading) external onlyOwner {\r\n isUpgrading = _isUpgrading;\r\n emit Upgrading(isUpgrading);\r\n }\r\n\r\n function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {\r\n require(_wrappedCurrency != NULL_ADDRESS, \"Bridge: wrapp is empty\");\r\n wrappedCurrency = IWrapped(_wrappedCurrency);\r\n emit WrappedCurrencyChanged(_wrappedCurrency);\r\n }\r\n\r\n function hasCrossed(bytes32 transactionHash) public view returns (bool) {\r\n return transactionsDataHashes[transactionHash] != bytes32(0);\r\n }\r\n\r\n function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {\r\n return claimed[transactionsDataHashes[transactionHash]];\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\r\n *\r\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\r\n * contract implement this interface (contract holders can be their own\r\n * implementer) and registering it on the\r\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\r\n *\r\n * See `IERC1820Registry` and `ERC1820Implementer`.\r\n */\r\ninterface IERC777Recipient {\r\n /**\r\n * @dev Called by an `IERC777` token contract whenever tokens are being\r\n * moved or created into a registered account (`to`). The type of operation\r\n * is conveyed by `from` being the zero address or not.\r\n *\r\n * This call occurs _after_ the token contract's state is updated, so\r\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\r\n *\r\n * This function may revert to prevent the operation from being executed.\r\n */\r\n function tokensReceived(\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes calldata userData,\r\n bytes calldata operatorData\r\n ) external;\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev Interface of the ERC777Token standard as defined in the EIP.\r\n *\r\n * This contract uses the\r\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\r\n * token holders and recipients react to token movements by using setting implementers\r\n * for the associated interfaces in said registry. See `IERC1820Registry` and\r\n * `ERC1820Implementer`.\r\n */\r\ninterface IERC777 {\r\n /**\r\n * @dev Returns the name of the token.\r\n */\r\n function name() external view returns (string memory);\r\n\r\n /**\r\n * @dev Returns the symbol of the token, usually a shorter version of the\r\n * name.\r\n */\r\n function symbol() external view returns (string memory);\r\n\r\n /**\r\n * @dev Returns the smallest part of the token that is not divisible. This\r\n * means all token operations (creation, movement and destruction) must have\r\n * amounts that are a multiple of this number.\r\n *\r\n * For most token contracts, this value will equal 1.\r\n */\r\n function granularity() external view returns (uint256);\r\n\r\n /**\r\n * @dev Returns the amount of tokens in existence.\r\n */\r\n function totalSupply() external view returns (uint256);\r\n\r\n /**\r\n * @dev Returns the amount of tokens owned by an account (`owner`).\r\n */\r\n function balanceOf(address owner) external view returns (uint256);\r\n\r\n /**\r\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\r\n *\r\n * If send or receive hooks are registered for the caller and `recipient`,\r\n * the corresponding functions will be called with `data` and empty\r\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\r\n *\r\n * Emits a `Sent` event.\r\n *\r\n * Requirements\r\n *\r\n * - the caller must have at least `amount` tokens.\r\n * - `recipient` cannot be the zero address.\r\n * - if `recipient` is a contract, it must implement the `tokensReceived`\r\n * interface.\r\n */\r\n function send(address recipient, uint256 amount, bytes calldata data) external;\r\n\r\n /**\r\n * @dev Destroys `amount` tokens from the caller's account, reducing the\r\n * total supply.\r\n *\r\n * If a send hook is registered for the caller, the corresponding function\r\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\r\n *\r\n * Emits a `Burned` event.\r\n *\r\n * Requirements\r\n *\r\n * - the caller must have at least `amount` tokens.\r\n */\r\n function burn(uint256 amount, bytes calldata data) external;\r\n\r\n /**\r\n * @dev Returns true if an account is an operator of `tokenHolder`.\r\n * Operators can send and burn tokens on behalf of their owners. All\r\n * accounts are their own operator.\r\n *\r\n * See `operatorSend` and `operatorBurn`.\r\n */\r\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\r\n\r\n /**\r\n * @dev Make an account an operator of the caller.\r\n *\r\n * See `isOperatorFor`.\r\n *\r\n * Emits an `AuthorizedOperator` event.\r\n *\r\n * Requirements\r\n *\r\n * - `operator` cannot be calling address.\r\n */\r\n function authorizeOperator(address operator) external;\r\n\r\n /**\r\n * @dev Make an account an operator of the caller.\r\n *\r\n * See `isOperatorFor` and `defaultOperators`.\r\n *\r\n * Emits a `RevokedOperator` event.\r\n *\r\n * Requirements\r\n *\r\n * - `operator` cannot be calling address.\r\n */\r\n function revokeOperator(address operator) external;\r\n\r\n /**\r\n * @dev Returns the list of default operators. These accounts are operators\r\n * for all token holders, even if `authorizeOperator` was never called on\r\n * them.\r\n *\r\n * This list is immutable, but individual holders may revoke these via\r\n * `revokeOperator`, in which case `isOperatorFor` will return false.\r\n */\r\n function defaultOperators() external view returns (address[] memory);\r\n\r\n /**\r\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\r\n * be an operator of `sender`.\r\n *\r\n * If send or receive hooks are registered for `sender` and `recipient`,\r\n * the corresponding functions will be called with `data` and\r\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\r\n *\r\n * Emits a `Sent` event.\r\n *\r\n * Requirements\r\n *\r\n * - `sender` cannot be the zero address.\r\n * - `sender` must have at least `amount` tokens.\r\n * - the caller must be an operator for `sender`.\r\n * - `recipient` cannot be the zero address.\r\n * - if `recipient` is a contract, it must implement the `tokensReceived`\r\n * interface.\r\n */\r\n function operatorSend(\r\n address sender,\r\n address recipient,\r\n uint256 amount,\r\n bytes calldata data,\r\n bytes calldata operatorData\r\n ) external;\r\n\r\n /**\r\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\r\n * The caller must be an operator of `account`.\r\n *\r\n * If a send hook is registered for `account`, the corresponding function\r\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\r\n *\r\n * Emits a `Burned` event.\r\n *\r\n * Requirements\r\n *\r\n * - `account` cannot be the zero address.\r\n * - `account` must have at least `amount` tokens.\r\n * - the caller must be an operator for `account`.\r\n */\r\n function operatorBurn(\r\n address account,\r\n uint256 amount,\r\n bytes calldata data,\r\n bytes calldata operatorData\r\n ) external;\r\n\r\n event Sent(\r\n address indexed operator,\r\n address indexed from,\r\n address indexed to,\r\n uint256 amount,\r\n bytes data,\r\n bytes operatorData\r\n );\r\n\r\n function decimals() external returns (uint8);\r\n\r\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\r\n\r\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\r\n\r\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\r\n\r\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\r\n}\r\n"
+ },
+ "contracts/interface/IBridge.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\ninterface IBridge {\r\n\r\n struct ClaimData {\r\n address payable to;\r\n uint256 amount;\r\n bytes32 blockHash;\r\n bytes32 transactionHash;\r\n uint32 logIndex;\r\n }\r\n\r\n function version() external pure returns (string memory);\r\n\r\n function getFeePercentage() external view returns(uint);\r\n\r\n /**\r\n * ERC-20 tokens approve and transferFrom pattern\r\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\r\n */\r\n function receiveTokensTo(address tokenToUse, address to, uint256 amount) external;\r\n\r\n /**\r\n * Use network currency and cross it.\r\n */\r\n function depositTo(address to) external payable;\r\n\r\n /**\r\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\r\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\r\n */\r\n function tokensReceived (\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes calldata userData,\r\n bytes calldata operatorData\r\n ) external;\r\n\r\n /**\r\n * Accepts the transaction from the other chain that was voted and sent by the Federation contract\r\n */\r\n function acceptTransfer(\r\n address _originalTokenAddress,\r\n address payable _from,\r\n address payable _to,\r\n uint256 _amount,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n ) external;\r\n\r\n /**\r\n * Claims the crossed transaction using the hash, this sends the funds to the address indicated in\r\n */\r\n function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\r\n\r\n function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);\r\n\r\n function claimGasless(\r\n ClaimData calldata _claimData,\r\n address payable _relayer,\r\n uint256 _fee,\r\n uint256 _deadline,\r\n uint8 _v,\r\n bytes32 _r,\r\n bytes32 _s\r\n ) external returns (uint256 receivedAmount);\r\n\r\n function getTransactionDataHash(\r\n address _to,\r\n uint256 _amount,\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n uint32 _logIndex\r\n ) external returns(bytes32);\r\n\r\n event Cross(\r\n address indexed _tokenAddress,\r\n address indexed _from,\r\n address indexed _to,\r\n uint256 _amount,\r\n bytes _userData\r\n );\r\n event NewSideToken(\r\n address indexed _newSideTokenAddress,\r\n address indexed _originalTokenAddress,\r\n string _newSymbol,\r\n uint256 _granularity\r\n );\r\n event AcceptedCrossTransfer(\r\n bytes32 indexed _transactionHash,\r\n address indexed _originalTokenAddress,\r\n address indexed _to,\r\n address _from,\r\n uint256 _amount,\r\n bytes32 _blockHash,\r\n uint256 _logIndex\r\n );\r\n event FeePercentageChanged(uint256 _amount);\r\n event Claimed(\r\n bytes32 indexed _transactionHash,\r\n address indexed _originalTokenAddress,\r\n address indexed _to,\r\n address _sender,\r\n uint256 _amount,\r\n bytes32 _blockHash,\r\n uint256 _logIndex,\r\n address _reciever,\r\n address _relayer,\r\n uint256 _fee\r\n );\r\n}"
+ },
+ "contracts/interface/ISideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\ninterface ISideToken {\r\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\r\n}"
+ },
+ "contracts/interface/ISideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\ninterface ISideTokenFactory {\r\n\r\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);\r\n\r\n event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);\r\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../zeppelin/ownership/Secondary.sol\";\r\nimport \"../interface/ISideTokenFactory.sol\";\r\nimport \"../SideToken/SideToken.sol\";\r\n\r\ncontract SideTokenFactory is ISideTokenFactory, Secondary {\r\n\r\n function createSideToken(string calldata name, string calldata symbol, uint256 granularity)\r\n external onlyPrimary override returns(address) {\r\n address sideToken = address(new SideToken(name, symbol, primary(), granularity));\r\n emit SideTokenCreated(sideToken, symbol, granularity);\r\n return sideToken;\r\n }\r\n}"
+ },
+ "contracts/zeppelin/ownership/Secondary.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../GSN/Context.sol\";\r\n/**\r\n * @dev A Secondary contract can only be used by its primary account (the one that created it).\r\n */\r\nabstract contract Secondary is Context {\r\n address private _primary;\r\n\r\n /**\r\n * @dev Emitted when the primary contract changes.\r\n */\r\n event PrimaryTransferred(\r\n address recipient\r\n );\r\n\r\n /**\r\n * @dev Sets the primary account to the one that is creating the Secondary contract.\r\n */\r\n constructor () {\r\n _primary = _msgSender();\r\n emit PrimaryTransferred(_primary);\r\n }\r\n\r\n /**\r\n * @dev Reverts if called from any account other than the primary.\r\n */\r\n modifier onlyPrimary() {\r\n require(_msgSender() == _primary, \"Secondary: caller is not the primary account\");\r\n _;\r\n }\r\n\r\n /**\r\n * @return the address of the primary.\r\n */\r\n function primary() public view returns (address) {\r\n return _primary;\r\n }\r\n\r\n /**\r\n * @dev Transfers contract to a new primary.\r\n * @param recipient The address of new primary.\r\n */\r\n function transferPrimary(address recipient) public onlyPrimary {\r\n require(recipient != address(0), \"Secondary: new primary is the zero address\");\r\n _primary = recipient;\r\n emit PrimaryTransferred(_primary);\r\n }\r\n}\r\n"
+ },
+ "contracts/SideToken/SideToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\r\nimport \"../interface/IERC677Receiver.sol\";\r\nimport \"../interface/ISideToken.sol\";\r\nimport \"../lib/LibEIP712.sol\";\r\n\r\ncontract SideToken is ISideToken, ERC777 {\r\n using Address for address;\r\n using SafeMath for uint256;\r\n\r\n address public minter;\r\n uint256 private _granularity;\r\n\r\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\r\n bytes32 public domainSeparator;\r\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\r\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\r\n mapping(address => uint) public nonces;\r\n\r\n // ERC677 Transfer Event\r\n event Transfer(address,address,uint256,bytes);\r\n\r\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\r\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\r\n require(_minterAddr != address(0), \"SideToken: Empty Minter\");\r\n require(_newGranularity >= 1, \"SideToken: Granularity < 1\");\r\n minter = _minterAddr;\r\n _granularity = _newGranularity;\r\n\r\n uint chainId;\r\n // solium-disable-next-line security/no-inline-assembly\r\n assembly {\r\n chainId := chainid()\r\n }\r\n domainSeparator = LibEIP712.hashEIP712Domain(\r\n name(),\r\n \"1\",\r\n chainId,\r\n address(this)\r\n );\r\n }\r\n\r\n modifier onlyMinter() {\r\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\r\n _;\r\n }\r\n\r\n function mint(\r\n address account,\r\n uint256 amount,\r\n bytes calldata userData,\r\n bytes calldata operatorData\r\n )\r\n external onlyMinter override\r\n {\r\n _mint(_msgSender(), account, amount, userData, operatorData);\r\n }\r\n\r\n /**\r\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\r\n * @param recipient The address to transfer to.\r\n * @param amount The amount to be transferred.\r\n * @param data The extra data to be passed to the receiving contract.\r\n */\r\n function transferAndCall(address recipient, uint amount, bytes calldata data)\r\n external returns (bool success)\r\n {\r\n address from = _msgSender();\r\n\r\n _send(from, from, recipient, amount, data, \"\", false);\r\n emit Transfer(from, recipient, amount, data);\r\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\r\n return true;\r\n }\r\n\r\n function granularity() public view override returns (uint256) {\r\n return _granularity;\r\n }\r\n\r\n // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md\r\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\r\n require(deadline >= block.timestamp, \"SideToken: EXPIRED\"); // solhint-disable-line not-rely-on-time\r\n bytes32 digest = LibEIP712.hashEIP712Message(\r\n domainSeparator,\r\n keccak256(\r\n abi.encode(\r\n PERMIT_TYPEHASH,\r\n owner,\r\n spender,\r\n value,\r\n nonces[owner]++,\r\n deadline\r\n )\r\n )\r\n );\r\n address recoveredAddress = ecrecover(digest, v, r, s);\r\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"SideToken: INVALID_SIGNATURE\");\r\n _approve(owner, spender, value);\r\n }\r\n\r\n}"
+ },
+ "contracts/zeppelin/token/ERC777/ERC777.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../../GSN/Context.sol\";\r\nimport \"./IERC777.sol\";\r\nimport \"./IERC777Recipient.sol\";\r\nimport \"./IERC777Sender.sol\";\r\nimport \"../../token/ERC20/IERC20.sol\";\r\nimport \"../../math/SafeMath.sol\";\r\nimport \"../../utils/Address.sol\";\r\nimport \"../../introspection/IERC1820Registry.sol\";\r\n\r\n/**\r\n * @dev Implementation of the {IERC777} interface.\r\n *\r\n * This implementation is agnostic to the way tokens are created. This means\r\n * that a supply mechanism has to be added in a derived contract using {_mint}.\r\n *\r\n * Support for ERC20 is included in this contract, as specified by the EIP: both\r\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\r\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\r\n * movements.\r\n *\r\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\r\n * are no special restrictions in the amount of tokens that created, moved, or\r\n * destroyed. This makes integration with ERC20 applications seamless.\r\n */\r\ncontract ERC777 is Context, IERC777, IERC20 {\r\n using SafeMath for uint256;\r\n using Address for address;\r\n\r\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\r\n\r\n mapping(address => uint256) private _balances;\r\n\r\n uint256 private _totalSupply;\r\n\r\n string private _name;\r\n string private _symbol;\r\n\r\n // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.\r\n // See https://github.com/ethereum/solidity/issues/4024.\r\n\r\n // keccak256(\"ERC777TokensSender\")\r\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\r\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\r\n\r\n // keccak256(\"ERC777TokensRecipient\")\r\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\r\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\r\n\r\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\r\n address[] private _defaultOperatorsArray;\r\n\r\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\r\n mapping(address => bool) private _defaultOperators;\r\n\r\n // For each account, a mapping of its operators and revoked default operators.\r\n mapping(address => mapping(address => bool)) private _operators;\r\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\r\n\r\n // ERC20-allowances\r\n mapping (address => mapping (address => uint256)) private _allowances;\r\n\r\n /**\r\n * @dev `defaultOperators` may be an empty array.\r\n */\r\n constructor(\r\n string memory aName,\r\n string memory aSymbol,\r\n address[] memory theDefaultOperators\r\n ) {\r\n _name = aName;\r\n _symbol = aSymbol;\r\n\r\n _defaultOperatorsArray = theDefaultOperators;\r\n for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {\r\n _defaultOperators[_defaultOperatorsArray[i]] = true;\r\n }\r\n\r\n // register interfaces\r\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\r\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-name}.\r\n */\r\n function name() public view override(IERC777) returns (string memory) {\r\n return _name;\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-symbol}.\r\n */\r\n function symbol() public view override(IERC777) returns (string memory) {\r\n return _symbol;\r\n }\r\n\r\n /**\r\n * @dev See {ERC20Detailed-decimals}.\r\n *\r\n * Always returns 18, as per the\r\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\r\n */\r\n function decimals() public pure override returns (uint8) {\r\n return 18;\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-granularity}.\r\n *\r\n * This implementation always returns `1`.\r\n */\r\n function granularity() public view virtual override(IERC777) returns (uint256) {\r\n return 1;\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-totalSupply}.\r\n */\r\n function totalSupply() public view override(IERC20, IERC777) returns (uint256) {\r\n return _totalSupply;\r\n }\r\n\r\n /**\r\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\r\n */\r\n function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {\r\n return _balances[tokenHolder];\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-send}.\r\n *\r\n * Also emits a {Transfer} event for ERC20 compatibility.\r\n */\r\n function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {\r\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-transfer}.\r\n *\r\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\r\n * interface if it is a contract.\r\n *\r\n * Also emits a {Sent} event.\r\n */\r\n function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {\r\n require(recipient != address(0), \"ERC777: transfer to zero address\");\r\n\r\n address from = _msgSender();\r\n\r\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\r\n\r\n _move(from, from, recipient, amount, \"\", \"\");\r\n\r\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-burn}.\r\n *\r\n * Also emits a {Transfer} event for ERC20 compatibility.\r\n */\r\n function burn(uint256 amount, bytes calldata data) external override(IERC777) {\r\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-isOperatorFor}.\r\n */\r\n function isOperatorFor(\r\n address operator,\r\n address tokenHolder\r\n ) public view override(IERC777) returns (bool) {\r\n return operator == tokenHolder ||\r\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\r\n _operators[tokenHolder][operator];\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-authorizeOperator}.\r\n */\r\n function authorizeOperator(address operator) external override(IERC777) {\r\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\r\n\r\n if (_defaultOperators[operator]) {\r\n delete _revokedDefaultOperators[_msgSender()][operator];\r\n } else {\r\n _operators[_msgSender()][operator] = true;\r\n }\r\n\r\n emit AuthorizedOperator(operator, _msgSender());\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-revokeOperator}.\r\n */\r\n function revokeOperator(address operator) external override(IERC777) {\r\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\r\n\r\n if (_defaultOperators[operator]) {\r\n _revokedDefaultOperators[_msgSender()][operator] = true;\r\n } else {\r\n delete _operators[_msgSender()][operator];\r\n }\r\n\r\n emit RevokedOperator(operator, _msgSender());\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-defaultOperators}.\r\n */\r\n function defaultOperators() public view override(IERC777) returns (address[] memory) {\r\n return _defaultOperatorsArray;\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-operatorSend}.\r\n *\r\n * Emits {Sent} and {Transfer} events.\r\n */\r\n function operatorSend(\r\n address sender,\r\n address recipient,\r\n uint256 amount,\r\n bytes calldata data,\r\n bytes calldata operatorData\r\n )\r\n external override(IERC777)\r\n {\r\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\r\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\r\n }\r\n\r\n /**\r\n * @dev See {IERC777-operatorBurn}.\r\n *\r\n * Emits {Burned} and {Transfer} events.\r\n */\r\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)\r\n external override(IERC777) {\r\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\r\n _burn(_msgSender(), account, amount, data, operatorData);\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-allowance}.\r\n *\r\n * Note that operator and allowance concepts are orthogonal: operators may\r\n * not have allowance, and accounts with allowance may not be operators\r\n * themselves.\r\n */\r\n function allowance(address holder, address spender)\r\n public view override(IERC20) returns (uint256) {\r\n return _allowances[holder][spender];\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-approve}.\r\n *\r\n * Note that accounts cannot have allowance issued by their operators.\r\n */\r\n function approve(address spender, uint256 value) external override(IERC20) returns (bool) {\r\n address holder = _msgSender();\r\n _approve(holder, spender, value);\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-transferFrom}.\r\n *\r\n * Note that operator and allowance concepts are orthogonal: operators cannot\r\n * call `transferFrom` (unless they have allowance), and accounts with\r\n * allowance cannot call `operatorSend` (unless they are operators).\r\n *\r\n * Emits {Sent}, {Transfer} and {Approval} events.\r\n */\r\n function transferFrom(address holder, address recipient, uint256 amount)\r\n external override(IERC20) returns (bool) {\r\n require(recipient != address(0), \"ERC777: transfer to zero address\");\r\n require(holder != address(0), \"ERC777: transfer from zero address\");\r\n\r\n address spender = _msgSender();\r\n\r\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\r\n\r\n _move(spender, holder, recipient, amount, \"\", \"\");\r\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\r\n\r\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\r\n * the total supply.\r\n *\r\n * If a send hook is registered for `account`, the corresponding function\r\n * will be called with `operator`, `data` and `operatorData`.\r\n *\r\n * See {IERC777Sender} and {IERC777Recipient}.\r\n *\r\n * Emits {Minted} and {Transfer} events.\r\n *\r\n * Requirements\r\n *\r\n * - `account` cannot be the zero address.\r\n * - if `account` is a contract, it must implement the {IERC777Recipient}\r\n * interface.\r\n */\r\n function _mint(\r\n address operator,\r\n address account,\r\n uint256 amount,\r\n bytes memory userData,\r\n bytes memory operatorData\r\n )\r\n internal\r\n {\r\n require(account != address(0), \"ERC777: mint to zero address\");\r\n\r\n // Update state variables\r\n _totalSupply = _totalSupply.add(amount);\r\n _balances[account] = _balances[account].add(amount);\r\n\r\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\r\n\r\n emit Minted(operator, account, amount, userData, operatorData);\r\n emit Transfer(address(0), account, amount);\r\n }\r\n\r\n /**\r\n * @dev Send tokens\r\n * @param operator address operator requesting the transfer\r\n * @param from address token holder address\r\n * @param to address recipient address\r\n * @param amount uint256 amount of tokens to transfer\r\n * @param userData bytes extra information provided by the token holder (if any)\r\n * @param operatorData bytes extra information provided by the operator (if any)\r\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\r\n */\r\n function _send(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256 amount,\r\n bytes memory userData,\r\n bytes memory operatorData,\r\n bool requireReceptionAck\r\n )\r\n internal\r\n {\r\n require(from != address(0), \"ERC777: send from zero address\");\r\n require(to != address(0), \"ERC777: send to zero address\");\r\n\r\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\r\n\r\n _move(operator, from, to, amount, userData, operatorData);\r\n\r\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\r\n }\r\n\r\n /**\r\n * @dev Burn tokens\r\n * @param operator address operator requesting the operation\r\n * @param from address token holder address\r\n * @param amount uint256 amount of tokens to burn\r\n * @param data bytes extra information provided by the token holder\r\n * @param operatorData bytes extra information provided by the operator (if any)\r\n */\r\n function _burn(\r\n address operator,\r\n address from,\r\n uint256 amount,\r\n bytes memory data,\r\n bytes memory operatorData\r\n )\r\n internal\r\n {\r\n require(from != address(0), \"ERC777: burn from zero address\");\r\n\r\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\r\n\r\n // Update state variables\r\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\r\n _totalSupply = _totalSupply.sub(amount);\r\n\r\n emit Burned(operator, from, amount, data, operatorData);\r\n emit Transfer(from, address(0), amount);\r\n }\r\n\r\n function _move(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256 amount,\r\n bytes memory userData,\r\n bytes memory operatorData\r\n )\r\n internal\r\n {\r\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\r\n _balances[to] = _balances[to].add(amount);\r\n\r\n emit Sent(operator, from, to, amount, userData, operatorData);\r\n emit Transfer(from, to, amount);\r\n }\r\n\r\n function _approve(address holder, address spender, uint256 value) internal {\r\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\r\n // currently unnecessary.\r\n //require(holder != address(0), \"ERC777: approve from the zero address\");\r\n require(spender != address(0), \"ERC777: approve to zero address\");\r\n\r\n _allowances[holder][spender] = value;\r\n emit Approval(holder, spender, value);\r\n }\r\n\r\n /**\r\n * @dev Call from.tokensToSend() if the interface is registered\r\n * @param operator address operator requesting the transfer\r\n * @param from address token holder address\r\n * @param to address recipient address\r\n * @param amount uint256 amount of tokens to transfer\r\n * @param userData bytes extra information provided by the token holder (if any)\r\n * @param operatorData bytes extra information provided by the operator (if any)\r\n */\r\n function _callTokensToSend(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256 amount,\r\n bytes memory userData,\r\n bytes memory operatorData\r\n )\r\n internal\r\n {\r\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\r\n if (implementer != address(0)) {\r\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\r\n }\r\n }\r\n\r\n /**\r\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\r\n * tokensReceived() was not registered for the recipient\r\n * @param operator address operator requesting the transfer\r\n * @param from address token holder address\r\n * @param to address recipient address\r\n * @param amount uint256 amount of tokens to transfer\r\n * @param userData bytes extra information provided by the token holder (if any)\r\n * @param operatorData bytes extra information provided by the operator (if any)\r\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\r\n */\r\n function _callTokensReceived(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256 amount,\r\n bytes memory userData,\r\n bytes memory operatorData,\r\n bool requireReceptionAck\r\n )\r\n private\r\n {\r\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\r\n if (implementer != address(0)) {\r\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\r\n } else if (requireReceptionAck) {\r\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\r\n }\r\n }\r\n}\r\n"
+ },
+ "contracts/interface/IERC677Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\ninterface IERC677Receiver {\r\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\r\n}"
+ },
+ "contracts/zeppelin/token/ERC777/IERC777Sender.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\r\n *\r\n * `IERC777` Token holders can be notified of operations performed on their\r\n * tokens by having a contract implement this interface (contract holders can be\r\n * their own implementer) and registering it on the\r\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\r\n *\r\n * See `IERC1820Registry` and `ERC1820Implementer`.\r\n */\r\ninterface IERC777Sender {\r\n /**\r\n * @dev Called by an `IERC777` token contract whenever a registered holder's\r\n * (`from`) tokens are about to be moved or destroyed. The type of operation\r\n * is conveyed by `to` being the zero address or not.\r\n *\r\n * This call occurs _before_ the token contract's state is updated, so\r\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\r\n *\r\n * This function may revert to prevent the operation from being executed.\r\n */\r\n function tokensToSend(\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes calldata userData,\r\n bytes calldata operatorData\r\n ) external;\r\n}\r\n"
+ },
+ "contracts/Bridge/BridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\n// Import base Initializable contract\r\nimport \"../zeppelin/upgradable/Initializable.sol\";\r\n// Import interface and library from OpenZeppelin contracts\r\nimport \"../zeppelin/upgradable/utils/ReentrancyGuard.sol\";\r\nimport \"../zeppelin/upgradable/lifecycle/UpgradablePausable.sol\";\r\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\r\n\r\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\r\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\r\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\r\nimport \"../zeppelin/token/ERC20/SafeERC20.sol\";\r\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\r\nimport \"../zeppelin/utils/Address.sol\";\r\nimport \"../zeppelin/math/SafeMath.sol\";\r\n\r\nimport \"./IBridgeV2.sol\";\r\nimport \"../interface/ISideToken.sol\";\r\nimport \"../interface/ISideTokenFactory.sol\";\r\nimport \"../AllowTokens/AllowTokensV0.sol\";\r\nimport \"../Utils/UtilsV1.sol\";\r\n\r\ncontract BridgeV2 is Initializable, IBridgeV2, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {\r\n using SafeMath for uint256;\r\n using SafeERC20 for IERC20;\r\n using Address for address;\r\n\r\n address constant private NULL_ADDRESS = address(0);\r\n bytes32 constant private NULL_HASH = bytes32(0);\r\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\r\n\r\n address private federation;\r\n uint256 private feePercentage;\r\n string public symbolPrefix;\r\n uint256 public lastDay;\r\n uint256 public spentToday;\r\n\r\n mapping (address => address) public mappedTokens; // OirignalToken => SideToken\r\n mapping (address => address) public originalTokens; // SideToken => OriginalToken\r\n mapping (address => bool) public knownTokens; // OriginalToken => true\r\n mapping(bytes32 => bool) public processed; // ProcessedHash => true\r\n AllowTokensV0 public allowTokens;\r\n ISideTokenFactory public sideTokenFactory;\r\n //Bridge_v1 variables\r\n bool public isUpgrading;\r\n uint256 constant public FEE_PERCENTAGE_DIVIDER = 10000; // Percentage with up to 2 decimals\r\n bool private alreadyRun;\r\n\r\n event FederationChanged(address _newFederation);\r\n event SideTokenFactoryChanged(address _newSideTokenFactory);\r\n event Upgrading(bool isUpgrading);\r\n function initialize(\r\n address _manager,\r\n address _federation,\r\n address _allowTokens,\r\n address _sideTokenFactory,\r\n string memory _symbolPrefix\r\n ) public initializer {\r\n UpgradableOwnable.initialize(_manager);\r\n UpgradablePausable.__Pausable_init(_manager);\r\n symbolPrefix = _symbolPrefix;\r\n allowTokens = AllowTokensV0(_allowTokens);\r\n _changeSideTokenFactory(_sideTokenFactory);\r\n _changeFederation(_federation);\r\n //keccak256(\"ERC777TokensRecipient\")\r\n ERC_1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\r\n }\r\n\r\n function version() external pure override returns (string memory) {\r\n return \"v2\";\r\n }\r\n\r\n modifier onlyFederation() {\r\n require(msg.sender == federation, \"Bridge: Sender not Federation\");\r\n _;\r\n }\r\n\r\n modifier whenNotUpgrading() {\r\n require(!isUpgrading, \"Bridge: Upgrading\");\r\n _;\r\n }\r\n\r\n function acceptTransfer(\r\n address tokenAddress,\r\n address receiver,\r\n uint256 amount,\r\n string calldata symbol,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex,\r\n uint8 decimals,\r\n uint256 granularity\r\n ) external onlyFederation whenNotPaused nonReentrant override returns(bool) {\r\n require(tokenAddress != NULL_ADDRESS, \"Bridge: Token is null\");\r\n require(receiver != NULL_ADDRESS, \"Bridge: Receiver is null\");\r\n require(amount > 0, \"Bridge: Amount 0\");\r\n require(bytes(symbol).length > 0, \"Bridge: Empty symbol\");\r\n require(blockHash != NULL_HASH, \"Bridge: BlockHash is null\");\r\n require(transactionHash != NULL_HASH, \"Bridge: Transaction is null\");\r\n require(decimals <= 18, \"Bridge: Decimals bigger 18\");\r\n require(UtilsV1.granularityToDecimals(granularity) <= 18, \"Bridge: invalid granularity\");\r\n\r\n _processTransaction(blockHash, transactionHash, receiver, amount, logIndex);\r\n\r\n if (knownTokens[tokenAddress]) {\r\n _acceptCrossBackToToken(receiver, tokenAddress, decimals, granularity, amount);\r\n } else {\r\n _acceptCrossToSideToken(receiver, tokenAddress, decimals, granularity, amount, symbol);\r\n }\r\n return true;\r\n }\r\n\r\n function _acceptCrossToSideToken(\r\n address receiver,\r\n address tokenAddress,\r\n uint8 decimals,\r\n uint256 granularity,\r\n uint256 amount,\r\n string memory symbol\r\n ) private {\r\n\r\n (uint256 calculatedGranularity,uint256 formattedAmount) = UtilsV1.calculateGranularityAndAmount(decimals, granularity, amount);\r\n address sideToken = mappedTokens[tokenAddress];\r\n if (sideToken == NULL_ADDRESS) {\r\n sideToken = _createSideToken(tokenAddress, symbol, calculatedGranularity);\r\n } else {\r\n require(calculatedGranularity == IERC777(sideToken).granularity(), \"Bridge: Granularity differ from side token\");\r\n }\r\n ISideToken(sideToken).mint(receiver, formattedAmount, \"\", \"\");\r\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, 18, calculatedGranularity);\r\n }\r\n\r\n function _acceptCrossBackToToken(address receiver, address tokenAddress, uint8 decimals, uint256 granularity, uint256 amount) private {\r\n require(decimals == 18, \"Bridge: Invalid decimals cross back\");\r\n //As side tokens are ERC777 we need to convert granularity to decimals\r\n (uint8 calculatedDecimals, uint256 formattedAmount) = UtilsV1.calculateDecimalsAndAmount(tokenAddress, granularity, amount);\r\n IERC20(tokenAddress).safeTransfer(receiver, formattedAmount);\r\n emit AcceptedCrossTransfer(tokenAddress, receiver, amount, decimals, granularity, formattedAmount, calculatedDecimals, 1);\r\n }\r\n\r\n /**\r\n * ERC-20 tokens approve and transferFrom pattern\r\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\r\n */\r\n function receiveTokens(address tokenToUse, uint256 amount) override external whenNotUpgrading whenNotPaused nonReentrant returns(bool) {\r\n address sender = _msgSender();\r\n require(!sender.isContract(), \"Bridge: Sender can't be a contract\");\r\n //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them\r\n IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);\r\n crossTokens(tokenToUse, sender, amount, \"\");\r\n return true;\r\n }\r\n\r\n /**\r\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\r\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\r\n */\r\n function tokensReceived (\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes calldata userData,\r\n bytes calldata\r\n ) external whenNotPaused whenNotUpgrading override(IBridgeV2, IERC777Recipient) {\r\n //Hook from ERC777address\r\n if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom\r\n require(to == address(this), \"Bridge: Not to address\");\r\n address tokenToUse = _msgSender();\r\n //This can only be used with trusted contracts\r\n crossTokens(tokenToUse, from, amount, userData);\r\n }\r\n\r\n function crossTokens(address tokenToUse, address from, uint256 amount, bytes memory userData) private {\r\n bool isASideToken = originalTokens[tokenToUse] != NULL_ADDRESS;\r\n //Send the payment to the MultiSig of the Federation\r\n uint256 fee = amount.mul(feePercentage).div(FEE_PERCENTAGE_DIVIDER);\r\n uint256 amountMinusFees = amount.sub(fee);\r\n if (isASideToken) {\r\n uint256 modulo = amountMinusFees.mod(IERC777(tokenToUse).granularity());\r\n fee = fee.add(modulo);\r\n amountMinusFees = amountMinusFees.sub(modulo);\r\n }\r\n if(fee > 0) {\r\n IERC20(tokenToUse).safeTransfer(owner(), fee);\r\n }\r\n if (isASideToken) {\r\n verifyWithAllowTokens(tokenToUse, amount, isASideToken);\r\n //Side Token Crossing\r\n IERC777(tokenToUse).burn(amountMinusFees, userData);\r\n // solium-disable-next-line max-len\r\n emit Cross(originalTokens[tokenToUse], from, amountMinusFees, IERC777(tokenToUse).symbol(), userData, IERC777(tokenToUse).decimals(), IERC777(tokenToUse).granularity());\r\n } else {\r\n //Main Token Crossing\r\n knownTokens[tokenToUse] = true;\r\n (uint8 decimals, uint256 granularity, string memory symbol) = UtilsV1.getTokenInfo(tokenToUse);\r\n uint formattedAmount = amount;\r\n if(decimals != 18) {\r\n formattedAmount = amount.mul(uint256(10)**(18-decimals));\r\n }\r\n //We consider the amount before fees converted to 18 decimals to check the limits\r\n verifyWithAllowTokens(tokenToUse, formattedAmount, isASideToken);\r\n emit Cross(tokenToUse, from, amountMinusFees, symbol, userData, decimals, granularity);\r\n }\r\n }\r\n\r\n function _createSideToken(address token, string memory symbol, uint256 granularity) private returns (address sideToken){\r\n string memory newSymbol = string(abi.encodePacked(symbolPrefix, symbol));\r\n address sideTokenAddress = sideTokenFactory.createSideToken(newSymbol, newSymbol, granularity);\r\n sideToken = sideTokenAddress;\r\n mappedTokens[token] = sideToken;\r\n originalTokens[sideTokenAddress] = token;\r\n emit NewSideToken(sideTokenAddress, token, newSymbol, granularity);\r\n return sideToken;\r\n }\r\n\r\n function verifyWithAllowTokens(address tokenToUse, uint256 amount, bool isASideToken) private {\r\n // solium-disable-next-line security/no-block-members\r\n if (block.timestamp > lastDay + 24 hours) { // solhint-disable-line not-rely-on-time\r\n // solium-disable-next-line security/no-block-members\r\n lastDay = block.timestamp; // solhint-disable-line not-rely-on-time\r\n spentToday = 0;\r\n }\r\n require(allowTokens.isValidTokenTransfer(tokenToUse, amount, spentToday, isASideToken), \"Bridge: Bigger than limit\");\r\n spentToday = spentToday.add(amount);\r\n }\r\n\r\n function getTransactionId(\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n address _receiver,\r\n uint256 _amount,\r\n uint32 _logIndex\r\n )\r\n public pure returns(bytes32)\r\n {\r\n return keccak256(abi.encodePacked(_blockHash, _transactionHash, _receiver, _amount, _logIndex));\r\n }\r\n\r\n function _processTransaction(\r\n bytes32 _blockHash,\r\n bytes32 _transactionHash,\r\n address _receiver,\r\n uint256 _amount,\r\n uint32 _logIndex\r\n )\r\n private\r\n {\r\n bytes32 compiledId = getTransactionId(_blockHash, _transactionHash, _receiver, _amount, _logIndex);\r\n require(!processed[compiledId], \"Bridge: Already processed\");\r\n processed[compiledId] = true;\r\n }\r\n\r\n function setFeePercentage(uint amount) external onlyOwner whenNotPaused {\r\n require(amount < (FEE_PERCENTAGE_DIVIDER/10), \"Bridge: bigger than 10%\");\r\n feePercentage = amount;\r\n emit FeePercentageChanged(feePercentage);\r\n }\r\n\r\n function getFeePercentage() override external view returns(uint) {\r\n return feePercentage;\r\n }\r\n\r\n function calcMaxWithdraw() override external view returns (uint) {\r\n uint spent = spentToday;\r\n // solium-disable-next-line security/no-block-members\r\n if (block.timestamp > lastDay + 24 hours) // solhint-disable-line not-rely-on-time\r\n spent = 0;\r\n return allowTokens.calcMaxWithdraw(spent);\r\n }\r\n\r\n function changeFederation(address newFederation) external onlyOwner returns(bool) {\r\n _changeFederation(newFederation);\r\n return true;\r\n }\r\n\r\n function _changeFederation(address newFederation) internal {\r\n require(newFederation != NULL_ADDRESS, \"Bridge: Federation is empty\");\r\n federation = newFederation;\r\n emit FederationChanged(federation);\r\n }\r\n\r\n function getFederation() external view returns(address) {\r\n return federation;\r\n }\r\n\r\n function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner returns(bool) {\r\n _changeSideTokenFactory(newSideTokenFactory);\r\n return true;\r\n }\r\n\r\n function _changeSideTokenFactory(address newSideTokenFactory) internal {\r\n require(newSideTokenFactory != NULL_ADDRESS, \"Bridge: SideTokenFactory is empty\");\r\n sideTokenFactory = ISideTokenFactory(newSideTokenFactory);\r\n emit SideTokenFactoryChanged(newSideTokenFactory);\r\n }\r\n\r\n function startUpgrade() external onlyOwner {\r\n isUpgrading = true;\r\n emit Upgrading(isUpgrading);\r\n }\r\n\r\n function endUpgrade() external onlyOwner {\r\n isUpgrading = false;\r\n emit Upgrading(isUpgrading);\r\n }\r\n\r\n //This method is only to recreate the USDT and USDC tokens on rsk without granularity restrictions.\r\n function clearSideToken() external onlyOwner returns(bool) {\r\n require(!alreadyRun, \"already done\");\r\n alreadyRun = true;\r\n address payable[4] memory sideTokens = [\r\n 0xe506F698b31a66049BD4653ed934E7a07Cbc5549,\r\n 0x5a42221D7AaE8e185BC0054Bb036D9757eC18857,\r\n 0xcdc8ccBbFB6407c53118fE47259e8d00C81F42CD,\r\n 0x6117C9529F15c52e2d3188d5285C745B757b5825\r\n ];\r\n for (uint i = 0; i < sideTokens.length; i++) {\r\n address originalToken = address(originalTokens[sideTokens[i]]);\r\n originalTokens[sideTokens[i]] = NULL_ADDRESS;\r\n mappedTokens[originalToken] = address(NULL_ADDRESS);\r\n }\r\n return true;\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/Bridge/IBridgeV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\ninterface IBridgeV2 {function version() external pure returns (string memory);\r\n\r\n function getFeePercentage() external view returns(uint);\r\n\r\n function calcMaxWithdraw() external view returns (uint);\r\n\r\n /**\r\n * ERC-20 tokens approve and transferFrom pattern\r\n * See https://eips.ethereum.org/EIPS/eip-20#transferfrom\r\n */\r\n function receiveTokens(address tokenToUse, uint256 amount) external returns(bool);\r\n\r\n /**\r\n * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction\r\n * See https://eips.ethereum.org/EIPS/eip-777#motivation for details\r\n */\r\n function tokensReceived (\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes calldata userData,\r\n bytes calldata operatorData\r\n ) external;\r\n\r\n /**\r\n * Accepts the transaction from the other chain that was voted and sent by the federation contract\r\n */\r\n function acceptTransfer(\r\n address originalTokenAddress,\r\n address receiver,\r\n uint256 amount,\r\n string calldata symbol,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex,\r\n uint8 decimals,\r\n uint256 granularity\r\n ) external returns(bool);\r\n\r\n event Cross(address indexed _tokenAddress, address indexed _to, uint256 _amount, string _symbol, bytes _userData,\r\n uint8 _decimals, uint256 _granularity);\r\n event NewSideToken(address indexed _newSideTokenAddress, address indexed _originalTokenAddress, string _newSymbol, uint256 _granularity);\r\n event AcceptedCrossTransfer(address indexed _tokenAddress, address indexed _to, uint256 _amount, uint8 _decimals, uint256 _granularity,\r\n uint256 _formattedAmount, uint8 _calculatedDecimals, uint256 _calculatedGranularity);\r\n event FeePercentageChanged(uint256 _amount);\r\n}"
+ },
+ "contracts/AllowTokens/AllowTokensV0.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/math/SafeMath.sol\";\r\nimport \"../zeppelin/ownership/Ownable.sol\";\r\n\r\ncontract AllowTokensV0 is Ownable {\r\n using SafeMath for uint256;\r\n\r\n address constant private NULL_ADDRESS = address(0);\r\n\r\n mapping (address => bool) public allowedTokens;\r\n bool private validateAllowedTokens;\r\n uint256 private maxTokensAllowed;\r\n uint256 private minTokensAllowed;\r\n uint256 public dailyLimit;\r\n\r\n event AllowedTokenAdded(address indexed _tokenAddress);\r\n event AllowedTokenRemoved(address indexed _tokenAddress);\r\n event AllowedTokenValidation(bool _enabled);\r\n event MaxTokensAllowedChanged(uint256 _maxTokens);\r\n event MinTokensAllowedChanged(uint256 _minTokens);\r\n event DailyLimitChanged(uint256 dailyLimit);\r\n\r\n modifier notNull(address _address) {\r\n require(_address != NULL_ADDRESS, \"AllowTokens: Address cannot be empty\");\r\n _;\r\n }\r\n\r\n constructor(address _manager) {\r\n transferOwnership(_manager);\r\n validateAllowedTokens = true;\r\n maxTokensAllowed = 10000 ether;\r\n minTokensAllowed = 1 ether;\r\n dailyLimit = 100000 ether;\r\n }\r\n\r\n function isValidatingAllowedTokens() external view returns(bool) {\r\n return validateAllowedTokens;\r\n }\r\n\r\n function getMaxTokensAllowed() external view returns(uint256) {\r\n return maxTokensAllowed;\r\n }\r\n\r\n function getMinTokensAllowed() external view returns(uint256) {\r\n return minTokensAllowed;\r\n }\r\n\r\n function allowedTokenExist(address token) private view notNull(token) returns (bool) {\r\n return allowedTokens[token];\r\n }\r\n\r\n function isTokenAllowed(address token) public view notNull(token) returns (bool) {\r\n if (validateAllowedTokens) {\r\n return allowedTokenExist(token);\r\n }\r\n return true;\r\n }\r\n\r\n function addAllowedToken(address token) external onlyOwner {\r\n require(!allowedTokenExist(token), \"AllowTokens: Token already exists in allowedTokens\");\r\n allowedTokens[token] = true;\r\n emit AllowedTokenAdded(token);\r\n }\r\n\r\n function removeAllowedToken(address token) external onlyOwner {\r\n require(allowedTokenExist(token), \"AllowTokens: Token does not exis in allowedTokenst\");\r\n allowedTokens[token] = false;\r\n emit AllowedTokenRemoved(token);\r\n }\r\n\r\n function enableAllowedTokensValidation() external onlyOwner {\r\n validateAllowedTokens = true;\r\n emit AllowedTokenValidation(validateAllowedTokens);\r\n }\r\n\r\n function disableAllowedTokensValidation() external onlyOwner {\r\n // Before disabling Allowed Tokens Validations some kind of contract validation system\r\n // should be implemented on the Bridge for the methods receiveTokens, tokenFallback and tokensReceived\r\n validateAllowedTokens = false;\r\n emit AllowedTokenValidation(validateAllowedTokens);\r\n }\r\n\r\n function setMaxTokensAllowed(uint256 maxTokens) external onlyOwner {\r\n require(maxTokens >= minTokensAllowed, \"AllowTokens: Max Tokens should be equal or bigger than Min Token\");\r\n maxTokensAllowed = maxTokens;\r\n emit MaxTokensAllowedChanged(maxTokensAllowed);\r\n }\r\n\r\n function setMinTokensAllowed(uint256 minTokens) external onlyOwner {\r\n require(maxTokensAllowed >= minTokens, \"AllowTokens: minTokens should be equal or smaller than maxTokens\");\r\n minTokensAllowed = minTokens;\r\n emit MinTokensAllowedChanged(minTokensAllowed);\r\n }\r\n\r\n function changeDailyLimit(uint256 _dailyLimit) external onlyOwner {\r\n require(_dailyLimit >= maxTokensAllowed, \"AllowTokens: dailyLimit should be equal or bigger than maxTokens\");\r\n dailyLimit = _dailyLimit;\r\n emit DailyLimitChanged(_dailyLimit);\r\n }\r\n\r\n // solium-disable-next-line max-len\r\n function isValidTokenTransfer(address tokenToUse, uint amount, uint spentToday, bool isSideToken) external view returns (bool) {\r\n if(amount > maxTokensAllowed)\r\n return false;\r\n if(amount < minTokensAllowed)\r\n return false;\r\n if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\r\n return false;\r\n if(!isSideToken && !isTokenAllowed(tokenToUse))\r\n return false;\r\n return true;\r\n }\r\n\r\n function calcMaxWithdraw(uint spentToday) external view returns (uint) {\r\n uint maxWithrow = dailyLimit - spentToday;\r\n if (dailyLimit < spentToday)\r\n return 0;\r\n if(maxWithrow > maxTokensAllowed)\r\n maxWithrow = maxTokensAllowed;\r\n return maxWithrow;\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/Utils/UtilsV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/math/SafeMath.sol\";\r\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\r\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\r\n\r\nlibrary UtilsV1 {\r\n using SafeMath for uint256;\r\n\r\n IERC1820Registry constant private ERC_1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\r\n // keccak256(\"ERC777Token\")\r\n bytes32 constant private TOKENS_ERC777_HASH = 0xac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054;\r\n\r\n function getTokenInfo(address tokenToUse) external view returns (uint8 decimals, uint256 granularity, string memory symbol) {\r\n decimals = getDecimals(tokenToUse);\r\n granularity = getGranularity(tokenToUse);\r\n symbol = getSymbol(tokenToUse);\r\n }\r\n\r\n function getSymbol(address tokenToUse) public view returns (string memory symbol) {\r\n //support 32 bytes or string symbol\r\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"symbol()\"));\r\n require(success, \"Utils: Token hasn't symbol()\");\r\n if (data.length == 32) {\r\n symbol = bytes32ToString(abi.decode(data, (bytes32)));\r\n } else {\r\n symbol = abi.decode(data, (string));\r\n }\r\n require(bytes(symbol).length > 0, \"Utils: Token empty symbol\");\r\n return symbol;\r\n }\r\n\r\n function getDecimals(address tokenToUse) public view returns (uint8) {\r\n //support decimals as uint256 or uint8\r\n (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature(\"decimals()\"));\r\n require(success, \"Utils: No decimals\");\r\n require(data.length == 32, \"Utils: Decimals not uint\");\r\n // uint: enc(X) is the big-endian encoding of X,\r\n //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.\r\n uint256 decimalsDecoded = abi.decode(data, (uint256));\r\n require(decimalsDecoded <= 18, \"Utils: Decimals not in 0 to 18\");\r\n return uint8(decimalsDecoded);\r\n }\r\n\r\n function getGranularity(address tokenToUse) public view returns (uint256 granularity) {\r\n granularity = 1;\r\n //support granularity if ERC777\r\n address implementer = ERC_1820.getInterfaceImplementer(tokenToUse, TOKENS_ERC777_HASH);\r\n if (implementer != address(0)) {\r\n granularity = IERC777(implementer).granularity();\r\n //Verify granularity is power of 10 to keep it compatible with ERC20 decimals\r\n granularityToDecimals(granularity);\r\n }\r\n return granularity;\r\n }\r\n\r\n /* bytes32 (fixed-size array) to string (dynamically-sized array) */\r\n function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) {\r\n uint8 i = 0;\r\n while(i < 32 && _bytes32[i] != 0) {\r\n i++;\r\n }\r\n bytes memory bytesArray = new bytes(i);\r\n for (i = 0; i < 32 && _bytes32[i] != 0; i++) {\r\n bytesArray[i] = _bytes32[i];\r\n }\r\n return string(bytesArray);\r\n }\r\n\r\n function decimalsToGranularity(uint8 decimals) public pure returns (uint256) {\r\n require(decimals <= 18, \"Utils: Decimals not in 0 to 18\");\r\n return uint256(10)**(18-decimals);\r\n }\r\n\r\n function granularityToDecimals(uint256 granularity) public pure returns (uint8) {\r\n if(granularity == 1) return 18;\r\n if(granularity == 10) return 17;\r\n if(granularity == 100) return 16;\r\n if(granularity == 1000) return 15;\r\n if(granularity == 10000) return 14;\r\n if(granularity == 100000) return 13;\r\n if(granularity == 1000000) return 12;\r\n if(granularity == 10000000) return 11;\r\n if(granularity == 100000000) return 10;\r\n if(granularity == 1000000000) return 9;\r\n if(granularity == 10000000000) return 8;\r\n if(granularity == 100000000000) return 7;\r\n if(granularity == 1000000000000) return 6;\r\n if(granularity == 10000000000000) return 5;\r\n if(granularity == 100000000000000) return 4;\r\n if(granularity == 1000000000000000) return 3;\r\n if(granularity == 10000000000000000) return 2;\r\n if(granularity == 100000000000000000) return 1;\r\n if(granularity == 1000000000000000000) return 0;\r\n require(false, \"Utils: invalid granularity\");\r\n return 0;\r\n }\r\n\r\n function calculateGranularityAndAmount(uint8 decimals, uint256 granularity, uint256 amount) external pure\r\n returns(uint256 calculatedGranularity, uint256 formattedAmount) {\r\n\r\n if(decimals == 18) {\r\n //tokenAddress is a ERC20 with 18 decimals should have 1 granularity\r\n //tokenAddress is a ERC777 token we give the same granularity\r\n calculatedGranularity = granularity;\r\n formattedAmount = amount;\r\n } else {\r\n //tokenAddress is a ERC20 with other than 18 decimals\r\n calculatedGranularity = decimalsToGranularity(decimals);\r\n formattedAmount = amount.mul(calculatedGranularity);\r\n }\r\n }\r\n\r\n function calculateDecimalsAndAmount(address tokenAddress, uint256 granularity, uint256 amount)\r\n external view returns (uint8 calculatedDecimals, uint256 formattedAmount) {\r\n uint8 tokenDecimals = getDecimals(tokenAddress);\r\n //As side tokens are ERC777 we need to convert granularity to decimals\r\n calculatedDecimals = granularityToDecimals(granularity);\r\n require(tokenDecimals == calculatedDecimals, \"Utils: Token decimals differ from decimals - granularity\");\r\n formattedAmount = amount.div(granularity);\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/zeppelin/ownership/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../GSN/Context.sol\";\r\n/**\r\n * @dev Contract module which provides a basic access control mechanism, where\r\n * there is an account (an owner) that can be granted exclusive access to\r\n * specific functions.\r\n *\r\n * This module is used through inheritance. It will make available the modifier\r\n * `onlyOwner`, which can be applied to your functions to restrict their use to\r\n * the owner.\r\n */\r\nabstract contract Ownable is Context {\r\n address private _owner;\r\n\r\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\r\n\r\n /**\r\n * @dev Initializes the contract setting the deployer as the initial owner.\r\n */\r\n constructor () {\r\n _owner = _msgSender();\r\n emit OwnershipTransferred(address(0), _owner);\r\n }\r\n\r\n /**\r\n * @dev Returns the address of the current owner.\r\n */\r\n function owner() public view returns (address) {\r\n return _owner;\r\n }\r\n\r\n /**\r\n * @dev Throws if called by any account other than the owner.\r\n */\r\n modifier onlyOwner() {\r\n require(isOwner(), \"Ownable: caller is not the owner\");\r\n _;\r\n }\r\n\r\n /**\r\n * @dev Returns true if the caller is the current owner.\r\n */\r\n function isOwner() public view returns (bool) {\r\n return _msgSender() == _owner;\r\n }\r\n\r\n /**\r\n * @dev Leaves the contract without owner. It will not be possible to call\r\n * `onlyOwner` functions anymore. Can only be called by the current owner.\r\n *\r\n * NOTE: Renouncing ownership will leave the contract without an owner,\r\n * thereby removing any functionality that is only available to the owner.\r\n */\r\n function renounceOwnership() public onlyOwner {\r\n emit OwnershipTransferred(_owner, address(0));\r\n _owner = address(0);\r\n }\r\n\r\n /**\r\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n * Can only be called by the current owner.\r\n */\r\n function transferOwnership(address newOwner) public onlyOwner {\r\n _transferOwnership(newOwner);\r\n }\r\n\r\n /**\r\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n */\r\n function _transferOwnership(address newOwner) internal {\r\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\r\n emit OwnershipTransferred(_owner, newOwner);\r\n _owner = newOwner;\r\n }\r\n}\r\n"
+ },
+ "contracts/test/mockReceiveTokensCall.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../interface/IBridge.sol\";\r\nimport \"../zeppelin/token/ERC20/IERC20.sol\";\r\nimport \"../zeppelin/token/ERC777/IERC777.sol\";\r\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\r\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\r\n\r\ncontract mockReceiveTokensCall is IERC777Recipient {\r\n address public bridge;\r\n IERC1820Registry constant public erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\r\n\r\n constructor(address _bridge) {\r\n bridge = _bridge;\r\n //keccak256(\"ERC777TokensRecipient\")\r\n erc1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));\r\n }\r\n\r\n function callReceiveTokens(address tokenToUse, address receiver, uint256 amount) external {\r\n IERC20(tokenToUse).approve(bridge, amount);\r\n IBridge(bridge).receiveTokensTo(tokenToUse, receiver, amount);\r\n }\r\n\r\n function callDepositTo(address receiver) external payable {\r\n IBridge(bridge).depositTo{ value: msg.value }(receiver);\r\n }\r\n\r\n function callTokensReceived(address tokenToUse, uint256 amount, bytes calldata data) external {\r\n IERC777(tokenToUse).send(bridge, amount, data);\r\n }\r\n\r\n // Mandatory for IERC777Recipient\r\n function tokensReceived(\r\n address,\r\n address,\r\n address,\r\n uint,\r\n bytes calldata,\r\n bytes calldata\r\n ) override external view {\r\n this;\r\n }\r\n}"
+ },
+ "contracts/test/mockERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/token/ERC777/IERC777Recipient.sol\";\r\nimport \"../zeppelin/introspection/IERC1820Registry.sol\";\r\n\r\ncontract mockERC777Recipient is IERC777Recipient {\r\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\r\n\r\n constructor() {\r\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777TokensRecipient\"), address(this));\r\n }\r\n\r\n event Success(\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes userData,\r\n bytes operatorData);\r\n\r\n /**\r\n * ERC-677's only method implementation\r\n * See https://github.com/ethereum/EIPs/issues/677 for details\r\n */\r\n function tokensReceived(\r\n address operator,\r\n address from,\r\n address to,\r\n uint amount,\r\n bytes calldata userData,\r\n bytes calldata operatorData\r\n ) override external {\r\n emit Success(operator, from, to, amount, userData, operatorData);\r\n }\r\n}"
+ },
+ "contracts/SideToken/SideTokenV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/token/ERC777/ERC777.sol\";\r\n\r\ncontract SideTokenV1 is ERC777 {\r\n address public minter;\r\n\r\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr)\r\n ERC777(_tokenName, _tokenSymbol, new address[](0)) {\r\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\r\n minter = _minterAddr;\r\n }\r\n\r\n modifier onlyMinter() {\r\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\r\n _;\r\n }\r\n function mint(\r\n address account,\r\n uint256 amount,\r\n bytes calldata userData,\r\n bytes calldata operatorData\r\n )\r\n external onlyMinter\r\n {\r\n _mint(_msgSender(), account, amount, userData, operatorData);\r\n }\r\n\r\n}"
+ },
+ "contracts/SideTokenFactory/SideTokenFactoryV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/ownership/Secondary.sol\";\r\nimport \"../SideToken/SideTokenV1.sol\";\r\n\r\ncontract SideTokenFactoryV1 is Secondary {\r\n event CreatedSideToken(address sideToken, string symbol);\r\n\r\n function createSideToken(string calldata name, string calldata symbol) external onlyPrimary returns(SideTokenV1) {\r\n SideTokenV1 sideToken = new SideTokenV1(name, symbol, primary());\r\n emit CreatedSideToken(address(sideToken), symbol);\r\n return sideToken;\r\n }\r\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./IERC1155.sol\";\r\nimport \"./IERC1155MetadataURI.sol\";\r\nimport \"./IERC1155Receiver.sol\";\r\nimport \"../../GSN/Context.sol\";\r\nimport \"../../introspection/ERC165.sol\";\r\nimport \"../../math/SafeMath.sol\";\r\nimport \"../../utils/Address.sol\";\r\n\r\n/**\r\n *\r\n * @dev Implementation of the basic standard multi-token.\r\n * See https://eips.ethereum.org/EIPS/eip-1155\r\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\r\n *\r\n * _Available since v3.1._\r\n */\r\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\r\n using SafeMath for uint256;\r\n using Address for address;\r\n\r\n // Mapping from token ID to account balances\r\n mapping (uint256 => mapping(address => uint256)) private _balances;\r\n\r\n // Mapping from account to operator approvals\r\n mapping (address => mapping(address => bool)) private _operatorApprovals;\r\n\r\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\r\n string private _uri;\r\n\r\n /*\r\n * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\r\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\r\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\r\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\r\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\r\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\r\n *\r\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\r\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\r\n */\r\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\r\n\r\n /*\r\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\r\n */\r\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\r\n\r\n /**\r\n * @dev See {_setURI}.\r\n */\r\n constructor (string memory uri_) {\r\n _setURI(uri_);\r\n\r\n // register the supported interfaces to conform to ERC1155 via ERC165\r\n _registerInterface(_INTERFACE_ID_ERC1155);\r\n\r\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\r\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\r\n }\r\n\r\n /**\r\n * @dev See {IERC1155MetadataURI-uri}.\r\n *\r\n * This implementation returns the same URI for *all* token types. It relies\r\n * on the token type ID substitution mechanism\r\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\r\n *\r\n * Clients calling this function must replace the `\\{id\\}` substring with the\r\n * actual token type ID.\r\n */\r\n function uri(uint256) external view virtual override returns (string memory) {\r\n return _uri;\r\n }\r\n\r\n /**\r\n * @dev See {IERC1155-balanceOf}.\r\n *\r\n * Requirements:\r\n *\r\n * - `account` cannot be the zero address.\r\n */\r\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\r\n require(account != address(0), \"ERC1155: balance query for the zero address\");\r\n return _balances[id][account];\r\n }\r\n\r\n /**\r\n * @dev See {IERC1155-balanceOfBatch}.\r\n *\r\n * Requirements:\r\n *\r\n * - `accounts` and `ids` must have the same length.\r\n */\r\n function balanceOfBatch(\r\n address[] memory accounts,\r\n uint256[] memory ids\r\n )\r\n public\r\n view\r\n virtual\r\n override\r\n returns (uint256[] memory)\r\n {\r\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\r\n\r\n uint256[] memory batchBalances = new uint256[](accounts.length);\r\n\r\n for (uint256 i = 0; i < accounts.length; ++i) {\r\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\r\n }\r\n\r\n return batchBalances;\r\n }\r\n\r\n /**\r\n * @dev See {IERC1155-setApprovalForAll}.\r\n */\r\n function setApprovalForAll(address operator, bool approved) public virtual override {\r\n require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\r\n\r\n _operatorApprovals[_msgSender()][operator] = approved;\r\n emit ApprovalForAll(_msgSender(), operator, approved);\r\n }\r\n\r\n /**\r\n * @dev See {IERC1155-isApprovedForAll}.\r\n */\r\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\r\n return _operatorApprovals[account][operator];\r\n }\r\n\r\n /**\r\n * @dev See {IERC1155-safeTransferFrom}.\r\n */\r\n function safeTransferFrom(\r\n address from,\r\n address to,\r\n uint256 id,\r\n uint256 amount,\r\n bytes memory data\r\n )\r\n public\r\n virtual\r\n override\r\n {\r\n require(to != address(0), \"ERC1155: transfer to the zero address\");\r\n require(\r\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\r\n \"ERC1155: caller is not owner nor approved\"\r\n );\r\n\r\n address operator = _msgSender();\r\n\r\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\r\n\r\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\r\n _balances[id][to] = _balances[id][to].add(amount);\r\n\r\n emit TransferSingle(operator, from, to, id, amount);\r\n\r\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\r\n }\r\n\r\n /**\r\n * @dev See {IERC1155-safeBatchTransferFrom}.\r\n */\r\n function safeBatchTransferFrom(\r\n address from,\r\n address to,\r\n uint256[] memory ids,\r\n uint256[] memory amounts,\r\n bytes memory data\r\n )\r\n public\r\n virtual\r\n override\r\n {\r\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\r\n require(to != address(0), \"ERC1155: transfer to the zero address\");\r\n require(\r\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\r\n \"ERC1155: transfer caller is not owner nor approved\"\r\n );\r\n\r\n address operator = _msgSender();\r\n\r\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\r\n\r\n for (uint256 i = 0; i < ids.length; ++i) {\r\n uint256 id = ids[i];\r\n uint256 amount = amounts[i];\r\n\r\n _balances[id][from] = _balances[id][from].sub(\r\n amount,\r\n \"ERC1155: insufficient balance for transfer\"\r\n );\r\n _balances[id][to] = _balances[id][to].add(amount);\r\n }\r\n\r\n emit TransferBatch(operator, from, to, ids, amounts);\r\n\r\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\r\n }\r\n\r\n /**\r\n * @dev Sets a new URI for all token types, by relying on the token type ID\r\n * substitution mechanism\r\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\r\n *\r\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\r\n * URI or any of the amounts in the JSON file at said URI will be replaced by\r\n * clients with the token type ID.\r\n *\r\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\r\n * interpreted by clients as\r\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\r\n * for token type ID 0x4cce0.\r\n *\r\n * See {uri}.\r\n *\r\n * Because these URIs cannot be meaningfully represented by the {URI} event,\r\n * this function emits no events.\r\n */\r\n function _setURI(string memory newuri) internal virtual {\r\n _uri = newuri;\r\n }\r\n\r\n /**\r\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\r\n *\r\n * Emits a {TransferSingle} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `account` cannot be the zero address.\r\n * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\r\n * acceptance magic value.\r\n */\r\n function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\r\n require(account != address(0), \"ERC1155: mint to the zero address\");\r\n\r\n address operator = _msgSender();\r\n\r\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\r\n\r\n _balances[id][account] = _balances[id][account].add(amount);\r\n emit TransferSingle(operator, address(0), account, id, amount);\r\n\r\n _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\r\n }\r\n\r\n /**\r\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\r\n *\r\n * Requirements:\r\n *\r\n * - `ids` and `amounts` must have the same length.\r\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\r\n * acceptance magic value.\r\n */\r\n function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\r\n require(to != address(0), \"ERC1155: mint to the zero address\");\r\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\r\n\r\n address operator = _msgSender();\r\n\r\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\r\n\r\n for (uint i = 0; i < ids.length; i++) {\r\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\r\n }\r\n\r\n emit TransferBatch(operator, address(0), to, ids, amounts);\r\n\r\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\r\n }\r\n\r\n /**\r\n * @dev Destroys `amount` tokens of token type `id` from `account`\r\n *\r\n * Requirements:\r\n *\r\n * - `account` cannot be the zero address.\r\n * - `account` must have at least `amount` tokens of token type `id`.\r\n */\r\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\r\n require(account != address(0), \"ERC1155: burn from the zero address\");\r\n\r\n address operator = _msgSender();\r\n\r\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\r\n\r\n _balances[id][account] = _balances[id][account].sub(\r\n amount,\r\n \"ERC1155: burn amount exceeds balance\"\r\n );\r\n\r\n emit TransferSingle(operator, account, address(0), id, amount);\r\n }\r\n\r\n /**\r\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\r\n *\r\n * Requirements:\r\n *\r\n * - `ids` and `amounts` must have the same length.\r\n */\r\n function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\r\n require(account != address(0), \"ERC1155: burn from the zero address\");\r\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\r\n\r\n address operator = _msgSender();\r\n\r\n _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\r\n\r\n for (uint i = 0; i < ids.length; i++) {\r\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\r\n amounts[i],\r\n \"ERC1155: burn amount exceeds balance\"\r\n );\r\n }\r\n\r\n emit TransferBatch(operator, account, address(0), ids, amounts);\r\n }\r\n\r\n /**\r\n * @dev Hook that is called before any token transfer. This includes minting\r\n * and burning, as well as batched variants.\r\n *\r\n * The same hook is called on both single and batched variants. For single\r\n * transfers, the length of the `id` and `amount` arrays will be 1.\r\n *\r\n * Calling conditions (for each `id` and `amount` pair):\r\n *\r\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\r\n * of token type `id` will be transferred to `to`.\r\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\r\n * for `to`.\r\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\r\n * will be burned.\r\n * - `from` and `to` are never both zero.\r\n * - `ids` and `amounts` have the same, non-zero length.\r\n *\r\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\r\n */\r\n function _beforeTokenTransfer(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256[] memory ids,\r\n uint256[] memory amounts,\r\n bytes memory data\r\n )\r\n internal\r\n virtual\r\n { }\r\n\r\n function _doSafeTransferAcceptanceCheck(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256 id,\r\n uint256 amount,\r\n bytes memory data\r\n )\r\n private\r\n {\r\n if (to.isContract()) {\r\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\r\n if (response != IERC1155Receiver(to).onERC1155Received.selector) {\r\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\r\n }\r\n } catch Error(string memory reason) {\r\n revert(reason);\r\n } catch {\r\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\r\n }\r\n }\r\n }\r\n\r\n function _doSafeBatchTransferAcceptanceCheck(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256[] memory ids,\r\n uint256[] memory amounts,\r\n bytes memory data\r\n )\r\n private\r\n {\r\n if (to.isContract()) {\r\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\r\n if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\r\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\r\n }\r\n } catch Error(string memory reason) {\r\n revert(reason);\r\n } catch {\r\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\r\n }\r\n }\r\n }\r\n\r\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\r\n uint256[] memory array = new uint256[](1);\r\n array[0] = element;\r\n\r\n return array;\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../../introspection/IERC165.sol\";\r\n\r\n/**\r\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\r\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\r\n *\r\n * _Available since v3.1._\r\n */\r\ninterface IERC1155 is IERC165 {\r\n /**\r\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\r\n */\r\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\r\n\r\n /**\r\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\r\n * transfers.\r\n */\r\n event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\r\n\r\n /**\r\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\r\n * `approved`.\r\n */\r\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\r\n\r\n /**\r\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\r\n *\r\n * If an {URI} event was emitted for `id`, the standard\r\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\r\n * returned by {IERC1155MetadataURI-uri}.\r\n */\r\n event URI(string value, uint256 indexed id);\r\n\r\n /**\r\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\r\n *\r\n * Requirements:\r\n *\r\n * - `account` cannot be the zero address.\r\n */\r\n function balanceOf(address account, uint256 id) external view returns (uint256);\r\n\r\n /**\r\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\r\n *\r\n * Requirements:\r\n *\r\n * - `accounts` and `ids` must have the same length.\r\n */\r\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\r\n\r\n /**\r\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\r\n *\r\n * Emits an {ApprovalForAll} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `operator` cannot be the caller.\r\n */\r\n function setApprovalForAll(address operator, bool approved) external;\r\n\r\n /**\r\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\r\n *\r\n * See {setApprovalForAll}.\r\n */\r\n function isApprovedForAll(address account, address operator) external view returns (bool);\r\n\r\n /**\r\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\r\n *\r\n * Emits a {TransferSingle} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `to` cannot be the zero address.\r\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\r\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\r\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\r\n * acceptance magic value.\r\n */\r\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\r\n\r\n /**\r\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\r\n *\r\n * Emits a {TransferBatch} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `ids` and `amounts` must have the same length.\r\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\r\n * acceptance magic value.\r\n */\r\n function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155MetadataURI.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./IERC1155.sol\";\r\n\r\n/**\r\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\r\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\r\n *\r\n * _Available since v3.1._\r\n */\r\ninterface IERC1155MetadataURI is IERC1155 {\r\n /**\r\n * @dev Returns the URI for token type `id`.\r\n *\r\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\r\n * clients with the actual token type ID.\r\n */\r\n function uri(uint256 id) external view returns (string memory);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../../introspection/IERC165.sol\";\r\n\r\n/**\r\n * _Available since v3.1._\r\n */\r\ninterface IERC1155Receiver is IERC165 {\r\n\r\n /**\r\n @dev Handles the receipt of a single ERC1155 token type. This function is\r\n called at the end of a `safeTransferFrom` after the balance has been updated.\r\n To accept the transfer, this must return\r\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\r\n (i.e. 0xf23a6e61, or its own function selector).\r\n @param operator The address which initiated the transfer (i.e. msg.sender)\r\n @param from The address which previously owned the token\r\n @param id The ID of the token being transferred\r\n @param value The amount of tokens being transferred\r\n @param data Additional data with no specified format\r\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\r\n */\r\n function onERC1155Received(\r\n address operator,\r\n address from,\r\n uint256 id,\r\n uint256 value,\r\n bytes calldata data\r\n )\r\n external\r\n returns(bytes4);\r\n\r\n /**\r\n @dev Handles the receipt of a multiple ERC1155 token types. This function\r\n is called at the end of a `safeBatchTransferFrom` after the balances have\r\n been updated. To accept the transfer(s), this must return\r\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\r\n (i.e. 0xbc197c81, or its own function selector).\r\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\r\n @param from The address which previously owned the token\r\n @param ids An array containing ids of each token being transferred (order and length must match values array)\r\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\r\n @param data Additional data with no specified format\r\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\r\n */\r\n function onERC1155BatchReceived(\r\n address operator,\r\n address from,\r\n uint256[] calldata ids,\r\n uint256[] calldata values,\r\n bytes calldata data\r\n )\r\n external\r\n returns(bytes4);\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./ERC1155.sol\";\r\nimport \"../../lifecycle/Pausable.sol\";\r\n\r\n/**\r\n * @dev ERC1155 token with pausable token transfers, minting and burning.\r\n *\r\n * Useful for scenarios such as preventing trades until the end of an evaluation\r\n * period, or having an emergency switch for freezing all token transfers in the\r\n * event of a large bug.\r\n *\r\n * _Available since v3.1._\r\n */\r\nabstract contract ERC1155Pausable is ERC1155, Pausable {\r\n /**\r\n * @dev See {ERC1155-_beforeTokenTransfer}.\r\n *\r\n * Requirements:\r\n *\r\n * - the contract must not be paused.\r\n */\r\n function _beforeTokenTransfer(\r\n address operator,\r\n address from,\r\n address to,\r\n uint256[] memory ids,\r\n uint256[] memory amounts,\r\n bytes memory data\r\n )\r\n internal\r\n virtual\r\n override\r\n {\r\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\r\n\r\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/lifecycle/Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../GSN/Context.sol\";\r\nimport \"../access/roles/PauserRole.sol\";\r\n\r\n/**\r\n * @dev Contract module which allows children to implement an emergency stop\r\n * mechanism that can be triggered by an authorized account.\r\n *\r\n * This module is used through inheritance. It will make available the\r\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\r\n * the functions of your contract. Note that they will not be pausable by\r\n * simply including this module, only once the modifiers are put in place.\r\n */\r\nabstract contract Pausable is Context, PauserRole {\r\n /**\r\n * @dev Emitted when the pause is triggered by a pauser (`account`).\r\n */\r\n event Paused(address account);\r\n\r\n /**\r\n * @dev Emitted when the pause is lifted by a pauser (`account`).\r\n */\r\n event Unpaused(address account);\r\n\r\n bool private _paused;\r\n\r\n /**\r\n * @dev Initializes the contract in unpaused state. Assigns the Pauser role\r\n * to the deployer.\r\n */\r\n constructor () {\r\n _paused = false;\r\n }\r\n\r\n /**\r\n * @dev Returns true if the contract is paused, and false otherwise.\r\n */\r\n function paused() public view returns (bool) {\r\n return _paused;\r\n }\r\n\r\n /**\r\n * @dev Modifier to make a function callable only when the contract is not paused.\r\n */\r\n modifier whenNotPaused() {\r\n require(!_paused, \"Pausable: paused\");\r\n _;\r\n }\r\n\r\n /**\r\n * @dev Modifier to make a function callable only when the contract is paused.\r\n */\r\n modifier whenPaused() {\r\n require(_paused, \"Pausable: not paused\");\r\n _;\r\n }\r\n\r\n /**\r\n * @dev Called by a pauser to pause, triggers stopped state.\r\n */\r\n function pause() public onlyPauser whenNotPaused {\r\n _paused = true;\r\n emit Paused(_msgSender());\r\n }\r\n\r\n /**\r\n * @dev Called by a pauser to unpause, returns to normal state.\r\n */\r\n function unpause() public onlyPauser whenPaused {\r\n _paused = false;\r\n emit Unpaused(_msgSender());\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/access/roles/PauserRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../../GSN/Context.sol\";\r\nimport \"../Roles.sol\";\r\n\r\nabstract contract PauserRole is Context {\r\n using Roles for Roles.Role;\r\n\r\n event PauserAdded(address indexed account);\r\n event PauserRemoved(address indexed account);\r\n\r\n Roles.Role private _pausers;\r\n\r\n constructor () {\r\n _addPauser(_msgSender());\r\n }\r\n\r\n modifier onlyPauser() {\r\n require(isPauser(_msgSender()), \"PauserRole: caller doesn't have the role\");\r\n _;\r\n }\r\n\r\n function isPauser(address account) public view returns (bool) {\r\n return _pausers.has(account);\r\n }\r\n\r\n function addPauser(address account) public onlyPauser {\r\n _addPauser(account);\r\n }\r\n\r\n function renouncePauser() public {\r\n _removePauser(_msgSender());\r\n }\r\n\r\n function _addPauser(address account) internal {\r\n _pausers.add(account);\r\n emit PauserAdded(account);\r\n }\r\n\r\n function _removePauser(address account) internal {\r\n _pausers.remove(account);\r\n emit PauserRemoved(account);\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Pausable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./ERC721.sol\";\r\nimport \"../../lifecycle/Pausable.sol\";\r\n\r\n/**\r\n * @dev ERC721 token with pausable token transfers, minting and burning.\r\n *\r\n * Useful for scenarios such as preventing trades until the end of an evaluation\r\n * period, or having an emergency switch for freezing all token transfers in the\r\n * event of a large bug.\r\n */\r\nabstract contract ERC721Pausable is ERC721, Pausable {\r\n /**\r\n * @dev See {ERC721-_beforeTokenTransfer}.\r\n *\r\n * Requirements:\r\n *\r\n * - the contract must not be paused.\r\n */\r\n function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {\r\n super._beforeTokenTransfer(from, to, tokenId);\r\n\r\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\r\n }\r\n}\r\n"
+ },
+ "contracts/test/nftbridge/OpenSea721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n// created using https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol\r\n// and https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/Creature.sol\r\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\r\nimport \"../../zeppelin/ownership/Ownable.sol\";\r\nimport \"../../zeppelin/math/SafeMath.sol\";\r\nimport \"../../zeppelin/utils/Strings.sol\";\r\nimport \"./OpenSeaEIP712Base.sol\";\r\n\r\n\r\n/**\r\n * @title OpenSea721\r\n * OpenSea721 - ERC721 contract that whitelists a trading address, and has minting functionality.\r\n */\r\ncontract OpenSea721 is ERC721, OpenSeaEIP712Base, Ownable {\r\n using SafeMath for uint256;\r\n\r\n uint256 private _currentTokenId = 0;\r\n\r\n constructor(\r\n string memory _name,\r\n string memory _symbol\r\n ) ERC721(_name, _symbol) {\r\n _initializeEIP712(_name);\r\n }\r\n\r\n function baseTokenURI() public pure returns (string memory) {\r\n return \"https://creatures-api.opensea.io/api/creature/\";\r\n }\r\n\r\n function contractURI() public pure returns (string memory) {\r\n return \"https://creatures-api.opensea.io/contract/opensea-creatures\";\r\n }\r\n\r\n /**\r\n * @dev Mints a token to an address with a tokenURI.\r\n * @param _to address of the future owner of the token\r\n */\r\n function mintTo(address _to) public onlyOwner {\r\n uint256 newTokenId = _getNextTokenId();\r\n _mint(_to, newTokenId);\r\n _incrementTokenId();\r\n }\r\n\r\n /**\r\n * @dev calculates the next token ID based on value of _currentTokenId\r\n * @return uint256 for the next token ID\r\n */\r\n function _getNextTokenId() private view returns (uint256) {\r\n return _currentTokenId.add(1);\r\n }\r\n\r\n /**\r\n * @dev increments the value of _currentTokenId\r\n */\r\n function _incrementTokenId() private {\r\n _currentTokenId++;\r\n }\r\n\r\n function tokenURI(uint256 _tokenId) override public pure returns (string memory) {\r\n return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));\r\n }\r\n\r\n}"
+ },
+ "contracts/test/nftbridge/OpenSeaEIP712Base.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../../zeppelin/upgradable/Initializable.sol\";\r\n\r\ncontract OpenSeaEIP712Base is Initializable {\r\n struct EIP712Domain {\r\n string name;\r\n string version;\r\n address verifyingContract;\r\n bytes32 salt;\r\n }\r\n\r\n string constant public ERC712_VERSION = \"1\";\r\n\r\n bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(\r\n bytes(\r\n \"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)\"\r\n )\r\n );\r\n bytes32 internal domainSeperator;\r\n\r\n // supposed to be called once while initializing.\r\n // one of the contracts that inherits this contract follows proxy pattern\r\n // so it is not possible to do this in a constructor\r\n function _initializeEIP712(\r\n string memory name\r\n )\r\n internal\r\n initializer\r\n {\r\n _setDomainSeperator(name);\r\n }\r\n\r\n function _setDomainSeperator(string memory name) internal {\r\n domainSeperator = keccak256(\r\n abi.encode(\r\n EIP712_DOMAIN_TYPEHASH,\r\n keccak256(bytes(name)),\r\n keccak256(bytes(ERC712_VERSION)),\r\n address(this),\r\n bytes32(getChainId())\r\n )\r\n );\r\n }\r\n\r\n function getDomainSeperator() public view returns (bytes32) {\r\n return domainSeperator;\r\n }\r\n\r\n function getChainId() public pure returns (uint256) {\r\n uint256 id;\r\n assembly {\r\n id := chainid()\r\n }\r\n return id;\r\n }\r\n\r\n /**\r\n * Accept message hash and returns hash message in EIP712 compatible form\r\n * So that it can be used to recover signer from signature signed using EIP712 formatted data\r\n * https://eips.ethereum.org/EIPS/eip-712\r\n * \"\\\\x19\" makes the encoding deterministic\r\n * \"\\\\x01\" is the version byte to make it compatible to EIP-191\r\n */\r\n function toTypedMessageHash(bytes32 messageHash)\r\n internal\r\n view\r\n returns (bytes32)\r\n {\r\n return\r\n keccak256(\r\n abi.encodePacked(\"\\x19\\x01\", getDomainSeperator(), messageHash)\r\n );\r\n }\r\n}\r\n"
+ },
+ "contracts/Federation/FederationV2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n// Upgradables\r\nimport \"../zeppelin/upgradable/Initializable.sol\";\r\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\r\n\r\nimport \"../interface/IBridge.sol\";\r\n\r\ncontract FederationV2 is Initializable, UpgradableOwnable {\r\n uint constant public MAX_MEMBER_COUNT = 50;\r\n address constant private NULL_ADDRESS = address(0);\r\n\r\n IBridge public bridge;\r\n address[] public members;\r\n uint public required;\r\n\r\n mapping (address => bool) public isMember;\r\n mapping (bytes32 => mapping (address => bool)) public votes;\r\n mapping(bytes32 => bool) public processed;\r\n\r\n event Executed(\r\n address indexed federator,\r\n bytes32 indexed transactionHash,\r\n bytes32 indexed transactionId,\r\n address originalTokenAddress,\r\n address sender,\r\n address receiver,\r\n uint256 amount,\r\n bytes32 blockHash,\r\n uint32 logIndex\r\n );\r\n event MemberAddition(address indexed member);\r\n event MemberRemoval(address indexed member);\r\n event RequirementChange(uint required);\r\n event BridgeChanged(address bridge);\r\n event Voted(\r\n address indexed federator,\r\n bytes32 indexed transactionHash,\r\n bytes32 indexed transactionId,\r\n address originalTokenAddress,\r\n address sender,\r\n address receiver,\r\n uint256 amount,\r\n bytes32 blockHash,\r\n uint32 logIndex\r\n );\r\n event HeartBeat(\r\n address indexed sender,\r\n uint256 fedRskBlock,\r\n uint256 fedEthBlock,\r\n string federatorVersion,\r\n string nodeRskInfo,\r\n string nodeEthInfo\r\n );\r\n\r\n modifier onlyMember() {\r\n require(isMember[_msgSender()], \"Federation: Not Federator\");\r\n _;\r\n }\r\n\r\n modifier validRequirement(uint membersCount, uint _required) {\r\n // solium-disable-next-line max-len\r\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\r\n _;\r\n }\r\n\r\n function initialize(address[] memory _members, uint _required, address _bridge, address owner)\r\n public validRequirement(_members.length, _required) initializer {\r\n UpgradableOwnable.initialize(owner);\r\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\r\n members = _members;\r\n for (uint i = 0; i < _members.length; i++) {\r\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\r\n isMember[_members[i]] = true;\r\n emit MemberAddition(_members[i]);\r\n }\r\n required = _required;\r\n emit RequirementChange(required);\r\n _setBridge(_bridge);\r\n }\r\n\r\n function version() external pure returns (string memory) {\r\n return \"v2\";\r\n }\r\n\r\n function setBridge(address _bridge) external onlyOwner {\r\n _setBridge(_bridge);\r\n }\r\n\r\n function _setBridge(address _bridge) internal {\r\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\r\n bridge = IBridge(_bridge);\r\n emit BridgeChanged(_bridge);\r\n }\r\n\r\n function voteTransaction(\r\n address originalTokenAddress,\r\n address payable sender,\r\n address payable receiver,\r\n uint256 amount,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex\r\n )\r\n public onlyMember returns(bool)\r\n {\r\n bytes32 transactionId = getTransactionId(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n amount,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n );\r\n if (processed[transactionId])\r\n return true;\r\n\r\n if (votes[transactionId][_msgSender()])\r\n return true;\r\n\r\n votes[transactionId][_msgSender()] = true;\r\n emit Voted(\r\n _msgSender(),\r\n transactionHash,\r\n transactionId,\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n amount,\r\n blockHash,\r\n logIndex\r\n );\r\n\r\n uint transactionCount = getTransactionCount(transactionId);\r\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\r\n processed[transactionId] = true;\r\n bridge.acceptTransfer(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n amount,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n );\r\n emit Executed(\r\n _msgSender(),\r\n transactionHash,\r\n transactionId,\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n amount,\r\n blockHash,\r\n logIndex\r\n );\r\n return true;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\r\n uint count = 0;\r\n for (uint i = 0; i < members.length; i++) {\r\n if (votes[transactionId][members[i]])\r\n count += 1;\r\n }\r\n return count;\r\n }\r\n\r\n function hasVoted(bytes32 transactionId) external view returns(bool)\r\n {\r\n return votes[transactionId][_msgSender()];\r\n }\r\n\r\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\r\n {\r\n return processed[transactionId];\r\n }\r\n\r\n function getTransactionId(\r\n address originalTokenAddress,\r\n address sender,\r\n address receiver,\r\n uint256 amount,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex\r\n ) public pure returns(bytes32)\r\n {\r\n return keccak256(\r\n abi.encodePacked(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n amount,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n )\r\n );\r\n }\r\n\r\n function addMember(address _newMember) external onlyOwner\r\n {\r\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\r\n require(!isMember[_newMember], \"Federation: Member already exists\");\r\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\r\n\r\n isMember[_newMember] = true;\r\n members.push(_newMember);\r\n emit MemberAddition(_newMember);\r\n }\r\n\r\n function removeMember(address _oldMember) external onlyOwner\r\n {\r\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\r\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\r\n require(members.length > 1, \"Federation: Can't remove all the members\");\r\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\r\n\r\n isMember[_oldMember] = false;\r\n for (uint i = 0; i < members.length - 1; i++) {\r\n if (members[i] == _oldMember) {\r\n members[i] = members[members.length - 1];\r\n break;\r\n }\r\n }\r\n members.pop(); // remove an element from the end of the array.\r\n emit MemberRemoval(_oldMember);\r\n }\r\n\r\n function getMembers() external view returns (address[] memory)\r\n {\r\n return members;\r\n }\r\n\r\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\r\n {\r\n require(_required >= 2, \"Federation: Requires at least 2\");\r\n required = _required;\r\n emit RequirementChange(_required);\r\n }\r\n\r\n function emitHeartbeat(\r\n uint256 fedRskBlock,\r\n uint256 fedEthBlock,\r\n string calldata federatorVersion,\r\n string calldata nodeRskInfo,\r\n string calldata nodeEthInfo\r\n ) external onlyMember {\r\n emit HeartBeat(\r\n _msgSender(),\r\n fedRskBlock,\r\n fedEthBlock,\r\n federatorVersion,\r\n nodeRskInfo,\r\n nodeEthInfo\r\n );\r\n }\r\n}"
+ },
+ "contracts/Federation/Federation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n// Upgradables\r\nimport \"../zeppelin/upgradable/Initializable.sol\";\r\nimport \"../zeppelin/upgradable/ownership/UpgradableOwnable.sol\";\r\n\r\nimport \"../nftbridge/INFTBridge.sol\";\r\nimport \"../interface/IBridge.sol\";\r\nimport \"../interface/IFederation.sol\";\r\n\r\ncontract Federation is Initializable, UpgradableOwnable, IFederation {\r\n uint constant public MAX_MEMBER_COUNT = 50;\r\n address constant private NULL_ADDRESS = address(0);\r\n\r\n IBridge public bridge;\r\n address[] public members;\r\n\r\n /**\r\n @notice The minimum amount of votes to approve a transaction\r\n @dev It should have more members than the required amount\r\n */\r\n uint public required;\r\n\r\n /**\r\n @notice All the addresses that are members of the federation\r\n @dev The address should be a member to vote in transactions\r\n */\r\n mapping (address => bool) public isMember;\r\n\r\n /**\r\n (bytes32) transactionId = keccak256(\r\n abi.encodePacked(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n amount,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n )\r\n ) => (\r\n (address) members => (bool) voted\r\n )\r\n @notice Votes by members by the transaction ID\r\n @dev usually the members should approve the transaction by 50% + 1\r\n */\r\n mapping (bytes32 => mapping (address => bool)) public votes;\r\n\r\n /**\r\n (bytes32) transactionId => (bool) voted\r\n @notice Check if that transaction was already processed\r\n */\r\n mapping(bytes32 => bool) public processed;\r\n\r\n /** Federator v3 variables */\r\n INFTBridge public bridgeNFT;\r\n\r\n modifier onlyMember() {\r\n require(isMember[_msgSender()], \"Federation: Not Federator\");\r\n _;\r\n }\r\n\r\n modifier validRequirement(uint membersCount, uint _required) {\r\n // solium-disable-next-line max-len\r\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\r\n _;\r\n }\r\n\r\n function initialize(address[] memory _members, uint _required, address _bridge, address owner, address _bridgeNFT) public\r\n validRequirement(_members.length, _required) initializer {\r\n UpgradableOwnable.initialize(owner);\r\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Too many members\");\r\n members = _members;\r\n for (uint i = 0; i < _members.length; i++) {\r\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\r\n isMember[_members[i]] = true;\r\n emit MemberAddition(_members[i]);\r\n }\r\n required = _required;\r\n emit RequirementChange(required);\r\n _setBridge(_bridge);\r\n _setNFTBridge(_bridgeNFT);\r\n }\r\n\r\n /**\r\n @notice Current version of the contract\r\n @return version in v{Number}\r\n */\r\n function version() external pure override returns (string memory) {\r\n return \"v3\";\r\n }\r\n\r\n /**\r\n @notice Sets a new bridge contract\r\n @dev Emits BridgeChanged event\r\n @param _bridge the new bridge contract address that should implement the IBridge interface\r\n */\r\n function setBridge(address _bridge) external onlyOwner override {\r\n _setBridge(_bridge);\r\n }\r\n\r\n function _setBridge(address _bridge) internal {\r\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\r\n bridge = IBridge(_bridge);\r\n emit BridgeChanged(_bridge);\r\n }\r\n\r\n /**\r\n @notice Sets a new NFT bridge contract\r\n @dev Emits NFTBridgeChanged event\r\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\r\n */\r\n function setNFTBridge(address _bridgeNFT) external onlyOwner override {\r\n _setNFTBridge(_bridgeNFT);\r\n }\r\n\r\n function _setNFTBridge(address _bridgeNFT) internal {\r\n require(_bridgeNFT != NULL_ADDRESS, \"Federation: Empty NFT bridge\");\r\n bridgeNFT = INFTBridge(_bridgeNFT);\r\n emit NFTBridgeChanged(_bridgeNFT);\r\n }\r\n\r\n function validateTransaction(bytes32 transactionId) internal view returns(bool) {\r\n uint transactionCount = getTransactionCount(transactionId);\r\n return transactionCount >= required && transactionCount >= members.length / 2 + 1;\r\n }\r\n\r\n /**\r\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\r\n @param originalTokenAddress The address of the token in the origin (main) chain\r\n @param sender The address who solicited the cross token\r\n @param receiver Who is going to receive the token in the opposite chain\r\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\r\n @param blockHash The block hash in which the transaction with the cross event occurred\r\n @param transactionHash The transaction in which the cross event occurred\r\n @param logIndex Index of the event in the logs\r\n @param tokenType Is the type of bridge to be used\r\n */\r\n function voteTransaction(\r\n address originalTokenAddress,\r\n address payable sender,\r\n address payable receiver,\r\n uint256 value,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex,\r\n TokenType tokenType\r\n ) external onlyMember override {\r\n bytes32 transactionId = getTransactionId(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n value,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n );\r\n if (processed[transactionId])\r\n return;\r\n\r\n if (votes[transactionId][_msgSender()])\r\n return;\r\n\r\n votes[transactionId][_msgSender()] = true;\r\n emit Voted(\r\n _msgSender(),\r\n transactionHash,\r\n transactionId,\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n value,\r\n blockHash,\r\n logIndex\r\n );\r\n\r\n if (validateTransaction(transactionId)) {\r\n processed[transactionId] = true;\r\n acceptTransfer(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n value,\r\n blockHash,\r\n transactionHash,\r\n logIndex,\r\n tokenType\r\n );\r\n\r\n emit Executed(\r\n _msgSender(),\r\n transactionHash,\r\n transactionId,\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n value,\r\n blockHash,\r\n logIndex\r\n );\r\n return;\r\n }\r\n }\r\n\r\n function acceptTransfer(\r\n address originalTokenAddress,\r\n address payable sender,\r\n address payable receiver,\r\n uint256 value,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex,\r\n TokenType tokenType\r\n ) internal {\r\n if (tokenType == TokenType.NFT) {\r\n require(address(bridgeNFT) != NULL_ADDRESS, \"Federation: Empty NFTBridge\");\r\n bridgeNFT.acceptTransfer(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n value,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n );\r\n return;\r\n }\r\n\r\n bridge.acceptTransfer(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n value,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n );\r\n }\r\n\r\n /**\r\n @notice Get the amount of approved votes for that transactionId\r\n @param transactionId The transaction hashed from getTransactionId function\r\n */\r\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\r\n uint count = 0;\r\n for (uint i = 0; i < members.length; i++) {\r\n if (votes[transactionId][members[i]])\r\n count += 1;\r\n }\r\n return count;\r\n }\r\n\r\n function hasVoted(bytes32 transactionId) external view returns(bool)\r\n {\r\n return votes[transactionId][_msgSender()];\r\n }\r\n\r\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\r\n {\r\n return processed[transactionId];\r\n }\r\n\r\n /**\r\n @notice Gets the hash of transaction from the following parameters encoded and keccaked\r\n @dev It encodes and applies keccak256 to the parameters received in the same order\r\n @param originalTokenAddress The address of the token in the origin (main) chain\r\n @param sender The address who solicited the cross token\r\n @param receiver Who is going to receive the token in the opposite chain\r\n @param amount Could be the amount or the tokenId\r\n @param blockHash The block hash in which the transaction with the cross event occurred\r\n @param transactionHash The transaction in which the cross event occurred\r\n @param logIndex Index of the event in the logs\r\n @return The hash generated by the parameters.\r\n */\r\n function getTransactionId(\r\n address originalTokenAddress,\r\n address sender,\r\n address receiver,\r\n uint256 amount,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex\r\n ) public pure returns(bytes32) {\r\n return keccak256(\r\n abi.encodePacked(\r\n originalTokenAddress,\r\n sender,\r\n receiver,\r\n amount,\r\n blockHash,\r\n transactionHash,\r\n logIndex\r\n )\r\n );\r\n }\r\n\r\n function addMember(address _newMember) external onlyOwner override\r\n {\r\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\r\n require(!isMember[_newMember], \"Federation: Member already exists\");\r\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\r\n\r\n isMember[_newMember] = true;\r\n members.push(_newMember);\r\n emit MemberAddition(_newMember);\r\n }\r\n\r\n function removeMember(address _oldMember) external onlyOwner override\r\n {\r\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\r\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\r\n require(members.length > 1, \"Federation: Can't remove all the members\");\r\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\r\n\r\n isMember[_oldMember] = false;\r\n for (uint i = 0; i < members.length - 1; i++) {\r\n if (members[i] == _oldMember) {\r\n members[i] = members[members.length - 1];\r\n break;\r\n }\r\n }\r\n members.pop(); // remove an element from the end of the array.\r\n emit MemberRemoval(_oldMember);\r\n }\r\n\r\n /**\r\n @notice Return all the current members of the federation\r\n @return Current members\r\n */\r\n function getMembers() external view override returns (address[] memory) {\r\n return members;\r\n }\r\n\r\n /**\r\n @notice Changes the number of required members to vote and approve an transaction\r\n @dev Emits the RequirementChange event\r\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\r\n */\r\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {\r\n require(_required >= 2, \"Federation: Requires at least 2\");\r\n required = _required;\r\n emit RequirementChange(_required);\r\n }\r\n\r\n /**\r\n @notice It emits an HeartBeat like an health check\r\n @dev Emits HeartBeat event\r\n */\r\n function emitHeartbeat(\r\n uint256 fedRskBlock,\r\n uint256 fedEthBlock,\r\n string calldata federatorVersion,\r\n string calldata nodeRskInfo,\r\n string calldata nodeEthInfo\r\n ) external onlyMember override {\r\n emit HeartBeat(\r\n _msgSender(),\r\n fedRskBlock,\r\n fedEthBlock,\r\n federatorVersion,\r\n nodeRskInfo,\r\n nodeEthInfo\r\n );\r\n }\r\n}\r\n"
+ },
+ "contracts/interface/IFederation.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\ninterface IFederation {\r\n enum TokenType{ COIN, NFT }\r\n\r\n /**\r\n @notice Current version of the contract\r\n @return version in v{Number}\r\n */\r\n function version() external pure returns (string memory);\r\n\r\n /**\r\n @notice Sets a new bridge contract\r\n @param _bridge the new bridge contract address that should implement the IBridge interface\r\n */\r\n function setBridge(address _bridge) external;\r\n\r\n /**\r\n @notice Sets a new NFT bridge contract\r\n @param _bridgeNFT the new NFT bridge contract address that should implement the INFTBridge interface\r\n */\r\n function setNFTBridge(address _bridgeNFT) external;\r\n\r\n /**\r\n @notice Vote in a transaction, if it has enough votes it accepts the transfer\r\n @param originalTokenAddress The address of the token in the origin (main) chain\r\n @param sender The address who solicited the cross token\r\n @param receiver Who is going to receive the token in the opposite chain\r\n @param value Could be the amount if tokenType == COIN or the tokenId if tokenType == NFT\r\n @param blockHash The block hash in which the transaction with the cross event occurred\r\n @param transactionHash The transaction in which the cross event occurred\r\n @param logIndex Index of the event in the logs\r\n @param tokenType Is the type of bridge to be used\r\n */\r\n function voteTransaction(\r\n address originalTokenAddress,\r\n address payable sender,\r\n address payable receiver,\r\n uint256 value,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex,\r\n TokenType tokenType\r\n ) external;\r\n\r\n /**\r\n @notice Add a new member to the federation\r\n @param _newMember address of the new member\r\n */\r\n function addMember(address _newMember) external;\r\n\r\n /**\r\n @notice Remove a member of the federation\r\n @param _oldMember address of the member to be removed from federation\r\n */\r\n function removeMember(address _oldMember) external;\r\n\r\n /**\r\n @notice Return all the current members of the federation\r\n @return Current members\r\n */\r\n function getMembers() external view returns (address[] memory);\r\n\r\n /**\r\n @notice Changes the number of required members to vote and approve an transaction\r\n @param _required the number of minimum members to approve an transaction, it has to be bigger than 1\r\n */\r\n function changeRequirement(uint _required) external;\r\n\r\n /**\r\n @notice It emmits an HeartBeat like an healthy check\r\n */\r\n function emitHeartbeat(\r\n uint256 fedRskBlock,\r\n uint256 fedEthBlock,\r\n string calldata federatorVersion,\r\n string calldata nodeRskInfo,\r\n string calldata nodeEthInfo\r\n ) external;\r\n\r\n event Executed(\r\n address indexed federator,\r\n bytes32 indexed transactionHash,\r\n bytes32 indexed transactionId,\r\n address originalTokenAddress,\r\n address sender,\r\n address receiver,\r\n uint256 amount,\r\n bytes32 blockHash,\r\n uint32 logIndex\r\n );\r\n event MemberAddition(address indexed member);\r\n event MemberRemoval(address indexed member);\r\n event RequirementChange(uint required);\r\n event BridgeChanged(address bridge);\r\n event NFTBridgeChanged(address bridgeNFT);\r\n event Voted(\r\n address indexed federator,\r\n bytes32 indexed transactionHash,\r\n bytes32 indexed transactionId,\r\n address originalTokenAddress,\r\n address sender,\r\n address receiver,\r\n uint256 amount,\r\n bytes32 blockHash,\r\n uint32 logIndex\r\n );\r\n event HeartBeat(\r\n address indexed sender,\r\n uint256 fedRskBlock,\r\n uint256 fedEthBlock,\r\n string federatorVersion,\r\n string nodeRskInfo,\r\n string nodeEthInfo\r\n );\r\n\r\n}\r\n"
+ },
+ "contracts/zeppelin/access/roles/MinterRole.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../../GSN/Context.sol\";\r\nimport \"../Roles.sol\";\r\n\r\nabstract contract MinterRole is Context {\r\n using Roles for Roles.Role;\r\n\r\n event MinterAdded(address indexed account);\r\n event MinterRemoved(address indexed account);\r\n\r\n Roles.Role private _minters;\r\n\r\n constructor () {\r\n _addMinter(_msgSender());\r\n }\r\n\r\n modifier onlyMinter() {\r\n require(isMinter(_msgSender()), \"MinterRole: caller doesn't have the role\");\r\n _;\r\n }\r\n\r\n function isMinter(address account) public view returns (bool) {\r\n return _minters.has(account);\r\n }\r\n\r\n function addMinter(address account) public onlyMinter {\r\n _addMinter(account);\r\n }\r\n\r\n function renounceMinter() public {\r\n _removeMinter(_msgSender());\r\n }\r\n\r\n function _addMinter(address account) internal {\r\n _minters.add(account);\r\n emit MinterAdded(account);\r\n }\r\n\r\n function _removeMinter(address account) internal {\r\n _minters.remove(account);\r\n emit MinterRemoved(account);\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../../GSN/Context.sol\";\r\nimport \"./IERC20.sol\";\r\nimport \"../../math/SafeMath.sol\";\r\n\r\n/**\r\n * @dev Implementation of the {IERC20} interface.\r\n *\r\n * This implementation is agnostic to the way tokens are created. This means\r\n * that a supply mechanism has to be added in a derived contract using {_mint}.\r\n * For a generic mechanism see {ERC20Mintable}.\r\n *\r\n * TIP: For a detailed writeup see our guide\r\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\r\n * to implement supply mechanisms].\r\n *\r\n * We have followed general OpenZeppelin guidelines: functions revert instead\r\n * of returning `false` on failure. This behavior is nonetheless conventional\r\n * and does not conflict with the expectations of ERC20 applications.\r\n *\r\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\r\n * This allows applications to reconstruct the allowance for all accounts just\r\n * by listening to said events. Other implementations of the EIP may not emit\r\n * these events, as it isn't required by the specification.\r\n *\r\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\r\n * functions have been added to mitigate the well-known issues around setting\r\n * allowances. See {IERC20-approve}.\r\n */\r\ncontract ERC20 is Context, IERC20 {\r\n using SafeMath for uint256;\r\n\r\n mapping (address => uint256) private _balances;\r\n\r\n mapping (address => mapping (address => uint256)) private _allowances;\r\n\r\n uint256 private _totalSupply;\r\n\r\n /**\r\n * @dev See {IERC20-totalSupply}.\r\n */\r\n function totalSupply() override public view returns (uint256) {\r\n return _totalSupply;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-balanceOf}.\r\n */\r\n function balanceOf(address account) override public view returns (uint256) {\r\n return _balances[account];\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-transfer}.\r\n *\r\n * Requirements:\r\n *\r\n * - `recipient` cannot be the zero address.\r\n * - the caller must have a balance of at least `amount`.\r\n */\r\n function transfer(address recipient, uint256 amount) override public returns (bool) {\r\n _transfer(_msgSender(), recipient, amount);\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-allowance}.\r\n */\r\n function allowance(address owner, address spender) override public view returns (uint256) {\r\n return _allowances[owner][spender];\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-approve}.\r\n *\r\n * Requirements:\r\n *\r\n * - `spender` cannot be the zero address.\r\n */\r\n function approve(address spender, uint256 amount) override public returns (bool) {\r\n _approve(_msgSender(), spender, amount);\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev See {IERC20-transferFrom}.\r\n *\r\n * Emits an {Approval} event indicating the updated allowance. This is not\r\n * required by the EIP. See the note at the beginning of {ERC20};\r\n *\r\n * Requirements:\r\n * - `sender` and `recipient` cannot be the zero address.\r\n * - `sender` must have a balance of at least `amount`.\r\n * - the caller must have allowance for `sender`'s tokens of at least\r\n * `amount`.\r\n */\r\n function transferFrom(address sender, address recipient, uint256 amount) override public returns (bool) {\r\n _transfer(sender, recipient, amount);\r\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Atomically increases the allowance granted to `spender` by the caller.\r\n *\r\n * This is an alternative to {approve} that can be used as a mitigation for\r\n * problems described in {IERC20-approve}.\r\n *\r\n * Emits an {Approval} event indicating the updated allowance.\r\n *\r\n * Requirements:\r\n *\r\n * - `spender` cannot be the zero address.\r\n */\r\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\r\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\r\n *\r\n * This is an alternative to {approve} that can be used as a mitigation for\r\n * problems described in {IERC20-approve}.\r\n *\r\n * Emits an {Approval} event indicating the updated allowance.\r\n *\r\n * Requirements:\r\n *\r\n * - `spender` cannot be the zero address.\r\n * - `spender` must have allowance for the caller of at least\r\n * `subtractedValue`.\r\n */\r\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\r\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\r\n return true;\r\n }\r\n\r\n /**\r\n * @dev Moves tokens `amount` from `sender` to `recipient`.\r\n *\r\n * This is internal function is equivalent to {transfer}, and can be used to\r\n * e.g. implement automatic token fees, slashing mechanisms, etc.\r\n *\r\n * Emits a {Transfer} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `sender` cannot be the zero address.\r\n * - `recipient` cannot be the zero address.\r\n * - `sender` must have a balance of at least `amount`.\r\n */\r\n function _transfer(address sender, address recipient, uint256 amount) internal {\r\n require(sender != address(0), \"ERC20: transfer from zero address\");\r\n require(recipient != address(0), \"ERC20: transfer to zero address\");\r\n\r\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\r\n _balances[recipient] = _balances[recipient].add(amount);\r\n emit Transfer(sender, recipient, amount);\r\n }\r\n\r\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\r\n * the total supply.\r\n *\r\n * Emits a {Transfer} event with `from` set to the zero address.\r\n *\r\n * Requirements\r\n *\r\n * - `to` cannot be the zero address.\r\n */\r\n function _mint(address account, uint256 amount) internal {\r\n require(account != address(0), \"ERC20: mint to zero address\");\r\n\r\n _totalSupply = _totalSupply.add(amount);\r\n _balances[account] = _balances[account].add(amount);\r\n emit Transfer(address(0), account, amount);\r\n }\r\n\r\n /**\r\n * @dev Destroys `amount` tokens from `account`, reducing the\r\n * total supply.\r\n *\r\n * Emits a {Transfer} event with `to` set to the zero address.\r\n *\r\n * Requirements\r\n *\r\n * - `account` cannot be the zero address.\r\n * - `account` must have at least `amount` tokens.\r\n */\r\n function _burn(address account, uint256 amount) internal {\r\n require(account != address(0), \"ERC20: burn from zero address\");\r\n\r\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\r\n _totalSupply = _totalSupply.sub(amount);\r\n emit Transfer(account, address(0), amount);\r\n }\r\n\r\n /**\r\n * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\r\n *\r\n * This is internal function is equivalent to `approve`, and can be used to\r\n * e.g. set automatic allowances for certain subsystems, etc.\r\n *\r\n * Emits an {Approval} event.\r\n *\r\n * Requirements:\r\n *\r\n * - `owner` cannot be the zero address.\r\n * - `spender` cannot be the zero address.\r\n */\r\n function _approve(address owner, address spender, uint256 amount) internal {\r\n require(owner != address(0), \"ERC20: approve from zero address\");\r\n require(spender != address(0), \"ERC20: approve to zero address\");\r\n\r\n _allowances[owner][spender] = amount;\r\n emit Approval(owner, spender, amount);\r\n }\r\n\r\n /**\r\n * @dev Destroys `amount` tokens from `account`.`amount` is then deducted\r\n * from the caller's allowance.\r\n *\r\n * See {_burn} and {_approve}.\r\n */\r\n function _burnFrom(address account, uint256 amount) internal {\r\n _burn(account, amount);\r\n _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, \"ERC20: burn amount exceeds allowance\"));\r\n }\r\n}\r\n"
+ },
+ "contracts/test/mockERC677Reciever.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\r\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\r\nimport \"../interface/IERC677Receiver.sol\";\r\n\r\ncontract mockERC677Receiver is IERC677Receiver {\r\n event Success(address _sender, uint _value, bytes _data);\r\n /**\r\n * ERC-677's only method implementation\r\n * See https://github.com/ethereum/EIPs/issues/677 for details\r\n */\r\n function onTokenTransfer(address _sender, uint _value, bytes memory _data) override public {\r\n emit Success(_sender, _value, _data);\r\n }\r\n}"
+ },
+ "contracts/zeppelin/token/ERC20/ERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"./IERC20.sol\";\r\n\r\n/**\r\n * @dev Optional functions from the ERC20 standard.\r\n */\r\nabstract contract ERC20Detailed is IERC20 {\r\n string private _name;\r\n string private _symbol;\r\n uint8 private _decimals;\r\n\r\n /**\r\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\r\n * these values are immutable: they can only be set once during\r\n * construction.\r\n */\r\n constructor (string memory aName, string memory aSymbol, uint8 theDecimals) {\r\n _name = aName;\r\n _symbol = aSymbol;\r\n _decimals = theDecimals;\r\n }\r\n\r\n /**\r\n * @dev Returns the name of the token.\r\n */\r\n function name() public view returns (string memory) {\r\n return _name;\r\n }\r\n\r\n /**\r\n * @dev Returns the symbol of the token, usually a shorter version of the\r\n * name.\r\n */\r\n function symbol() public view returns (string memory) {\r\n return _symbol;\r\n }\r\n\r\n /**\r\n * @dev Returns the number of decimals used to get its user representation.\r\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\r\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\r\n *\r\n * Tokens usually opt for a value of 18, imitating the relationship between\r\n * Ether and Wei.\r\n *\r\n * NOTE: This information is only used for _display_ purposes: it in\r\n * no way affects any of the arithmetic of the contract, including\r\n * {IERC20-balanceOf} and {IERC20-transfer}.\r\n */\r\n function decimals() public view returns (uint8) {\r\n return _decimals;\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"./Proxy.sol\";\r\nimport \"../../utils/Address.sol\";\r\n\r\n/**\r\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\r\n * implementation address that can be changed. This address is stored in storage in the location specified by\r\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\r\n * implementation behind the proxy.\r\n *\r\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\r\n * {TransparentUpgradeableProxy}.\r\n */\r\ncontract UpgradeableProxy is Proxy {\r\n /**\r\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\r\n *\r\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\r\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\r\n */\r\n constructor(address _logic, bytes memory _data) payable {\r\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\r\n _setImplementation(_logic);\r\n if(_data.length > 0) {\r\n Address.functionDelegateCall(_logic, _data);\r\n }\r\n }\r\n\r\n /**\r\n * @dev Emitted when the implementation is upgraded.\r\n */\r\n event Upgraded(address indexed implementation);\r\n\r\n /**\r\n * @dev Storage slot with the address of the current implementation.\r\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\r\n * validated in the constructor.\r\n */\r\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\r\n\r\n /**\r\n * @dev Returns the current implementation address.\r\n */\r\n function _implementation() internal view virtual override returns (address impl) {\r\n bytes32 slot = _IMPLEMENTATION_SLOT;\r\n // solhint-disable-next-line no-inline-assembly\r\n assembly {\r\n impl := sload(slot)\r\n }\r\n }\r\n\r\n /**\r\n * @dev Upgrades the proxy to a new implementation.\r\n *\r\n * Emits an {Upgraded} event.\r\n */\r\n function _upgradeTo(address newImplementation) internal virtual {\r\n _setImplementation(newImplementation);\r\n emit Upgraded(newImplementation);\r\n }\r\n\r\n /**\r\n * @dev Stores a new address in the EIP1967 implementation slot.\r\n */\r\n function _setImplementation(address newImplementation) private {\r\n require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\r\n\r\n bytes32 slot = _IMPLEMENTATION_SLOT;\r\n\r\n // solhint-disable-next-line no-inline-assembly\r\n assembly {\r\n sstore(slot, newImplementation)\r\n }\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\n/**\r\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\r\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\r\n * be specified by overriding the virtual {_implementation} function.\r\n *\r\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\r\n * different contract through the {_delegate} function.\r\n *\r\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\r\n */\r\nabstract contract Proxy {\r\n /**\r\n * @dev Delegates the current call to `implementation`.\r\n *\r\n * This function does not return to its internall call site, it will return directly to the external caller.\r\n */\r\n function _delegate(address implementation) internal virtual {\r\n // solhint-disable-next-line no-inline-assembly\r\n assembly {\r\n // Copy msg.data. We take full control of memory in this inline assembly\r\n // block because it will not return to Solidity code. We overwrite the\r\n // Solidity scratch pad at memory position 0.\r\n calldatacopy(0, 0, calldatasize())\r\n\r\n // Call the implementation.\r\n // out and outsize are 0 because we don't know the size yet.\r\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\r\n\r\n // Copy the returned data.\r\n returndatacopy(0, 0, returndatasize())\r\n\r\n switch result\r\n // delegatecall returns 0 on error.\r\n case 0 { revert(0, returndatasize()) }\r\n default { return(0, returndatasize()) }\r\n }\r\n }\r\n\r\n /**\r\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\r\n * and {_fallback} should delegate.\r\n */\r\n function _implementation() internal view virtual returns (address);\r\n\r\n /**\r\n * @dev Delegates the current call to the address returned by `_implementation()`.\r\n *\r\n * This function does not return to its internall call site, it will return directly to the external caller.\r\n */\r\n function _fallback() internal virtual {\r\n _beforeFallback();\r\n _delegate(_implementation());\r\n }\r\n\r\n /**\r\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\r\n * function in the contract matches the call data.\r\n */\r\n fallback () external payable virtual {\r\n _fallback();\r\n }\r\n\r\n /**\r\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\r\n * is empty.\r\n */\r\n receive () external payable virtual {\r\n _fallback();\r\n }\r\n\r\n /**\r\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\r\n * call, or as part of the Solidity `fallback` or `receive` functions.\r\n *\r\n * If overriden should call `super._beforeFallback()`.\r\n */\r\n function _beforeFallback() internal virtual {\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"./UpgradeableProxy.sol\";\r\n\r\n/**\r\n * @dev This contract implements a proxy that is upgradeable by an admin.\r\n *\r\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\r\n * clashing], which can potentially be used in an attack, this contract uses the\r\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\r\n * things that go hand in hand:\r\n *\r\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\r\n * that call matches one of the admin functions exposed by the proxy itself.\r\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\r\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\r\n * \"admin cannot fallback to proxy target\".\r\n *\r\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\r\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\r\n * to sudden errors when trying to call a function from the proxy implementation.\r\n *\r\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\r\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\r\n */\r\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\r\n /**\r\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\r\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\r\n */\r\n constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {\r\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\r\n _setAdmin(admin_);\r\n }\r\n\r\n /**\r\n * @dev Emitted when the admin account has changed.\r\n */\r\n event AdminChanged(address previousAdmin, address newAdmin);\r\n\r\n /**\r\n * @dev Storage slot with the admin of the contract.\r\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\r\n * validated in the constructor.\r\n */\r\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\r\n\r\n /**\r\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\r\n */\r\n modifier ifAdmin() {\r\n if (msg.sender == _admin()) {\r\n _;\r\n } else {\r\n _fallback();\r\n }\r\n }\r\n\r\n /**\r\n * @dev Returns the current admin.\r\n *\r\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\r\n *\r\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\r\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\r\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\r\n */\r\n function admin() external ifAdmin returns (address admin_) {\r\n admin_ = _admin();\r\n }\r\n\r\n /**\r\n * @dev Returns the current implementation.\r\n *\r\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\r\n *\r\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\r\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\r\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\r\n */\r\n function implementation() external ifAdmin returns (address implementation_) {\r\n implementation_ = _implementation();\r\n }\r\n\r\n /**\r\n * @dev Changes the admin of the proxy.\r\n *\r\n * Emits an {AdminChanged} event.\r\n *\r\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\r\n */\r\n function changeAdmin(address newAdmin) external virtual ifAdmin {\r\n require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\r\n emit AdminChanged(_admin(), newAdmin);\r\n _setAdmin(newAdmin);\r\n }\r\n\r\n /**\r\n * @dev Upgrade the implementation of the proxy.\r\n *\r\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\r\n */\r\n function upgradeTo(address newImplementation) external virtual ifAdmin {\r\n _upgradeTo(newImplementation);\r\n }\r\n\r\n /**\r\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\r\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\r\n * proxied contract.\r\n *\r\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\r\n */\r\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\r\n _upgradeTo(newImplementation);\r\n Address.functionDelegateCall(newImplementation, data);\r\n }\r\n\r\n /**\r\n * @dev Returns the current admin.\r\n */\r\n function _admin() internal view virtual returns (address adm) {\r\n bytes32 slot = _ADMIN_SLOT;\r\n // solhint-disable-next-line no-inline-assembly\r\n assembly {\r\n adm := sload(slot)\r\n }\r\n }\r\n\r\n /**\r\n * @dev Stores a new address in the EIP1967 admin slot.\r\n */\r\n function _setAdmin(address newAdmin) private {\r\n bytes32 slot = _ADMIN_SLOT;\r\n\r\n // solhint-disable-next-line no-inline-assembly\r\n assembly {\r\n sstore(slot, newAdmin)\r\n }\r\n }\r\n\r\n /**\r\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\r\n */\r\n function _beforeFallback() internal virtual override {\r\n require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\r\n super._beforeFallback();\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../../ownership/Ownable.sol\";\r\nimport \"./TransparentUpgradeableProxy.sol\";\r\n\r\n/**\r\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\r\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\r\n */\r\ncontract ProxyAdmin is Ownable {\r\n\r\n /**\r\n * @dev Returns the current implementation of `proxy`.\r\n *\r\n * Requirements:\r\n *\r\n * - This contract must be the admin of `proxy`.\r\n */\r\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\r\n // We need to manually run the static call since the getter cannot be flagged as view\r\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\r\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\r\n require(success);\r\n return abi.decode(returndata, (address));\r\n }\r\n\r\n /**\r\n * @dev Returns the current admin of `proxy`.\r\n *\r\n * Requirements:\r\n *\r\n * - This contract must be the admin of `proxy`.\r\n */\r\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\r\n // We need to manually run the static call since the getter cannot be flagged as view\r\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\r\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\r\n require(success);\r\n return abi.decode(returndata, (address));\r\n }\r\n\r\n /**\r\n * @dev Changes the admin of `proxy` to `newAdmin`.\r\n *\r\n * Requirements:\r\n *\r\n * - This contract must be the current admin of `proxy`.\r\n */\r\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\r\n proxy.changeAdmin(newAdmin);\r\n }\r\n\r\n /**\r\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\r\n *\r\n * Requirements:\r\n *\r\n * - This contract must be the admin of `proxy`.\r\n */\r\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\r\n proxy.upgradeTo(implementation);\r\n }\r\n\r\n /**\r\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\r\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\r\n *\r\n * Requirements:\r\n *\r\n * - This contract must be the admin of `proxy`.\r\n */\r\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\r\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\r\n }\r\n}\r\n"
+ },
+ "contracts/Federation/FederationV1.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../Bridge/IBridgeV2.sol\";\r\nimport \"../zeppelin/ownership/Ownable.sol\";\r\n\r\ncontract FederationV1 is Ownable {\r\n uint constant public MAX_MEMBER_COUNT = 50;\r\n address constant private NULL_ADDRESS = address(0);\r\n\r\n IBridgeV2 public bridge;\r\n address[] public members;\r\n uint public required;\r\n\r\n mapping (address => bool) public isMember;\r\n mapping (bytes32 => mapping (address => bool)) public votes;\r\n mapping(bytes32 => bool) public processed;\r\n // solium-disable-next-line max-len\r\n event Voted(address indexed sender, bytes32 indexed transactionId, address originalTokenAddress, address receiver, uint256 amount, string symbol, bytes32 blockHash, bytes32 indexed transactionHash, uint32 logIndex, uint8 decimals, uint256 granularity);\r\n event Executed(bytes32 indexed transactionId);\r\n event MemberAddition(address indexed member);\r\n event MemberRemoval(address indexed member);\r\n event RequirementChange(uint required);\r\n event BridgeChanged(address bridge);\r\n\r\n modifier onlyMember() {\r\n require(isMember[_msgSender()], \"Federation: Caller not a Federator\");\r\n _;\r\n }\r\n\r\n modifier validRequirement(uint membersCount, uint _required) {\r\n // solium-disable-next-line max-len\r\n require(_required <= membersCount && _required != 0 && membersCount != 0, \"Federation: Invalid requirements\");\r\n _;\r\n }\r\n\r\n constructor(address[] memory _members, uint _required) validRequirement(_members.length, _required) {\r\n require(_members.length <= MAX_MEMBER_COUNT, \"Federation: Members larger than max allowed\");\r\n members = _members;\r\n for (uint i = 0; i < _members.length; i++) {\r\n require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, \"Federation: Invalid members\");\r\n isMember[_members[i]] = true;\r\n emit MemberAddition(_members[i]);\r\n }\r\n required = _required;\r\n emit RequirementChange(required);\r\n }\r\n\r\n function setBridge(address _bridge) external onlyOwner {\r\n require(_bridge != NULL_ADDRESS, \"Federation: Empty bridge\");\r\n bridge = IBridgeV2(_bridge);\r\n emit BridgeChanged(_bridge);\r\n }\r\n\r\n function voteTransaction(\r\n address originalTokenAddress,\r\n address receiver,\r\n uint256 amount,\r\n string calldata symbol,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex,\r\n uint8 decimals,\r\n uint256 granularity)\r\n external onlyMember returns(bool)\r\n {\r\n // solium-disable-next-line max-len\r\n bytes32 transactionId = getTransactionId(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\r\n if (processed[transactionId])\r\n return true;\r\n\r\n if (votes[transactionId][_msgSender()])\r\n return true;\r\n\r\n votes[transactionId][_msgSender()] = true;\r\n // solium-disable-next-line max-len\r\n emit Voted(_msgSender(), transactionId, originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\r\n\r\n uint transactionCount = getTransactionCount(transactionId);\r\n if (transactionCount >= required && transactionCount >= members.length / 2 + 1) {\r\n processed[transactionId] = true;\r\n bool acceptTransfer = bridge.acceptTransfer(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity);\r\n require(acceptTransfer, \"Federation: Bridge acceptTransfer error\");\r\n emit Executed(transactionId);\r\n return true;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n function getTransactionCount(bytes32 transactionId) public view returns(uint) {\r\n uint count = 0;\r\n for (uint i = 0; i < members.length; i++) {\r\n if (votes[transactionId][members[i]])\r\n count += 1;\r\n }\r\n return count;\r\n }\r\n\r\n function hasVoted(bytes32 transactionId) external view returns(bool)\r\n {\r\n return votes[transactionId][_msgSender()];\r\n }\r\n\r\n function transactionWasProcessed(bytes32 transactionId) external view returns(bool)\r\n {\r\n return processed[transactionId];\r\n }\r\n\r\n function getTransactionId(\r\n address originalTokenAddress,\r\n address receiver,\r\n uint256 amount,\r\n string memory symbol,\r\n bytes32 blockHash,\r\n bytes32 transactionHash,\r\n uint32 logIndex,\r\n uint8 decimals,\r\n uint256 granularity)\r\n public pure returns(bytes32)\r\n {\r\n // solium-disable-next-line max-len\r\n return keccak256(abi.encodePacked(originalTokenAddress, receiver, amount, symbol, blockHash, transactionHash, logIndex, decimals, granularity));\r\n }\r\n\r\n function addMember(address _newMember) external onlyOwner\r\n {\r\n require(_newMember != NULL_ADDRESS, \"Federation: Empty member\");\r\n require(!isMember[_newMember], \"Federation: Member already exists\");\r\n require(members.length < MAX_MEMBER_COUNT, \"Federation: Max members reached\");\r\n\r\n isMember[_newMember] = true;\r\n members.push(_newMember);\r\n emit MemberAddition(_newMember);\r\n }\r\n\r\n function removeMember(address _oldMember) external onlyOwner\r\n {\r\n require(_oldMember != NULL_ADDRESS, \"Federation: Empty member\");\r\n require(isMember[_oldMember], \"Federation: Member doesn't exists\");\r\n require(members.length > 1, \"Federation: Can't remove all the members\");\r\n require(members.length - 1 >= required, \"Federation: Can't have less than required members\");\r\n\r\n isMember[_oldMember] = false;\r\n for (uint i = 0; i < members.length - 1; i++) {\r\n if (members[i] == _oldMember) {\r\n members[i] = members[members.length - 1];\r\n break;\r\n }\r\n }\r\n members.pop(); // remove last element\r\n emit MemberRemoval(_oldMember);\r\n }\r\n\r\n function getMembers() external view returns (address[] memory)\r\n {\r\n return members;\r\n }\r\n\r\n function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required)\r\n {\r\n require(_required >= 2, \"Federation: Requires at least 2\");\r\n required = _required;\r\n emit RequirementChange(_required);\r\n }\r\n\r\n}"
+ },
+ "contracts/Proxies.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"./zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol\";\r\n\r\ncontract BridgeProxy is TransparentUpgradeableProxy {\r\n // solhint-disable-next-line no-empty-blocks\r\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\r\n}\r\n\r\ncontract AllowTokensProxy is TransparentUpgradeableProxy {\r\n // solhint-disable-next-line no-empty-blocks\r\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\r\n}\r\n\r\ncontract FederationProxy is TransparentUpgradeableProxy {\r\n // solhint-disable-next-line no-empty-blocks\r\n constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}\r\n}"
+ },
+ "contracts/test/MainToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/token/ERC20/ERC20Detailed.sol\";\r\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\r\n\r\ncontract MainToken is ERC20Detailed, ERC20 {\r\n constructor(string memory name, string memory symbol, uint8 decimals, uint totalSupply)\r\n ERC20Detailed(name, symbol, decimals)\r\n {\r\n _mint(msg.sender, totalSupply);\r\n }\r\n\r\n /**\r\n * ERC-677's only method implementation\r\n * See https://github.com/ethereum/EIPs/issues/677 for details\r\n */\r\n function transferAndCall(address _to, uint _value, bytes memory _data) public returns (bool) {\r\n bool result = transfer(_to, _value);\r\n if (!result) return false;\r\n\r\n ERC677TransferReceiver receiver = ERC677TransferReceiver(_to);\r\n receiver.tokenFallback(msg.sender, _value, _data);\r\n\r\n // IMPORTANT: the ERC-677 specification does not say\r\n // anything about the use of the receiver contract's\r\n // tokenFallback method return value. Given\r\n // its return type matches with this method's return\r\n // type, returning it could be a possibility.\r\n // We here take the more conservative approach and\r\n // ignore the return value, returning true\r\n // to signal a succesful transfer despite tokenFallback's\r\n // return value -- fact being tokens are transferred\r\n // in any case.\r\n return true;\r\n }\r\n}\r\n\r\ninterface ERC677TransferReceiver {\r\n function tokenFallback(address from, uint256 amount, bytes calldata data) external returns (bool);\r\n}"
+ },
+ "contracts/test/AlternativeERC20Detailed.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../zeppelin/token/ERC20/ERC20.sol\";\r\n\r\ncontract AlternativeERC20Detailed is ERC20 {\r\n string private _name;\r\n bytes32 private _symbol;\r\n uint256 private _decimals;\r\n\r\n constructor(string memory aName, bytes32 aSymbol, uint256 someDecimals, uint256 aTotalSupply)\r\n {\r\n _name = aName;\r\n _symbol = aSymbol;\r\n _decimals = someDecimals;\r\n _mint(msg.sender, aTotalSupply);\r\n }\r\n\r\n function name() public view returns (string memory) {\r\n return _name;\r\n }\r\n\r\n function symbol() public view returns (bytes32) {\r\n return _symbol;\r\n }\r\n\r\n function decimals() public view returns (uint256) {\r\n return _decimals;\r\n }\r\n}"
+ },
+ "contracts/test/nftbridge/NFTERC721TestToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.7.6;\r\n\r\nimport \"../../zeppelin/token/ERC721/ERC721.sol\";\r\n\r\ncontract NFTERC721TestToken is ERC721 {\r\n\r\n string private _contractURI;\r\n\r\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\r\n\r\n function safeMint(address to, uint256 tokenId) public {\r\n _safeMint(to, tokenId);\r\n }\r\n\r\n function setBaseURI(string memory baseURI) public {\r\n _setBaseURI(baseURI);\r\n }\r\n\r\n function setContractURI(string memory contractURI_) public {\r\n _contractURI = contractURI_;\r\n }\r\n\r\n function contractURI() public view returns (string memory) {\r\n return _contractURI;\r\n }\r\n\r\n function setTokenURI(uint256 tokenId, string memory _tokenURI) public {\r\n _setTokenURI(tokenId, _tokenURI);\r\n }\r\n\r\n}\r\n"
+ },
+ "contracts/nftbridge/SideNFTToken.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"./ISideNFTToken.sol\";\r\nimport \"../zeppelin/token/ERC721/ERC721.sol\";\r\nimport \"../zeppelin/token/ERC721/ERC721Burnable.sol\";\r\n\r\ncontract SideNFTToken is ISideNFTToken, ERC721, ERC721Burnable {\r\n address public minter;\r\n string private _contractURI;\r\n\r\n constructor(string memory _name, string memory _symbol, address _minter, string memory _baseURI, string memory contractURI_) ERC721(_name, _symbol) {\r\n require(_minter != address(0), \"SideToken: Empty Minter\");\r\n minter = _minter;\r\n _setBaseURI(_baseURI);\r\n _setContractURI(contractURI_);\r\n }\r\n\r\n function _setContractURI(string memory contractURI_) internal {\r\n _contractURI = contractURI_;\r\n }\r\n\r\n function contractURI() public view returns (string memory) {\r\n return _contractURI;\r\n }\r\n\r\n modifier onlyMinter() {\r\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\r\n _;\r\n }\r\n\r\n function mint(address account, uint256 tokenId) external onlyMinter override {\r\n _mint(account, tokenId);\r\n }\r\n}"
+ },
+ "contracts/nftbridge/SideNFTTokenFactory.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\npragma abicoder v2;\r\n\r\nimport \"../zeppelin/ownership/Secondary.sol\";\r\nimport \"./ISideNFTTokenFactory.sol\";\r\nimport \"./SideNFTToken.sol\";\r\n\r\ncontract SideNFTTokenFactory is ISideNFTTokenFactory, Secondary {\r\n\r\n function createSideNFTToken(string calldata name, string calldata symbol, string calldata baseURI,\r\n string calldata contractURI) external onlyPrimary override returns(address) {\r\n address sideTokenAddress = address(new SideNFTToken(name, symbol, primary(), baseURI, contractURI));\r\n emit SideNFTTokenCreated(sideTokenAddress, symbol, baseURI, contractURI);\r\n return sideTokenAddress;\r\n }\r\n}"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./IERC1155Receiver.sol\";\r\nimport \"../../introspection/ERC165.sol\";\r\n\r\n/**\r\n * @dev _Available since v3.1._\r\n */\r\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\r\n constructor() {\r\n _registerInterface(\r\n ERC1155Receiver(address(0)).onERC1155Received.selector ^\r\n ERC1155Receiver(address(0)).onERC1155BatchReceived.selector\r\n );\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./ERC1155Receiver.sol\";\r\n\r\n/**\r\n * @dev _Available since v3.1._\r\n */\r\ncontract ERC1155Holder is ERC1155Receiver {\r\n function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\r\n return this.onERC1155Received.selector;\r\n }\r\n\r\n function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\r\n return this.onERC1155BatchReceived.selector;\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC721/ERC721Holder.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./IERC721Receiver.sol\";\r\n\r\n /**\r\n * @dev Implementation of the {IERC721Receiver} interface.\r\n *\r\n * Accepts all token transfers. \r\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\r\n */\r\ncontract ERC721Holder is IERC721Receiver {\r\n\r\n /**\r\n * @dev See {IERC721Receiver-onERC721Received}.\r\n *\r\n * Always returns `IERC721Receiver.onERC721Received.selector`.\r\n */\r\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\r\n return this.onERC721Received.selector;\r\n }\r\n}\r\n"
+ },
+ "contracts/zeppelin/token/ERC1155/ERC1155Burnable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"./ERC1155.sol\";\r\n\r\n/**\r\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\r\n * own tokens and those that they have been approved to use.\r\n *\r\n * _Available since v3.1._\r\n */\r\nabstract contract ERC1155Burnable is ERC1155 {\r\n function burn(address account, uint256 id, uint256 value) public virtual {\r\n require(\r\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\r\n \"ERC1155: caller is not owner nor approved\"\r\n );\r\n\r\n _burn(account, id, value);\r\n }\r\n\r\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\r\n require(\r\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\r\n \"ERC1155: caller is not owner nor approved\"\r\n );\r\n\r\n _burnBatch(account, ids, values);\r\n }\r\n}\r\n"
+ },
+ "contracts/test/LibUtilsHarness.sol": {
+ "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.7.0;\r\n\r\nimport \"../lib/LibUtils.sol\";\r\n\r\ncontract LibUtilsHarness {\r\n\r\n function decimalsToGranularity(uint8 decimals) external pure returns (uint256) {\r\n return LibUtils.decimalsToGranularity(decimals);\r\n }\r\n\r\n function getDecimals(address tokenToUse) external view returns (uint8) {\r\n return LibUtils.getDecimals(tokenToUse);\r\n }\r\n\r\n function getGranularity(address tokenToUse) external view returns (uint256) {\r\n return LibUtils.getGranularity(tokenToUse);\r\n }\r\n\r\n function bytesToAddress(bytes memory bys) external pure returns (address addr) {\r\n return LibUtils.bytesToAddress(bys);\r\n }\r\n\r\n}\r\n"
+ }
+ },
+ "settings": {
+ "evmVersion": "istanbul",
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/deploysymm.cmd b/bridge/deploysymm.cmd
deleted file mode 100644
index c6a861d36..000000000
--- a/bridge/deploysymm.cmd
+++ /dev/null
@@ -1,2 +0,0 @@
-call truffle exec maindeploy.js --network development
-call truffle exec niamdeploy.js --network development
diff --git a/bridge/deploysymm2.cmd b/bridge/deploysymm2.cmd
deleted file mode 100644
index e326f9e54..000000000
--- a/bridge/deploysymm2.cmd
+++ /dev/null
@@ -1,2 +0,0 @@
-call truffle exec maindeploy.js --network development
-call truffle exec niamdeploy.js --network regtest
diff --git a/bridge/deploysymmr.cmd b/bridge/deploysymmr.cmd
deleted file mode 100644
index 1eb2e97a4..000000000
--- a/bridge/deploysymmr.cmd
+++ /dev/null
@@ -1,2 +0,0 @@
-call truffle exec maindeploy.js --network regtest
-call truffle exec niamdeploy.js --network regtest
diff --git a/bridge/flatten/.gitignore b/bridge/flatten/.gitignore
new file mode 100644
index 000000000..63bde210b
--- /dev/null
+++ b/bridge/flatten/.gitignore
@@ -0,0 +1,12 @@
+# Ignore everything
+*
+
+# But not these files...
+!.gitignore
+!AllowTokens.sol
+!Bridge.sol
+!Federation.sol
+!Proxies.sol
+!ProxyAdmin.sol
+!SideToken.sol
+!SiteTokenFactory.sol
\ No newline at end of file
diff --git a/bridge/flatten/AllowTokens.sol b/bridge/flatten/AllowTokens.sol
new file mode 100644
index 000000000..e2f4b6e15
--- /dev/null
+++ b/bridge/flatten/AllowTokens.sol
@@ -0,0 +1,664 @@
+// Dependency file: contracts/zeppelin/math/SafeMath.sol
+
+// SPDX-License-Identifier: MIT
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Wrappers over Solidity's arithmetic operations with added overflow
+ * checks.
+ *
+ * Arithmetic operations in Solidity wrap on overflow. This can easily result
+ * in bugs, because programmers usually assume that an overflow raises an
+ * error, which is the standard behavior in high level programming languages.
+ * `SafeMath` restores this intuition by reverting the transaction when an
+ * operation overflows.
+ *
+ * Using this library instead of the unchecked operations eliminates an entire
+ * class of bugs, so it's recommended to use it always.
+ */
+library SafeMath {
+ /**
+ * @dev Returns the addition of two unsigned integers, reverting on
+ * overflow.
+ *
+ * Counterpart to Solidity's `+` operator.
+ *
+ * Requirements:
+ * - Addition cannot overflow.
+ */
+ function add(uint256 a, uint256 b) internal pure returns (uint256) {
+ uint256 c = a + b;
+ require(c >= a, "SafeMath: addition overflow");
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the subtraction of two unsigned integers, reverting on
+ * overflow (when the result is negative).
+ *
+ * Counterpart to Solidity's `-` operator.
+ *
+ * Requirements:
+ * - Subtraction cannot overflow.
+ */
+ function sub(uint256 a, uint256 b) internal pure returns (uint256) {
+ return sub(a, b, "SafeMath: subtraction overflow");
+ }
+
+ /**
+ * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
+ * overflow (when the result is negative).
+ *
+ * Counterpart to Solidity's `-` operator.
+ *
+ * Requirements:
+ * - Subtraction cannot overflow.
+ *
+ * _Available since v2.4.0._
+ */
+ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
+ require(b <= a, errorMessage);
+ uint256 c = a - b;
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the multiplication of two unsigned integers, reverting on
+ * overflow.
+ *
+ * Counterpart to Solidity's `*` operator.
+ *
+ * Requirements:
+ * - Multiplication cannot overflow.
+ */
+ function mul(uint256 a, uint256 b) internal pure returns (uint256) {
+ // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
+ // benefit is lost if 'b' is also tested.
+ // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
+ if (a == 0) {
+ return 0;
+ }
+
+ uint256 c = a * b;
+ require(c / a == b, "SafeMath: multiplication overflow");
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the integer division of two unsigned integers. Reverts on
+ * division by zero. The result is rounded towards zero.
+ *
+ * Counterpart to Solidity's `/` operator. Note: this function uses a
+ * `revert` opcode (which leaves remaining gas untouched) while Solidity
+ * uses an invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ */
+ function div(uint256 a, uint256 b) internal pure returns (uint256) {
+ return div(a, b, "SafeMath: division by zero");
+ }
+
+ /**
+ * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
+ * division by zero. The result is rounded towards zero.
+ *
+ * Counterpart to Solidity's `/` operator. Note: this function uses a
+ * `revert` opcode (which leaves remaining gas untouched) while Solidity
+ * uses an invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ *
+ * _Available since v2.4.0._
+ */
+ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
+ // Solidity only automatically asserts when dividing by 0
+ require(b > 0, errorMessage);
+ uint256 c = a / b;
+ // assert(a == b * c + a % b); // There is no case in which this doesn't hold
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
+ * Reverts when dividing by zero.
+ *
+ * Counterpart to Solidity's `%` operator. This function uses a `revert`
+ * opcode (which leaves remaining gas untouched) while Solidity uses an
+ * invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ */
+ function mod(uint256 a, uint256 b) internal pure returns (uint256) {
+ return mod(a, b, "SafeMath: modulo by zero");
+ }
+
+ /**
+ * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
+ * Reverts with custom message when dividing by zero.
+ *
+ * Counterpart to Solidity's `%` operator. This function uses a `revert`
+ * opcode (which leaves remaining gas untouched) while Solidity uses an
+ * invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ *
+ * _Available since v2.4.0._
+ */
+ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
+ require(b != 0, errorMessage);
+ return a % b;
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/upgradable/Initializable.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @title Initializable
+ *
+ * @dev Helper contract to support initializer functions. To use it, replace
+ * the constructor with a function that has the `initializer` modifier.
+ * WARNING: Unlike constructors, initializer functions must be manually
+ * invoked. This applies both to deploying an Initializable contract, as well
+ * as extending an Initializable contract via inheritance.
+ * WARNING: When used with inheritance, manual care must be taken to not invoke
+ * a parent initializer twice, or ensure that all initializers are idempotent,
+ * because this is not dealt with automatically as with constructors.
+ */
+contract Initializable {
+
+ /**
+ * @dev Indicates that the contract has been initialized.
+ */
+ bool private initialized;
+
+ /**
+ * @dev Indicates that the contract is in the process of being initialized.
+ */
+ bool private initializing;
+
+ /**
+ * @dev Modifier to use in the initializer function of a contract.
+ */
+ modifier initializer() {
+ require(initializing || !initialized, "Contract instance is already initialized");
+
+ bool isTopLevelCall = !initializing;
+ if (isTopLevelCall) {
+ initializing = true;
+ initialized = true;
+ }
+
+ _;
+
+ if (isTopLevelCall) {
+ initializing = false;
+ }
+ }
+
+ // Reserved storage space to allow for layout changes in the future.
+ uint256[50] private ______gap;
+}
+
+// Dependency file: contracts/zeppelin/GSN/Context.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/*
+ * @dev Provides information about the current execution context, including the
+ * sender of the transaction and its data. While these are generally available
+ * via msg.sender and msg.data, they should not be accessed in such a direct
+ * manner, since when dealing with GSN meta-transactions the account sending and
+ * paying for execution may not be the actual sender (as far as an application
+ * is concerned).
+ *
+ * This contract is only required for intermediate, library-like contracts.
+ */
+abstract contract Context {
+
+ function _msgSender() internal view returns (address payable) {
+ return payable(msg.sender);
+ }
+
+ function _msgData() internal view returns (bytes memory) {
+ this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
+ return msg.data;
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/upgradable/Initializable.sol";
+
+// import "contracts/zeppelin/GSN/Context.sol";
+
+/**
+ * @dev Contract module which provides a basic access control mechanism, where
+ * there is an account (an owner) that can be granted exclusive access to
+ * specific functions.
+ *
+ * This module is used through inheritance. It will make available the modifier
+ * `onlyOwner`, which can be aplied to your functions to restrict their use to
+ * the owner.
+ */
+contract UpgradableOwnable is Initializable, Context {
+ address private _owner;
+
+ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
+
+ /**
+ * @dev Initializes the contract setting the deployer as the initial owner.
+ */
+ function initialize(address sender) public initializer {
+ _owner = sender;
+ emit OwnershipTransferred(address(0), _owner);
+ }
+
+ /**
+ * @dev Returns the address of the current owner.
+ */
+ function owner() public view returns (address) {
+ return _owner;
+ }
+
+ /**
+ * @dev Throws if called by any account other than the owner.
+ */
+ modifier onlyOwner() {
+ require(isOwner(), "Ownable: caller is not the owner");
+ _;
+ }
+
+ /**
+ * @dev Returns true if the caller is the current owner.
+ */
+ function isOwner() public view returns (bool) {
+ return _msgSender() == _owner;
+ }
+
+ /**
+ * @dev Leaves the contract without owner. It will not be possible to call
+ * `onlyOwner` functions anymore. Can only be called by the current owner.
+ *
+ * > Note: Renouncing ownership will leave the contract without an owner,
+ * thereby removing any functionality that is only available to the owner.
+ */
+ function renounceOwnership() public onlyOwner {
+ emit OwnershipTransferred(_owner, address(0));
+ _owner = address(0);
+ }
+
+ /**
+ * @dev Transfers ownership of the contract to a new account (`newOwner`).
+ * Can only be called by the current owner.
+ */
+ function transferOwnership(address newOwner) public onlyOwner {
+ _transferOwnership(newOwner);
+ }
+
+ /**
+ * @dev Transfers ownership of the contract to a new account (`newOwner`).
+ */
+ function _transferOwnership(address newOwner) internal {
+ require(newOwner != address(0), "Ownable: new owner is zero address");
+ emit OwnershipTransferred(_owner, newOwner);
+ _owner = newOwner;
+ }
+
+}
+
+
+// Dependency file: contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/upgradable/Initializable.sol";
+
+// import "contracts/zeppelin/GSN/Context.sol";
+
+/**
+ * @dev A Secondary contract can only be used by its primary account (the one that created it).
+ */
+contract UpgradableSecondary is Initializable, Context {
+ address private _primary;
+
+ /**
+ * @dev Emitted when the primary contract changes.
+ */
+ event PrimaryTransferred(
+ address recipient
+ );
+
+ /**
+ * @dev Sets the primary account to the one that is creating the Secondary contract.
+ */
+ function __Secondary_init(address sender) public initializer {
+ _primary = sender;
+ emit PrimaryTransferred(_primary);
+ }
+
+ /**
+ * @dev Reverts if called from any account other than the primary.
+ */
+ modifier onlyPrimary() {
+ require(_msgSender() == _primary, "Secondary: caller is not the primary account");
+ _;
+ }
+
+ /**
+ * @return the address of the primary.
+ */
+ function primary() public view returns (address) {
+ return _primary;
+ }
+
+ /**
+ * @dev Transfers contract to a new primary.
+ * @param recipient The address of new primary.
+ */
+ function transferPrimary(address recipient) public onlyPrimary {
+ require(recipient != address(0), "Secondary: new primary is the zero address");
+ _primary = recipient;
+ emit PrimaryTransferred(recipient);
+ }
+
+}
+
+// Dependency file: contracts/interface/IAllowTokens.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+interface IAllowTokens {
+
+ struct Limits {
+ uint256 min;
+ uint256 max;
+ uint256 daily;
+ uint256 mediumAmount;
+ uint256 largeAmount;
+ }
+
+ struct TokenInfo {
+ bool allowed;
+ uint256 typeId;
+ uint256 spentToday;
+ uint256 lastDay;
+ }
+
+ struct TypeInfo {
+ string description;
+ Limits limits;
+ }
+
+ struct TokensAndType {
+ address token;
+ uint256 typeId;
+ }
+
+ function version() external pure returns (string memory);
+
+ function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);
+
+ function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);
+
+ function getTypesLimits() external view returns(Limits[] memory limits);
+
+ function getTypeDescriptionsLength() external view returns(uint256);
+
+ function getTypeDescriptions() external view returns(string[] memory descriptions);
+
+ function setToken(address token, uint256 typeId) external;
+
+ function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);
+
+ function isTokenAllowed(address token) external view returns (bool);
+
+ function updateTokenTransfer(address token, uint256 amount) external;
+}
+
+// Root file: contracts/AllowTokens/AllowTokens.sol
+
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/math/SafeMath.sol";
+// Upgradables
+// import "contracts/zeppelin/upgradable/Initializable.sol";
+// import "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol";
+// import "contracts/zeppelin/upgradable/ownership/UpgradableSecondary.sol";
+
+// import "contracts/interface/IAllowTokens.sol";
+
+contract AllowTokens is Initializable, UpgradableOwnable, UpgradableSecondary, IAllowTokens {
+ using SafeMath for uint256;
+
+ address constant private NULL_ADDRESS = address(0);
+ uint256 constant public MAX_TYPES = 250;
+ mapping (address => TokenInfo) public allowedTokens;
+ mapping (uint256 => Limits) public typeLimits;
+ uint256 public smallAmountConfirmations;
+ uint256 public mediumAmountConfirmations;
+ uint256 public largeAmountConfirmations;
+ string[] public typeDescriptions;
+
+ event SetToken(address indexed _tokenAddress, uint256 _typeId);
+ event AllowedTokenRemoved(address indexed _tokenAddress);
+ event TokenTypeAdded(uint256 indexed _typeId, string _typeDescription);
+ event TypeLimitsChanged(uint256 indexed _typeId, Limits limits);
+ event UpdateTokensTransfered(address indexed _tokenAddress, uint256 _lastDay, uint256 _spentToday);
+ event ConfirmationsChanged(uint256 _smallAmountConfirmations, uint256 _mediumAmountConfirmations, uint256 _largeAmountConfirmations);
+
+ modifier notNull(address _address) {
+ require(_address != NULL_ADDRESS, "AllowTokens: Null Address");
+ _;
+ }
+
+ function initialize(
+ address _manager,
+ address _primary,
+ uint256 _smallAmountConfirmations,
+ uint256 _mediumAmountConfirmations,
+ uint256 _largeAmountConfirmations,
+ TypeInfo[] memory typesInfo) public initializer {
+ UpgradableOwnable.initialize(_manager);
+ UpgradableSecondary.__Secondary_init(_primary);
+ _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);
+ for(uint i = 0; i < typesInfo.length; i = i + 1) {
+ _addTokenType(typesInfo[i].description, typesInfo[i].limits);
+ }
+ }
+
+ function version() override external pure returns (string memory) {
+ return "v1";
+ }
+
+ function tokenInfo(address tokenAddress) public view returns(TokenInfo memory) {
+ return allowedTokens[tokenAddress];
+ }
+
+ function setTokenInfoByTokenAddress(address tokenAddress, TokenInfo memory info) public {
+ require(isOwner() || _msgSender() == primary(), "AllowTokens: unauthorized sender");
+ allowedTokens[tokenAddress] = info;
+ }
+
+ function getInfoAndLimits(
+ address tokenAddress
+ ) public view override returns (
+ TokenInfo memory info,
+ Limits memory limit
+ ) {
+ info = tokenInfo(tokenAddress);
+ limit = typeLimits[info.typeId];
+ return (info, limit);
+ }
+
+ function calcMaxWithdraw(address token) public view override returns (uint256 maxWithdraw) {
+ (TokenInfo memory info, Limits memory limits) = getInfoAndLimits(token);
+ return _calcMaxWithdraw(info, limits);
+ }
+
+ function _calcMaxWithdraw(TokenInfo memory info, Limits memory limits) private view returns (uint256 maxWithdraw) {
+ // solium-disable-next-line security/no-block-members
+ if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time
+ info.spentToday = 0;
+ }
+ if (limits.daily <= info.spentToday) {
+ return 0;
+ }
+ maxWithdraw = limits.daily - info.spentToday;
+ if (maxWithdraw > limits.max) {
+ maxWithdraw = limits.max;
+ }
+ return maxWithdraw;
+ }
+
+ function updateTokenTransfer(address token, uint256 amount) override external onlyPrimary {
+ (TokenInfo memory info, Limits memory limit) = getInfoAndLimits(token);
+ require(isTokenAllowed(token), "AllowTokens: Not whitelisted");
+ require(amount >= limit.min, "AllowTokens: Lower than limit");
+
+ // solium-disable-next-line security/no-block-members
+ if (block.timestamp > info.lastDay + 24 hours) { // solhint-disable-line not-rely-on-time
+ // solium-disable-next-line security/no-block-members
+ info.lastDay = block.timestamp; // solhint-disable-line not-rely-on-time
+ info.spentToday = 0;
+ }
+ uint maxWithdraw = _calcMaxWithdraw(info, limit);
+ require(amount <= maxWithdraw, "AllowTokens: Exceeded limit");
+ info.spentToday = info.spentToday.add(amount);
+ setTokenInfoByTokenAddress(token, info);
+
+ emit UpdateTokensTransfered(token, info.lastDay, info.spentToday);
+ }
+
+ function _addTokenType(string memory description, Limits memory limits) private returns(uint256 len) {
+ require(bytes(description).length > 0, "AllowTokens: Empty description");
+ len = typeDescriptions.length;
+ require(len + 1 <= MAX_TYPES, "AllowTokens: Reached MAX_TYPES");
+ typeDescriptions.push(description);
+ _setTypeLimits(len, limits);
+ emit TokenTypeAdded(len, description);
+ return len;
+ }
+
+ function addTokenType(string calldata description, Limits calldata limits) external onlyOwner returns(uint256 len) {
+ return _addTokenType(description, limits);
+ }
+
+ function _setTypeLimits(uint256 typeId, Limits memory limits) private {
+ require(typeId < typeDescriptions.length, "AllowTokens: bigger than typeDescriptions");
+ require(limits.max >= limits.min, "AllowTokens: maxTokens smaller than minTokens");
+ require(limits.daily >= limits.max, "AllowTokens: dailyLimit smaller than maxTokens");
+ require(limits.mediumAmount > limits.min, "AllowTokens: limits.mediumAmount smaller than min");
+ require(limits.largeAmount > limits.mediumAmount, "AllowTokens: limits.largeAmount smaller than mediumAmount");
+ typeLimits[typeId] = limits;
+ emit TypeLimitsChanged(typeId, limits);
+ }
+
+ function setTypeLimits(uint256 typeId, Limits memory limits) public onlyOwner {
+ _setTypeLimits(typeId, limits);
+ }
+
+ function getTypesLimits() external view override returns(Limits[] memory limits) {
+ limits = new Limits[](typeDescriptions.length);
+ for (uint256 i = 0; i < typeDescriptions.length; i++) {
+ limits[i] = typeLimits[i];
+ }
+ return limits;
+ }
+
+ function getTypeDescriptionsLength() external view override returns(uint256) {
+ return typeDescriptions.length;
+ }
+
+ function getTypeDescriptions() external view override returns(string[] memory descriptions) {
+ descriptions = new string[](typeDescriptions.length);
+ for (uint256 i = 0; i < typeDescriptions.length; i++) {
+ descriptions[i] = typeDescriptions[i];
+ }
+ return descriptions;
+ }
+
+ function isTokenAllowed(address token) public view notNull(token) override returns (bool) {
+ return tokenInfo(token).allowed;
+ }
+
+ function setToken(address token, uint256 typeId) override public notNull(token) {
+ require(isOwner() || _msgSender() == primary(), "AllowTokens: unauthorized sender");
+ require(typeId < typeDescriptions.length, "AllowTokens: typeId does not exist");
+ TokenInfo memory info = tokenInfo(token);
+ info.allowed = true;
+ info.typeId = typeId;
+ setTokenInfoByTokenAddress(token, info);
+ emit SetToken(token, typeId);
+ }
+
+ function setMultipleTokens(TokensAndType[] calldata tokensAndTypes) external onlyOwner {
+ require(tokensAndTypes.length > 0, "AllowTokens: empty tokens");
+ for(uint256 i = 0; i < tokensAndTypes.length; i = i + 1) {
+ setToken(tokensAndTypes[i].token, tokensAndTypes[i].typeId);
+ }
+ }
+
+ function removeAllowedToken(address token) external notNull(token) onlyOwner {
+ TokenInfo memory info = tokenInfo(token);
+ require(info.allowed, "AllowTokens: Not Allowed");
+ info.allowed = false;
+ setTokenInfoByTokenAddress(token, info);
+ emit AllowedTokenRemoved(token);
+ }
+
+ function setConfirmations(
+ uint256 _smallAmountConfirmations,
+ uint256 _mediumAmountConfirmations,
+ uint256 _largeAmountConfirmations) external onlyOwner {
+ _setConfirmations(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);
+ }
+
+ function _setConfirmations(
+ uint256 _smallAmountConfirmations,
+ uint256 _mediumAmountConfirmations,
+ uint256 _largeAmountConfirmations) private {
+ require(_smallAmountConfirmations <= _mediumAmountConfirmations, "AllowTokens: small bigger than medium confirmations");
+ require(_mediumAmountConfirmations <= _largeAmountConfirmations, "AllowTokens: medium bigger than large confirmations");
+ smallAmountConfirmations = _smallAmountConfirmations;
+ mediumAmountConfirmations = _mediumAmountConfirmations;
+ largeAmountConfirmations = _largeAmountConfirmations;
+ emit ConfirmationsChanged(_smallAmountConfirmations, _mediumAmountConfirmations, _largeAmountConfirmations);
+ }
+
+ function getConfirmations() external view override
+ returns (
+ uint256 smallAmount,
+ uint256 mediumAmount,
+ uint256 largeAmount
+ ) {
+ return (smallAmountConfirmations, mediumAmountConfirmations, largeAmountConfirmations);
+ }
+
+}
diff --git a/bridge/flatten/Bridge.sol b/bridge/flatten/Bridge.sol
new file mode 100644
index 000000000..60b0fb2ee
--- /dev/null
+++ b/bridge/flatten/Bridge.sol
@@ -0,0 +1,3883 @@
+// Dependency file: hardhat/console.sol
+
+// SPDX-License-Identifier: MIT
+// pragma solidity >= 0.4.22 <0.9.0;
+
+library console {
+ address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);
+
+ function _sendLogPayload(bytes memory payload) private view {
+ uint256 payloadLength = payload.length;
+ address consoleAddress = CONSOLE_ADDRESS;
+ assembly {
+ let payloadStart := add(payload, 32)
+ let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)
+ }
+ }
+
+ function log() internal view {
+ _sendLogPayload(abi.encodeWithSignature("log()"));
+ }
+
+ function logInt(int p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(int)", p0));
+ }
+
+ function logUint(uint p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
+ }
+
+ function logString(string memory p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string)", p0));
+ }
+
+ function logBool(bool p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
+ }
+
+ function logAddress(address p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address)", p0));
+ }
+
+ function logBytes(bytes memory p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
+ }
+
+ function logBytes1(bytes1 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
+ }
+
+ function logBytes2(bytes2 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
+ }
+
+ function logBytes3(bytes3 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
+ }
+
+ function logBytes4(bytes4 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
+ }
+
+ function logBytes5(bytes5 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
+ }
+
+ function logBytes6(bytes6 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
+ }
+
+ function logBytes7(bytes7 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
+ }
+
+ function logBytes8(bytes8 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
+ }
+
+ function logBytes9(bytes9 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
+ }
+
+ function logBytes10(bytes10 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
+ }
+
+ function logBytes11(bytes11 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
+ }
+
+ function logBytes12(bytes12 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
+ }
+
+ function logBytes13(bytes13 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
+ }
+
+ function logBytes14(bytes14 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
+ }
+
+ function logBytes15(bytes15 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
+ }
+
+ function logBytes16(bytes16 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
+ }
+
+ function logBytes17(bytes17 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
+ }
+
+ function logBytes18(bytes18 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
+ }
+
+ function logBytes19(bytes19 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
+ }
+
+ function logBytes20(bytes20 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
+ }
+
+ function logBytes21(bytes21 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
+ }
+
+ function logBytes22(bytes22 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
+ }
+
+ function logBytes23(bytes23 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
+ }
+
+ function logBytes24(bytes24 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
+ }
+
+ function logBytes25(bytes25 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
+ }
+
+ function logBytes26(bytes26 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
+ }
+
+ function logBytes27(bytes27 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
+ }
+
+ function logBytes28(bytes28 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
+ }
+
+ function logBytes29(bytes29 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
+ }
+
+ function logBytes30(bytes30 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
+ }
+
+ function logBytes31(bytes31 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
+ }
+
+ function logBytes32(bytes32 p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
+ }
+
+ function log(uint p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
+ }
+
+ function log(string memory p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string)", p0));
+ }
+
+ function log(bool p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
+ }
+
+ function log(address p0) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address)", p0));
+ }
+
+ function log(uint p0, uint p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1));
+ }
+
+ function log(uint p0, string memory p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1));
+ }
+
+ function log(uint p0, bool p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1));
+ }
+
+ function log(uint p0, address p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1));
+ }
+
+ function log(string memory p0, uint p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1));
+ }
+
+ function log(string memory p0, string memory p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
+ }
+
+ function log(string memory p0, bool p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
+ }
+
+ function log(string memory p0, address p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
+ }
+
+ function log(bool p0, uint p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1));
+ }
+
+ function log(bool p0, string memory p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
+ }
+
+ function log(bool p0, bool p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
+ }
+
+ function log(bool p0, address p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
+ }
+
+ function log(address p0, uint p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1));
+ }
+
+ function log(address p0, string memory p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
+ }
+
+ function log(address p0, bool p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
+ }
+
+ function log(address p0, address p1) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
+ }
+
+ function log(uint p0, uint p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2));
+ }
+
+ function log(uint p0, uint p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2));
+ }
+
+ function log(uint p0, uint p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2));
+ }
+
+ function log(uint p0, uint p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2));
+ }
+
+ function log(uint p0, string memory p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2));
+ }
+
+ function log(uint p0, string memory p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2));
+ }
+
+ function log(uint p0, string memory p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2));
+ }
+
+ function log(uint p0, string memory p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2));
+ }
+
+ function log(uint p0, bool p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2));
+ }
+
+ function log(uint p0, bool p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2));
+ }
+
+ function log(uint p0, bool p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2));
+ }
+
+ function log(uint p0, bool p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2));
+ }
+
+ function log(uint p0, address p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2));
+ }
+
+ function log(uint p0, address p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2));
+ }
+
+ function log(uint p0, address p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2));
+ }
+
+ function log(uint p0, address p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2));
+ }
+
+ function log(string memory p0, uint p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2));
+ }
+
+ function log(string memory p0, uint p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2));
+ }
+
+ function log(string memory p0, uint p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2));
+ }
+
+ function log(string memory p0, uint p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2));
+ }
+
+ function log(string memory p0, string memory p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2));
+ }
+
+ function log(string memory p0, string memory p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
+ }
+
+ function log(string memory p0, string memory p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
+ }
+
+ function log(string memory p0, string memory p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
+ }
+
+ function log(string memory p0, bool p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2));
+ }
+
+ function log(string memory p0, bool p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
+ }
+
+ function log(string memory p0, bool p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
+ }
+
+ function log(string memory p0, bool p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
+ }
+
+ function log(string memory p0, address p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2));
+ }
+
+ function log(string memory p0, address p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
+ }
+
+ function log(string memory p0, address p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
+ }
+
+ function log(string memory p0, address p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
+ }
+
+ function log(bool p0, uint p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2));
+ }
+
+ function log(bool p0, uint p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2));
+ }
+
+ function log(bool p0, uint p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2));
+ }
+
+ function log(bool p0, uint p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2));
+ }
+
+ function log(bool p0, string memory p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2));
+ }
+
+ function log(bool p0, string memory p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
+ }
+
+ function log(bool p0, string memory p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
+ }
+
+ function log(bool p0, string memory p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
+ }
+
+ function log(bool p0, bool p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2));
+ }
+
+ function log(bool p0, bool p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
+ }
+
+ function log(bool p0, bool p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
+ }
+
+ function log(bool p0, bool p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
+ }
+
+ function log(bool p0, address p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2));
+ }
+
+ function log(bool p0, address p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
+ }
+
+ function log(bool p0, address p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
+ }
+
+ function log(bool p0, address p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
+ }
+
+ function log(address p0, uint p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2));
+ }
+
+ function log(address p0, uint p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2));
+ }
+
+ function log(address p0, uint p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2));
+ }
+
+ function log(address p0, uint p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2));
+ }
+
+ function log(address p0, string memory p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2));
+ }
+
+ function log(address p0, string memory p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
+ }
+
+ function log(address p0, string memory p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
+ }
+
+ function log(address p0, string memory p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
+ }
+
+ function log(address p0, bool p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2));
+ }
+
+ function log(address p0, bool p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
+ }
+
+ function log(address p0, bool p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
+ }
+
+ function log(address p0, bool p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
+ }
+
+ function log(address p0, address p1, uint p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2));
+ }
+
+ function log(address p0, address p1, string memory p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
+ }
+
+ function log(address p0, address p1, bool p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
+ }
+
+ function log(address p0, address p1, address p2) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
+ }
+
+ function log(uint p0, uint p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, uint p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, string memory p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, bool p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(uint p0, address p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, uint p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, string memory p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, bool p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(string memory p0, address p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, uint p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, string memory p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, bool p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(bool p0, address p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, uint p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, string memory p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, bool p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, uint p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, uint p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, uint p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, uint p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, string memory p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, string memory p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, string memory p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, string memory p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, bool p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, bool p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, bool p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, bool p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, address p2, uint p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, address p2, string memory p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, address p2, bool p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
+ }
+
+ function log(address p0, address p1, address p2, address p3) internal view {
+ _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
+ }
+
+}
+
+
+// Dependency file: contracts/zeppelin/upgradable/Initializable.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @title Initializable
+ *
+ * @dev Helper contract to support initializer functions. To use it, replace
+ * the constructor with a function that has the `initializer` modifier.
+ * WARNING: Unlike constructors, initializer functions must be manually
+ * invoked. This applies both to deploying an Initializable contract, as well
+ * as extending an Initializable contract via inheritance.
+ * WARNING: When used with inheritance, manual care must be taken to not invoke
+ * a parent initializer twice, or ensure that all initializers are idempotent,
+ * because this is not dealt with automatically as with constructors.
+ */
+contract Initializable {
+
+ /**
+ * @dev Indicates that the contract has been initialized.
+ */
+ bool private initialized;
+
+ /**
+ * @dev Indicates that the contract is in the process of being initialized.
+ */
+ bool private initializing;
+
+ /**
+ * @dev Modifier to use in the initializer function of a contract.
+ */
+ modifier initializer() {
+ require(initializing || !initialized, "Contract instance is already initialized");
+
+ bool isTopLevelCall = !initializing;
+ if (isTopLevelCall) {
+ initializing = true;
+ initialized = true;
+ }
+
+ _;
+
+ if (isTopLevelCall) {
+ initializing = false;
+ }
+ }
+
+ // Reserved storage space to allow for layout changes in the future.
+ uint256[50] private ______gap;
+}
+
+// Dependency file: contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/upgradable/Initializable.sol";
+
+/**
+ * @title Helps contracts guard against reentrancy attacks.
+ * @author Remco Bloemen , Eenae
+ * @dev If you mark a function `nonReentrant`, you should also
+ * mark it `external`.
+ */
+contract ReentrancyGuard is Initializable {
+ /// @dev counter to allow mutex lock with only one SSTORE operation
+ uint256 private _guardCounter;
+
+ function initialize() public initializer {
+ // The counter starts at one to prevent changing it from zero to a non-zero
+ // value, which is a more expensive operation.
+ _guardCounter = 1;
+ }
+
+ /**
+ * @dev Prevents a contract from calling itself, directly or indirectly.
+ * Calling a `nonReentrant` function from another `nonReentrant`
+ * function is not supported. It is possible to prevent this from happening
+ * by making the `nonReentrant` function external, and make it call a
+ * `private` function that does the actual work.
+ */
+ modifier nonReentrant() {
+ _guardCounter += 1;
+ uint256 localCounter = _guardCounter;
+ _;
+ require(localCounter == _guardCounter, "ReentrancyGuard: no reentrant allowed");
+ }
+}
+
+// Dependency file: contracts/zeppelin/GSN/Context.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/*
+ * @dev Provides information about the current execution context, including the
+ * sender of the transaction and its data. While these are generally available
+ * via msg.sender and msg.data, they should not be accessed in such a direct
+ * manner, since when dealing with GSN meta-transactions the account sending and
+ * paying for execution may not be the actual sender (as far as an application
+ * is concerned).
+ *
+ * This contract is only required for intermediate, library-like contracts.
+ */
+abstract contract Context {
+
+ function _msgSender() internal view returns (address payable) {
+ return payable(msg.sender);
+ }
+
+ function _msgData() internal view returns (bytes memory) {
+ this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
+ return msg.data;
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/access/Roles.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @title Roles
+ * @dev Library for managing addresses assigned to a Role.
+ */
+library Roles {
+ struct Role {
+ mapping (address => bool) bearer;
+ }
+
+ /**
+ * @dev Give an account access to this role.
+ */
+ function add(Role storage role, address account) internal {
+ require(!has(role, account), "Roles: account already has role");
+ role.bearer[account] = true;
+ }
+
+ /**
+ * @dev Remove an account's access to this role.
+ */
+ function remove(Role storage role, address account) internal {
+ require(has(role, account), "Roles: account doesn't have role");
+ role.bearer[account] = false;
+ }
+
+ /**
+ * @dev Check if an account has this role.
+ * @return bool
+ */
+ function has(Role storage role, address account) internal view returns (bool) {
+ require(account != address(0), "Roles: account is the zero address");
+ return role.bearer[account];
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/upgradable/Initializable.sol";
+
+// import "contracts/zeppelin/GSN/Context.sol";
+// import "contracts/zeppelin/access/Roles.sol";
+
+contract UpgradablePauserRole is Initializable, Context {
+ using Roles for Roles.Role;
+
+ event PauserAdded(address indexed account);
+ event PauserRemoved(address indexed account);
+
+ Roles.Role private _pausers;
+
+ function __PauserRol_init(address sender) public initializer {
+ if (!isPauser(sender)) {
+ _addPauser(sender);
+ }
+ }
+
+ modifier onlyPauser() {
+ require(isPauser(_msgSender()), "PauserRole: caller doesn't have the role");
+ _;
+ }
+
+ function isPauser(address account) public view returns (bool) {
+ return _pausers.has(account);
+ }
+
+ function addPauser(address account) public onlyPauser {
+ _addPauser(account);
+ }
+
+ function renouncePauser() public {
+ _removePauser(_msgSender());
+ }
+
+ function _addPauser(address account) internal {
+ _pausers.add(account);
+ emit PauserAdded(account);
+ }
+
+ function _removePauser(address account) internal {
+ _pausers.remove(account);
+ emit PauserRemoved(account);
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/upgradable/Initializable.sol";
+
+// import "contracts/zeppelin/GSN/Context.sol";
+// import "contracts/zeppelin/upgradable/access/roles/UpgradablePauserRole.sol";
+
+/**
+ * @dev Contract module which allows children to implement an emergency stop
+ * mechanism that can be triggered by an authorized account.
+ *
+ * This module is used through inheritance. It will make available the
+ * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
+ * the functions of your contract. Note that they will not be pausable by
+ * simply including this module, only once the modifiers are put in place.
+ */
+contract UpgradablePausable is Initializable, Context, UpgradablePauserRole {
+ /**
+ * @dev Emitted when the pause is triggered by a pauser (`account`).
+ */
+ event Paused(address account);
+
+ /**
+ * @dev Emitted when the pause is lifted by a pauser (`account`).
+ */
+ event Unpaused(address account);
+
+ bool private _paused;
+
+ /**
+ * @dev Initializes the contract in unpaused state. Assigns the Pauser role
+ * to the deployer.
+ */
+ function __Pausable_init(address sender) public initializer {
+ UpgradablePauserRole.__PauserRol_init(sender);
+
+ _paused = false;
+ }
+
+ /**
+ * @dev Returns true if the contract is paused, and false otherwise.
+ */
+ function paused() public view returns (bool) {
+ return _paused;
+ }
+
+ /**
+ * @dev Modifier to make a function callable only when the contract is not paused.
+ */
+ modifier whenNotPaused() {
+ require(!_paused, "Pausable: paused");
+ _;
+ }
+
+ /**
+ * @dev Modifier to make a function callable only when the contract is paused.
+ */
+ modifier whenPaused() {
+ require(_paused, "Pausable: not paused");
+ _;
+ }
+
+ /**
+ * @dev Called by a pauser to pause, triggers stopped state.
+ */
+ function pause() public onlyPauser whenNotPaused {
+ _paused = true;
+ emit Paused(_msgSender());
+ }
+
+ /**
+ * @dev Called by a pauser to unpause, returns to normal state.
+ */
+ function unpause() public onlyPauser whenPaused {
+ _paused = false;
+ emit Unpaused(_msgSender());
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/upgradable/Initializable.sol";
+
+// import "contracts/zeppelin/GSN/Context.sol";
+
+/**
+ * @dev Contract module which provides a basic access control mechanism, where
+ * there is an account (an owner) that can be granted exclusive access to
+ * specific functions.
+ *
+ * This module is used through inheritance. It will make available the modifier
+ * `onlyOwner`, which can be aplied to your functions to restrict their use to
+ * the owner.
+ */
+contract UpgradableOwnable is Initializable, Context {
+ address private _owner;
+
+ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
+
+ /**
+ * @dev Initializes the contract setting the deployer as the initial owner.
+ */
+ function initialize(address sender) public initializer {
+ _owner = sender;
+ emit OwnershipTransferred(address(0), _owner);
+ }
+
+ /**
+ * @dev Returns the address of the current owner.
+ */
+ function owner() public view returns (address) {
+ return _owner;
+ }
+
+ /**
+ * @dev Throws if called by any account other than the owner.
+ */
+ modifier onlyOwner() {
+ require(isOwner(), "Ownable: caller is not the owner");
+ _;
+ }
+
+ /**
+ * @dev Returns true if the caller is the current owner.
+ */
+ function isOwner() public view returns (bool) {
+ return _msgSender() == _owner;
+ }
+
+ /**
+ * @dev Leaves the contract without owner. It will not be possible to call
+ * `onlyOwner` functions anymore. Can only be called by the current owner.
+ *
+ * > Note: Renouncing ownership will leave the contract without an owner,
+ * thereby removing any functionality that is only available to the owner.
+ */
+ function renounceOwnership() public onlyOwner {
+ emit OwnershipTransferred(_owner, address(0));
+ _owner = address(0);
+ }
+
+ /**
+ * @dev Transfers ownership of the contract to a new account (`newOwner`).
+ * Can only be called by the current owner.
+ */
+ function transferOwnership(address newOwner) public onlyOwner {
+ _transferOwnership(newOwner);
+ }
+
+ /**
+ * @dev Transfers ownership of the contract to a new account (`newOwner`).
+ */
+ function _transferOwnership(address newOwner) internal {
+ require(newOwner != address(0), "Ownable: new owner is zero address");
+ emit OwnershipTransferred(_owner, newOwner);
+ _owner = newOwner;
+ }
+
+}
+
+
+// Dependency file: contracts/zeppelin/introspection/IERC1820Registry.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface of the global ERC1820 Registry, as defined in the
+ * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register
+ * implementers for interfaces in this registry, as well as query support.
+ *
+ * Implementers may be shared by multiple accounts, and can also implement more
+ * than a single interface for each account. Contracts can implement interfaces
+ * for themselves, but externally-owned accounts (EOA) must delegate this to a
+ * contract.
+ *
+ * {IERC165} interfaces can also be queried via the registry.
+ *
+ * For an in-depth explanation and source code analysis, see the EIP text.
+ */
+interface IERC1820Registry {
+ /**
+ * @dev Sets `newManager` as the manager for `account`. A manager of an
+ * account is able to set interface implementers for it.
+ *
+ * By default, each account is its own manager. Passing a value of `0x0` in
+ * `newManager` will reset the manager to this initial state.
+ *
+ * Emits a {ManagerChanged} event.
+ *
+ * Requirements:
+ *
+ * - the caller must be the current manager for `account`.
+ */
+ function setManager(address account, address newManager) external;
+
+ /**
+ * @dev Returns the manager for `account`.
+ *
+ * See {setManager}.
+ */
+ function getManager(address account) external view returns (address);
+
+ /**
+ * @dev Sets the `implementer` contract as `account`'s implementer for
+ * `interfaceHash`.
+ *
+ * `account` being the zero address is an alias for the caller's address.
+ * The zero address can also be used in `implementer` to remove an old one.
+ *
+ * See {interfaceHash} to learn how these are created.
+ *
+ * Emits an {InterfaceImplementerSet} event.
+ *
+ * Requirements:
+ *
+ * - the caller must be the current manager for `_account`.
+ * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not
+ * end in 28 zeroes).
+ * - `_implementer` must implement {IERC1820Implementer} and return true when
+ * queried for support, unless `implementer` is the caller. See
+ * {IERC1820Implementer-canImplementInterfaceForAddress}.
+ */
+ function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;
+
+ /**
+ * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such
+ * implementer is registered, returns the zero address.
+ *
+ * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28
+ * zeroes), `_account` will be queried for support of it.
+ *
+ * `account` being the zero address is an alias for the caller's address.
+ */
+ function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);
+
+ /**
+ * @dev Returns the interface hash for an `interfaceName`, as defined in the
+ * corresponding
+ * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].
+ */
+ function interfaceHash(string calldata interfaceName) external pure returns (bytes32);
+
+ /**
+ * @notice Updates the cache with whether the contract implements an ERC165 interface or not.
+ * @param account Address of the contract for which to update the cache.
+ * @param interfaceId ERC165 interface for which to update the cache.
+ */
+ function updateERC165Cache(address account, bytes4 interfaceId) external;
+
+ /**
+ * @notice Checks whether a contract implements an ERC165 interface or not.
+ * If the result is not cached a direct lookup on the contract address is performed.
+ * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling
+ * {updateERC165Cache} with the contract address.
+ * @param account Address of the contract to check.
+ * @param interfaceId ERC165 interface to check.
+ * @return True if `account` implements `interfaceId`, false otherwise.
+ */
+ function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);
+
+ /**
+ * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.
+ * @param account Address of the contract to check.
+ * @param interfaceId ERC165 interface to check.
+ * @return True if `account` implements `interfaceId`, false otherwise.
+ */
+ function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);
+
+ event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);
+
+ event ManagerChanged(address indexed account, address indexed newManager);
+}
+
+
+// Dependency file: contracts/zeppelin/token/ERC777/IERC777Recipient.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.
+ *
+ * Accounts can be notified of `IERC777` tokens being sent to them by having a
+ * contract implement this interface (contract holders can be their own
+ * implementer) and registering it on the
+ * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).
+ *
+ * See `IERC1820Registry` and `ERC1820Implementer`.
+ */
+interface IERC777Recipient {
+ /**
+ * @dev Called by an `IERC777` token contract whenever tokens are being
+ * moved or created into a registered account (`to`). The type of operation
+ * is conveyed by `from` being the zero address or not.
+ *
+ * This call occurs _after_ the token contract's state is updated, so
+ * `IERC777.balanceOf`, etc., can be used to query the post-operation state.
+ *
+ * This function may revert to prevent the operation from being executed.
+ */
+ function tokensReceived(
+ address operator,
+ address from,
+ address to,
+ uint amount,
+ bytes calldata userData,
+ bytes calldata operatorData
+ ) external;
+}
+
+
+// Dependency file: contracts/zeppelin/token/ERC20/IERC20.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
+ * the optional functions; to access them see {ERC20Detailed}.
+ */
+interface IERC20 {
+ /**
+ * @dev Returns the amount of tokens in existence.
+ */
+ function totalSupply() external view returns (uint256);
+
+ /**
+ * @dev Returns the amount of tokens owned by `account`.
+ */
+ function balanceOf(address account) external view returns (uint256);
+
+ /**
+ * @dev Moves `amount` tokens from the caller's account to `recipient`.
+ *
+ * Returns a boolean value indicating whether the operation succeeded.
+ *
+ * Emits a {Transfer} event.
+ */
+ function transfer(address recipient, uint256 amount) external returns (bool);
+
+ /**
+ * @dev Returns the remaining number of tokens that `spender` will be
+ * allowed to spend on behalf of `owner` through {transferFrom}. This is
+ * zero by default.
+ *
+ * This value changes when {approve} or {transferFrom} are called.
+ */
+ function allowance(address owner, address spender) external view returns (uint256);
+
+ /**
+ * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
+ *
+ * Returns a boolean value indicating whether the operation succeeded.
+ *
+ * IMPORTANT: Beware that changing an allowance with this method brings the risk
+ * that someone may use both the old and the new allowance by unfortunate
+ * transaction ordering. One possible solution to mitigate this race
+ * condition is to first reduce the spender's allowance to 0 and set the
+ * desired value afterwards:
+ * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
+ *
+ * Emits an {Approval} event.
+ */
+ function approve(address spender, uint256 amount) external returns (bool);
+
+ /**
+ * @dev Moves `amount` tokens from `sender` to `recipient` using the
+ * allowance mechanism. `amount` is then deducted from the caller's
+ * allowance.
+ *
+ * Returns a boolean value indicating whether the operation succeeded.
+ *
+ * Emits a {Transfer} event.
+ */
+ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
+
+ /**
+ * @dev Emitted when `value` tokens are moved from one account (`from`) to
+ * another (`to`).
+ *
+ * Note that `value` may be zero.
+ */
+ event Transfer(address indexed from, address indexed to, uint256 value);
+
+ /**
+ * @dev Emitted when the allowance of a `spender` for an `owner` is set by
+ * a call to {approve}. `value` is the new allowance.
+ */
+ event Approval(address indexed owner, address indexed spender, uint256 value);
+}
+
+
+// Dependency file: contracts/zeppelin/math/SafeMath.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Wrappers over Solidity's arithmetic operations with added overflow
+ * checks.
+ *
+ * Arithmetic operations in Solidity wrap on overflow. This can easily result
+ * in bugs, because programmers usually assume that an overflow raises an
+ * error, which is the standard behavior in high level programming languages.
+ * `SafeMath` restores this intuition by reverting the transaction when an
+ * operation overflows.
+ *
+ * Using this library instead of the unchecked operations eliminates an entire
+ * class of bugs, so it's recommended to use it always.
+ */
+library SafeMath {
+ /**
+ * @dev Returns the addition of two unsigned integers, reverting on
+ * overflow.
+ *
+ * Counterpart to Solidity's `+` operator.
+ *
+ * Requirements:
+ * - Addition cannot overflow.
+ */
+ function add(uint256 a, uint256 b) internal pure returns (uint256) {
+ uint256 c = a + b;
+ require(c >= a, "SafeMath: addition overflow");
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the subtraction of two unsigned integers, reverting on
+ * overflow (when the result is negative).
+ *
+ * Counterpart to Solidity's `-` operator.
+ *
+ * Requirements:
+ * - Subtraction cannot overflow.
+ */
+ function sub(uint256 a, uint256 b) internal pure returns (uint256) {
+ return sub(a, b, "SafeMath: subtraction overflow");
+ }
+
+ /**
+ * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
+ * overflow (when the result is negative).
+ *
+ * Counterpart to Solidity's `-` operator.
+ *
+ * Requirements:
+ * - Subtraction cannot overflow.
+ *
+ * _Available since v2.4.0._
+ */
+ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
+ require(b <= a, errorMessage);
+ uint256 c = a - b;
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the multiplication of two unsigned integers, reverting on
+ * overflow.
+ *
+ * Counterpart to Solidity's `*` operator.
+ *
+ * Requirements:
+ * - Multiplication cannot overflow.
+ */
+ function mul(uint256 a, uint256 b) internal pure returns (uint256) {
+ // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
+ // benefit is lost if 'b' is also tested.
+ // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
+ if (a == 0) {
+ return 0;
+ }
+
+ uint256 c = a * b;
+ require(c / a == b, "SafeMath: multiplication overflow");
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the integer division of two unsigned integers. Reverts on
+ * division by zero. The result is rounded towards zero.
+ *
+ * Counterpart to Solidity's `/` operator. Note: this function uses a
+ * `revert` opcode (which leaves remaining gas untouched) while Solidity
+ * uses an invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ */
+ function div(uint256 a, uint256 b) internal pure returns (uint256) {
+ return div(a, b, "SafeMath: division by zero");
+ }
+
+ /**
+ * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
+ * division by zero. The result is rounded towards zero.
+ *
+ * Counterpart to Solidity's `/` operator. Note: this function uses a
+ * `revert` opcode (which leaves remaining gas untouched) while Solidity
+ * uses an invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ *
+ * _Available since v2.4.0._
+ */
+ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
+ // Solidity only automatically asserts when dividing by 0
+ require(b > 0, errorMessage);
+ uint256 c = a / b;
+ // assert(a == b * c + a % b); // There is no case in which this doesn't hold
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
+ * Reverts when dividing by zero.
+ *
+ * Counterpart to Solidity's `%` operator. This function uses a `revert`
+ * opcode (which leaves remaining gas untouched) while Solidity uses an
+ * invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ */
+ function mod(uint256 a, uint256 b) internal pure returns (uint256) {
+ return mod(a, b, "SafeMath: modulo by zero");
+ }
+
+ /**
+ * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
+ * Reverts with custom message when dividing by zero.
+ *
+ * Counterpart to Solidity's `%` operator. This function uses a `revert`
+ * opcode (which leaves remaining gas untouched) while Solidity uses an
+ * invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ *
+ * _Available since v2.4.0._
+ */
+ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
+ require(b != 0, errorMessage);
+ return a % b;
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/utils/Address.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Collection of functions related to the address type
+ */
+library Address {
+ /**
+ * @dev Returns true if `account` is a contract.
+ *
+ * [IMPORTANT]
+ * ====
+ * It is unsafe to assume that an address for which this function returns
+ * false is an externally-owned account (EOA) and not a contract.
+ *
+ * Among others, `isContract` will return false for the following
+ * types of addresses:
+ *
+ * - an externally-owned account
+ * - a contract in construction
+ * - an address where a contract will be created
+ * - an address where a contract lived, but was destroyed
+ * ====
+ */
+ function isContract(address account) internal view returns (bool) {
+ // This method relies on extcodesize, which returns 0 for contracts in
+ // construction, since the code is only stored at the end of the
+ // constructor execution.
+
+ uint256 size;
+ // solhint-disable-next-line no-inline-assembly
+ assembly { size := extcodesize(account) }
+ return size > 0;
+ }
+
+ /**
+ * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
+ * `recipient`, forwarding all available gas and reverting on errors.
+ *
+ * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
+ * of certain opcodes, possibly making contracts go over the 2300 gas limit
+ * imposed by `transfer`, making them unable to receive funds via
+ * `transfer`. {sendValue} removes this limitation.
+ *
+ * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
+ *
+ * IMPORTANT: because control is transferred to `recipient`, care must be
+ * taken to not create reentrancy vulnerabilities. Consider using
+ * {ReentrancyGuard} or the
+ * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
+ */
+ function sendValue(address payable recipient, uint256 amount) internal {
+ require(address(this).balance >= amount, "Address: insufficient balance");
+
+ // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
+ (bool success, ) = recipient.call{ value: amount }("");
+ require(success, "Address: unable to send value, recipient may have reverted");
+ }
+
+ /**
+ * @dev Performs a Solidity function call using a low level `call`. A
+ * plain`call` is an unsafe replacement for a function call: use this
+ * function instead.
+ *
+ * If `target` reverts with a revert reason, it is bubbled up by this
+ * function (like regular Solidity function calls).
+ *
+ * Returns the raw returned data. To convert to the expected return value,
+ * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
+ *
+ * Requirements:
+ *
+ * - `target` must be a contract.
+ * - calling `target` with `data` must not revert.
+ *
+ * _Available since v3.1._
+ */
+ function functionCall(address target, bytes memory data) internal returns (bytes memory) {
+ return functionCall(target, data, "Address: low-level call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
+ * `errorMessage` as a fallback revert reason when `target` reverts.
+ *
+ * _Available since v3.1._
+ */
+ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
+ return functionCallWithValue(target, data, 0, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but also transferring `value` wei to `target`.
+ *
+ * Requirements:
+ *
+ * - the calling contract must have an ETH balance of at least `value`.
+ * - the called Solidity function must be `payable`.
+ *
+ * _Available since v3.1._
+ */
+ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
+ return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
+ * with `errorMessage` as a fallback revert reason when `target` reverts.
+ *
+ * _Available since v3.1._
+ */
+ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
+ require(address(this).balance >= value, "Address: insufficient balance for call");
+ require(isContract(target), "Address: call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.call{ value: value }(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but performing a static call.
+ *
+ * _Available since v3.3._
+ */
+ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
+ return functionStaticCall(target, data, "Address: low-level static call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
+ * but performing a static call.
+ *
+ * _Available since v3.3._
+ */
+ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
+ require(isContract(target), "Address: static call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.staticcall(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but performing a delegate call.
+ *
+ * _Available since v3.4._
+ */
+ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
+ return functionDelegateCall(target, data, "Address: low-level delegate call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
+ * but performing a delegate call.
+ *
+ * _Available since v3.4._
+ */
+ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
+ require(isContract(target), "Address: delegate call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.delegatecall(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
+ if (success) {
+ return returndata;
+ } else {
+ // Look for revert reason and bubble it up if present
+ if (returndata.length > 0) {
+ // The easiest way to bubble the revert reason is using memory via assembly
+
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ let returndata_size := mload(returndata)
+ revert(add(32, returndata), returndata_size)
+ }
+ } else {
+ revert(errorMessage);
+ }
+ }
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/token/ERC20/SafeERC20.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/token/ERC20/IERC20.sol";
+// import "contracts/zeppelin/math/SafeMath.sol";
+// import "contracts/zeppelin/utils/Address.sol";
+
+/**
+ * @title SafeERC20
+ * @dev Wrappers around ERC20 operations that throw on failure (when the token
+ * contract returns false). Tokens that return no value (and instead revert or
+ * throw on failure) are also supported, non-reverting calls are assumed to be
+ * successful.
+ * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
+ * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
+ */
+library SafeERC20 {
+ using SafeMath for uint256;
+ using Address for address;
+
+ function safeTransfer(IERC20 token, address to, uint256 value) internal {
+ callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
+ }
+
+ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
+ callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
+ }
+
+ function safeApprove(IERC20 token, address spender, uint256 value) internal {
+ // safeApprove should only be called when setting an initial allowance,
+ // or when resetting it to zero. To increase and decrease it, use
+ // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
+ // solhint-disable-next-line max-line-length
+ require((value == 0) || (token.allowance(address(this), spender) == 0),
+ "SafeERC20: approve non-zero to non-zero allowance"
+ );
+ callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
+ }
+
+ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
+ uint256 newAllowance = token.allowance(address(this), spender).add(value);
+ callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
+ }
+
+ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
+ uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
+ callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
+ }
+
+ /**
+ * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
+ * on the return value: the return value is optional (but if data is returned, it must not be false).
+ * @param token The token targeted by the call.
+ * @param data The call data (encoded using abi.encode or one of its variants).
+ */
+ function callOptionalReturn(IERC20 token, bytes memory data) private {
+ // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
+ // we're implementing it ourselves.
+
+ // A Solidity high level call has three parts:
+ // 1. The target address is checked to verify it contains contract code
+ // 2. The call itself is made, and success asserted
+ // 3. The return value is decoded, which in turn checks the size of the returned data.
+ // solhint-disable-next-line max-line-length
+ require(address(token).isContract(), "SafeERC20: call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = address(token).call(data);
+ require(success, "SafeERC20: low-level call failed");
+
+ if (returndata.length > 0) { // Return data is optional
+ // solhint-disable-next-line max-line-length
+ require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
+ }
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/token/ERC777/IERC777.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface of the ERC777Token standard as defined in the EIP.
+ *
+ * This contract uses the
+ * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let
+ * token holders and recipients react to token movements by using setting implementers
+ * for the associated interfaces in said registry. See `IERC1820Registry` and
+ * `ERC1820Implementer`.
+ */
+interface IERC777 {
+ /**
+ * @dev Returns the name of the token.
+ */
+ function name() external view returns (string memory);
+
+ /**
+ * @dev Returns the symbol of the token, usually a shorter version of the
+ * name.
+ */
+ function symbol() external view returns (string memory);
+
+ /**
+ * @dev Returns the smallest part of the token that is not divisible. This
+ * means all token operations (creation, movement and destruction) must have
+ * amounts that are a multiple of this number.
+ *
+ * For most token contracts, this value will equal 1.
+ */
+ function granularity() external view returns (uint256);
+
+ /**
+ * @dev Returns the amount of tokens in existence.
+ */
+ function totalSupply() external view returns (uint256);
+
+ /**
+ * @dev Returns the amount of tokens owned by an account (`owner`).
+ */
+ function balanceOf(address owner) external view returns (uint256);
+
+ /**
+ * @dev Moves `amount` tokens from the caller's account to `recipient`.
+ *
+ * If send or receive hooks are registered for the caller and `recipient`,
+ * the corresponding functions will be called with `data` and empty
+ * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.
+ *
+ * Emits a `Sent` event.
+ *
+ * Requirements
+ *
+ * - the caller must have at least `amount` tokens.
+ * - `recipient` cannot be the zero address.
+ * - if `recipient` is a contract, it must implement the `tokensReceived`
+ * interface.
+ */
+ function send(address recipient, uint256 amount, bytes calldata data) external;
+
+ /**
+ * @dev Destroys `amount` tokens from the caller's account, reducing the
+ * total supply.
+ *
+ * If a send hook is registered for the caller, the corresponding function
+ * will be called with `data` and empty `operatorData`. See `IERC777Sender`.
+ *
+ * Emits a `Burned` event.
+ *
+ * Requirements
+ *
+ * - the caller must have at least `amount` tokens.
+ */
+ function burn(uint256 amount, bytes calldata data) external;
+
+ /**
+ * @dev Returns true if an account is an operator of `tokenHolder`.
+ * Operators can send and burn tokens on behalf of their owners. All
+ * accounts are their own operator.
+ *
+ * See `operatorSend` and `operatorBurn`.
+ */
+ function isOperatorFor(address operator, address tokenHolder) external view returns (bool);
+
+ /**
+ * @dev Make an account an operator of the caller.
+ *
+ * See `isOperatorFor`.
+ *
+ * Emits an `AuthorizedOperator` event.
+ *
+ * Requirements
+ *
+ * - `operator` cannot be calling address.
+ */
+ function authorizeOperator(address operator) external;
+
+ /**
+ * @dev Make an account an operator of the caller.
+ *
+ * See `isOperatorFor` and `defaultOperators`.
+ *
+ * Emits a `RevokedOperator` event.
+ *
+ * Requirements
+ *
+ * - `operator` cannot be calling address.
+ */
+ function revokeOperator(address operator) external;
+
+ /**
+ * @dev Returns the list of default operators. These accounts are operators
+ * for all token holders, even if `authorizeOperator` was never called on
+ * them.
+ *
+ * This list is immutable, but individual holders may revoke these via
+ * `revokeOperator`, in which case `isOperatorFor` will return false.
+ */
+ function defaultOperators() external view returns (address[] memory);
+
+ /**
+ * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must
+ * be an operator of `sender`.
+ *
+ * If send or receive hooks are registered for `sender` and `recipient`,
+ * the corresponding functions will be called with `data` and
+ * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.
+ *
+ * Emits a `Sent` event.
+ *
+ * Requirements
+ *
+ * - `sender` cannot be the zero address.
+ * - `sender` must have at least `amount` tokens.
+ * - the caller must be an operator for `sender`.
+ * - `recipient` cannot be the zero address.
+ * - if `recipient` is a contract, it must implement the `tokensReceived`
+ * interface.
+ */
+ function operatorSend(
+ address sender,
+ address recipient,
+ uint256 amount,
+ bytes calldata data,
+ bytes calldata operatorData
+ ) external;
+
+ /**
+ * @dev Destoys `amount` tokens from `account`, reducing the total supply.
+ * The caller must be an operator of `account`.
+ *
+ * If a send hook is registered for `account`, the corresponding function
+ * will be called with `data` and `operatorData`. See `IERC777Sender`.
+ *
+ * Emits a `Burned` event.
+ *
+ * Requirements
+ *
+ * - `account` cannot be the zero address.
+ * - `account` must have at least `amount` tokens.
+ * - the caller must be an operator for `account`.
+ */
+ function operatorBurn(
+ address account,
+ uint256 amount,
+ bytes calldata data,
+ bytes calldata operatorData
+ ) external;
+
+ event Sent(
+ address indexed operator,
+ address indexed from,
+ address indexed to,
+ uint256 amount,
+ bytes data,
+ bytes operatorData
+ );
+
+ function decimals() external returns (uint8);
+
+ event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
+
+ event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);
+
+ event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
+
+ event RevokedOperator(address indexed operator, address indexed tokenHolder);
+}
+
+
+// Dependency file: contracts/lib/LibEIP712.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol
+library LibEIP712 {
+
+ // Hash of the EIP712 Domain Separator Schema
+ // keccak256(abi.encodePacked(
+ // "EIP712Domain(",
+ // "string name,",
+ // "string version,",
+ // "uint256 chainId,",
+ // "address verifyingContract",
+ // ")"
+ // ))
+ bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;
+
+ /// @dev Calculates a EIP712 domain separator.
+ /// @param name The EIP712 domain name.
+ /// @param version The EIP712 domain version.
+ /// @param verifyingContract The EIP712 verifying contract.
+ /// @return result EIP712 domain separator.
+ function hashEIP712Domain(
+ string memory name,
+ string memory version,
+ uint256 chainId,
+ address verifyingContract
+ )
+ internal
+ pure
+ returns (bytes32 result)
+ {
+ bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;
+
+ // Assembly for more efficient computing:
+ // keccak256(abi.encodePacked(
+ // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,
+ // keccak256(bytes(name)),
+ // keccak256(bytes(version)),
+ // chainId,
+ // uint256(verifyingContract)
+ // ))
+
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ // Calculate hashes of dynamic data
+ let nameHash := keccak256(add(name, 32), mload(name))
+ let versionHash := keccak256(add(version, 32), mload(version))
+
+ // Load free memory pointer
+ let memPtr := mload(64)
+
+ // Store params in memory
+ mstore(memPtr, schemaHash)
+ mstore(add(memPtr, 32), nameHash)
+ mstore(add(memPtr, 64), versionHash)
+ mstore(add(memPtr, 96), chainId)
+ mstore(add(memPtr, 128), verifyingContract)
+
+ // Compute hash
+ result := keccak256(memPtr, 160)
+ }
+ return result;
+ }
+
+ /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.
+ /// @param eip712DomainHash Hash of the domain domain separator data, computed
+ /// with getDomainHash().
+ /// @param hashStruct The EIP712 hash struct.
+ /// @return result EIP712 hash applied to the given EIP712 Domain.
+ function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)
+ internal
+ pure
+ returns (bytes32 result)
+ {
+ // Assembly for more efficient computing:
+ // keccak256(abi.encodePacked(
+ // EIP191_HEADER,
+ // EIP712_DOMAIN_HASH,
+ // hashStruct
+ // ));
+
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ // Load free memory pointer
+ let memPtr := mload(64)
+
+ mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header
+ mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash
+ mstore(add(memPtr, 34), hashStruct) // Hash of struct
+
+ // Compute hash
+ result := keccak256(memPtr, 66)
+ }
+ return result;
+ }
+}
+
+// Dependency file: contracts/lib/LibUtils.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+library LibUtils {
+
+ function decimalsToGranularity(uint8 decimals) internal pure returns (uint256) {
+ require(decimals <= 18, "LibUtils: Decimals not <= 18");
+ return uint256(10)**(18-decimals);
+ }
+
+ function getDecimals(address tokenToUse) internal view returns (uint8) {
+ //support decimals as uint256 or uint8
+ (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature("decimals()"));
+ require(success, "LibUtils: No decimals");
+ // uint: enc(X) is the big-endian encoding of X,
+ //padded on the higher-order (left) side with zero-bytes such that the length is 32 bytes.
+ return uint8(abi.decode(data, (uint256)));
+ }
+
+ function getGranularity(address tokenToUse) internal view returns (uint256) {
+ //support granularity if ERC777
+ (bool success, bytes memory data) = tokenToUse.staticcall(abi.encodeWithSignature("granularity()"));
+ require(success, "LibUtils: No granularity");
+
+ return abi.decode(data, (uint256));
+ }
+
+ function bytesToAddress(bytes memory bys) internal pure returns (address addr) {
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ addr := mload(add(bys,20))
+ }
+ }
+
+ function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
+ require(_bytes.length >= _start + 20, "LibUtils: toAddress_outOfBounds");
+ address tempAddress;
+
+ assembly {
+ tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
+ }
+
+ return tempAddress;
+ }
+
+ function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
+ require(_bytes.length >= _start + 16, "LibUtils: toUint128_outOfBounds");
+ uint128 tempUint;
+
+ assembly {
+ tempUint := mload(add(add(_bytes, 0x10), _start))
+ }
+
+ return tempUint;
+ }
+
+ function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
+ require(_bytes.length >= _start + 32, "LibUtils: toUint256_outOfBounds");
+ uint256 tempUint;
+
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ tempUint := mload(add(add(_bytes, 0x20), _start))
+ }
+
+ return tempUint;
+ }
+}
+
+
+// Dependency file: contracts/interface/IBridge.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+interface IBridge {
+
+ struct ClaimData {
+ address payable to;
+ uint256 amount;
+ bytes32 blockHash;
+ bytes32 transactionHash;
+ uint32 logIndex;
+ uint256 originChainId;
+ }
+
+ struct OriginalToken {
+ address tokenAddress;
+ uint256 originChainId;
+ }
+
+ function version() external pure returns (string memory);
+
+ function getFeePercentage() external view returns(uint);
+
+ /**
+ * ERC-20 tokens approve and transferFrom pattern
+ * See https://eips.ethereum.org/EIPS/eip-20#transferfrom
+ */
+ function receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;
+
+ /**
+ * Use network currency and cross it.
+ */
+ function depositTo(uint256 chainId, address to) external payable;
+
+ /**
+ * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction
+ * See https://eips.ethereum.org/EIPS/eip-777#motivation for details
+ * @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination
+ * const userData = web3.eth.abi.encodeParameters(
+ * ["address", "uint256"],
+ * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]
+ * );
+ * or you also can send only the destination chain id, and the receiver would be the same as the from parameter
+ * const userData = web3.eth.abi.encodeParameters(["uint256"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);
+ */
+ function tokensReceived (
+ address operator,
+ address from,
+ address to,
+ uint amount,
+ bytes calldata userData,
+ bytes calldata operatorData
+ ) external;
+
+ /**
+ * Accepts the transaction from the other chain that was voted and sent by the Federation contract
+ */
+ function acceptTransfer(
+ address _originalTokenAddress,
+ address payable _from,
+ address payable _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex,
+ uint256 _originChainId,
+ uint256 _destinationChainId
+ ) external;
+
+ /**
+ * Claims the crossed transaction using the hash, this sends the funds to the address indicated in
+ */
+ function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);
+
+ function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);
+
+ function claimGasless(
+ ClaimData calldata _claimData,
+ address payable _relayer,
+ uint256 _fee,
+ uint256 _deadline,
+ uint8 _v,
+ bytes32 _r,
+ bytes32 _s
+ ) external returns (uint256 receivedAmount);
+
+ function createSideToken(
+ uint256 _typeId,
+ address _originalTokenAddress,
+ uint8 _originalTokenDecimals,
+ string calldata _originalTokenSymbol,
+ string calldata _originalTokenName,
+ uint256 _chainId
+ ) external;
+
+ function getTransactionDataHash(
+ address _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex,
+ uint256 _originChainId,
+ uint256 _destinationChainId
+ ) external returns(bytes32);
+
+ event Cross(
+ address indexed _tokenAddress,
+ address indexed _to,
+ uint256 indexed _destinationChainId,
+ address _from,
+ uint256 _originChainId,
+ uint256 _amount,
+ bytes _userData
+ );
+
+ event NewSideToken(
+ address indexed _newSideTokenAddress,
+ address indexed _originalTokenAddress,
+ string _newSymbol,
+ uint256 _granularity,
+ uint256 _chainId
+ );
+ event AcceptedCrossTransfer(
+ bytes32 indexed _transactionHash,
+ address indexed _originalTokenAddress,
+ address indexed _to,
+ address _from,
+ uint256 _amount,
+ bytes32 _blockHash,
+ uint256 _logIndex,
+ uint256 _originChainId,
+ uint256 _destinationChainId
+ );
+ event FeePercentageChanged(uint256 _amount);
+ event Claimed(
+ bytes32 indexed _transactionHash,
+ address indexed _originalTokenAddress,
+ address indexed _to,
+ address _sender,
+ uint256 _amount,
+ bytes32 _blockHash,
+ uint256 _logIndex,
+ address _reciever,
+ address _relayer,
+ uint256 _fee,
+ uint256 _destinationChainId,
+ uint256 _originChainId
+ );
+}
+
+// Dependency file: contracts/interface/ISideToken.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+interface ISideToken {
+ function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;
+}
+
+// Dependency file: contracts/interface/ISideTokenFactory.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+interface ISideTokenFactory {
+
+ function createSideToken(string calldata name, string calldata symbol, uint256 granularity) external returns(address);
+
+ event SideTokenCreated(address indexed sideToken, string symbol, uint256 granularity);
+}
+
+// Dependency file: contracts/interface/IAllowTokens.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+interface IAllowTokens {
+
+ struct Limits {
+ uint256 min;
+ uint256 max;
+ uint256 daily;
+ uint256 mediumAmount;
+ uint256 largeAmount;
+ }
+
+ struct TokenInfo {
+ bool allowed;
+ uint256 typeId;
+ uint256 spentToday;
+ uint256 lastDay;
+ }
+
+ struct TypeInfo {
+ string description;
+ Limits limits;
+ }
+
+ struct TokensAndType {
+ address token;
+ uint256 typeId;
+ }
+
+ function version() external pure returns (string memory);
+
+ function getInfoAndLimits(address token) external view returns (TokenInfo memory info, Limits memory limit);
+
+ function calcMaxWithdraw(address token) external view returns (uint256 maxWithdraw);
+
+ function getTypesLimits() external view returns(Limits[] memory limits);
+
+ function getTypeDescriptionsLength() external view returns(uint256);
+
+ function getTypeDescriptions() external view returns(string[] memory descriptions);
+
+ function setToken(address token, uint256 typeId) external;
+
+ function getConfirmations() external view returns (uint256 smallAmount, uint256 mediumAmount, uint256 largeAmount);
+
+ function isTokenAllowed(address token) external view returns (bool);
+
+ function updateTokenTransfer(address token, uint256 amount) external;
+}
+
+// Dependency file: contracts/interface/IWrapped.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+interface IWrapped {
+ function balanceOf(address) external returns(uint);
+
+ function deposit() external payable;
+
+ function withdraw(uint wad) external;
+
+ function totalSupply() external view returns (uint);
+
+ function approve(address guy, uint wad) external returns (bool);
+
+ function transfer(address dst, uint wad) external returns (bool);
+
+ function transferFrom(address src, address dst, uint wad)
+ external
+ returns (bool);
+}
+
+// Root file: contracts/Bridge/Bridge.sol
+
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "hardhat/console.sol";
+// Import base Initializable contract
+// import "contracts/zeppelin/upgradable/Initializable.sol";
+// Import interface and library from OpenZeppelin contracts
+// import "contracts/zeppelin/upgradable/utils/ReentrancyGuard.sol";
+// import "contracts/zeppelin/upgradable/lifecycle/UpgradablePausable.sol";
+// import "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol";
+
+// import "contracts/zeppelin/introspection/IERC1820Registry.sol";
+// import "contracts/zeppelin/token/ERC777/IERC777Recipient.sol";
+// import "contracts/zeppelin/token/ERC20/IERC20.sol";
+// import "contracts/zeppelin/token/ERC20/SafeERC20.sol";
+// import "contracts/zeppelin/utils/Address.sol";
+// import "contracts/zeppelin/math/SafeMath.sol";
+// import "contracts/zeppelin/token/ERC777/IERC777.sol";
+
+// import "contracts/lib/LibEIP712.sol";
+// import "contracts/lib/LibUtils.sol";
+
+// import "contracts/interface/IBridge.sol";
+// import "contracts/interface/ISideToken.sol";
+// import "contracts/interface/ISideTokenFactory.sol";
+// import "contracts/interface/IAllowTokens.sol";
+// import "contracts/interface/IWrapped.sol";
+
+// solhint-disable-next-line max-states-count
+contract Bridge is Initializable, IBridge, IERC777Recipient, UpgradablePausable, UpgradableOwnable, ReentrancyGuard {
+ using SafeMath for uint256;
+ using SafeERC20 for IERC20;
+ using Address for address;
+
+ address constant internal NULL_ADDRESS = address(0);
+ bytes32 constant internal NULL_HASH = bytes32(0);
+ IERC1820Registry constant internal ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
+
+ address internal federation;
+ uint256 internal feePercentage;
+ string public deprecatedSymbolPrefix;
+ // domainSeparator replaces uint256 internal _depprecatedLastDay;
+ bytes32 public domainSeparator;
+ uint256 internal _deprecatedSpentToday;
+
+ mapping (address => address) public deprecatedMappedTokens; // OriginalToken => SideToken
+ mapping (address => address) public deprecatedOriginalTokens; // SideToken => OriginalToken
+ mapping (address => bool) public deprecatedKnownTokens; // OriginalToken => true
+
+ // claimed can use the same of bytes32
+ mapping (bytes32 => bool) public claimed; // transactionDataHash => true // previously named processed
+
+ IAllowTokens public allowTokens;
+ ISideTokenFactory public sideTokenFactory;
+ //Bridge_v1 variables
+ bool public isUpgrading;
+ // Percentage with up to 2 decimals
+ uint256 constant public feePercentageDivider = 10000; // solhint-disable-line const-name-snakecase
+ //Bridge_v2 variables
+ bytes32 constant internal _erc777Interface = keccak256("ERC777Token"); // solhint-disable-line const-name-snakecase
+ IWrapped public wrappedCurrency;
+ mapping (bytes32 => bytes32) public transactionsDataHashes; // transactionHash => transactionDataHash
+ mapping (bytes32 => address) public originalTokenAddresses; // transactionHash => originalTokenAddress
+ mapping (bytes32 => address) public senderAddresses; // transactionHash => senderAddress
+
+ // keccak256("Claim(address to,uint256 amount,bytes32 transactionHash,uint256 originChainId,address relayer,uint256 fee,uint256 nonce,uint256 deadline)");
+ bytes32 public constant CLAIM_TYPEHASH = 0xaf3ac34fea9cc1b1def33a9bdc482d988feb61b5015ae4a55e2a62bb3600d54c;
+ mapping(address => uint) public nonces;
+
+ //Bridge_v3 variables multichain
+ mapping (uint256 => mapping(address => address)) public sideTokenByOriginalTokenByChain; // chainId => OriginalToken Address => SideToken Address
+ mapping (address => OriginalToken) public originalTokenBySideToken; // SideTokenAddress => struct {}
+ mapping (uint256 => mapping(address => bool)) public knownTokenByChain; // chainId => OriginalToken Address => Know
+
+ event AllowTokensChanged(address _newAllowTokens);
+ event FederationChanged(address _newFederation);
+ event SideTokenFactoryChanged(address _newSideTokenFactory);
+ event Upgrading(bool _isUpgrading);
+ event WrappedCurrencyChanged(address _wrappedCurrency);
+
+ function initialize(
+ address _manager,
+ address _federation,
+ address _allowTokens,
+ address _sideTokenFactory
+ ) public initializer {
+ UpgradableOwnable.initialize(_manager);
+ UpgradablePausable.__Pausable_init(_manager);
+ allowTokens = IAllowTokens(_allowTokens);
+ sideTokenFactory = ISideTokenFactory(_sideTokenFactory);
+ federation = _federation;
+ //keccak256("ERC777TokensRecipient")
+ ERC1820.setInterfaceImplementer(address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this));
+ initDomainSeparator();
+ }
+
+ receive () external payable {
+ // The fallback function is needed to use WRBTC
+ require(_msgSender() == address(wrappedCurrency), "Bridge: not wrappedCurrency");
+ }
+
+ function version() override external pure returns (string memory) {
+ return "v4";
+ }
+
+ function initDomainSeparator() public {
+ domainSeparator = LibEIP712.hashEIP712Domain(
+ "RSK Token Bridge",
+ "1",
+ block.chainid,
+ address(this)
+ );
+ }
+
+ modifier whenNotUpgrading() {
+ require(!isUpgrading, "Bridge: Upgrading");
+ _;
+ }
+
+ function shouldBeCurrentChainId(uint256 chainId) internal view {
+ require(chainId == block.chainid, "Bridge: Not block.chainid");
+ }
+
+ function sideTokenByOriginalToken(uint256 chainId, address originalToken) public view returns(address) {
+ address sideTokenAddr = sideTokenByOriginalTokenByChain[chainId][originalToken];
+
+ if (sideTokenAddr != NULL_ADDRESS) {
+ return sideTokenAddr;
+ }
+
+ // specification for retrocompatibility
+ return deprecatedMappedTokens[originalToken];
+ }
+
+ function setSideTokenByOriginalAddressByChain(uint256 chainId, address originalToken, address sideToken) public onlyOwner {
+ sideTokenByOriginalTokenByChain[chainId][originalToken] = sideToken;
+ }
+
+ function getOriginalTokenBySideToken(address sideToken) public view returns(OriginalToken memory originalToken) {
+ originalToken = originalTokenBySideToken[sideToken];
+ if (originalToken.tokenAddress != NULL_ADDRESS) {
+ return originalToken;
+ }
+
+ // specification for retrocompatibility
+ originalToken.originChainId = 1; // ethereum main chain id
+ originalToken.tokenAddress = deprecatedOriginalTokens[sideToken];
+ return originalToken;
+ }
+
+ function setOriginalTokenBySideTokenByChain(address sideToken, OriginalToken memory originalToken) public onlyOwner {
+ originalTokenBySideToken[sideToken] = originalToken;
+ }
+
+ function knownToken(uint256 chainId, address originalToken) public view returns(bool) {
+ bool knowToken = knownTokenByChain[chainId][originalToken];
+ if (knowToken) {
+ return knowToken;
+ }
+
+ // specification for retrocompatibility
+ return deprecatedKnownTokens[originalToken];
+ }
+
+ function _setKnownTokenByChain(uint256 chainId, address originalToken, bool knownTokenValue) internal {
+ knownTokenByChain[chainId][originalToken] = knownTokenValue;
+ }
+
+ function acceptTransfer(
+ address _originalTokenAddress,
+ address payable _from,
+ address payable _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex,
+ uint256 _originChainId,
+ uint256 _destinationChainId
+ ) external whenNotPaused nonReentrant override {
+ require(_msgSender() == federation, "Bridge: Not Federation");
+ checkChainId(_originChainId);
+ shouldBeCurrentChainId(_destinationChainId);
+ require(knownToken(_originChainId, _originalTokenAddress) ||
+ sideTokenByOriginalToken(_originChainId, _originalTokenAddress) != NULL_ADDRESS,
+ "Bridge: Unknown token"
+ );
+ require(_to != NULL_ADDRESS, "Bridge: Null To");
+ require(_amount > 0, "Bridge: Amount 0");
+ require(_blockHash != NULL_HASH, "Bridge: Null BlockHash");
+ require(_transactionHash != NULL_HASH, "Bridge: Null TxHash");
+ require(transactionsDataHashes[_transactionHash] == bytes32(0), "Bridge: Already accepted");
+
+ bytes32 _transactionDataHash = getTransactionDataHash(
+ _to,
+ _amount,
+ _blockHash,
+ _transactionHash,
+ _logIndex
+ );
+
+ bytes32 _transactionDataHashMultichain = getTransactionDataHash(
+ _to,
+ _amount,
+ _blockHash,
+ _transactionHash,
+ _logIndex,
+ _originChainId,
+ _destinationChainId
+ );
+ // Do not remove, claimed also has the previously processed using the older bridge version
+ // https://github.com/rsksmart/tokenbridge/blob/TOKENBRIDGE-1.2.0/bridge/contracts/Bridge.sol#L41
+ require(!isClaimed(_transactionDataHash, _transactionDataHashMultichain), "Bridge: Already claimed");
+
+ transactionsDataHashes[_transactionHash] = _transactionDataHashMultichain;
+ originalTokenAddresses[_transactionHash] = _originalTokenAddress;
+ senderAddresses[_transactionHash] = _from;
+
+ emit AcceptedCrossTransfer(
+ _transactionHash,
+ _originalTokenAddress,
+ _to,
+ _from,
+ _amount,
+ _blockHash,
+ _logIndex,
+ _originChainId,
+ _destinationChainId
+ );
+ }
+
+ function checkChainId(uint256 chainId) internal pure {
+ require(chainId > 0, "Bridge: ChainId is 0");
+ }
+
+ function createSideToken(
+ uint256 _typeId,
+ address _originalTokenAddress,
+ uint8 _originalTokenDecimals,
+ string calldata _tokenSymbol,
+ string calldata _tokenName,
+ uint256 _originChainId
+ ) external onlyOwner override {
+ require(_originalTokenAddress != NULL_ADDRESS, "Bridge: Null token");
+ checkChainId(_originChainId);
+ address sideToken = sideTokenByOriginalToken(_originChainId, _originalTokenAddress);
+ require(sideToken == NULL_ADDRESS, "Bridge: Already exists");
+
+ uint256 granularity = LibUtils.decimalsToGranularity(_originalTokenDecimals);
+
+ // Create side token
+ sideToken = sideTokenFactory.createSideToken(_tokenName, _tokenSymbol, granularity);
+
+ setSideTokenByOriginalAddressByChain(_originChainId, _originalTokenAddress, sideToken);
+
+ OriginalToken memory originalToken;
+ originalToken.originChainId = _originChainId;
+ originalToken.tokenAddress = _originalTokenAddress;
+ setOriginalTokenBySideTokenByChain(sideToken, originalToken);
+ allowTokens.setToken(sideToken, _typeId);
+
+ emit NewSideToken(sideToken, _originalTokenAddress, _tokenSymbol, granularity, _originChainId);
+ }
+
+ function claim(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {
+ receivedAmount = _claim(
+ _claimData,
+ _claimData.to,
+ payable(address(0)),
+ 0
+ );
+ return receivedAmount;
+ }
+
+ function claimFallback(ClaimData calldata _claimData) external override returns (uint256 receivedAmount) {
+ require(_msgSender() == senderAddresses[_claimData.transactionHash],"Bridge: invalid sender");
+ receivedAmount = _claim(
+ _claimData,
+ _msgSender(),
+ payable(address(0)),
+ 0
+ );
+ return receivedAmount;
+ }
+
+ function getDigest(
+ ClaimData memory _claimData,
+ address payable _relayer,
+ uint256 _fee,
+ uint256 _deadline
+ ) internal returns (bytes32) {
+ return LibEIP712.hashEIP712Message(
+ domainSeparator,
+ keccak256(
+ abi.encode(
+ CLAIM_TYPEHASH,
+ _claimData.to,
+ _claimData.amount,
+ _claimData.transactionHash,
+ _claimData.originChainId,
+ _relayer,
+ _fee,
+ nonces[_claimData.to]++,
+ _deadline
+ )
+ )
+ );
+ }
+
+ // Inspired by https://github.com/dapphub/ds-dach/blob/master/src/dach.sol
+ function claimGasless(
+ ClaimData calldata _claimData,
+ address payable _relayer,
+ uint256 _fee,
+ uint256 _deadline,
+ uint8 _v,
+ bytes32 _r,
+ bytes32 _s
+ ) external override returns (uint256 receivedAmount) {
+ require(_deadline >= block.timestamp, "Bridge: EXPIRED"); // solhint-disable-line not-rely-on-time
+
+ bytes32 digest = getDigest(_claimData, _relayer, _fee, _deadline);
+ address recoveredAddress = ecrecover(digest, _v, _r, _s);
+ require(_claimData.to != address(0) && recoveredAddress == _claimData.to, "Bridge: INVALID_SIGNATURE");
+
+ return _claim(
+ _claimData,
+ _claimData.to,
+ _relayer,
+ _fee
+ );
+ }
+
+ function isClaimed(bytes32 transactionDataHash, bytes32 transactionDataHashMultichain) public view returns(bool) {
+ return claimed[transactionDataHash] || claimed[transactionDataHashMultichain];
+ }
+
+ function isClaimed(ClaimData calldata _claimData, bytes32 transactionDataHashMultichain) public view returns(bool) {
+ bytes32 transactionDataHash = getTransactionDataHash(
+ _claimData.to,
+ _claimData.amount,
+ _claimData.blockHash,
+ _claimData.transactionHash,
+ _claimData.logIndex
+ );
+
+ return claimed[transactionDataHash] || claimed[transactionDataHashMultichain];
+ }
+
+ function _claim(
+ ClaimData calldata _claimData,
+ address payable _reciever,
+ address payable _relayer,
+ uint256 _fee
+ ) internal nonReentrant returns (uint256 receivedAmount) {
+ address originalTokenAddress = originalTokenAddresses[_claimData.transactionHash];
+ require(originalTokenAddress != NULL_ADDRESS, "Bridge: Tx not crossed");
+
+ bytes32 transactionDataHash = getTransactionDataHash(
+ _claimData.to,
+ _claimData.amount,
+ _claimData.blockHash,
+ _claimData.transactionHash,
+ _claimData.logIndex,
+ _claimData.originChainId,
+ block.chainid
+ );
+
+ require(transactionsDataHashes[_claimData.transactionHash] == transactionDataHash, "Bridge: Wrong transactionDataHash");
+ require(!isClaimed(_claimData, transactionDataHash), "Bridge: Already claimed");
+ claimed[transactionDataHash] = true;
+
+ receivedAmount = _claimCross(
+ _claimData.originChainId,
+ originalTokenAddress,
+ _reciever,
+ _claimData.amount,
+ _relayer,
+ _fee
+ );
+
+ emitClaimed(_claimData, originalTokenAddress, _reciever, _relayer, _fee);
+ return receivedAmount;
+ }
+
+ function emitClaimed(
+ ClaimData calldata _claimData,
+ address _originalTokenAddress,
+ address payable _reciever,
+ address payable _relayer,
+ uint256 _fee
+ ) internal {
+ emit Claimed(
+ _claimData.transactionHash,
+ _originalTokenAddress,
+ _claimData.to,
+ senderAddresses[_claimData.transactionHash],
+ _claimData.amount,
+ _claimData.blockHash,
+ _claimData.logIndex,
+ _reciever,
+ _relayer,
+ _fee,
+ _claimData.originChainId,
+ block.chainid
+ );
+ }
+
+ function _claimCross(
+ uint256 _originalChainId,
+ address _originalTokenAddress,
+ address payable _reciever,
+ uint256 _amount,
+ address payable _relayer,
+ uint256 _fee
+ ) internal returns (uint256) {
+ checkChainId(_originalChainId);
+ if (knownToken(_originalChainId, _originalTokenAddress)) {
+ return _claimCrossBackToToken(
+ _originalTokenAddress,
+ _reciever,
+ _amount,
+ _relayer,
+ _fee
+ );
+ }
+
+ return _claimCrossToSideToken(
+ sideTokenByOriginalToken(_originalChainId, _originalTokenAddress),
+ _reciever,
+ _amount,
+ _relayer,
+ _fee
+ );
+ }
+
+ function _claimCrossToSideToken(
+ address _sideToken,
+ address payable _receiver,
+ uint256 _amount,
+ address payable _relayer,
+ uint256 _fee
+ ) internal returns (uint256 receivedAmount) {
+ require(_sideToken != NULL_ADDRESS, "Bridge: side token is null");
+ uint256 granularity = IERC777(_sideToken).granularity();
+ uint256 formattedAmount = _amount.mul(granularity);
+ require(_fee <= formattedAmount, "Bridge: fee too high");
+ receivedAmount = formattedAmount.sub(_fee);
+ ISideToken(_sideToken).mint(_receiver, receivedAmount, "", "");
+ if (_fee > 0) {
+ ISideToken(_sideToken).mint(_relayer, _fee, "", "relayer fee");
+ }
+ return receivedAmount;
+ }
+
+ function _claimCrossBackToToken(
+ address _originalTokenAddress,
+ address payable _receiver,
+ uint256 _amount,
+ address payable _relayer,
+ uint256 _fee
+ ) internal returns (uint256 receivedAmount) {
+ uint256 decimals = LibUtils.getDecimals(_originalTokenAddress);
+ //As side tokens are ERC777 they will always have 18 decimals
+ uint256 formattedAmount = _amount.div(uint256(10) ** (18 - decimals));
+ require(_fee <= formattedAmount, "Bridge: fee too high");
+ receivedAmount = formattedAmount.sub(_fee);
+ if (address(wrappedCurrency) == _originalTokenAddress) {
+ wrappedCurrency.withdraw(formattedAmount);
+ _receiver.transfer(receivedAmount);
+ if(_fee > 0) {
+ _relayer.transfer(_fee);
+ }
+ } else {
+ IERC20(_originalTokenAddress).safeTransfer(_receiver, receivedAmount);
+ if(_fee > 0) {
+ IERC20(_originalTokenAddress).safeTransfer(_relayer, _fee);
+ }
+ }
+ return receivedAmount;
+ }
+
+ /**
+ * ERC-20 tokens approve and transferFrom pattern
+ * See https://eips.ethereum.org/EIPS/eip-20#transferfrom
+ */
+ function receiveTokensTo(uint256 destinationChainId, address tokenToUse, address to, uint256 amount) external override {
+ address sender = _msgSender();
+ //Transfer the tokens on IERC20, they should be already Approved for the bridge Address to use them
+ IERC20(tokenToUse).safeTransferFrom(sender, address(this), amount);
+ crossTokens(tokenToUse, sender, to, amount, "", destinationChainId);
+ }
+
+ /**
+ * Use network currency and cross it.
+ */
+ function depositTo(uint256 chainId, address to) external payable override {
+ address sender = _msgSender();
+ require(address(wrappedCurrency) != NULL_ADDRESS, "Bridge: wrappedCurrency empty");
+ wrappedCurrency.deposit{ value: msg.value }();
+ crossTokens(address(wrappedCurrency), sender, to, msg.value, "", chainId);
+ }
+
+ /**
+ * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction
+ * See https://eips.ethereum.org/EIPS/eip-777#motivation for details
+ * @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination
+ * const userData = web3.eth.abi.encodeParameters(
+ * ["address", "uint256"],
+ * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]
+ * );
+ * or you also can send only the destination chain id, and the receiver would be the same as the from parameter
+ * const userData = web3.eth.abi.encodeParameters(["uint256"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);
+ */
+ function tokensReceived(
+ address operator,
+ address from,
+ address to,
+ uint amount,
+ bytes calldata userData, // [address,uint256] user addrest receiver, destinationChainId || [uint256] same as from, destinationChainId
+ bytes calldata
+ ) external override(IBridge, IERC777Recipient) {
+ //Hook from ERC777address
+ if(operator == address(this)) return; // Avoid loop from bridge calling to ERC77transferFrom
+ require(to == address(this), "Bridge: Not to this address");
+ address tokenToUse = _msgSender();
+ require(ERC1820.getInterfaceImplementer(tokenToUse, _erc777Interface) != NULL_ADDRESS, "Bridge: Not ERC777 token");
+ require(userData.length >= 32, "Bridge: user data with at least the destinationChainId");
+ require(userData.length == 64 || !from.isContract(), "Bridge: Specify receiver address in data");
+ address receiver = userData.length == 32 ? from : LibUtils.toAddress(userData, 12);
+ uint256 destinationChainId = LibUtils.toUint256(userData, userData.length - 32);
+ crossTokens(tokenToUse, from, receiver, amount, userData, destinationChainId);
+ }
+
+ function crossTokens(
+ address tokenToUse,
+ address from,
+ address to,
+ uint256 amount,
+ bytes memory userData,
+ uint256 destinationChainId
+ ) internal whenNotUpgrading whenNotPaused nonReentrant {
+ require(block.chainid != destinationChainId, "Bridge: destination chain id equal current chain id");
+ checkChainId(destinationChainId);
+ _setKnownTokenByChain(destinationChainId, tokenToUse, true);
+ uint256 fee = amount.mul(feePercentage).div(feePercentageDivider);
+ uint256 amountMinusFees = amount.sub(fee);
+ uint8 decimals = LibUtils.getDecimals(tokenToUse);
+ uint formattedAmount = amount;
+ if (decimals != 18) {
+ formattedAmount = amount.mul(uint256(10)**(18-decimals));
+ }
+ // We consider the amount before fees converted to 18 decimals to check the limits
+ // updateTokenTransfer revert if token not allowed
+ allowTokens.updateTokenTransfer(tokenToUse, formattedAmount);
+
+ OriginalToken memory sideToken = getOriginalTokenBySideToken(tokenToUse);
+ if (sideToken.tokenAddress != NULL_ADDRESS) {
+ // Side Token Crossing back
+ { // Created scope to avoid stack too deep
+ uint256 granularity = LibUtils.getGranularity(tokenToUse);
+ uint256 modulo = amountMinusFees.mod(granularity);
+ fee = fee.add(modulo);
+ amountMinusFees = amountMinusFees.sub(modulo);
+ IERC777(tokenToUse).burn(amountMinusFees, userData);
+ }
+ emit Cross(
+ sideToken.tokenAddress,
+ to,
+ destinationChainId,
+ from,
+ block.chainid,
+ amountMinusFees,
+ userData
+ );
+ } else {
+ emit Cross(
+ tokenToUse,
+ to,
+ destinationChainId,
+ from,
+ block.chainid,
+ amountMinusFees,
+ userData
+ );
+ }
+
+ if (fee > 0) {
+ //Send the payment to the MultiSig of the Federation
+ IERC20(tokenToUse).safeTransfer(owner(), fee);
+ }
+ }
+
+ // function for retrocompatibility
+ function getTransactionDataHash(
+ address _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex
+ ) internal pure returns(bytes32) {
+ return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex));
+ }
+
+ function getTransactionDataHash(
+ address _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex,
+ uint256 _originChainId,
+ uint256 _destinationChainId
+ ) public pure override returns(bytes32) {
+ return keccak256(abi.encodePacked(_blockHash, _transactionHash, _to, _amount, _logIndex, _originChainId, _destinationChainId));
+ }
+
+ function setFeePercentage(uint amount) external onlyOwner {
+ require(amount < (feePercentageDivider/10), "Bridge: bigger than 10%");
+ feePercentage = amount;
+ emit FeePercentageChanged(feePercentage);
+ }
+
+ function getFeePercentage() external view override returns(uint) {
+ return feePercentage;
+ }
+
+ function changeFederation(address newFederation) external onlyOwner {
+ require(newFederation != NULL_ADDRESS, "Bridge: Federation is empty");
+ federation = newFederation;
+ emit FederationChanged(federation);
+ }
+
+ function changeAllowTokens(address newAllowTokens) external onlyOwner {
+ require(newAllowTokens != NULL_ADDRESS, "Bridge: AllowTokens is empty");
+ allowTokens = IAllowTokens(newAllowTokens);
+ emit AllowTokensChanged(newAllowTokens);
+ }
+
+ function getFederation() external view returns(address) {
+ return federation;
+ }
+
+ function changeSideTokenFactory(address newSideTokenFactory) external onlyOwner {
+ require(newSideTokenFactory != NULL_ADDRESS, "Bridge: SideTokenFactory is empty");
+ sideTokenFactory = ISideTokenFactory(newSideTokenFactory);
+ emit SideTokenFactoryChanged(newSideTokenFactory);
+ }
+
+ function setUpgrading(bool _isUpgrading) external onlyOwner {
+ isUpgrading = _isUpgrading;
+ emit Upgrading(isUpgrading);
+ }
+
+ function setWrappedCurrency(address _wrappedCurrency) external onlyOwner {
+ require(_wrappedCurrency != NULL_ADDRESS, "Bridge: wrapp is empty");
+ wrappedCurrency = IWrapped(_wrappedCurrency);
+ emit WrappedCurrencyChanged(_wrappedCurrency);
+ }
+
+ function hasCrossed(bytes32 transactionHash) public view returns (bool) {
+ return transactionsDataHashes[transactionHash] != bytes32(0);
+ }
+
+ function hasBeenClaimed(bytes32 transactionHash) public view returns (bool) {
+ return claimed[transactionsDataHashes[transactionHash]];
+ }
+
+}
diff --git a/bridge/flatten/Federation.sol b/bridge/flatten/Federation.sol
new file mode 100644
index 000000000..770add929
--- /dev/null
+++ b/bridge/flatten/Federation.sol
@@ -0,0 +1,841 @@
+// Dependency file: contracts/zeppelin/upgradable/Initializable.sol
+
+// SPDX-License-Identifier: MIT
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @title Initializable
+ *
+ * @dev Helper contract to support initializer functions. To use it, replace
+ * the constructor with a function that has the `initializer` modifier.
+ * WARNING: Unlike constructors, initializer functions must be manually
+ * invoked. This applies both to deploying an Initializable contract, as well
+ * as extending an Initializable contract via inheritance.
+ * WARNING: When used with inheritance, manual care must be taken to not invoke
+ * a parent initializer twice, or ensure that all initializers are idempotent,
+ * because this is not dealt with automatically as with constructors.
+ */
+contract Initializable {
+
+ /**
+ * @dev Indicates that the contract has been initialized.
+ */
+ bool private initialized;
+
+ /**
+ * @dev Indicates that the contract is in the process of being initialized.
+ */
+ bool private initializing;
+
+ /**
+ * @dev Modifier to use in the initializer function of a contract.
+ */
+ modifier initializer() {
+ require(initializing || !initialized, "Contract instance is already initialized");
+
+ bool isTopLevelCall = !initializing;
+ if (isTopLevelCall) {
+ initializing = true;
+ initialized = true;
+ }
+
+ _;
+
+ if (isTopLevelCall) {
+ initializing = false;
+ }
+ }
+
+ // Reserved storage space to allow for layout changes in the future.
+ uint256[50] private ______gap;
+}
+
+// Dependency file: contracts/zeppelin/GSN/Context.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/*
+ * @dev Provides information about the current execution context, including the
+ * sender of the transaction and its data. While these are generally available
+ * via msg.sender and msg.data, they should not be accessed in such a direct
+ * manner, since when dealing with GSN meta-transactions the account sending and
+ * paying for execution may not be the actual sender (as far as an application
+ * is concerned).
+ *
+ * This contract is only required for intermediate, library-like contracts.
+ */
+abstract contract Context {
+
+ function _msgSender() internal view returns (address payable) {
+ return payable(msg.sender);
+ }
+
+ function _msgData() internal view returns (bytes memory) {
+ this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
+ return msg.data;
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/upgradable/Initializable.sol";
+
+// import "contracts/zeppelin/GSN/Context.sol";
+
+/**
+ * @dev Contract module which provides a basic access control mechanism, where
+ * there is an account (an owner) that can be granted exclusive access to
+ * specific functions.
+ *
+ * This module is used through inheritance. It will make available the modifier
+ * `onlyOwner`, which can be aplied to your functions to restrict their use to
+ * the owner.
+ */
+contract UpgradableOwnable is Initializable, Context {
+ address private _owner;
+
+ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
+
+ /**
+ * @dev Initializes the contract setting the deployer as the initial owner.
+ */
+ function initialize(address sender) public initializer {
+ _owner = sender;
+ emit OwnershipTransferred(address(0), _owner);
+ }
+
+ /**
+ * @dev Returns the address of the current owner.
+ */
+ function owner() public view returns (address) {
+ return _owner;
+ }
+
+ /**
+ * @dev Throws if called by any account other than the owner.
+ */
+ modifier onlyOwner() {
+ require(isOwner(), "Ownable: caller is not the owner");
+ _;
+ }
+
+ /**
+ * @dev Returns true if the caller is the current owner.
+ */
+ function isOwner() public view returns (bool) {
+ return _msgSender() == _owner;
+ }
+
+ /**
+ * @dev Leaves the contract without owner. It will not be possible to call
+ * `onlyOwner` functions anymore. Can only be called by the current owner.
+ *
+ * > Note: Renouncing ownership will leave the contract without an owner,
+ * thereby removing any functionality that is only available to the owner.
+ */
+ function renounceOwnership() public onlyOwner {
+ emit OwnershipTransferred(_owner, address(0));
+ _owner = address(0);
+ }
+
+ /**
+ * @dev Transfers ownership of the contract to a new account (`newOwner`).
+ * Can only be called by the current owner.
+ */
+ function transferOwnership(address newOwner) public onlyOwner {
+ _transferOwnership(newOwner);
+ }
+
+ /**
+ * @dev Transfers ownership of the contract to a new account (`newOwner`).
+ */
+ function _transferOwnership(address newOwner) internal {
+ require(newOwner != address(0), "Ownable: new owner is zero address");
+ emit OwnershipTransferred(_owner, newOwner);
+ _owner = newOwner;
+ }
+
+}
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+
+// Dependency file: contracts/interface/IBridge.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+interface IBridge {
+
+ struct ClaimData {
+ address payable to;
+ uint256 amount;
+ bytes32 blockHash;
+ bytes32 transactionHash;
+ uint32 logIndex;
+ uint256 originChainId;
+ }
+
+ struct OriginalToken {
+ address tokenAddress;
+ uint256 originChainId;
+ }
+
+ function version() external pure returns (string memory);
+
+ function getFeePercentage() external view returns(uint);
+
+ /**
+ * ERC-20 tokens approve and transferFrom pattern
+ * See https://eips.ethereum.org/EIPS/eip-20#transferfrom
+ */
+ function receiveTokensTo(uint256 chainId, address tokenToUse, address to, uint256 amount) external;
+
+ /**
+ * Use network currency and cross it.
+ */
+ function depositTo(uint256 chainId, address to) external payable;
+
+ /**
+ * ERC-777 tokensReceived hook allows to send tokens to a contract and notify it in a single transaction
+ * See https://eips.ethereum.org/EIPS/eip-777#motivation for details
+ * @param userData it can be 2 options in the first one you can send the receiver and the chain id of the destination
+ * const userData = web3.eth.abi.encodeParameters(
+ * ["address", "uint256"],
+ * [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]
+ * );
+ * or you also can send only the destination chain id, and the receiver would be the same as the from parameter
+ * const userData = web3.eth.abi.encodeParameters(["uint256"], [chains.ETHEREUM_MAIN_NET_CHAIN_ID]);
+ */
+ function tokensReceived (
+ address operator,
+ address from,
+ address to,
+ uint amount,
+ bytes calldata userData,
+ bytes calldata operatorData
+ ) external;
+
+ /**
+ * Accepts the transaction from the other chain that was voted and sent by the Federation contract
+ */
+ function acceptTransfer(
+ address _originalTokenAddress,
+ address payable _from,
+ address payable _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex,
+ uint256 _originChainId,
+ uint256 _destinationChainId
+ ) external;
+
+ /**
+ * Claims the crossed transaction using the hash, this sends the funds to the address indicated in
+ */
+ function claim(ClaimData calldata _claimData) external returns (uint256 receivedAmount);
+
+ function claimFallback(ClaimData calldata _claimData) external returns (uint256 receivedAmount);
+
+ function claimGasless(
+ ClaimData calldata _claimData,
+ address payable _relayer,
+ uint256 _fee,
+ uint256 _deadline,
+ uint8 _v,
+ bytes32 _r,
+ bytes32 _s
+ ) external returns (uint256 receivedAmount);
+
+ function createSideToken(
+ uint256 _typeId,
+ address _originalTokenAddress,
+ uint8 _originalTokenDecimals,
+ string calldata _originalTokenSymbol,
+ string calldata _originalTokenName,
+ uint256 _chainId
+ ) external;
+
+ function getTransactionDataHash(
+ address _to,
+ uint256 _amount,
+ bytes32 _blockHash,
+ bytes32 _transactionHash,
+ uint32 _logIndex,
+ uint256 _originChainId,
+ uint256 _destinationChainId
+ ) external returns(bytes32);
+
+ event Cross(
+ address indexed _tokenAddress,
+ address indexed _to,
+ uint256 indexed _destinationChainId,
+ address _from,
+ uint256 _originChainId,
+ uint256 _amount,
+ bytes _userData
+ );
+
+ event NewSideToken(
+ address indexed _newSideTokenAddress,
+ address indexed _originalTokenAddress,
+ string _newSymbol,
+ uint256 _granularity,
+ uint256 _chainId
+ );
+ event AcceptedCrossTransfer(
+ bytes32 indexed _transactionHash,
+ address indexed _originalTokenAddress,
+ address indexed _to,
+ address _from,
+ uint256 _amount,
+ bytes32 _blockHash,
+ uint256 _logIndex,
+ uint256 _originChainId,
+ uint256 _destinationChainId
+ );
+ event FeePercentageChanged(uint256 _amount);
+ event Claimed(
+ bytes32 indexed _transactionHash,
+ address indexed _originalTokenAddress,
+ address indexed _to,
+ address _sender,
+ uint256 _amount,
+ bytes32 _blockHash,
+ uint256 _logIndex,
+ address _reciever,
+ address _relayer,
+ uint256 _fee,
+ uint256 _destinationChainId,
+ uint256 _originChainId
+ );
+}
+
+// Dependency file: contracts/interface/IFederation.sol
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+interface IFederation {
+
+ /**
+ @notice Current version of the contract
+ @return version in v{Number}
+ */
+ function version() external pure returns (string memory);
+
+ /**
+ @notice Sets a new bridge contract
+ @param _bridge the new bridge contract address that should implement the IBridge interface
+ */
+ function setBridge(address _bridge) external;
+
+ /**
+ @notice Vote in a transaction, if it has enough votes it accepts the transfer
+ @param originalTokenAddress The address of the token in the origin (main) chain
+ @param sender The address who solicited the cross token
+ @param receiver Who is going to receive the token in the opposite chain
+ @param value Amount
+ @param blockHash The block hash in which the transaction with the cross event occurred
+ @param transactionHash The transaction in which the cross event occurred
+ @param logIndex Index of the event in the logs
+ @param originChainId Is chainId of the original chain
+ @param destinationChainId Is chainId of the destination chain
+ */
+ function voteTransaction(
+ address originalTokenAddress,
+ address payable sender,
+ address payable receiver,
+ uint256 value,
+ bytes32 blockHash,
+ bytes32 transactionHash,
+ uint32 logIndex,
+ uint256 originChainId,
+ uint256 destinationChainId
+ ) external;
+
+ /**
+ @notice Add a new member to the federation
+ @param _newMember address of the new member
+ */
+ function addMember(address _newMember) external;
+
+ /**
+ @notice Remove a member of the federation
+ @param _oldMember address of the member to be removed from federation
+ */
+ function removeMember(address _oldMember) external;
+
+ /**
+ @notice Return all the current members of the federation
+ @return Current members
+ */
+ function getMembers() external view returns (address[] memory);
+
+ /**
+ @notice Changes the number of required members to vote and approve an transaction
+ @param _required the number of minimum members to approve an transaction, it has to be bigger than 1
+ */
+ function changeRequirement(uint _required) external;
+
+ /**
+ @notice It emmits an HeartBeat like an healthy check
+ */
+ function emitHeartbeat(
+ string calldata federatorVersion,
+ uint256[] calldata fedChainsIds,
+ uint256[] calldata fedChainsBlocks,
+ string[] calldata fedChainsInfo
+ ) external;
+
+ event Executed(
+ address indexed federator,
+ bytes32 indexed transactionHash,
+ bytes32 indexed transactionId,
+ address originalTokenAddress,
+ address sender,
+ address receiver,
+ uint256 amount,
+ bytes32 blockHash,
+ uint32 logIndex,
+ uint256 originChainId,
+ uint256 destinationChainId
+ );
+ event MemberAddition(address indexed member);
+ event MemberRemoval(address indexed member);
+ event RequirementChange(uint required);
+ event BridgeChanged(address bridge);
+ event Voted(
+ address indexed federator,
+ bytes32 indexed transactionHash,
+ bytes32 indexed transactionId,
+ address originalTokenAddress,
+ address sender,
+ address receiver,
+ uint256 amount,
+ bytes32 blockHash,
+ uint32 logIndex,
+ uint256 originChainId,
+ uint256 destinationChainId
+ );
+ event HeartBeat(
+ address indexed sender,
+ uint256 currentChainId,
+ uint256 currentBlock,
+ string fedVersion,
+ uint256[] fedChainsIds,
+ uint256[] fedChainsBlocks,
+ string[] fedChainsInfo
+ );
+
+}
+
+
+// Root file: contracts/federation/Federation.sol
+
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// Upgradables
+// import "contracts/zeppelin/upgradable/Initializable.sol";
+// import "contracts/zeppelin/upgradable/ownership/UpgradableOwnable.sol";
+// import "contracts/interface/IBridge.sol";
+// import "contracts/interface/IFederation.sol";
+contract Federation is Initializable, UpgradableOwnable, IFederation {
+ uint constant public MAX_MEMBER_COUNT = 50;
+ address constant private NULL_ADDRESS = address(0);
+
+ IBridge public bridge;
+ address[] public members;
+
+ /**
+ @notice The minimum amount of votes to approve a transaction
+ @dev It should have at least the required amount of members
+ */
+ uint public required;
+
+ /**
+ @notice All the addresses that are members of the federation
+ @dev The address should be a member to vote in transactions
+ */
+ mapping (address => bool) public isMember;
+
+ /**
+ (bytes32) transactionId = keccak256(
+ abi.encodePacked(
+ originalTokenAddress,
+ sender,
+ receiver,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex
+ )
+ ) => (
+ (address) members => (bool) voted
+ )
+ @notice Votes by members by the transaction ID
+ @dev the members should approve the transaction by 50% + 1
+ */
+ mapping (bytes32 => mapping (address => bool)) public votes;
+
+ /**
+ (bytes32) transactionId => (bool) voted
+ @notice Check if that transaction was already processed
+ */
+ mapping(bytes32 => bool) public processed;
+
+ modifier onlyMember() {
+ require(isMember[_msgSender()], "Federation: Not Federator");
+ _;
+ }
+
+ modifier validRequirement(uint membersCount, uint _required) {
+ require(_required <= membersCount && _required != 0 && membersCount != 0, "Federation: Invalid requirements");
+ _;
+ }
+
+ function initialize(
+ address[] calldata _members,
+ uint _required,
+ address _bridge,
+ address owner
+ ) public validRequirement(_members.length, _required) initializer {
+ UpgradableOwnable.initialize(owner);
+ require(_members.length <= MAX_MEMBER_COUNT, "Federation: Too many members");
+ members = _members;
+ for (uint i = 0; i < _members.length; i++) {
+ require(!isMember[_members[i]] && _members[i] != NULL_ADDRESS, "Federation: Invalid members");
+ isMember[_members[i]] = true;
+ emit MemberAddition(_members[i]);
+ }
+ required = _required;
+ emit RequirementChange(required);
+ _setBridge(_bridge);
+ }
+
+ /**
+ @notice Current version of the contract
+ @return version in v{Number}
+ */
+ function version() external pure override returns (string memory) {
+ return "v3";
+ }
+
+ /**
+ @notice Sets a new bridge contract
+ @dev Emits BridgeChanged event
+ @param _bridge the new bridge contract address that should implement the IBridge interface
+ */
+ function setBridge(address _bridge) external onlyOwner override {
+ _setBridge(_bridge);
+ }
+
+ function _setBridge(address _bridge) internal {
+ require(_bridge != NULL_ADDRESS, "Federation: Empty bridge");
+ bridge = IBridge(_bridge);
+ emit BridgeChanged(_bridge);
+ }
+
+ function validateTransaction(bytes32 transactionId, bytes32 transactionIdMultichain) internal view returns(bool) {
+ uint256 minimumVotes = getMinimalNumberOfVotes();
+ uint256 amountVotes = 0;
+
+ for (uint256 i = 0; i < members.length; i++) {
+ if (votes[transactionIdMultichain][members[i]]) {
+ amountVotes += 1;
+ } else if (votes[transactionId][members[i]]) {
+ amountVotes += 1;
+ }
+
+ if (amountVotes >= minimumVotes && amountVotes >= required) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ function getMinimalNumberOfVotes() internal view returns(uint256) {
+ return members.length / 2 + 1;
+ }
+
+ function isProcessed(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {
+ return processed[transactionIdMultichain] || processed[transactionId];
+ }
+
+ function isVoted(bytes32 transactionId, bytes32 transactionIdMultichain) public view returns(bool) {
+ return votes[transactionIdMultichain][_msgSender()] || votes[transactionId][_msgSender()];
+ }
+
+ function shouldBeCurrentChainId(uint256 chainId) internal view {
+ require(chainId == block.chainid, "Federation: Not block.chainid");
+ }
+
+ /**
+ @notice Vote in a transaction, if it has enough votes it accepts the transfer
+ @param originalTokenAddress The address of the token in the origin (main) chain
+ @param sender The address who solicited the cross token
+ @param receiver Who is going to receive the token in the opposite chain
+ @param value Amount
+ @param blockHash The block hash in which the transaction with the cross event occurred
+ @param transactionHash The transaction in which the cross event occurred
+ @param logIndex Index of the event in the logs
+ @param originChainId Is chainId of the original chain
+ @param destinationChainId Is chainId of the destination chain
+ */
+ function voteTransaction(
+ address originalTokenAddress,
+ address payable sender,
+ address payable receiver,
+ uint256 value,
+ bytes32 blockHash,
+ bytes32 transactionHash,
+ uint32 logIndex,
+ uint256 originChainId,
+ uint256 destinationChainId
+ ) external onlyMember override {
+ shouldBeCurrentChainId(destinationChainId);
+ bytes32 transactionId = keccak256(
+ abi.encodePacked(
+ originalTokenAddress,
+ sender,
+ receiver,
+ value,
+ blockHash,
+ transactionHash,
+ logIndex
+ )
+ );
+
+ bytes32 transactionIdMultichain = getTransactionId(
+ originalTokenAddress,
+ sender,
+ receiver,
+ value,
+ blockHash,
+ transactionHash,
+ logIndex,
+ originChainId,
+ destinationChainId
+ );
+
+ if (isProcessed(transactionId, transactionIdMultichain))
+ return;
+
+ if (isVoted(transactionId, transactionIdMultichain))
+ return;
+
+ votes[transactionIdMultichain][_msgSender()] = true;
+ emit Voted(
+ _msgSender(),
+ transactionHash,
+ transactionIdMultichain,
+ originalTokenAddress,
+ sender,
+ receiver,
+ value,
+ blockHash,
+ logIndex,
+ originChainId,
+ destinationChainId
+ );
+
+ if (validateTransaction(transactionId, transactionIdMultichain)) {
+ processed[transactionIdMultichain] = true;
+
+ acceptTransfer(
+ originalTokenAddress,
+ sender,
+ receiver,
+ value,
+ blockHash,
+ transactionHash,
+ logIndex,
+ originChainId,
+ destinationChainId
+ );
+
+ emit Executed(
+ _msgSender(),
+ transactionHash,
+ transactionIdMultichain,
+ originalTokenAddress,
+ sender,
+ receiver,
+ value,
+ blockHash,
+ logIndex,
+ originChainId,
+ destinationChainId
+ );
+ }
+ }
+
+ function acceptTransfer(
+ address originalTokenAddress,
+ address payable sender,
+ address payable receiver,
+ uint256 value,
+ bytes32 blockHash,
+ bytes32 transactionHash,
+ uint32 logIndex,
+ uint256 originChainId,
+ uint256 destinationChainId
+ ) internal {
+ bridge.acceptTransfer(
+ originalTokenAddress,
+ sender,
+ receiver,
+ value,
+ blockHash,
+ transactionHash,
+ logIndex,
+ originChainId,
+ destinationChainId
+ );
+ }
+
+ /**
+ @notice Get the amount of approved votes for that transactionId
+ @param transactionId The transaction hashed from getTransactionId function
+ */
+ function getTransactionCount(bytes32 transactionId) public view returns(uint) {
+ uint count = 0;
+ for (uint i = 0; i < members.length; i++) {
+ if (votes[transactionId][members[i]])
+ count += 1;
+ }
+ return count;
+ }
+
+ function hasVoted(bytes32 transactionId) external view returns(bool) {
+ return votes[transactionId][_msgSender()];
+ }
+
+ function transactionWasProcessed(bytes32 transactionId) external view returns(bool) {
+ return processed[transactionId];
+ }
+
+ /**
+ @notice Gets the hash of transaction from the following parameters encoded and keccaked
+ @dev It encodes and applies keccak256 to the parameters received in the same order
+ @param originalTokenAddress The address of the token in the origin (main) chain
+ @param sender The address who solicited the cross token
+ @param receiver Who is going to receive the token in the opposite chain
+ @param amount Could be the amount or the tokenId
+ @param blockHash The block hash in which the transaction with the cross event occurred
+ @param transactionHash The transaction in which the cross event occurred
+ @param logIndex Index of the event in the logs
+ @param originChainId Is chainId of the original chain
+ @param destinationChainId Is chainId of the destination chain
+ @return The hash generated by the parameters.
+ */
+ function getTransactionId(
+ address originalTokenAddress,
+ address sender,
+ address receiver,
+ uint256 amount,
+ bytes32 blockHash,
+ bytes32 transactionHash,
+ uint32 logIndex,
+ uint256 originChainId,
+ uint256 destinationChainId
+ ) public pure returns(bytes32) {
+ return keccak256(
+ abi.encodePacked(
+ originalTokenAddress,
+ sender,
+ receiver,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ originChainId,
+ destinationChainId
+ )
+ );
+ }
+
+ function addMember(address _newMember) external onlyOwner override {
+ require(_newMember != NULL_ADDRESS, "Federation: Empty member");
+ require(!isMember[_newMember], "Federation: Member already exists");
+ require(members.length < MAX_MEMBER_COUNT, "Federation: Max members reached");
+
+ isMember[_newMember] = true;
+ members.push(_newMember);
+ emit MemberAddition(_newMember);
+ }
+
+ function removeMember(address _oldMember) external onlyOwner override {
+ require(_oldMember != NULL_ADDRESS, "Federation: Empty member");
+ require(isMember[_oldMember], "Federation: Member doesn't exists");
+ require(members.length > 1, "Federation: Can't remove all the members");
+ require(members.length - 1 >= required, "Federation: Can't have less than required members");
+
+ isMember[_oldMember] = false;
+ for (uint i = 0; i < members.length - 1; i++) {
+ if (members[i] == _oldMember) {
+ members[i] = members[members.length - 1];
+ break;
+ }
+ }
+ members.pop(); // remove an element from the end of the array.
+ emit MemberRemoval(_oldMember);
+ }
+
+ /**
+ @notice Return all the current members of the federation
+ @return Current members
+ */
+ function getMembers() external view override returns (address[] memory) {
+ return members;
+ }
+
+ /**
+ @notice Changes the number of required members to vote and approve an transaction
+ @dev Emits the RequirementChange event
+ @param _required the number of minimum members to approve an transaction, it has to be bigger than 1
+ */
+ function changeRequirement(uint _required) external onlyOwner validRequirement(members.length, _required) override {
+ require(_required >= 2, "Federation: Requires at least 2");
+ required = _required;
+ emit RequirementChange(_required);
+ }
+
+ /**
+ @notice It emits an HeartBeat like an health check
+ @dev Emits HeartBeat event
+ */
+ function emitHeartbeat(
+ string calldata fedVersion,
+ uint256[] calldata fedChainsIds,
+ uint256[] calldata fedChainsBlocks,
+ string[] calldata fedChainsInfo
+ ) external onlyMember override {
+ require(fedChainsIds.length == fedChainsBlocks.length &&
+ fedChainsIds.length == fedChainsInfo.length, "Federation: Length missmatch");
+ emit HeartBeat(
+ _msgSender(),
+ block.chainid,
+ block.number,
+ fedVersion,
+ fedChainsIds,
+ fedChainsBlocks,
+ fedChainsInfo
+ );
+ }
+}
diff --git a/bridge/flatten/Proxies.sol b/bridge/flatten/Proxies.sol
new file mode 100644
index 000000000..7e2a2917c
--- /dev/null
+++ b/bridge/flatten/Proxies.sol
@@ -0,0 +1,540 @@
+// Dependency file: contracts/zeppelin/upgradable/proxy/Proxy.sol
+
+// SPDX-License-Identifier: MIT
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
+ * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
+ * be specified by overriding the virtual {_implementation} function.
+ *
+ * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
+ * different contract through the {_delegate} function.
+ *
+ * The success and return data of the delegated call will be returned back to the caller of the proxy.
+ */
+abstract contract Proxy {
+ /**
+ * @dev Delegates the current call to `implementation`.
+ *
+ * This function does not return to its internall call site, it will return directly to the external caller.
+ */
+ function _delegate(address implementation) internal virtual {
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ // Copy msg.data. We take full control of memory in this inline assembly
+ // block because it will not return to Solidity code. We overwrite the
+ // Solidity scratch pad at memory position 0.
+ calldatacopy(0, 0, calldatasize())
+
+ // Call the implementation.
+ // out and outsize are 0 because we don't know the size yet.
+ let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
+
+ // Copy the returned data.
+ returndatacopy(0, 0, returndatasize())
+
+ switch result
+ // delegatecall returns 0 on error.
+ case 0 { revert(0, returndatasize()) }
+ default { return(0, returndatasize()) }
+ }
+ }
+
+ /**
+ * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function
+ * and {_fallback} should delegate.
+ */
+ function _implementation() internal view virtual returns (address);
+
+ /**
+ * @dev Delegates the current call to the address returned by `_implementation()`.
+ *
+ * This function does not return to its internall call site, it will return directly to the external caller.
+ */
+ function _fallback() internal virtual {
+ _beforeFallback();
+ _delegate(_implementation());
+ }
+
+ /**
+ * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
+ * function in the contract matches the call data.
+ */
+ fallback () external payable virtual {
+ _fallback();
+ }
+
+ /**
+ * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
+ * is empty.
+ */
+ receive () external payable virtual {
+ _fallback();
+ }
+
+ /**
+ * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
+ * call, or as part of the Solidity `fallback` or `receive` functions.
+ *
+ * If overriden should call `super._beforeFallback()`.
+ */
+ function _beforeFallback() internal virtual {
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/utils/Address.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Collection of functions related to the address type
+ */
+library Address {
+ /**
+ * @dev Returns true if `account` is a contract.
+ *
+ * [IMPORTANT]
+ * ====
+ * It is unsafe to assume that an address for which this function returns
+ * false is an externally-owned account (EOA) and not a contract.
+ *
+ * Among others, `isContract` will return false for the following
+ * types of addresses:
+ *
+ * - an externally-owned account
+ * - a contract in construction
+ * - an address where a contract will be created
+ * - an address where a contract lived, but was destroyed
+ * ====
+ */
+ function isContract(address account) internal view returns (bool) {
+ // This method relies on extcodesize, which returns 0 for contracts in
+ // construction, since the code is only stored at the end of the
+ // constructor execution.
+
+ uint256 size;
+ // solhint-disable-next-line no-inline-assembly
+ assembly { size := extcodesize(account) }
+ return size > 0;
+ }
+
+ /**
+ * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
+ * `recipient`, forwarding all available gas and reverting on errors.
+ *
+ * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
+ * of certain opcodes, possibly making contracts go over the 2300 gas limit
+ * imposed by `transfer`, making them unable to receive funds via
+ * `transfer`. {sendValue} removes this limitation.
+ *
+ * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
+ *
+ * IMPORTANT: because control is transferred to `recipient`, care must be
+ * taken to not create reentrancy vulnerabilities. Consider using
+ * {ReentrancyGuard} or the
+ * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
+ */
+ function sendValue(address payable recipient, uint256 amount) internal {
+ require(address(this).balance >= amount, "Address: insufficient balance");
+
+ // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
+ (bool success, ) = recipient.call{ value: amount }("");
+ require(success, "Address: unable to send value, recipient may have reverted");
+ }
+
+ /**
+ * @dev Performs a Solidity function call using a low level `call`. A
+ * plain`call` is an unsafe replacement for a function call: use this
+ * function instead.
+ *
+ * If `target` reverts with a revert reason, it is bubbled up by this
+ * function (like regular Solidity function calls).
+ *
+ * Returns the raw returned data. To convert to the expected return value,
+ * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
+ *
+ * Requirements:
+ *
+ * - `target` must be a contract.
+ * - calling `target` with `data` must not revert.
+ *
+ * _Available since v3.1._
+ */
+ function functionCall(address target, bytes memory data) internal returns (bytes memory) {
+ return functionCall(target, data, "Address: low-level call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
+ * `errorMessage` as a fallback revert reason when `target` reverts.
+ *
+ * _Available since v3.1._
+ */
+ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
+ return functionCallWithValue(target, data, 0, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but also transferring `value` wei to `target`.
+ *
+ * Requirements:
+ *
+ * - the calling contract must have an ETH balance of at least `value`.
+ * - the called Solidity function must be `payable`.
+ *
+ * _Available since v3.1._
+ */
+ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
+ return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
+ * with `errorMessage` as a fallback revert reason when `target` reverts.
+ *
+ * _Available since v3.1._
+ */
+ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
+ require(address(this).balance >= value, "Address: insufficient balance for call");
+ require(isContract(target), "Address: call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.call{ value: value }(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but performing a static call.
+ *
+ * _Available since v3.3._
+ */
+ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
+ return functionStaticCall(target, data, "Address: low-level static call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
+ * but performing a static call.
+ *
+ * _Available since v3.3._
+ */
+ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
+ require(isContract(target), "Address: static call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.staticcall(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but performing a delegate call.
+ *
+ * _Available since v3.4._
+ */
+ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
+ return functionDelegateCall(target, data, "Address: low-level delegate call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
+ * but performing a delegate call.
+ *
+ * _Available since v3.4._
+ */
+ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
+ require(isContract(target), "Address: delegate call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.delegatecall(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
+ if (success) {
+ return returndata;
+ } else {
+ // Look for revert reason and bubble it up if present
+ if (returndata.length > 0) {
+ // The easiest way to bubble the revert reason is using memory via assembly
+
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ let returndata_size := mload(returndata)
+ revert(add(32, returndata), returndata_size)
+ }
+ } else {
+ revert(errorMessage);
+ }
+ }
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/upgradable/proxy/Proxy.sol";
+// import "contracts/zeppelin/utils/Address.sol";
+
+/**
+ * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
+ * implementation address that can be changed. This address is stored in storage in the location specified by
+ * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
+ * implementation behind the proxy.
+ *
+ * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see
+ * {TransparentUpgradeableProxy}.
+ */
+contract UpgradeableProxy is Proxy {
+ /**
+ * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
+ *
+ * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
+ * function call, and allows initializating the storage of the proxy like a Solidity constructor.
+ */
+ constructor(address _logic, bytes memory _data) payable {
+ assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
+ _setImplementation(_logic);
+ if(_data.length > 0) {
+ Address.functionDelegateCall(_logic, _data);
+ }
+ }
+
+ /**
+ * @dev Emitted when the implementation is upgraded.
+ */
+ event Upgraded(address indexed implementation);
+
+ /**
+ * @dev Storage slot with the address of the current implementation.
+ * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
+ * validated in the constructor.
+ */
+ bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
+
+ /**
+ * @dev Returns the current implementation address.
+ */
+ function _implementation() internal view virtual override returns (address impl) {
+ bytes32 slot = _IMPLEMENTATION_SLOT;
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ impl := sload(slot)
+ }
+ }
+
+ /**
+ * @dev Upgrades the proxy to a new implementation.
+ *
+ * Emits an {Upgraded} event.
+ */
+ function _upgradeTo(address newImplementation) internal virtual {
+ _setImplementation(newImplementation);
+ emit Upgraded(newImplementation);
+ }
+
+ /**
+ * @dev Stores a new address in the EIP1967 implementation slot.
+ */
+ function _setImplementation(address newImplementation) private {
+ require(Address.isContract(newImplementation), "UpgradeableProxy: new implementation is not a contract");
+
+ bytes32 slot = _IMPLEMENTATION_SLOT;
+
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ sstore(slot, newImplementation)
+ }
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol";
+
+/**
+ * @dev This contract implements a proxy that is upgradeable by an admin.
+ *
+ * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector
+ * clashing], which can potentially be used in an attack, this contract uses the
+ * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two
+ * things that go hand in hand:
+ *
+ * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if
+ * that call matches one of the admin functions exposed by the proxy itself.
+ * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the
+ * implementation. If the admin tries to call a function on the implementation it will fail with an error that says
+ * "admin cannot fallback to proxy target".
+ *
+ * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing
+ * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due
+ * to sudden errors when trying to call a function from the proxy implementation.
+ *
+ * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,
+ * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.
+ */
+contract TransparentUpgradeableProxy is UpgradeableProxy {
+ /**
+ * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and
+ * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.
+ */
+ constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {
+ assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));
+ _setAdmin(admin_);
+ }
+
+ /**
+ * @dev Emitted when the admin account has changed.
+ */
+ event AdminChanged(address previousAdmin, address newAdmin);
+
+ /**
+ * @dev Storage slot with the admin of the contract.
+ * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
+ * validated in the constructor.
+ */
+ bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
+
+ /**
+ * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.
+ */
+ modifier ifAdmin() {
+ if (msg.sender == _admin()) {
+ _;
+ } else {
+ _fallback();
+ }
+ }
+
+ /**
+ * @dev Returns the current admin.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.
+ *
+ * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
+ * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
+ * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
+ */
+ function admin() external ifAdmin returns (address admin_) {
+ admin_ = _admin();
+ }
+
+ /**
+ * @dev Returns the current implementation.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.
+ *
+ * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
+ * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
+ * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
+ */
+ function implementation() external ifAdmin returns (address implementation_) {
+ implementation_ = _implementation();
+ }
+
+ /**
+ * @dev Changes the admin of the proxy.
+ *
+ * Emits an {AdminChanged} event.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.
+ */
+ function changeAdmin(address newAdmin) external virtual ifAdmin {
+ require(newAdmin != address(0), "TransparentUpgradeableProxy: new admin is the zero address");
+ emit AdminChanged(_admin(), newAdmin);
+ _setAdmin(newAdmin);
+ }
+
+ /**
+ * @dev Upgrade the implementation of the proxy.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.
+ */
+ function upgradeTo(address newImplementation) external virtual ifAdmin {
+ _upgradeTo(newImplementation);
+ }
+
+ /**
+ * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified
+ * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the
+ * proxied contract.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.
+ */
+ function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {
+ _upgradeTo(newImplementation);
+ Address.functionDelegateCall(newImplementation, data);
+ }
+
+ /**
+ * @dev Returns the current admin.
+ */
+ function _admin() internal view virtual returns (address adm) {
+ bytes32 slot = _ADMIN_SLOT;
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ adm := sload(slot)
+ }
+ }
+
+ /**
+ * @dev Stores a new address in the EIP1967 admin slot.
+ */
+ function _setAdmin(address newAdmin) private {
+ bytes32 slot = _ADMIN_SLOT;
+
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ sstore(slot, newAdmin)
+ }
+ }
+
+ /**
+ * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.
+ */
+ function _beforeFallback() internal virtual override {
+ require(msg.sender != _admin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target");
+ super._beforeFallback();
+ }
+}
+
+
+// Root file: contracts/Proxies.sol
+
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol";
+
+contract BridgeProxy is TransparentUpgradeableProxy {
+ // solhint-disable-next-line no-empty-blocks
+ constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}
+}
+
+contract AllowTokensProxy is TransparentUpgradeableProxy {
+ // solhint-disable-next-line no-empty-blocks
+ constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}
+}
+
+contract FederationProxy is TransparentUpgradeableProxy {
+ // solhint-disable-next-line no-empty-blocks
+ constructor(address _logic, address _admin, bytes memory _data) TransparentUpgradeableProxy(_logic,_admin, _data) payable {}
+}
\ No newline at end of file
diff --git a/bridge/flatten/ProxyAdmin.sol b/bridge/flatten/ProxyAdmin.sol
new file mode 100644
index 000000000..61956bf6b
--- /dev/null
+++ b/bridge/flatten/ProxyAdmin.sol
@@ -0,0 +1,707 @@
+// Dependency file: contracts/zeppelin/GSN/Context.sol
+
+// SPDX-License-Identifier: MIT
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/*
+ * @dev Provides information about the current execution context, including the
+ * sender of the transaction and its data. While these are generally available
+ * via msg.sender and msg.data, they should not be accessed in such a direct
+ * manner, since when dealing with GSN meta-transactions the account sending and
+ * paying for execution may not be the actual sender (as far as an application
+ * is concerned).
+ *
+ * This contract is only required for intermediate, library-like contracts.
+ */
+abstract contract Context {
+
+ function _msgSender() internal view returns (address payable) {
+ return payable(msg.sender);
+ }
+
+ function _msgData() internal view returns (bytes memory) {
+ this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
+ return msg.data;
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/ownership/Ownable.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/GSN/Context.sol";
+/**
+ * @dev Contract module which provides a basic access control mechanism, where
+ * there is an account (an owner) that can be granted exclusive access to
+ * specific functions.
+ *
+ * This module is used through inheritance. It will make available the modifier
+ * `onlyOwner`, which can be applied to your functions to restrict their use to
+ * the owner.
+ */
+abstract contract Ownable is Context {
+ address private _owner;
+
+ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
+
+ /**
+ * @dev Initializes the contract setting the deployer as the initial owner.
+ */
+ constructor () {
+ _owner = _msgSender();
+ emit OwnershipTransferred(address(0), _owner);
+ }
+
+ /**
+ * @dev Returns the address of the current owner.
+ */
+ function owner() public view returns (address) {
+ return _owner;
+ }
+
+ /**
+ * @dev Throws if called by any account other than the owner.
+ */
+ modifier onlyOwner() {
+ require(isOwner(), "Ownable: caller is not the owner");
+ _;
+ }
+
+ /**
+ * @dev Returns true if the caller is the current owner.
+ */
+ function isOwner() public view returns (bool) {
+ return _msgSender() == _owner;
+ }
+
+ /**
+ * @dev Leaves the contract without owner. It will not be possible to call
+ * `onlyOwner` functions anymore. Can only be called by the current owner.
+ *
+ * NOTE: Renouncing ownership will leave the contract without an owner,
+ * thereby removing any functionality that is only available to the owner.
+ */
+ function renounceOwnership() public onlyOwner {
+ emit OwnershipTransferred(_owner, address(0));
+ _owner = address(0);
+ }
+
+ /**
+ * @dev Transfers ownership of the contract to a new account (`newOwner`).
+ * Can only be called by the current owner.
+ */
+ function transferOwnership(address newOwner) public onlyOwner {
+ _transferOwnership(newOwner);
+ }
+
+ /**
+ * @dev Transfers ownership of the contract to a new account (`newOwner`).
+ */
+ function _transferOwnership(address newOwner) internal {
+ require(newOwner != address(0), "Ownable: new owner is the zero address");
+ emit OwnershipTransferred(_owner, newOwner);
+ _owner = newOwner;
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/upgradable/proxy/Proxy.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
+ * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
+ * be specified by overriding the virtual {_implementation} function.
+ *
+ * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
+ * different contract through the {_delegate} function.
+ *
+ * The success and return data of the delegated call will be returned back to the caller of the proxy.
+ */
+abstract contract Proxy {
+ /**
+ * @dev Delegates the current call to `implementation`.
+ *
+ * This function does not return to its internall call site, it will return directly to the external caller.
+ */
+ function _delegate(address implementation) internal virtual {
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ // Copy msg.data. We take full control of memory in this inline assembly
+ // block because it will not return to Solidity code. We overwrite the
+ // Solidity scratch pad at memory position 0.
+ calldatacopy(0, 0, calldatasize())
+
+ // Call the implementation.
+ // out and outsize are 0 because we don't know the size yet.
+ let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
+
+ // Copy the returned data.
+ returndatacopy(0, 0, returndatasize())
+
+ switch result
+ // delegatecall returns 0 on error.
+ case 0 { revert(0, returndatasize()) }
+ default { return(0, returndatasize()) }
+ }
+ }
+
+ /**
+ * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function
+ * and {_fallback} should delegate.
+ */
+ function _implementation() internal view virtual returns (address);
+
+ /**
+ * @dev Delegates the current call to the address returned by `_implementation()`.
+ *
+ * This function does not return to its internall call site, it will return directly to the external caller.
+ */
+ function _fallback() internal virtual {
+ _beforeFallback();
+ _delegate(_implementation());
+ }
+
+ /**
+ * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
+ * function in the contract matches the call data.
+ */
+ fallback () external payable virtual {
+ _fallback();
+ }
+
+ /**
+ * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
+ * is empty.
+ */
+ receive () external payable virtual {
+ _fallback();
+ }
+
+ /**
+ * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
+ * call, or as part of the Solidity `fallback` or `receive` functions.
+ *
+ * If overriden should call `super._beforeFallback()`.
+ */
+ function _beforeFallback() internal virtual {
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/utils/Address.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Collection of functions related to the address type
+ */
+library Address {
+ /**
+ * @dev Returns true if `account` is a contract.
+ *
+ * [IMPORTANT]
+ * ====
+ * It is unsafe to assume that an address for which this function returns
+ * false is an externally-owned account (EOA) and not a contract.
+ *
+ * Among others, `isContract` will return false for the following
+ * types of addresses:
+ *
+ * - an externally-owned account
+ * - a contract in construction
+ * - an address where a contract will be created
+ * - an address where a contract lived, but was destroyed
+ * ====
+ */
+ function isContract(address account) internal view returns (bool) {
+ // This method relies on extcodesize, which returns 0 for contracts in
+ // construction, since the code is only stored at the end of the
+ // constructor execution.
+
+ uint256 size;
+ // solhint-disable-next-line no-inline-assembly
+ assembly { size := extcodesize(account) }
+ return size > 0;
+ }
+
+ /**
+ * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
+ * `recipient`, forwarding all available gas and reverting on errors.
+ *
+ * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
+ * of certain opcodes, possibly making contracts go over the 2300 gas limit
+ * imposed by `transfer`, making them unable to receive funds via
+ * `transfer`. {sendValue} removes this limitation.
+ *
+ * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
+ *
+ * IMPORTANT: because control is transferred to `recipient`, care must be
+ * taken to not create reentrancy vulnerabilities. Consider using
+ * {ReentrancyGuard} or the
+ * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
+ */
+ function sendValue(address payable recipient, uint256 amount) internal {
+ require(address(this).balance >= amount, "Address: insufficient balance");
+
+ // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
+ (bool success, ) = recipient.call{ value: amount }("");
+ require(success, "Address: unable to send value, recipient may have reverted");
+ }
+
+ /**
+ * @dev Performs a Solidity function call using a low level `call`. A
+ * plain`call` is an unsafe replacement for a function call: use this
+ * function instead.
+ *
+ * If `target` reverts with a revert reason, it is bubbled up by this
+ * function (like regular Solidity function calls).
+ *
+ * Returns the raw returned data. To convert to the expected return value,
+ * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
+ *
+ * Requirements:
+ *
+ * - `target` must be a contract.
+ * - calling `target` with `data` must not revert.
+ *
+ * _Available since v3.1._
+ */
+ function functionCall(address target, bytes memory data) internal returns (bytes memory) {
+ return functionCall(target, data, "Address: low-level call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
+ * `errorMessage` as a fallback revert reason when `target` reverts.
+ *
+ * _Available since v3.1._
+ */
+ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
+ return functionCallWithValue(target, data, 0, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but also transferring `value` wei to `target`.
+ *
+ * Requirements:
+ *
+ * - the calling contract must have an ETH balance of at least `value`.
+ * - the called Solidity function must be `payable`.
+ *
+ * _Available since v3.1._
+ */
+ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
+ return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
+ * with `errorMessage` as a fallback revert reason when `target` reverts.
+ *
+ * _Available since v3.1._
+ */
+ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
+ require(address(this).balance >= value, "Address: insufficient balance for call");
+ require(isContract(target), "Address: call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.call{ value: value }(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but performing a static call.
+ *
+ * _Available since v3.3._
+ */
+ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
+ return functionStaticCall(target, data, "Address: low-level static call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
+ * but performing a static call.
+ *
+ * _Available since v3.3._
+ */
+ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
+ require(isContract(target), "Address: static call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.staticcall(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but performing a delegate call.
+ *
+ * _Available since v3.4._
+ */
+ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
+ return functionDelegateCall(target, data, "Address: low-level delegate call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
+ * but performing a delegate call.
+ *
+ * _Available since v3.4._
+ */
+ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
+ require(isContract(target), "Address: delegate call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.delegatecall(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
+ if (success) {
+ return returndata;
+ } else {
+ // Look for revert reason and bubble it up if present
+ if (returndata.length > 0) {
+ // The easiest way to bubble the revert reason is using memory via assembly
+
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ let returndata_size := mload(returndata)
+ revert(add(32, returndata), returndata_size)
+ }
+ } else {
+ revert(errorMessage);
+ }
+ }
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/upgradable/proxy/Proxy.sol";
+// import "contracts/zeppelin/utils/Address.sol";
+
+/**
+ * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
+ * implementation address that can be changed. This address is stored in storage in the location specified by
+ * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
+ * implementation behind the proxy.
+ *
+ * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see
+ * {TransparentUpgradeableProxy}.
+ */
+contract UpgradeableProxy is Proxy {
+ /**
+ * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
+ *
+ * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
+ * function call, and allows initializating the storage of the proxy like a Solidity constructor.
+ */
+ constructor(address _logic, bytes memory _data) payable {
+ assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
+ _setImplementation(_logic);
+ if(_data.length > 0) {
+ Address.functionDelegateCall(_logic, _data);
+ }
+ }
+
+ /**
+ * @dev Emitted when the implementation is upgraded.
+ */
+ event Upgraded(address indexed implementation);
+
+ /**
+ * @dev Storage slot with the address of the current implementation.
+ * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
+ * validated in the constructor.
+ */
+ bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
+
+ /**
+ * @dev Returns the current implementation address.
+ */
+ function _implementation() internal view virtual override returns (address impl) {
+ bytes32 slot = _IMPLEMENTATION_SLOT;
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ impl := sload(slot)
+ }
+ }
+
+ /**
+ * @dev Upgrades the proxy to a new implementation.
+ *
+ * Emits an {Upgraded} event.
+ */
+ function _upgradeTo(address newImplementation) internal virtual {
+ _setImplementation(newImplementation);
+ emit Upgraded(newImplementation);
+ }
+
+ /**
+ * @dev Stores a new address in the EIP1967 implementation slot.
+ */
+ function _setImplementation(address newImplementation) private {
+ require(Address.isContract(newImplementation), "UpgradeableProxy: new implementation is not a contract");
+
+ bytes32 slot = _IMPLEMENTATION_SLOT;
+
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ sstore(slot, newImplementation)
+ }
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/upgradable/proxy/UpgradeableProxy.sol";
+
+/**
+ * @dev This contract implements a proxy that is upgradeable by an admin.
+ *
+ * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector
+ * clashing], which can potentially be used in an attack, this contract uses the
+ * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two
+ * things that go hand in hand:
+ *
+ * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if
+ * that call matches one of the admin functions exposed by the proxy itself.
+ * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the
+ * implementation. If the admin tries to call a function on the implementation it will fail with an error that says
+ * "admin cannot fallback to proxy target".
+ *
+ * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing
+ * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due
+ * to sudden errors when trying to call a function from the proxy implementation.
+ *
+ * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,
+ * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.
+ */
+contract TransparentUpgradeableProxy is UpgradeableProxy {
+ /**
+ * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and
+ * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.
+ */
+ constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {
+ assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));
+ _setAdmin(admin_);
+ }
+
+ /**
+ * @dev Emitted when the admin account has changed.
+ */
+ event AdminChanged(address previousAdmin, address newAdmin);
+
+ /**
+ * @dev Storage slot with the admin of the contract.
+ * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
+ * validated in the constructor.
+ */
+ bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
+
+ /**
+ * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.
+ */
+ modifier ifAdmin() {
+ if (msg.sender == _admin()) {
+ _;
+ } else {
+ _fallback();
+ }
+ }
+
+ /**
+ * @dev Returns the current admin.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.
+ *
+ * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
+ * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
+ * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
+ */
+ function admin() external ifAdmin returns (address admin_) {
+ admin_ = _admin();
+ }
+
+ /**
+ * @dev Returns the current implementation.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.
+ *
+ * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
+ * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
+ * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
+ */
+ function implementation() external ifAdmin returns (address implementation_) {
+ implementation_ = _implementation();
+ }
+
+ /**
+ * @dev Changes the admin of the proxy.
+ *
+ * Emits an {AdminChanged} event.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.
+ */
+ function changeAdmin(address newAdmin) external virtual ifAdmin {
+ require(newAdmin != address(0), "TransparentUpgradeableProxy: new admin is the zero address");
+ emit AdminChanged(_admin(), newAdmin);
+ _setAdmin(newAdmin);
+ }
+
+ /**
+ * @dev Upgrade the implementation of the proxy.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.
+ */
+ function upgradeTo(address newImplementation) external virtual ifAdmin {
+ _upgradeTo(newImplementation);
+ }
+
+ /**
+ * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified
+ * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the
+ * proxied contract.
+ *
+ * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.
+ */
+ function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {
+ _upgradeTo(newImplementation);
+ Address.functionDelegateCall(newImplementation, data);
+ }
+
+ /**
+ * @dev Returns the current admin.
+ */
+ function _admin() internal view virtual returns (address adm) {
+ bytes32 slot = _ADMIN_SLOT;
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ adm := sload(slot)
+ }
+ }
+
+ /**
+ * @dev Stores a new address in the EIP1967 admin slot.
+ */
+ function _setAdmin(address newAdmin) private {
+ bytes32 slot = _ADMIN_SLOT;
+
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ sstore(slot, newAdmin)
+ }
+ }
+
+ /**
+ * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.
+ */
+ function _beforeFallback() internal virtual override {
+ require(msg.sender != _admin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target");
+ super._beforeFallback();
+ }
+}
+
+
+// Root file: contracts/zeppelin/upgradable/proxy/ProxyAdmin.sol
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/ownership/Ownable.sol";
+// import "contracts/zeppelin/upgradable/proxy/TransparentUpgradeableProxy.sol";
+
+/**
+ * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an
+ * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.
+ */
+contract ProxyAdmin is Ownable {
+
+ /**
+ * @dev Returns the current implementation of `proxy`.
+ *
+ * Requirements:
+ *
+ * - This contract must be the admin of `proxy`.
+ */
+ function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {
+ // We need to manually run the static call since the getter cannot be flagged as view
+ // bytes4(keccak256("implementation()")) == 0x5c60da1b
+ (bool success, bytes memory returndata) = address(proxy).staticcall(hex"5c60da1b");
+ require(success);
+ return abi.decode(returndata, (address));
+ }
+
+ /**
+ * @dev Returns the current admin of `proxy`.
+ *
+ * Requirements:
+ *
+ * - This contract must be the admin of `proxy`.
+ */
+ function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {
+ // We need to manually run the static call since the getter cannot be flagged as view
+ // bytes4(keccak256("admin()")) == 0xf851a440
+ (bool success, bytes memory returndata) = address(proxy).staticcall(hex"f851a440");
+ require(success);
+ return abi.decode(returndata, (address));
+ }
+
+ /**
+ * @dev Changes the admin of `proxy` to `newAdmin`.
+ *
+ * Requirements:
+ *
+ * - This contract must be the current admin of `proxy`.
+ */
+ function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {
+ proxy.changeAdmin(newAdmin);
+ }
+
+ /**
+ * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.
+ *
+ * Requirements:
+ *
+ * - This contract must be the admin of `proxy`.
+ */
+ function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {
+ proxy.upgradeTo(implementation);
+ }
+
+ /**
+ * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See
+ * {TransparentUpgradeableProxy-upgradeToAndCall}.
+ *
+ * Requirements:
+ *
+ * - This contract must be the admin of `proxy`.
+ */
+ function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {
+ proxy.upgradeToAndCall{value: msg.value}(implementation, data);
+ }
+}
diff --git a/bridge/flatten/SideToken.sol b/bridge/flatten/SideToken.sol
new file mode 100644
index 000000000..d40b51642
--- /dev/null
+++ b/bridge/flatten/SideToken.sol
@@ -0,0 +1,1557 @@
+// Dependency file: contracts/zeppelin/GSN/Context.sol
+
+// SPDX-License-Identifier: MIT
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/*
+ * @dev Provides information about the current execution context, including the
+ * sender of the transaction and its data. While these are generally available
+ * via msg.sender and msg.data, they should not be accessed in such a direct
+ * manner, since when dealing with GSN meta-transactions the account sending and
+ * paying for execution may not be the actual sender (as far as an application
+ * is concerned).
+ *
+ * This contract is only required for intermediate, library-like contracts.
+ */
+abstract contract Context {
+
+ function _msgSender() internal view returns (address payable) {
+ return payable(msg.sender);
+ }
+
+ function _msgData() internal view returns (bytes memory) {
+ this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
+ return msg.data;
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/token/ERC777/IERC777.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface of the ERC777Token standard as defined in the EIP.
+ *
+ * This contract uses the
+ * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let
+ * token holders and recipients react to token movements by using setting implementers
+ * for the associated interfaces in said registry. See `IERC1820Registry` and
+ * `ERC1820Implementer`.
+ */
+interface IERC777 {
+ /**
+ * @dev Returns the name of the token.
+ */
+ function name() external view returns (string memory);
+
+ /**
+ * @dev Returns the symbol of the token, usually a shorter version of the
+ * name.
+ */
+ function symbol() external view returns (string memory);
+
+ /**
+ * @dev Returns the smallest part of the token that is not divisible. This
+ * means all token operations (creation, movement and destruction) must have
+ * amounts that are a multiple of this number.
+ *
+ * For most token contracts, this value will equal 1.
+ */
+ function granularity() external view returns (uint256);
+
+ /**
+ * @dev Returns the amount of tokens in existence.
+ */
+ function totalSupply() external view returns (uint256);
+
+ /**
+ * @dev Returns the amount of tokens owned by an account (`owner`).
+ */
+ function balanceOf(address owner) external view returns (uint256);
+
+ /**
+ * @dev Moves `amount` tokens from the caller's account to `recipient`.
+ *
+ * If send or receive hooks are registered for the caller and `recipient`,
+ * the corresponding functions will be called with `data` and empty
+ * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.
+ *
+ * Emits a `Sent` event.
+ *
+ * Requirements
+ *
+ * - the caller must have at least `amount` tokens.
+ * - `recipient` cannot be the zero address.
+ * - if `recipient` is a contract, it must implement the `tokensReceived`
+ * interface.
+ */
+ function send(address recipient, uint256 amount, bytes calldata data) external;
+
+ /**
+ * @dev Destroys `amount` tokens from the caller's account, reducing the
+ * total supply.
+ *
+ * If a send hook is registered for the caller, the corresponding function
+ * will be called with `data` and empty `operatorData`. See `IERC777Sender`.
+ *
+ * Emits a `Burned` event.
+ *
+ * Requirements
+ *
+ * - the caller must have at least `amount` tokens.
+ */
+ function burn(uint256 amount, bytes calldata data) external;
+
+ /**
+ * @dev Returns true if an account is an operator of `tokenHolder`.
+ * Operators can send and burn tokens on behalf of their owners. All
+ * accounts are their own operator.
+ *
+ * See `operatorSend` and `operatorBurn`.
+ */
+ function isOperatorFor(address operator, address tokenHolder) external view returns (bool);
+
+ /**
+ * @dev Make an account an operator of the caller.
+ *
+ * See `isOperatorFor`.
+ *
+ * Emits an `AuthorizedOperator` event.
+ *
+ * Requirements
+ *
+ * - `operator` cannot be calling address.
+ */
+ function authorizeOperator(address operator) external;
+
+ /**
+ * @dev Make an account an operator of the caller.
+ *
+ * See `isOperatorFor` and `defaultOperators`.
+ *
+ * Emits a `RevokedOperator` event.
+ *
+ * Requirements
+ *
+ * - `operator` cannot be calling address.
+ */
+ function revokeOperator(address operator) external;
+
+ /**
+ * @dev Returns the list of default operators. These accounts are operators
+ * for all token holders, even if `authorizeOperator` was never called on
+ * them.
+ *
+ * This list is immutable, but individual holders may revoke these via
+ * `revokeOperator`, in which case `isOperatorFor` will return false.
+ */
+ function defaultOperators() external view returns (address[] memory);
+
+ /**
+ * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must
+ * be an operator of `sender`.
+ *
+ * If send or receive hooks are registered for `sender` and `recipient`,
+ * the corresponding functions will be called with `data` and
+ * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.
+ *
+ * Emits a `Sent` event.
+ *
+ * Requirements
+ *
+ * - `sender` cannot be the zero address.
+ * - `sender` must have at least `amount` tokens.
+ * - the caller must be an operator for `sender`.
+ * - `recipient` cannot be the zero address.
+ * - if `recipient` is a contract, it must implement the `tokensReceived`
+ * interface.
+ */
+ function operatorSend(
+ address sender,
+ address recipient,
+ uint256 amount,
+ bytes calldata data,
+ bytes calldata operatorData
+ ) external;
+
+ /**
+ * @dev Destoys `amount` tokens from `account`, reducing the total supply.
+ * The caller must be an operator of `account`.
+ *
+ * If a send hook is registered for `account`, the corresponding function
+ * will be called with `data` and `operatorData`. See `IERC777Sender`.
+ *
+ * Emits a `Burned` event.
+ *
+ * Requirements
+ *
+ * - `account` cannot be the zero address.
+ * - `account` must have at least `amount` tokens.
+ * - the caller must be an operator for `account`.
+ */
+ function operatorBurn(
+ address account,
+ uint256 amount,
+ bytes calldata data,
+ bytes calldata operatorData
+ ) external;
+
+ event Sent(
+ address indexed operator,
+ address indexed from,
+ address indexed to,
+ uint256 amount,
+ bytes data,
+ bytes operatorData
+ );
+
+ function decimals() external returns (uint8);
+
+ event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
+
+ event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);
+
+ event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
+
+ event RevokedOperator(address indexed operator, address indexed tokenHolder);
+}
+
+
+// Dependency file: contracts/zeppelin/token/ERC777/IERC777Recipient.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.
+ *
+ * Accounts can be notified of `IERC777` tokens being sent to them by having a
+ * contract implement this interface (contract holders can be their own
+ * implementer) and registering it on the
+ * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).
+ *
+ * See `IERC1820Registry` and `ERC1820Implementer`.
+ */
+interface IERC777Recipient {
+ /**
+ * @dev Called by an `IERC777` token contract whenever tokens are being
+ * moved or created into a registered account (`to`). The type of operation
+ * is conveyed by `from` being the zero address or not.
+ *
+ * This call occurs _after_ the token contract's state is updated, so
+ * `IERC777.balanceOf`, etc., can be used to query the post-operation state.
+ *
+ * This function may revert to prevent the operation from being executed.
+ */
+ function tokensReceived(
+ address operator,
+ address from,
+ address to,
+ uint amount,
+ bytes calldata userData,
+ bytes calldata operatorData
+ ) external;
+}
+
+
+// Dependency file: contracts/zeppelin/token/ERC777/IERC777Sender.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface of the ERC777TokensSender standard as defined in the EIP.
+ *
+ * `IERC777` Token holders can be notified of operations performed on their
+ * tokens by having a contract implement this interface (contract holders can be
+ * their own implementer) and registering it on the
+ * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).
+ *
+ * See `IERC1820Registry` and `ERC1820Implementer`.
+ */
+interface IERC777Sender {
+ /**
+ * @dev Called by an `IERC777` token contract whenever a registered holder's
+ * (`from`) tokens are about to be moved or destroyed. The type of operation
+ * is conveyed by `to` being the zero address or not.
+ *
+ * This call occurs _before_ the token contract's state is updated, so
+ * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.
+ *
+ * This function may revert to prevent the operation from being executed.
+ */
+ function tokensToSend(
+ address operator,
+ address from,
+ address to,
+ uint amount,
+ bytes calldata userData,
+ bytes calldata operatorData
+ ) external;
+}
+
+
+// Dependency file: contracts/zeppelin/token/ERC20/IERC20.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
+ * the optional functions; to access them see {ERC20Detailed}.
+ */
+interface IERC20 {
+ /**
+ * @dev Returns the amount of tokens in existence.
+ */
+ function totalSupply() external view returns (uint256);
+
+ /**
+ * @dev Returns the amount of tokens owned by `account`.
+ */
+ function balanceOf(address account) external view returns (uint256);
+
+ /**
+ * @dev Moves `amount` tokens from the caller's account to `recipient`.
+ *
+ * Returns a boolean value indicating whether the operation succeeded.
+ *
+ * Emits a {Transfer} event.
+ */
+ function transfer(address recipient, uint256 amount) external returns (bool);
+
+ /**
+ * @dev Returns the remaining number of tokens that `spender` will be
+ * allowed to spend on behalf of `owner` through {transferFrom}. This is
+ * zero by default.
+ *
+ * This value changes when {approve} or {transferFrom} are called.
+ */
+ function allowance(address owner, address spender) external view returns (uint256);
+
+ /**
+ * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
+ *
+ * Returns a boolean value indicating whether the operation succeeded.
+ *
+ * IMPORTANT: Beware that changing an allowance with this method brings the risk
+ * that someone may use both the old and the new allowance by unfortunate
+ * transaction ordering. One possible solution to mitigate this race
+ * condition is to first reduce the spender's allowance to 0 and set the
+ * desired value afterwards:
+ * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
+ *
+ * Emits an {Approval} event.
+ */
+ function approve(address spender, uint256 amount) external returns (bool);
+
+ /**
+ * @dev Moves `amount` tokens from `sender` to `recipient` using the
+ * allowance mechanism. `amount` is then deducted from the caller's
+ * allowance.
+ *
+ * Returns a boolean value indicating whether the operation succeeded.
+ *
+ * Emits a {Transfer} event.
+ */
+ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
+
+ /**
+ * @dev Emitted when `value` tokens are moved from one account (`from`) to
+ * another (`to`).
+ *
+ * Note that `value` may be zero.
+ */
+ event Transfer(address indexed from, address indexed to, uint256 value);
+
+ /**
+ * @dev Emitted when the allowance of a `spender` for an `owner` is set by
+ * a call to {approve}. `value` is the new allowance.
+ */
+ event Approval(address indexed owner, address indexed spender, uint256 value);
+}
+
+
+// Dependency file: contracts/zeppelin/math/SafeMath.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Wrappers over Solidity's arithmetic operations with added overflow
+ * checks.
+ *
+ * Arithmetic operations in Solidity wrap on overflow. This can easily result
+ * in bugs, because programmers usually assume that an overflow raises an
+ * error, which is the standard behavior in high level programming languages.
+ * `SafeMath` restores this intuition by reverting the transaction when an
+ * operation overflows.
+ *
+ * Using this library instead of the unchecked operations eliminates an entire
+ * class of bugs, so it's recommended to use it always.
+ */
+library SafeMath {
+ /**
+ * @dev Returns the addition of two unsigned integers, reverting on
+ * overflow.
+ *
+ * Counterpart to Solidity's `+` operator.
+ *
+ * Requirements:
+ * - Addition cannot overflow.
+ */
+ function add(uint256 a, uint256 b) internal pure returns (uint256) {
+ uint256 c = a + b;
+ require(c >= a, "SafeMath: addition overflow");
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the subtraction of two unsigned integers, reverting on
+ * overflow (when the result is negative).
+ *
+ * Counterpart to Solidity's `-` operator.
+ *
+ * Requirements:
+ * - Subtraction cannot overflow.
+ */
+ function sub(uint256 a, uint256 b) internal pure returns (uint256) {
+ return sub(a, b, "SafeMath: subtraction overflow");
+ }
+
+ /**
+ * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
+ * overflow (when the result is negative).
+ *
+ * Counterpart to Solidity's `-` operator.
+ *
+ * Requirements:
+ * - Subtraction cannot overflow.
+ *
+ * _Available since v2.4.0._
+ */
+ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
+ require(b <= a, errorMessage);
+ uint256 c = a - b;
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the multiplication of two unsigned integers, reverting on
+ * overflow.
+ *
+ * Counterpart to Solidity's `*` operator.
+ *
+ * Requirements:
+ * - Multiplication cannot overflow.
+ */
+ function mul(uint256 a, uint256 b) internal pure returns (uint256) {
+ // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
+ // benefit is lost if 'b' is also tested.
+ // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
+ if (a == 0) {
+ return 0;
+ }
+
+ uint256 c = a * b;
+ require(c / a == b, "SafeMath: multiplication overflow");
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the integer division of two unsigned integers. Reverts on
+ * division by zero. The result is rounded towards zero.
+ *
+ * Counterpart to Solidity's `/` operator. Note: this function uses a
+ * `revert` opcode (which leaves remaining gas untouched) while Solidity
+ * uses an invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ */
+ function div(uint256 a, uint256 b) internal pure returns (uint256) {
+ return div(a, b, "SafeMath: division by zero");
+ }
+
+ /**
+ * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
+ * division by zero. The result is rounded towards zero.
+ *
+ * Counterpart to Solidity's `/` operator. Note: this function uses a
+ * `revert` opcode (which leaves remaining gas untouched) while Solidity
+ * uses an invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ *
+ * _Available since v2.4.0._
+ */
+ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
+ // Solidity only automatically asserts when dividing by 0
+ require(b > 0, errorMessage);
+ uint256 c = a / b;
+ // assert(a == b * c + a % b); // There is no case in which this doesn't hold
+
+ return c;
+ }
+
+ /**
+ * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
+ * Reverts when dividing by zero.
+ *
+ * Counterpart to Solidity's `%` operator. This function uses a `revert`
+ * opcode (which leaves remaining gas untouched) while Solidity uses an
+ * invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ */
+ function mod(uint256 a, uint256 b) internal pure returns (uint256) {
+ return mod(a, b, "SafeMath: modulo by zero");
+ }
+
+ /**
+ * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
+ * Reverts with custom message when dividing by zero.
+ *
+ * Counterpart to Solidity's `%` operator. This function uses a `revert`
+ * opcode (which leaves remaining gas untouched) while Solidity uses an
+ * invalid opcode to revert (consuming all remaining gas).
+ *
+ * Requirements:
+ * - The divisor cannot be zero.
+ *
+ * _Available since v2.4.0._
+ */
+ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
+ require(b != 0, errorMessage);
+ return a % b;
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/utils/Address.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Collection of functions related to the address type
+ */
+library Address {
+ /**
+ * @dev Returns true if `account` is a contract.
+ *
+ * [IMPORTANT]
+ * ====
+ * It is unsafe to assume that an address for which this function returns
+ * false is an externally-owned account (EOA) and not a contract.
+ *
+ * Among others, `isContract` will return false for the following
+ * types of addresses:
+ *
+ * - an externally-owned account
+ * - a contract in construction
+ * - an address where a contract will be created
+ * - an address where a contract lived, but was destroyed
+ * ====
+ */
+ function isContract(address account) internal view returns (bool) {
+ // This method relies on extcodesize, which returns 0 for contracts in
+ // construction, since the code is only stored at the end of the
+ // constructor execution.
+
+ uint256 size;
+ // solhint-disable-next-line no-inline-assembly
+ assembly { size := extcodesize(account) }
+ return size > 0;
+ }
+
+ /**
+ * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
+ * `recipient`, forwarding all available gas and reverting on errors.
+ *
+ * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
+ * of certain opcodes, possibly making contracts go over the 2300 gas limit
+ * imposed by `transfer`, making them unable to receive funds via
+ * `transfer`. {sendValue} removes this limitation.
+ *
+ * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
+ *
+ * IMPORTANT: because control is transferred to `recipient`, care must be
+ * taken to not create reentrancy vulnerabilities. Consider using
+ * {ReentrancyGuard} or the
+ * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
+ */
+ function sendValue(address payable recipient, uint256 amount) internal {
+ require(address(this).balance >= amount, "Address: insufficient balance");
+
+ // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
+ (bool success, ) = recipient.call{ value: amount }("");
+ require(success, "Address: unable to send value, recipient may have reverted");
+ }
+
+ /**
+ * @dev Performs a Solidity function call using a low level `call`. A
+ * plain`call` is an unsafe replacement for a function call: use this
+ * function instead.
+ *
+ * If `target` reverts with a revert reason, it is bubbled up by this
+ * function (like regular Solidity function calls).
+ *
+ * Returns the raw returned data. To convert to the expected return value,
+ * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
+ *
+ * Requirements:
+ *
+ * - `target` must be a contract.
+ * - calling `target` with `data` must not revert.
+ *
+ * _Available since v3.1._
+ */
+ function functionCall(address target, bytes memory data) internal returns (bytes memory) {
+ return functionCall(target, data, "Address: low-level call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
+ * `errorMessage` as a fallback revert reason when `target` reverts.
+ *
+ * _Available since v3.1._
+ */
+ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
+ return functionCallWithValue(target, data, 0, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but also transferring `value` wei to `target`.
+ *
+ * Requirements:
+ *
+ * - the calling contract must have an ETH balance of at least `value`.
+ * - the called Solidity function must be `payable`.
+ *
+ * _Available since v3.1._
+ */
+ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
+ return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
+ * with `errorMessage` as a fallback revert reason when `target` reverts.
+ *
+ * _Available since v3.1._
+ */
+ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
+ require(address(this).balance >= value, "Address: insufficient balance for call");
+ require(isContract(target), "Address: call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.call{ value: value }(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but performing a static call.
+ *
+ * _Available since v3.3._
+ */
+ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
+ return functionStaticCall(target, data, "Address: low-level static call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
+ * but performing a static call.
+ *
+ * _Available since v3.3._
+ */
+ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
+ require(isContract(target), "Address: static call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.staticcall(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
+ * but performing a delegate call.
+ *
+ * _Available since v3.4._
+ */
+ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
+ return functionDelegateCall(target, data, "Address: low-level delegate call failed");
+ }
+
+ /**
+ * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
+ * but performing a delegate call.
+ *
+ * _Available since v3.4._
+ */
+ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
+ require(isContract(target), "Address: delegate call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.delegatecall(data);
+ return _verifyCallResult(success, returndata, errorMessage);
+ }
+
+ function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
+ if (success) {
+ return returndata;
+ } else {
+ // Look for revert reason and bubble it up if present
+ if (returndata.length > 0) {
+ // The easiest way to bubble the revert reason is using memory via assembly
+
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ let returndata_size := mload(returndata)
+ revert(add(32, returndata), returndata_size)
+ }
+ } else {
+ revert(errorMessage);
+ }
+ }
+ }
+}
+
+
+// Dependency file: contracts/zeppelin/introspection/IERC1820Registry.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+/**
+ * @dev Interface of the global ERC1820 Registry, as defined in the
+ * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register
+ * implementers for interfaces in this registry, as well as query support.
+ *
+ * Implementers may be shared by multiple accounts, and can also implement more
+ * than a single interface for each account. Contracts can implement interfaces
+ * for themselves, but externally-owned accounts (EOA) must delegate this to a
+ * contract.
+ *
+ * {IERC165} interfaces can also be queried via the registry.
+ *
+ * For an in-depth explanation and source code analysis, see the EIP text.
+ */
+interface IERC1820Registry {
+ /**
+ * @dev Sets `newManager` as the manager for `account`. A manager of an
+ * account is able to set interface implementers for it.
+ *
+ * By default, each account is its own manager. Passing a value of `0x0` in
+ * `newManager` will reset the manager to this initial state.
+ *
+ * Emits a {ManagerChanged} event.
+ *
+ * Requirements:
+ *
+ * - the caller must be the current manager for `account`.
+ */
+ function setManager(address account, address newManager) external;
+
+ /**
+ * @dev Returns the manager for `account`.
+ *
+ * See {setManager}.
+ */
+ function getManager(address account) external view returns (address);
+
+ /**
+ * @dev Sets the `implementer` contract as `account`'s implementer for
+ * `interfaceHash`.
+ *
+ * `account` being the zero address is an alias for the caller's address.
+ * The zero address can also be used in `implementer` to remove an old one.
+ *
+ * See {interfaceHash} to learn how these are created.
+ *
+ * Emits an {InterfaceImplementerSet} event.
+ *
+ * Requirements:
+ *
+ * - the caller must be the current manager for `_account`.
+ * - `_interfaceHash` must not be an {IERC165} interface id (i.e. it must not
+ * end in 28 zeroes).
+ * - `_implementer` must implement {IERC1820Implementer} and return true when
+ * queried for support, unless `implementer` is the caller. See
+ * {IERC1820Implementer-canImplementInterfaceForAddress}.
+ */
+ function setInterfaceImplementer(address _account, bytes32 _interfaceHash, address _implementer) external;
+
+ /**
+ * @dev Returns the implementer of `_interfaceHash` for `_account`. If no such
+ * implementer is registered, returns the zero address.
+ *
+ * If `_interfaceHash` is an {IERC165} interface id (i.e. it ends with 28
+ * zeroes), `_account` will be queried for support of it.
+ *
+ * `account` being the zero address is an alias for the caller's address.
+ */
+ function getInterfaceImplementer(address _account, bytes32 _interfaceHash) external view returns (address);
+
+ /**
+ * @dev Returns the interface hash for an `interfaceName`, as defined in the
+ * corresponding
+ * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].
+ */
+ function interfaceHash(string calldata interfaceName) external pure returns (bytes32);
+
+ /**
+ * @notice Updates the cache with whether the contract implements an ERC165 interface or not.
+ * @param account Address of the contract for which to update the cache.
+ * @param interfaceId ERC165 interface for which to update the cache.
+ */
+ function updateERC165Cache(address account, bytes4 interfaceId) external;
+
+ /**
+ * @notice Checks whether a contract implements an ERC165 interface or not.
+ * If the result is not cached a direct lookup on the contract address is performed.
+ * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling
+ * {updateERC165Cache} with the contract address.
+ * @param account Address of the contract to check.
+ * @param interfaceId ERC165 interface to check.
+ * @return True if `account` implements `interfaceId`, false otherwise.
+ */
+ function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);
+
+ /**
+ * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.
+ * @param account Address of the contract to check.
+ * @param interfaceId ERC165 interface to check.
+ * @return True if `account` implements `interfaceId`, false otherwise.
+ */
+ function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);
+
+ event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);
+
+ event ManagerChanged(address indexed account, address indexed newManager);
+}
+
+
+// Dependency file: contracts/zeppelin/token/ERC777/ERC777.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/GSN/Context.sol";
+// import "contracts/zeppelin/token/ERC777/IERC777.sol";
+// import "contracts/zeppelin/token/ERC777/IERC777Recipient.sol";
+// import "contracts/zeppelin/token/ERC777/IERC777Sender.sol";
+// import "contracts/zeppelin/token/ERC20/IERC20.sol";
+// import "contracts/zeppelin/math/SafeMath.sol";
+// import "contracts/zeppelin/utils/Address.sol";
+// import "contracts/zeppelin/introspection/IERC1820Registry.sol";
+
+/**
+ * @dev Implementation of the {IERC777} interface.
+ *
+ * This implementation is agnostic to the way tokens are created. This means
+ * that a supply mechanism has to be added in a derived contract using {_mint}.
+ *
+ * Support for ERC20 is included in this contract, as specified by the EIP: both
+ * the ERC777 and ERC20 interfaces can be safely used when interacting with it.
+ * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token
+ * movements.
+ *
+ * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there
+ * are no special restrictions in the amount of tokens that created, moved, or
+ * destroyed. This makes integration with ERC20 applications seamless.
+ */
+contract ERC777 is Context, IERC777, IERC20 {
+ using SafeMath for uint256;
+ using Address for address;
+
+ IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
+
+ mapping(address => uint256) private _balances;
+
+ uint256 private _totalSupply;
+
+ string private _name;
+ string private _symbol;
+
+ // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.
+ // See https://github.com/ethereum/solidity/issues/4024.
+
+ // keccak256("ERC777TokensSender")
+ bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =
+ 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;
+
+ // keccak256("ERC777TokensRecipient")
+ bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =
+ 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;
+
+ // This isn't ever read from - it's only used to respond to the defaultOperators query.
+ address[] private _defaultOperatorsArray;
+
+ // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).
+ mapping(address => bool) private _defaultOperators;
+
+ // For each account, a mapping of its operators and revoked default operators.
+ mapping(address => mapping(address => bool)) private _operators;
+ mapping(address => mapping(address => bool)) private _revokedDefaultOperators;
+
+ // ERC20-allowances
+ mapping (address => mapping (address => uint256)) private _allowances;
+
+ /**
+ * @dev `defaultOperators` may be an empty array.
+ */
+ constructor(
+ string memory aName,
+ string memory aSymbol,
+ address[] memory theDefaultOperators
+ ) {
+ _name = aName;
+ _symbol = aSymbol;
+
+ _defaultOperatorsArray = theDefaultOperators;
+ for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {
+ _defaultOperators[_defaultOperatorsArray[i]] = true;
+ }
+
+ // register interfaces
+ _erc1820.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this));
+ _erc1820.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this));
+ }
+
+ /**
+ * @dev See {IERC777-name}.
+ */
+ function name() public view override(IERC777) returns (string memory) {
+ return _name;
+ }
+
+ /**
+ * @dev See {IERC777-symbol}.
+ */
+ function symbol() public view override(IERC777) returns (string memory) {
+ return _symbol;
+ }
+
+ /**
+ * @dev See {ERC20Detailed-decimals}.
+ *
+ * Always returns 18, as per the
+ * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).
+ */
+ function decimals() public pure override returns (uint8) {
+ return 18;
+ }
+
+ /**
+ * @dev See {IERC777-granularity}.
+ *
+ * This implementation always returns `1`.
+ */
+ function granularity() public view virtual override(IERC777) returns (uint256) {
+ return 1;
+ }
+
+ /**
+ * @dev See {IERC777-totalSupply}.
+ */
+ function totalSupply() public view override(IERC20, IERC777) returns (uint256) {
+ return _totalSupply;
+ }
+
+ /**
+ * @dev Returns the amount of tokens owned by an account (`tokenHolder`).
+ */
+ function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {
+ return _balances[tokenHolder];
+ }
+
+ /**
+ * @dev See {IERC777-send}.
+ *
+ * Also emits a {Transfer} event for ERC20 compatibility.
+ */
+ function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777) {
+ _send(_msgSender(), _msgSender(), recipient, amount, data, "", true);
+ }
+
+ /**
+ * @dev See {IERC20-transfer}.
+ *
+ * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}
+ * interface if it is a contract.
+ *
+ * Also emits a {Sent} event.
+ */
+ function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool) {
+ require(recipient != address(0), "ERC777: transfer to zero address");
+
+ address from = _msgSender();
+
+ _callTokensToSend(from, from, recipient, amount, "", "");
+
+ _move(from, from, recipient, amount, "", "");
+
+ _callTokensReceived(from, from, recipient, amount, "", "", false);
+
+ return true;
+ }
+
+ /**
+ * @dev See {IERC777-burn}.
+ *
+ * Also emits a {Transfer} event for ERC20 compatibility.
+ */
+ function burn(uint256 amount, bytes calldata data) external override(IERC777) {
+ _burn(_msgSender(), _msgSender(), amount, data, "");
+ }
+
+ /**
+ * @dev See {IERC777-isOperatorFor}.
+ */
+ function isOperatorFor(
+ address operator,
+ address tokenHolder
+ ) public view override(IERC777) returns (bool) {
+ return operator == tokenHolder ||
+ (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||
+ _operators[tokenHolder][operator];
+ }
+
+ /**
+ * @dev See {IERC777-authorizeOperator}.
+ */
+ function authorizeOperator(address operator) external override(IERC777) {
+ require(_msgSender() != operator, "ERC777: authorizing self as operator");
+
+ if (_defaultOperators[operator]) {
+ delete _revokedDefaultOperators[_msgSender()][operator];
+ } else {
+ _operators[_msgSender()][operator] = true;
+ }
+
+ emit AuthorizedOperator(operator, _msgSender());
+ }
+
+ /**
+ * @dev See {IERC777-revokeOperator}.
+ */
+ function revokeOperator(address operator) external override(IERC777) {
+ require(operator != _msgSender(), "ERC777: revoking self as operator");
+
+ if (_defaultOperators[operator]) {
+ _revokedDefaultOperators[_msgSender()][operator] = true;
+ } else {
+ delete _operators[_msgSender()][operator];
+ }
+
+ emit RevokedOperator(operator, _msgSender());
+ }
+
+ /**
+ * @dev See {IERC777-defaultOperators}.
+ */
+ function defaultOperators() public view override(IERC777) returns (address[] memory) {
+ return _defaultOperatorsArray;
+ }
+
+ /**
+ * @dev See {IERC777-operatorSend}.
+ *
+ * Emits {Sent} and {Transfer} events.
+ */
+ function operatorSend(
+ address sender,
+ address recipient,
+ uint256 amount,
+ bytes calldata data,
+ bytes calldata operatorData
+ )
+ external override(IERC777)
+ {
+ require(isOperatorFor(_msgSender(), sender), "ERC777: caller is not an operator");
+ _send(_msgSender(), sender, recipient, amount, data, operatorData, true);
+ }
+
+ /**
+ * @dev See {IERC777-operatorBurn}.
+ *
+ * Emits {Burned} and {Transfer} events.
+ */
+ function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData)
+ external override(IERC777) {
+ require(isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator");
+ _burn(_msgSender(), account, amount, data, operatorData);
+ }
+
+ /**
+ * @dev See {IERC20-allowance}.
+ *
+ * Note that operator and allowance concepts are orthogonal: operators may
+ * not have allowance, and accounts with allowance may not be operators
+ * themselves.
+ */
+ function allowance(address holder, address spender)
+ public view override(IERC20) returns (uint256) {
+ return _allowances[holder][spender];
+ }
+
+ /**
+ * @dev See {IERC20-approve}.
+ *
+ * Note that accounts cannot have allowance issued by their operators.
+ */
+ function approve(address spender, uint256 value) external override(IERC20) returns (bool) {
+ address holder = _msgSender();
+ _approve(holder, spender, value);
+ return true;
+ }
+
+ /**
+ * @dev See {IERC20-transferFrom}.
+ *
+ * Note that operator and allowance concepts are orthogonal: operators cannot
+ * call `transferFrom` (unless they have allowance), and accounts with
+ * allowance cannot call `operatorSend` (unless they are operators).
+ *
+ * Emits {Sent}, {Transfer} and {Approval} events.
+ */
+ function transferFrom(address holder, address recipient, uint256 amount)
+ external override(IERC20) returns (bool) {
+ require(recipient != address(0), "ERC777: transfer to zero address");
+ require(holder != address(0), "ERC777: transfer from zero address");
+
+ address spender = _msgSender();
+
+ _callTokensToSend(spender, holder, recipient, amount, "", "");
+
+ _move(spender, holder, recipient, amount, "", "");
+ _approve(holder, spender, _allowances[holder][spender].sub(amount, "ERC777: transfer amount exceeds allowance"));
+
+ _callTokensReceived(spender, holder, recipient, amount, "", "", false);
+
+ return true;
+ }
+
+ /**
+ * @dev Creates `amount` tokens and assigns them to `account`, increasing
+ * the total supply.
+ *
+ * If a send hook is registered for `account`, the corresponding function
+ * will be called with `operator`, `data` and `operatorData`.
+ *
+ * See {IERC777Sender} and {IERC777Recipient}.
+ *
+ * Emits {Minted} and {Transfer} events.
+ *
+ * Requirements
+ *
+ * - `account` cannot be the zero address.
+ * - if `account` is a contract, it must implement the {IERC777Recipient}
+ * interface.
+ */
+ function _mint(
+ address operator,
+ address account,
+ uint256 amount,
+ bytes memory userData,
+ bytes memory operatorData
+ )
+ internal
+ {
+ require(account != address(0), "ERC777: mint to zero address");
+
+ // Update state variables
+ _totalSupply = _totalSupply.add(amount);
+ _balances[account] = _balances[account].add(amount);
+
+ _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);
+
+ emit Minted(operator, account, amount, userData, operatorData);
+ emit Transfer(address(0), account, amount);
+ }
+
+ /**
+ * @dev Send tokens
+ * @param operator address operator requesting the transfer
+ * @param from address token holder address
+ * @param to address recipient address
+ * @param amount uint256 amount of tokens to transfer
+ * @param userData bytes extra information provided by the token holder (if any)
+ * @param operatorData bytes extra information provided by the operator (if any)
+ * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
+ */
+ function _send(
+ address operator,
+ address from,
+ address to,
+ uint256 amount,
+ bytes memory userData,
+ bytes memory operatorData,
+ bool requireReceptionAck
+ )
+ internal
+ {
+ require(from != address(0), "ERC777: send from zero address");
+ require(to != address(0), "ERC777: send to zero address");
+
+ _callTokensToSend(operator, from, to, amount, userData, operatorData);
+
+ _move(operator, from, to, amount, userData, operatorData);
+
+ _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);
+ }
+
+ /**
+ * @dev Burn tokens
+ * @param operator address operator requesting the operation
+ * @param from address token holder address
+ * @param amount uint256 amount of tokens to burn
+ * @param data bytes extra information provided by the token holder
+ * @param operatorData bytes extra information provided by the operator (if any)
+ */
+ function _burn(
+ address operator,
+ address from,
+ uint256 amount,
+ bytes memory data,
+ bytes memory operatorData
+ )
+ internal
+ {
+ require(from != address(0), "ERC777: burn from zero address");
+
+ _callTokensToSend(operator, from, address(0), amount, data, operatorData);
+
+ // Update state variables
+ _balances[from] = _balances[from].sub(amount, "ERC777: burn amount exceeds balance");
+ _totalSupply = _totalSupply.sub(amount);
+
+ emit Burned(operator, from, amount, data, operatorData);
+ emit Transfer(from, address(0), amount);
+ }
+
+ function _move(
+ address operator,
+ address from,
+ address to,
+ uint256 amount,
+ bytes memory userData,
+ bytes memory operatorData
+ )
+ internal
+ {
+ _balances[from] = _balances[from].sub(amount, "ERC777: transfer amount exceeds balance");
+ _balances[to] = _balances[to].add(amount);
+
+ emit Sent(operator, from, to, amount, userData, operatorData);
+ emit Transfer(from, to, amount);
+ }
+
+ function _approve(address holder, address spender, uint256 value) internal {
+ // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is
+ // currently unnecessary.
+ //require(holder != address(0), "ERC777: approve from the zero address");
+ require(spender != address(0), "ERC777: approve to zero address");
+
+ _allowances[holder][spender] = value;
+ emit Approval(holder, spender, value);
+ }
+
+ /**
+ * @dev Call from.tokensToSend() if the interface is registered
+ * @param operator address operator requesting the transfer
+ * @param from address token holder address
+ * @param to address recipient address
+ * @param amount uint256 amount of tokens to transfer
+ * @param userData bytes extra information provided by the token holder (if any)
+ * @param operatorData bytes extra information provided by the operator (if any)
+ */
+ function _callTokensToSend(
+ address operator,
+ address from,
+ address to,
+ uint256 amount,
+ bytes memory userData,
+ bytes memory operatorData
+ )
+ internal
+ {
+ address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);
+ if (implementer != address(0)) {
+ IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);
+ }
+ }
+
+ /**
+ * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but
+ * tokensReceived() was not registered for the recipient
+ * @param operator address operator requesting the transfer
+ * @param from address token holder address
+ * @param to address recipient address
+ * @param amount uint256 amount of tokens to transfer
+ * @param userData bytes extra information provided by the token holder (if any)
+ * @param operatorData bytes extra information provided by the operator (if any)
+ * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
+ */
+ function _callTokensReceived(
+ address operator,
+ address from,
+ address to,
+ uint256 amount,
+ bytes memory userData,
+ bytes memory operatorData,
+ bool requireReceptionAck
+ )
+ private
+ {
+ address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);
+ if (implementer != address(0)) {
+ IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);
+ } else if (requireReceptionAck) {
+ require(!to.isContract(), "ERC777: token recipient contract has no implementer for ERC777TokensRecipient");
+ }
+ }
+}
+
+
+// Dependency file: contracts/interface/IERC677Receiver.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+interface IERC677Receiver {
+ function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;
+}
+
+// Dependency file: contracts/interface/ISideToken.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+interface ISideToken {
+ function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;
+}
+
+// Dependency file: contracts/lib/LibEIP712.sol
+
+
+// pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// https://github.com/0xProject/0x-monorepo/blob/development/contracts/utils/contracts/src/LibEIP712.sol
+library LibEIP712 {
+
+ // Hash of the EIP712 Domain Separator Schema
+ // keccak256(abi.encodePacked(
+ // "EIP712Domain(",
+ // "string name,",
+ // "string version,",
+ // "uint256 chainId,",
+ // "address verifyingContract",
+ // ")"
+ // ))
+ bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;
+
+ /// @dev Calculates a EIP712 domain separator.
+ /// @param name The EIP712 domain name.
+ /// @param version The EIP712 domain version.
+ /// @param verifyingContract The EIP712 verifying contract.
+ /// @return result EIP712 domain separator.
+ function hashEIP712Domain(
+ string memory name,
+ string memory version,
+ uint256 chainId,
+ address verifyingContract
+ )
+ internal
+ pure
+ returns (bytes32 result)
+ {
+ bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;
+
+ // Assembly for more efficient computing:
+ // keccak256(abi.encodePacked(
+ // _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,
+ // keccak256(bytes(name)),
+ // keccak256(bytes(version)),
+ // chainId,
+ // uint256(verifyingContract)
+ // ))
+
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ // Calculate hashes of dynamic data
+ let nameHash := keccak256(add(name, 32), mload(name))
+ let versionHash := keccak256(add(version, 32), mload(version))
+
+ // Load free memory pointer
+ let memPtr := mload(64)
+
+ // Store params in memory
+ mstore(memPtr, schemaHash)
+ mstore(add(memPtr, 32), nameHash)
+ mstore(add(memPtr, 64), versionHash)
+ mstore(add(memPtr, 96), chainId)
+ mstore(add(memPtr, 128), verifyingContract)
+
+ // Compute hash
+ result := keccak256(memPtr, 160)
+ }
+ return result;
+ }
+
+ /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.
+ /// @param eip712DomainHash Hash of the domain domain separator data, computed
+ /// with getDomainHash().
+ /// @param hashStruct The EIP712 hash struct.
+ /// @return result EIP712 hash applied to the given EIP712 Domain.
+ function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)
+ internal
+ pure
+ returns (bytes32 result)
+ {
+ // Assembly for more efficient computing:
+ // keccak256(abi.encodePacked(
+ // EIP191_HEADER,
+ // EIP712_DOMAIN_HASH,
+ // hashStruct
+ // ));
+
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ // Load free memory pointer
+ let memPtr := mload(64)
+
+ mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header
+ mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash
+ mstore(add(memPtr, 34), hashStruct) // Hash of struct
+
+ // Compute hash
+ result := keccak256(memPtr, 66)
+ }
+ return result;
+ }
+}
+
+// Root file: contracts/SideToken/SideToken.sol
+
+
+pragma solidity ^0.8.0;
+pragma abicoder v2;
+
+// import "contracts/zeppelin/token/ERC777/ERC777.sol";
+// import "contracts/interface/IERC677Receiver.sol";
+// import "contracts/interface/ISideToken.sol";
+// import "contracts/lib/LibEIP712.sol";
+
+contract SideToken is ISideToken, ERC777 {
+ using SafeMath for uint256;
+
+ address public minter;
+ uint256 private _granularity;
+
+ // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md
+ bytes32 public domainSeparator;
+ // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
+ bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
+ mapping(address => uint) public nonces;
+
+ // ERC677 Transfer Event
+ event Transfer(address,address,uint256,bytes);
+
+ constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)
+ ERC777(_tokenName, _tokenSymbol, new address[](0)) {
+ require(_minterAddr != address(0), "SideToken: Empty Minter");
+ require(_newGranularity >= 1, "SideToken: Granularity < 1");
+ minter = _minterAddr;
+ _granularity = _newGranularity;
+
+ domainSeparator = LibEIP712.hashEIP712Domain(
+ name(),
+ "1",
+ block.chainid,
+ address(this)
+ );
+ }
+
+ modifier onlyMinter() {
+ require(_msgSender() == minter, "SideToken: Caller is not the minter");
+ _;
+ }
+
+ function mint(
+ address account,
+ uint256 amount,
+ bytes calldata userData,
+ bytes calldata operatorData
+ )
+ external onlyMinter override
+ {
+ _mint(_msgSender(), account, amount, userData, operatorData);
+ }
+
+ /**
+ * @dev ERC677 transfer token with additional data if the recipient is a contact.
+ * @param recipient The address to transfer to.
+ * @param amount The amount to be transferred.
+ * @param data The extra data to be passed to the receiving contract.
+ */
+ function transferAndCall(address recipient, uint amount, bytes calldata data)
+ external returns (bool success)
+ {
+ address from = _msgSender();
+
+ _send(from, from, recipient, amount, data, "", false);
+ emit Transfer(from, recipient, amount, data);
+ IERC677Receiver(recipient).onTokenTransfer(from, amount, data);
+ return true;
+ }
+
+ function granularity() public view override returns (uint256) {
+ return _granularity;
+ }
+
+ // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2612.md
+ function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {
+ require(deadline >= block.timestamp, "SideToken: EXPIRED"); // solhint-disable-line not-rely-on-time
+ bytes32 digest = LibEIP712.hashEIP712Message(
+ domainSeparator,
+ keccak256(
+ abi.encode(
+ PERMIT_TYPEHASH,
+ owner,
+ spender,
+ value,
+ nonces[owner]++,
+ deadline
+ )
+ )
+ );
+ address recoveredAddress = ecrecover(digest, v, r, s);
+ require(recoveredAddress != address(0) && recoveredAddress == owner, "SideToken: INVALID_SIGNATURE");
+ _approve(owner, spender, value);
+ }
+
+}
\ No newline at end of file
diff --git a/bridge/hardhat.config.js b/bridge/hardhat.config.js
new file mode 100644
index 000000000..90bd704a1
--- /dev/null
+++ b/bridge/hardhat.config.js
@@ -0,0 +1,258 @@
+require('@nomiclabs/hardhat-web3');
+require('@nomiclabs/hardhat-truffle5');
+require('solidity-coverage');
+require('hardhat-gas-reporter');
+require('hardhat-deploy');
+require('hardhat-abi-exporter');
+require('hardhat-contract-sizer');
+require('@thinkanddev/hardhat-erc1820-rsk');
+require("@nomiclabs/hardhat-etherscan");
+
+const fs = require('fs');
+const chains = require('./hardhat/helper/chains');
+const MNEMONIC = fs.existsSync('./mnemonic.key') ? fs.readFileSync('./mnemonic.key', {encoding: 'utf8'}) : ''; // Your metamask's recovery words
+const ETHERESCAN_KEY = fs.existsSync('./etherscan.key') ? fs.readFileSync('./etherscan.key', {encoding: 'utf8'}) : ''; // Your Etherscan API Key to verify the contracts
+const INFURA_PROJECT_ID = fs.existsSync('./infura.key') ? fs.readFileSync('./infura.key', {encoding: 'utf8'}) : ''; // Your Infura project ID
+
+const DEFAULT_DEPLOYER_ACCOUNT_INDEX = 0;
+
+/**
+ * @type import('hardhat/config').HardhatUserConfig
+ */
+module.exports = {
+ solidity: {
+ version: '0.8.9', // Max Supported by hardhat https://hardhat.org/reference/solidity-support.html
+ settings: {
+ evmVersion: 'istanbul',
+ optimizer: {
+ enabled: true,
+ runs: 200,
+ },
+ },
+ },
+ gasReporter: {
+ currency: 'RBTC',
+ gasPrice: 0.06,
+ enabled: true,
+ },
+ abiExporter: {
+ path: './abi',
+ runOnCompile: true,
+ clear: true,
+ flat: true,
+ only: [
+ ':AllowTokens',
+ ':Bridge',
+ ':Federation',
+ ':IERC20$',
+ ':MainToken$',
+ ':ERC777$',
+ ':MultiSigWallet$',
+ ':ProxyAdmin$',
+ ':SideToken',
+ ':TransparentUpgradeableProxy$'
+ ],
+ },
+ namedAccounts: getNamedAccounts(),
+ etherscan: {
+ apiKey: {
+ mainnet: ETHERESCAN_KEY,
+ ropsten: ETHERESCAN_KEY,
+ rinkeby: ETHERESCAN_KEY,
+ goerli: ETHERESCAN_KEY,
+ kovan: ETHERESCAN_KEY,
+ }
+ },
+ networks: {
+ hardhat: {
+ live: false,
+ blockGasLimit: 6800000,
+ network_id: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ token_symbol: 'h',
+ gasPrice: 60000000,
+ hardfork: 'istanbul', // London hardfork is incompatible with RSK gasPrice
+
+ tags: ['test', 'local'],
+ },
+ //Ganache
+ development: {
+ live: false,
+ url: 'http://127.0.0.1:8545',
+ network_id: chains.GANACHE_DEV_NET_CHAIN_ID,
+ token_symbol: 'e',
+ gas: 6700000,
+ gasPrice: 20000000000,
+ hardfork: 'istanbul', // London hardfork is incompatible with RSK gasPrice
+ tags: ['integrationTest', 'local'],
+ saveDeployments: false,
+ },
+ mirrorDevelopment: {
+ live: false,
+ url: 'http://127.0.0.1:8546',
+ network_id: chains.GANACHE_DEV_MIRROR_CHAIN_ID,
+ token_symbol: 'e',
+ gas: 6700000,
+ gasPrice: 20000000000,
+ hardfork: 'istanbul', // London hardfork is incompatible with RSK gasPrice
+ tags: ['integrationTest', 'local'],
+ saveDeployments: false,
+ },
+ // RSK
+ rsktestnet: {
+ live: true,
+ url: 'https://public-node.testnet.rsk.co',
+ blockGasLimit: 6800000,
+ gasPrice: 68000000, // 0.06 gwei
+ network_id: chains.RSK_TEST_NET_CHAIN_ID,
+ token_symbol: 'r',
+ hardfork: 'istanbul', // London hardfork is incompatible with RSK gasPrice
+ accounts: {
+ mnemonic: MNEMONIC,
+ },
+ tags: ['staging'],
+ },
+ rskmainnet: {
+ live: true,
+ url: 'https://public-node.rsk.co',
+ blockGasLimit: 6800000,
+ gasPrice: 60000000, // 0.06 gwei
+ network_id: chains.RSK_MAIN_NET_CHAIN_ID,
+ token_symbol: 'r',
+ hardfork: 'istanbul', // London hardfork is incompatible with RSK gasPrice
+ accounts: {
+ mnemonic: MNEMONIC,
+ },
+ tags: ['prod'],
+ },
+ //Ethereum
+ kovan: {
+ live: true,
+ url: 'https://kovan.infura.io/v3/' + INFURA_PROJECT_ID,
+ network_id: chains.KOVAN_TEST_NET_CHAIN_ID,
+ token_symbol: 'e',
+ gas: 6700000,
+ gasPrice: 10000000000,
+ accounts: {
+ mnemonic: MNEMONIC,
+ },
+ tags: ['staging'],
+ },
+ rinkeby: {
+ live: true,
+ url: 'https://rinkeby.infura.io/v3/' + INFURA_PROJECT_ID,
+ network_id: chains.RINKEBY_TEST_NET_CHAIN_ID,
+ token_symbol: 'e',
+ gas: 6700000,
+ gasPrice: 10000000000,
+ accounts: {
+ mnemonic: MNEMONIC,
+ },
+ tags: ['staging'],
+ },
+ ethmainnet: {
+ live: true,
+ url: 'https://mainnet.infura.io/ws/v3/' + INFURA_PROJECT_ID,
+ network_id: chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ token_symbol: 'e',
+ gas: 6700000,
+ gasPrice: 250000000000,
+ accounts: {
+ mnemonic: MNEMONIC,
+ },
+ tags: ['prod'],
+ },
+ },
+};
+
+function getNamedAccounts() {
+ return {
+ deployer: {
+ default: DEFAULT_DEPLOYER_ACCOUNT_INDEX,
+ },
+ multiSig: getMultiSigAddressesByChainId(),
+ wrappedCurrency: getWrappedCurrencyAddressesByChainId(),
+ proxyAdmin: getProxyAdminAddressesByChainId(),
+ allowTokensProxy: getAllowTokensProxyAddressesByChainId(),
+ bridgeProxy: getBridgeProxyAddressesByChainId(),
+ federationProxy: getFederationProxyAddressesByChainId(),
+ sideTokenFactory: getSideTokenFactoryAddressesByChainId(),
+ };
+}
+
+function getMultiSigAddressesByChainId() {
+ const multiSigAddressesByChainId = {};
+ multiSigAddressesByChainId[chains.ETHEREUM_MAIN_NET_CHAIN_ID] = '0x040007b1804ad78a97f541bebed377dcb60e4138';
+ multiSigAddressesByChainId[chains.RSK_MAIN_NET_CHAIN_ID] = '0x040007b1804ad78a97f541bebed377dcb60e4138';
+ multiSigAddressesByChainId[chains.RSK_TEST_NET_CHAIN_ID] = '0x88f6b2bc66f4c31a3669b9b1359524abf79cfc4a';
+ multiSigAddressesByChainId[chains.KOVAN_TEST_NET_CHAIN_ID] = '0x040007b1804ad78a97f541bebed377dcb60e4138';
+ multiSigAddressesByChainId[chains.BSC_TEST_NET_CHAIN_ID] = '0xE3848f411587C2C8658A0d6F649e7F1E403873a6';
+ multiSigAddressesByChainId[chains.RINKEBY_TEST_NET_CHAIN_ID] = '0x04994d7fF4938c5953A6C8411ad30083C9097348';
+ return multiSigAddressesByChainId;
+}
+
+function getWrappedCurrencyAddressesByChainId() {
+ const wrappedCurrencyAddressesByChainId = {};
+ wrappedCurrencyAddressesByChainId[chains.ETHEREUM_MAIN_NET_CHAIN_ID] = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2';
+ wrappedCurrencyAddressesByChainId[chains.RSK_MAIN_NET_CHAIN_ID] = '0x967f8799af07df1534d48a95a5c9febe92c53ae0';
+ wrappedCurrencyAddressesByChainId[chains.RSK_TEST_NET_CHAIN_ID] = '0x09b6ca5e4496238a1f176aea6bb607db96c2286e';
+ wrappedCurrencyAddressesByChainId[chains.KOVAN_TEST_NET_CHAIN_ID] = '0xd0A1E359811322d97991E03f863a0C30C2cF029C';
+ wrappedCurrencyAddressesByChainId[chains.BSC_TEST_NET_CHAIN_ID] = '0xae13d989dac2f0debff460ac112a837c89baa7cd';
+ wrappedCurrencyAddressesByChainId[chains.BSC_MAIN_NET_CHAIN_ID] = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c';
+ wrappedCurrencyAddressesByChainId[chains.RINKEBY_TEST_NET_CHAIN_ID] = '0x1664Bd54e994C04bD0f9F7B7e9Ad7CC45d1537B1';
+ return wrappedCurrencyAddressesByChainId;
+}
+
+function getProxyAdminAddressesByChainId() {
+ const proxyAdminAddressesByChainId = {};
+ proxyAdminAddressesByChainId[chains.ETHEREUM_MAIN_NET_CHAIN_ID] = '0xe4d351911a6d599f91a3db1843e2ecb0f851e7e6';
+ proxyAdminAddressesByChainId[chains.RSK_MAIN_NET_CHAIN_ID] = '0x12ed69359919fc775bc2674860e8fe2d2b6a7b5d';
+ proxyAdminAddressesByChainId[chains.RSK_TEST_NET_CHAIN_ID] = '0x8c35e166d2dea7a8a28aaea11ad7933cdae4b0ab';
+ proxyAdminAddressesByChainId[chains.KOVAN_TEST_NET_CHAIN_ID] = '0xe4d351911a6d599f91a3db1843e2ecb0f851e7e6';
+ proxyAdminAddressesByChainId[chains.BSC_TEST_NET_CHAIN_ID] = '0xb37Bf97A42eee6b995732530595E3d16639D9977';
+ proxyAdminAddressesByChainId[chains.RINKEBY_TEST_NET_CHAIN_ID] = '0x0b32Ea549AB1F9F7390442B5E9438b58A105cB5f';
+ return proxyAdminAddressesByChainId;
+}
+
+function getAllowTokensProxyAddressesByChainId() {
+ const allowTokensProxyAddressesByChainId = {};
+ allowTokensProxyAddressesByChainId[chains.ETHEREUM_MAIN_NET_CHAIN_ID] = '0xa3fc98e0a7a979677bc14d541be770b2cb0a15f3';
+ allowTokensProxyAddressesByChainId[chains.RSK_MAIN_NET_CHAIN_ID] = '0xcb789036894a83a008a2aa5b3c2dde41d0605a9a';
+ allowTokensProxyAddressesByChainId[chains.RSK_TEST_NET_CHAIN_ID] = '0xc65bf0ae75dc1a5fc9e6f4215125692a548c773a';
+ allowTokensProxyAddressesByChainId[chains.KOVAN_TEST_NET_CHAIN_ID] = '0x92bf86334583909b60f9b798a9dd7debd899fec4';
+ allowTokensProxyAddressesByChainId[chains.BSC_TEST_NET_CHAIN_ID] = '0x9a64fc2416EE2157e19DC2C79B5B22D113a9E0C3';
+ allowTokensProxyAddressesByChainId[chains.RINKEBY_TEST_NET_CHAIN_ID] = '0xAE3852306015df037D458a65173BBc7527F4680b';
+ return allowTokensProxyAddressesByChainId;
+}
+
+function getBridgeProxyAddressesByChainId() {
+ const bridgeProxyAddressesByChainId = {};
+ bridgeProxyAddressesByChainId[chains.ETHEREUM_MAIN_NET_CHAIN_ID] = '0x12ed69359919fc775bc2674860e8fe2d2b6a7b5d';
+ bridgeProxyAddressesByChainId[chains.RSK_MAIN_NET_CHAIN_ID] = '0x9d11937e2179dc5270aa86a3f8143232d6da0e69';
+ bridgeProxyAddressesByChainId[chains.RSK_TEST_NET_CHAIN_ID] = '0x684a8a976635fb7ad74a0134ace990a6a0fcce84';
+ bridgeProxyAddressesByChainId[chains.KOVAN_TEST_NET_CHAIN_ID] = '0x12ed69359919fc775bc2674860e8fe2d2b6a7b5d';
+ bridgeProxyAddressesByChainId[chains.BSC_TEST_NET_CHAIN_ID] = '0xd9d2f9ee990ddb1147e595ae4f69ec468a0b58d0';
+ bridgeProxyAddressesByChainId[chains.RINKEBY_TEST_NET_CHAIN_ID] = '0x7E339118346364d7D86AB67cb0775CBB808E65F7';
+ return bridgeProxyAddressesByChainId;
+}
+
+function getFederationProxyAddressesByChainId() {
+ const federationProxyAddressesByChainId = {};
+ federationProxyAddressesByChainId[chains.ETHEREUM_MAIN_NET_CHAIN_ID] = '0x5e29c223d99648c88610519f96e85e627b3abe17';
+ federationProxyAddressesByChainId[chains.RSK_MAIN_NET_CHAIN_ID] = '0x7ecfda6072942577d36f939ad528b366b020004b';
+ federationProxyAddressesByChainId[chains.RSK_TEST_NET_CHAIN_ID] = '0x5d663981d930e8ec108280b9d80885658148ab0f';
+ federationProxyAddressesByChainId[chains.KOVAN_TEST_NET_CHAIN_ID] = '0xa347438bc288f56cb6083a79133e70dd2d1f6c2d';
+ federationProxyAddressesByChainId[chains.BSC_TEST_NET_CHAIN_ID] = '0xD40F8613173E636D570c47dB3A6Ac57EA9ccac83';
+ federationProxyAddressesByChainId[chains.RINKEBY_TEST_NET_CHAIN_ID] = '0xBC383764ceBc13b66c04E1abeb36804a0Caaa5C6';
+ return federationProxyAddressesByChainId;
+}
+
+function getSideTokenFactoryAddressesByChainId() {
+ const sideTokenFactoryAddressesByChainId = {};
+ sideTokenFactoryAddressesByChainId[chains.ETHEREUM_MAIN_NET_CHAIN_ID] = '0xF73C60863BF2930Bde2c69dF4CB8fE700Ae713fB';
+ sideTokenFactoryAddressesByChainId[chains.RSK_MAIN_NET_CHAIN_ID] = '0x44fcd0854d745efdef4cfe9868efe4d4eb51ecd6';
+ sideTokenFactoryAddressesByChainId[chains.RSK_TEST_NET_CHAIN_ID] = '0x08C191A7B5Edaa59853705F7eaE95E3E4238D73e';
+ sideTokenFactoryAddressesByChainId[chains.KOVAN_TEST_NET_CHAIN_ID] = '0x984192ad76A8FFF2edf39C260324d32d8A80512b';
+ sideTokenFactoryAddressesByChainId[chains.BSC_TEST_NET_CHAIN_ID] = '0xe2EBFC705d473C3dDd52CB49AF0bdE3132E8831e';
+ sideTokenFactoryAddressesByChainId[chains.RINKEBY_TEST_NET_CHAIN_ID] = '0x1CB41Dc4603612A4da692669916e8F4dEF2994dC';
+ return sideTokenFactoryAddressesByChainId;
+}
diff --git a/bridge/hardhat/helper/address.js b/bridge/hardhat/helper/address.js
new file mode 100644
index 000000000..4efc02526
--- /dev/null
+++ b/bridge/hardhat/helper/address.js
@@ -0,0 +1,80 @@
+let namedAccountsInstance = null;
+
+async function getNamedAccountsInstance(hre) {
+ if (namedAccountsInstance == null) {
+ const {getNamedAccounts} = hre;
+ namedAccountsInstance = await getNamedAccounts();
+ }
+ return namedAccountsInstance;
+}
+
+async function getProxyAdminAddress(hre) {
+ const {deployments} = hre;
+ const {proxyAdmin} = await getNamedAccountsInstance(hre);
+ return proxyAdmin ?? (await deployments.get('ProxyAdmin')).address;
+}
+
+async function getMultiSigAddress(hre) {
+ const {deployments} = hre;
+ const {multiSig} = await getNamedAccountsInstance(hre);
+ return multiSig ?? (await deployments.get('MultiSigWallet')).address;
+}
+
+async function getBridgeProxyAddress(hre) {
+ const {deployments} = hre;
+ const {bridgeProxy} = await getNamedAccountsInstance(hre);
+ if (bridgeProxy) {
+ return bridgeProxy
+ }
+ const bridgeProxyDeployment = await deployments.getOrNull('BridgeProxy')
+ if (bridgeProxyDeployment) {
+ return bridgeProxyDeployment.address;
+ }
+ return bridgeProxyDeployment;
+}
+
+async function getFederationProxyAddress(hre) {
+ const {deployments} = hre;
+ const {federationProxy} = await getNamedAccountsInstance(hre);
+
+ if (federationProxy) {
+ return federationProxy;
+ }
+ const federationProxyDeployment = await deployments.getOrNull('FederationProxy')
+ if (federationProxyDeployment) {
+ return federationProxyDeployment.address;
+ }
+ return federationProxyDeployment;
+}
+
+async function getAllowTokensProxyAddress(hre) {
+ const {deployments} = hre;
+ const {allowTokensProxy} = await getNamedAccountsInstance(hre);
+
+ if (allowTokensProxy) {
+ return allowTokensProxy;
+ }
+ const allowTokensProxyDeployment = await deployments.getOrNull('AllowTokensProxy')
+ if (allowTokensProxyDeployment) {
+ return allowTokensProxyDeployment.address;
+ }
+ return allowTokensProxyDeployment;
+}
+
+async function getSideTokenFactoryAddress(hre) {
+ const {deployments} = hre;
+ const {sideTokenFactory} = await getNamedAccountsInstance(hre);
+ return sideTokenFactory ?? (await deployments.get('SideTokenFactory')).address;
+}
+
+module.exports = {
+ getProxyAdminAddress: getProxyAdminAddress,
+ getMultiSigAddress: getMultiSigAddress,
+ getBridgeProxyAddress: getBridgeProxyAddress,
+ getFederationProxyAddress: getFederationProxyAddress,
+ getAllowTokensProxyAddress: getAllowTokensProxyAddress,
+ getSideTokenFactoryAddress: getSideTokenFactoryAddress,
+ NULL_ADDRESS: "0x0000000000000000000000000000000000000000",
+ NULL_HASH:
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+};
diff --git a/bridge/hardhat/helper/chains.js b/bridge/hardhat/helper/chains.js
new file mode 100644
index 000000000..dcbecab26
--- /dev/null
+++ b/bridge/hardhat/helper/chains.js
@@ -0,0 +1,51 @@
+const ETHEREUM_MAIN_NET_CHAIN_ID = 1;
+const RSK_MAIN_NET_CHAIN_ID = 30;
+const RSK_TEST_NET_CHAIN_ID = 31;
+const KOVAN_TEST_NET_CHAIN_ID = 42;
+const RINKEBY_TEST_NET_CHAIN_ID = 4;
+const BSC_MAIN_NET_CHAIN_ID = 56;
+const BSC_TEST_NET_CHAIN_ID = 97;
+const GANACHE_DEV_MIRROR_CHAIN_ID = 5776;
+const GANACHE_DEV_NET_CHAIN_ID = 5777;
+const HARDHAT_TEST_NET_CHAIN_ID = 31337;
+
+/** Network example
+ config: {
+ accounts: 'remote',
+ live: false,
+ network_id: 5777,
+ },
+ saveDeployments: false,
+ tags: (2) ['integrationTest', 'local'],
+ live: false,
+ name: 'development'
+*/
+function isRSK(network) {
+ const chainID = network.config.network_id;
+ return [RSK_MAIN_NET_CHAIN_ID, RSK_TEST_NET_CHAIN_ID].includes(chainID);
+}
+
+function tokenSymbol(network) {
+ return network.config.token_symbol ?? 'e';
+}
+
+function isMainnet(network) {
+ const chainID = network.config.network_id;
+ return [ETHEREUM_MAIN_NET_CHAIN_ID, RSK_MAIN_NET_CHAIN_ID, BSC_MAIN_NET_CHAIN_ID].includes(chainID);
+}
+
+module.exports = {
+ ETHEREUM_MAIN_NET_CHAIN_ID: ETHEREUM_MAIN_NET_CHAIN_ID,
+ RSK_MAIN_NET_CHAIN_ID: RSK_MAIN_NET_CHAIN_ID,
+ RSK_TEST_NET_CHAIN_ID: RSK_TEST_NET_CHAIN_ID,
+ KOVAN_TEST_NET_CHAIN_ID: KOVAN_TEST_NET_CHAIN_ID,
+ RINKEBY_TEST_NET_CHAIN_ID: RINKEBY_TEST_NET_CHAIN_ID,
+ BSC_MAIN_NET_CHAIN_ID: BSC_MAIN_NET_CHAIN_ID,
+ BSC_TEST_NET_CHAIN_ID: BSC_TEST_NET_CHAIN_ID,
+ GANACHE_DEV_MIRROR_CHAIN_ID: GANACHE_DEV_MIRROR_CHAIN_ID,
+ GANACHE_DEV_NET_CHAIN_ID: GANACHE_DEV_NET_CHAIN_ID,
+ HARDHAT_TEST_NET_CHAIN_ID: HARDHAT_TEST_NET_CHAIN_ID,
+ isRSK: isRSK,
+ tokenSymbol: tokenSymbol,
+ isMainnet: isMainnet,
+};
diff --git a/bridge/hardhat/helper/tokens.js b/bridge/hardhat/helper/tokens.js
new file mode 100644
index 000000000..da12bbc01
--- /dev/null
+++ b/bridge/hardhat/helper/tokens.js
@@ -0,0 +1,93 @@
+const chains = require('./chains');
+
+const ethereum = {
+ WBTC: {address: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', typeId: '0', isSideToken: false, decimals: 8, symbol: 'WBTC'}, //WBTC
+ renBTC: {address: '0xeb4c2781e4eba804ce9a9803c67d0893436bb27d', typeId: '0', isSideToken: false, decimals: 8, symbol: 'renBTC'}, //renBTC
+ WETH: {address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', typeId: '1', isSideToken: false, decimals: 18, symbol: 'ETH'}, //WETH
+ DAI: {address: '0x6b175474e89094c44da98b954eedeac495271d0f', typeId: '4', isSideToken: false, decimals: 18, symbol: 'DAI'}, //DAI
+ USDC: {address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', typeId: '5', isSideToken: false, decimals: 6, symbol: 'USDC'}, //USDC
+ USDT: {address: '0xdac17f958d2ee523a2206206994597c13d831ec7', typeId: '5', isSideToken: false, decimals: 6, symbol: 'USDT'}, //USDT
+ LINK: {address: '0x514910771af9ca656af840dff83e8264ecf986ca', typeId: '3', isSideToken: false, decimals: 18, symbol: 'LINK'}, //LINK
+ BUND: {address: '0x8d3e855f3f55109d473735ab76f753218400fe96', typeId: '3', isSideToken: false, decimals: 18, symbol: 'BUND'}, //BUND
+ FLIXX: {address: '0xf04a8ac553fcedb5ba99a64799155826c136b0be', typeId: '6', isSideToken: false, decimals: 18, symbol: 'FLIXX'}, //FLIXX
+ RFOX: {address: '0xa1d6Df714F91DeBF4e0802A542E13067f31b8262', typeId: '6', isSideToken: false, decimals: 18, symbol: 'RFOX'}, //RFOX
+ AMLT: {address: '0xca0e7269600d353f70b14ad118a49575455c0f2f', typeId: '6', isSideToken: false, decimals: 18, symbol: 'AMLT'}, //AMLT
+ // Side Tokens
+ eRIF: {address: '0x73c08467E23F7DCB7dDBbc8d05041B74467A498A', typeId: '5', isSideToken: true, decimals: 18, symbol: 'eRIF'}, //eRIF
+ eDOC: {address: '0x69f6d4d4813f8e2e618dae7572e04b6d5329e207', typeId: '4', isSideToken: true, decimals: 18, symbol: 'eDOC'} //eDOC
+}
+
+const rskMainnet = {
+ DOC: {address: '0xe700691da7b9851f2f35f8b8182c69c53ccad9db', typeId: '5', isSideToken: false, decimals: 18, symbol: 'DOC'}, //DOC
+ RIF: {address: '0x2acc95758f8b5f583470ba265eb685a8f45fc9d5', typeId: '6', isSideToken: false, decimals: 18, symbol: 'RIF'}, //RIF
+ // Side Tokens
+ rDAI: {address: '0x6b1a73d547f4009a26b8485b63d7015d248ad406', typeId: '4', isSideToken: true, decimals: 18, symbol: 'rDAI'}, //rDAI
+ rUSDC: {address: '0x1bda44fda023f2af8280a16fd1b01d1a493ba6c4', typeId: '4', isSideToken: true, decimals: 18, symbol: 'rUSDC'}, //rUSDC
+ rUSDT: {address: '0xef213441a85df4d7acbdae0cf78004e1e486bb96', typeId: '4', isSideToken: true, decimals: 18, symbol: 'rUSDT'}, //rUSDT
+ rLINK: {address: '0x14adae34bef7ca957ce2dde5add97ea050123827', typeId: '3', isSideToken: true, decimals: 18, symbol: 'rLINK'}, //rLINK
+ rBUND: {address: '0x4991516df6053121121274397a8c1dad608bc95b', typeId: '3', isSideToken: true, decimals: 18, symbol: 'rBUND'}, //rBUND
+ rFLIXX: {address: '0x73c08467E23F7DCB7dDBbc8d05041B74467A498A', typeId: '6', isSideToken: true, decimals: 18, symbol: 'rFLIXX'}, //rFLIXX
+ rRFOX: {address: '0x9c3a5f8d686fade293c0ce989a62a34408c4e307', typeId: '6', isSideToken: true, decimals: 18, symbol: 'rRFOX'}, //rRFOX
+ rAMLT: {address: '0xff9ea341d9ea91cb7c54342354377f5104fd403f', typeId: '6', isSideToken: true, decimals: 18, symbol: 'rAMLT'} //rAMLT
+}
+
+const kovan = {
+ WBTC: {address: '0xd1b98b6607330172f1d991521145a22bce793277', typeId: '0', isSideToken: false, decimals: 8, symbol: 'WBTC'}, //WBTC
+ renBTC: {address: '0x0a9add98c076448cbcfacf5e457da12ddbef4a8f', typeId: '0', isSideToken: false, decimals: 18, symbol: 'renBTC'}, //renBTC
+ WETH: {address: '0xd0A1E359811322d97991E03f863a0C30C2cF029C', typeId: '1', isSideToken: false, decimals: 18, symbol: 'ETH'}, //WETH
+ SAI: {address: '0xc7cc3413f169a027dccfeffe5208ca4f38ef0c40', typeId: '4', isSideToken: false, decimals: 18, symbol: 'SAI'}, //SAI
+ DAI: {address: '0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa', typeId: '4', isSideToken: false, decimals: 18, symbol: 'DAI'}, //DAI
+ TUSD: {address: '0x0000000000085d4780B73119b644AE5ecd22b376', typeId: '4', isSideToken: false, decimals: 18, symbol: 'TUSD'}, //TUSD
+ USDC: {address: '0xe22da380ee6B445bb8273C81944ADEB6E8450422', typeId: '4', isSideToken: false, decimals: 6, symbol: 'USDC'}, //USDC
+ USDT: {address: '0x13512979ade267ab5100878e2e0f485b568328a4', typeId: '4', isSideToken: false, decimals: 6, symbol: 'USDT'}, //USDT
+ LINK: {address: '0xa36085F69e2889c224210F603D836748e7dC0088', typeId: '3', isSideToken: false, decimals: 18, symbol: 'LINK'}, //LINK
+ BUND: {address: '0x8d3e855f3f55109d473735ab76f753218400fe96', typeId: '3', isSideToken: false, decimals: 18, symbol: 'BUND'}, //BUND
+ // SideToken
+ eRIF: {address: '0x69f6d4d4813f8e2e618dae7572e04b6d5329e207', typeId: '5', isSideToken: true, decimals: 18, symbol: 'eRIF'}, //eRIF
+ eDOC: {address: '0x09a8f2041Be23e8eC3c72790C9A92089BC70FbCa', typeId: '4', isSideToken: true, decimals: 18, symbol: 'eDOC'}, //eDOC
+ eBPro: {address: '0xB3c9ec8833bfA0d382a183EcED27aBc079520928', typeId: '0', isSideToken: true, decimals: 18, symbol: 'eBPro'} //eBPro
+}
+
+const rskTestnet = {
+ DOC: {address: '0xcb46c0ddc60d18efeb0e586c17af6ea36452dae0', typeId: '5', isSideToken: false, decimals: 18, symbol: 'DOC'}, //DOC
+ RIF: {address: '0x19f64674d8a5b4e652319f5e239efd3bc969a1fe', typeId: '6', isSideToken: false, decimals: 18, symbol: 'RIF'}, //RIF
+ BPro: {address: '0x4da7997a819bb46b6758b9102234c289dd2ad3bf', typeId: '0', isSideToken: false, decimals: 18, symbol: 'BPro'}, //BPro
+ // Side Tokens
+ rKovWETH: {address: '0xd15cdd74dff1a6a81ca639b038839b126bc01ff9', typeId: '1', isSideToken: true, decimals: 18, symbol: 'rKovWETH'}, //rKovWETH
+ rKovSAI: {address: '0x0d86fca9be034a363cf12c9834af08d54a10451c', typeId: '4', isSideToken: true, decimals: 18, symbol: 'rKovSAI'}, //rKovSAI
+ rKovDAI: {address: '0x7b846216a194c69bb1ea52ea8faa92d314866451', typeId: '4', isSideToken: true, decimals: 18, symbol: 'rKovDAI'}, //rKovDAI
+ rKovTUSD: {address: '0x0a8d098e31a60da2b9c874d97de6e6b385c28e9d', typeId: '4', isSideToken: true, decimals: 18, symbol: 'rKovTUSD'}, //rKovTUSD
+ rKovUSDC: {address: '0xed3334adb07a3a5947d268e5a8c67b84f5464963', typeId: '4', isSideToken: true, decimals: 18, symbol: 'rKovUSDC'}, //rKovUSDC
+ rKovUSDT: {address: '0x4cfE225cE54c6609a525768b13F7d87432358C57', typeId: '4', isSideToken: true, decimals: 18, symbol: 'rKovUSDT'}, //rKovUSDT
+ rKovLINK: {address: '0x8bbbd80981fe76d44854d8df305e8985c19f0e78', typeId: '3', isSideToken: true, decimals: 18, symbol: 'rKovLINK'}, //rKovLINK
+ rKovBUND: {address: '0xe95afdfec031f7b9cd942eb7e60f053fb605dfcd', typeId: '3', isSideToken: true, decimals: 18, symbol: 'rKovBUND'}, //rKovBUND
+ rKovWBTC: {address: '0xb8aE2CB769255359190fBcE89d3aD38687da5e65', typeId: '0', isSideToken: true, decimals: 18, symbol: 'rKovWBTC'}, //rKovWBTC
+}
+
+const tokensByChainId = (chainId) => {
+ switch (chainId) {
+ case chains.RSK_TEST_NET_CHAIN_ID:
+ return rskTestnet;
+
+ case chains.KOVAN_TEST_NET_CHAIN_ID:
+ return kovan;
+
+ case chains.RSK_MAIN_NET_CHAIN_ID:
+ return rskMainnet;
+
+ case chains.ETHEREUM_MAIN_NET_CHAIN_ID:
+ return ethereum;
+
+ default:
+ return [];
+ }
+
+}
+
+module.exports = {
+ tokensByChainId,
+ ethereum,
+ rskMainnet,
+ kovan,
+ rskTestnet,
+};
diff --git a/bridge/hardhat/script/addFederatorMember.js b/bridge/hardhat/script/addFederatorMember.js
new file mode 100644
index 000000000..027f2be90
--- /dev/null
+++ b/bridge/hardhat/script/addFederatorMember.js
@@ -0,0 +1,41 @@
+// How to run the script: npx hardhat run ./hardhat/script/addFederatorMemeber.js --network rsktestnetbsc
+const hre = require("hardhat");
+
+async function main() {
+ const {getNamedAccounts, deployments} = hre;
+ const {deployer} = await getNamedAccounts();
+ const transactionEtherValue = 0;
+ const memberFederatorAddress = "0x0e6fa08809bc166ab5ce237fdccb1802fdf13b27";
+
+ const Federation = await deployments.get('FederationV2');
+ const FederationProxy = await deployments.get('FederationProxy');
+ const MultiSigWallet = await deployments.get('MultiSigWallet');
+
+ const federator = new web3.eth.Contract(Federation.abi, FederationProxy.address);
+ const multiSigContract = new web3.eth.Contract(MultiSigWallet.abi, MultiSigWallet.address);
+
+ const methodCallAddNewMember = federator.methods.addMember(
+ memberFederatorAddress
+ );
+ const result = await methodCallAddNewMember.call({ from: MultiSigWallet.address});
+ console.log("Method call result", result);
+
+ const receipt = await multiSigContract.methods.submitTransaction(
+ FederationProxy.address,
+ transactionEtherValue,
+ methodCallAddNewMember.encodeABI()
+ ).send({
+ from: deployer,
+ gasLimit: 3000000
+ });
+ console.log("Transaction worked, member added, txHash:", receipt.transactionHash);
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
diff --git a/bridge/hardhat/script/createRifToken.js b/bridge/hardhat/script/createRifToken.js
new file mode 100644
index 000000000..d2de7d9ab
--- /dev/null
+++ b/bridge/hardhat/script/createRifToken.js
@@ -0,0 +1,69 @@
+// How to run the script: npx hardhat run ./hardhat/script/createRifToken.js --network bsctestnet
+const hre = require("hardhat");
+
+async function main() {
+ const {getNamedAccounts, deployments} = hre;
+ const {deployer} = await getNamedAccounts();
+
+ const transactionEtherValue = 0;
+ const tokenDecimals = 18;
+
+ const tokens = [
+ {
+ name: 'RifToken',
+ symbol: 'tRIF',
+ typeId: 5,
+ originalTokenAddress: '0x19F64674D8A5B4E652319F5e239eFd3bc969A1fE',
+ }
+ ];
+
+ const Bridge = await deployments.get('Bridge');
+ const BridgeProxy = await deployments.get('BridgeProxy');
+ const MultiSigWallet = await deployments.get('MultiSigWallet');
+
+ const bridge = new web3.eth.Contract(Bridge.abi, BridgeProxy.address);
+ const multiSigContract = new web3.eth.Contract(MultiSigWallet.abi, MultiSigWallet.address);
+
+
+ for (const token of tokens) {
+ console.log("Token", token);
+ console.log("deployer", deployer);
+ console.log("\nBridge", Bridge.address);
+ console.log("\nBridgeProxy", BridgeProxy.address);
+ console.log("\nMultiSigWallet", MultiSigWallet.address);
+
+ const methodCallCreateSideToken = bridge.methods.createSideToken(
+ token.typeId,
+ token.originalTokenAddress,
+ tokenDecimals,
+ token.symbol,
+ token.name
+ );
+ const result = await methodCallCreateSideToken.call({ from: MultiSigWallet.address});
+ console.log("Method call result", result);
+
+ const receipt = await multiSigContract.methods.submitTransaction(
+ BridgeProxy.address,
+ transactionEtherValue,
+ methodCallCreateSideToken.encodeABI()
+ ).send({
+ from: deployer,
+ gasLimit: 3000000
+ });
+ console.log("Transaction worked", receipt.transactionHash);
+
+ const tokenAddress = await bridge.methods.mappedTokens(token.originalTokenAddress).call({from: MultiSigWallet.address});
+ console.log("Token address for", token.name, ":", tokenAddress);
+ }
+
+ console.log("finish");
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
diff --git a/bridge/hardhat/script/createTokensERC20Rsk.js b/bridge/hardhat/script/createTokensERC20Rsk.js
new file mode 100644
index 000000000..034b7cb5b
--- /dev/null
+++ b/bridge/hardhat/script/createTokensERC20Rsk.js
@@ -0,0 +1,71 @@
+// How to run the script: npx hardhat run ./hardhat/script/createTokensERC20Rsk.js --network rsktestnet kovan bsctestnet rsktestnet rsktestnetbsc
+const hre = require("hardhat");
+
+async function main() {
+ const {getNamedAccounts, deployments} = hre;
+ const {deployer} = await getNamedAccounts();
+
+ const transactionEtherValue = 0;
+ const tokenDecimals = 18;
+
+ const tokens = [
+ {
+ name: 'Side Ethereum Test BTC (WTBTC)',
+ symbol: 'RWTBTC',
+ typeId: 1,
+ originalTokenAddress: '0x4ccc35c8f2e780203c5dc4b605f495acea9255bc',
+ }
+ ];
+
+ const Bridge = await deployments.get('Bridge');
+ const BridgeProxy = await deployments.get('BridgeProxy');
+ const MultiSigWallet = await deployments.get('MultiSigWallet');
+
+ const bridge = new web3.eth.Contract(Bridge.abi, BridgeProxy.address);
+ const multiSigContract = new web3.eth.Contract(MultiSigWallet.abi, MultiSigWallet.address);
+
+
+ for (const token of tokens) {
+ console.log("Token", token);
+ console.log("deployer", deployer);
+ console.log("\nBridge", Bridge.address);
+ console.log("\nBridgeProxy", BridgeProxy.address);
+ console.log("\nMultiSigWallet", MultiSigWallet.address);
+
+ const methodCallCreateSideToken = bridge.methods.createSideToken(
+ token.typeId,
+ token.originalTokenAddress,
+ tokenDecimals,
+ token.symbol,
+ token.name
+ );
+ const result = await methodCallCreateSideToken.call({ from: MultiSigWallet.address});
+ console.log("Method call result", result);
+
+ const receipt = await multiSigContract.methods.submitTransaction(
+ BridgeProxy.address,
+ transactionEtherValue,
+ methodCallCreateSideToken.encodeABI()
+ ).send({
+ from: deployer,
+ gasLimit: 3000000
+ });
+ console.log("Transaction worked", receipt.transactionHash);
+
+ const mappedTokenAddress = await bridge.methods.mappedTokens(token.originalTokenAddress).call({from: MultiSigWallet.address});
+ console.log("Mapped Token address for", token.name, ":", mappedTokenAddress);
+ const originalTokenAddress = await bridge.methods.originalTokens(token.originalTokenAddress).call({from: MultiSigWallet.address});
+ console.log("Original Token address for", token.name, ":", originalTokenAddress);
+ }
+
+ console.log("finish");
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors. 1.4539
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
diff --git a/bridge/hardhat/script/deleteFederatorMember.js b/bridge/hardhat/script/deleteFederatorMember.js
new file mode 100644
index 000000000..940b3d810
--- /dev/null
+++ b/bridge/hardhat/script/deleteFederatorMember.js
@@ -0,0 +1,41 @@
+// How to run the script: npx hardhat run ./hardhat/script/deleteFederatorMemeber.js --network rsktestnetbsc
+const hre = require("hardhat");
+
+async function main() {
+ const {getNamedAccounts, deployments} = hre;
+ const {deployer} = await getNamedAccounts();
+
+ const oldFederatorAddress = "0x8f397ff074ff190fc650e5cab4da039a8163e12a";
+
+ const Federation = await deployments.get('FederationV2');
+ const FederationProxy = await deployments.get('FederationProxy');
+ const MultiSigWallet = await deployments.get('MultiSigWallet');
+
+ const federator = new web3.eth.Contract(Federation.abi, FederationProxy.address);
+ const multiSigContract = new web3.eth.Contract(MultiSigWallet.abi, MultiSigWallet.address);
+
+ const methodCallRemoveOldMember = federator.methods.removeMember(
+ oldFederatorAddress
+ );
+ const result = await methodCallRemoveOldMember.call({ from: MultiSigWallet.address});
+ console.log("Method call result", result);
+
+ const receipt = await multiSigContract.methods.submitTransaction(
+ FederationProxy.address,
+ 0,
+ methodCallRemoveOldMember.encodeABI()
+ ).send({
+ from: deployer,
+ gasLimit: 3000000
+ });
+ console.log("Transaction worked, member removed, txHash:", receipt.transactionHash);
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
diff --git a/bridge/hardhat/script/getFederatorMembers.js b/bridge/hardhat/script/getFederatorMembers.js
new file mode 100644
index 000000000..0b220a44f
--- /dev/null
+++ b/bridge/hardhat/script/getFederatorMembers.js
@@ -0,0 +1,25 @@
+// How to run the script: npx hardhat run ./hardhat/script/getFederatorMembers.js --network rsktestnetbsc
+const hre = require("hardhat");
+
+async function main() {
+ const {deployments} = hre;
+
+ const Federation = await deployments.get('Federation');
+ const FederationProxy = await deployments.get('FederationProxy');
+ const MultiSigWallet = await deployments.get('MultiSigWallet');
+
+ const federator = new web3.eth.Contract(Federation.abi, FederationProxy.address);
+
+ const methodCallGetMembers = federator.methods.getMembers();
+ const result = await methodCallGetMembers.call({ from: MultiSigWallet.address});
+ console.log("Method call result", result);
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
diff --git a/bridge/hardhat/script/getFeeConfig.js b/bridge/hardhat/script/getFeeConfig.js
new file mode 100644
index 000000000..b6567a45b
--- /dev/null
+++ b/bridge/hardhat/script/getFeeConfig.js
@@ -0,0 +1,24 @@
+// How to run the script: npx hardhat run ./hardhat/script/getFeeConfig.js --network rsktestnetbsc
+const hre = require("hardhat");
+
+async function main() {
+ const {deployments} = hre;
+
+ const Bridge = await deployments.get('Bridge');
+ const BridgeProxy = await deployments.get('BridgeProxy');
+
+ const bridgeContract = new web3.eth.Contract(Bridge.abi, BridgeProxy.address);
+
+ const methodCallGetFeePercentage = bridgeContract.methods.getFeePercentage();
+ const result = await methodCallGetFeePercentage.call();
+ console.log("Method call result", result);
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
diff --git a/bridge/hardhat/script/getSideTokenAddress.js b/bridge/hardhat/script/getSideTokenAddress.js
new file mode 100644
index 000000000..24bd5bb1d
--- /dev/null
+++ b/bridge/hardhat/script/getSideTokenAddress.js
@@ -0,0 +1,33 @@
+// How to run the script: npx hardhat run ./hardhat/script/getSideTokenAddress.js --network rsktestnet
+const hre = require("hardhat");
+
+const { tokensByChainId } = require('../../hardhat/helper/tokens');
+
+async function main() {
+ const originalChainId = 42
+ const tokens = tokensByChainId(originalChainId);
+ const {deployments} = hre;
+
+ const Bridge = await deployments.get('Bridge');
+ const BridgeProxy = await deployments.get('BridgeProxy');
+
+ const bridgeContract = new web3.eth.Contract(Bridge.abi, BridgeProxy.address);
+
+ const sideTokenByOriginalToken = async (_originalChainId, _originalTokenAddress) => {
+ const sideTokenAddress = await bridgeContract.methods.sideTokenByOriginalToken(_originalChainId, _originalTokenAddress).call();
+ console.log("_originalChainId", _originalChainId, "_originalTokenAddress", _originalTokenAddress, "sideTokenAddress", sideTokenAddress);
+ }
+
+ for (const symbol in tokens) {
+ await sideTokenByOriginalToken(originalChainId, tokens[symbol].address);
+ }
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
diff --git a/bridge/hardhat/script/getTxStatus.js b/bridge/hardhat/script/getTxStatus.js
new file mode 100644
index 000000000..4cf8e97ad
--- /dev/null
+++ b/bridge/hardhat/script/getTxStatus.js
@@ -0,0 +1,27 @@
+
+// How to run the script: npx hardhat run ./hardhat/script/getFeeConfig.js --network rsktestnetbsc
+const hre = require("hardhat");
+const BN = web3.utils.BN;
+
+async function main() {
+ const {deployments} = hre;
+
+ const Bridge = await deployments.get('Bridge');
+ const BridgeProxy = await deployments.get('BridgeProxy');
+
+ const bridgeContract = new web3.eth.Contract(Bridge.abi, BridgeProxy.address);
+
+ const transactionHash = "0x77a49edea913f81268cceb4499525cf6c2c8a16233d323ca135e41f79249188f" //"0x5befad2a24647508bf848e8500b9be4f0340efd078631ad3de927b264c723267" // "0xba6a21df7b69fffcf00d39b1da003ad8041b41d07887226c8c935ab106fec7e9"
+
+ const hasBeenClaimed = await bridgeContract.methods.hasBeenClaimed(transactionHash).call();
+ console.log("Has Been Claimed", hasBeenClaimed);
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
\ No newline at end of file
diff --git a/bridge/hardhat/script/getWrappedCurrency.js b/bridge/hardhat/script/getWrappedCurrency.js
new file mode 100644
index 000000000..ff4a3e32d
--- /dev/null
+++ b/bridge/hardhat/script/getWrappedCurrency.js
@@ -0,0 +1,30 @@
+// How to run the script: npx hardhat run ./hardhat/script/getWrappedCurrency.js --network kovan bsctestnet rsktestnet rsktestnetbsc
+const hre = require("hardhat");
+
+async function main() {
+ const {deployments} = hre;
+
+ const Bridge = await deployments.get('Bridge');
+ const BridgeProxy = await deployments.get('BridgeProxy');
+ const MultiSigWallet = await deployments.get('MultiSigWallet');
+
+ const bridge = new web3.eth.Contract(Bridge.abi, BridgeProxy.address);
+
+ console.log("\nBridge", Bridge.address);
+ console.log("\nBridgeProxy", BridgeProxy.address);
+ console.log("\nMultiSigWallet", MultiSigWallet.address);
+
+ const wrappedTokenAddress = await bridge.methods.wrappedCurrency().call({from: MultiSigWallet.address});
+ console.log("Wrapped currency address", wrappedTokenAddress);
+
+ console.log("finish");
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
diff --git a/bridge/hardhat/script/isTokenAllowed.js b/bridge/hardhat/script/isTokenAllowed.js
new file mode 100644
index 000000000..3d3c673c3
--- /dev/null
+++ b/bridge/hardhat/script/isTokenAllowed.js
@@ -0,0 +1,34 @@
+// How to run the script: npx hardhat run ./hardhat/script/isTokenAllowed.js --network rsktestnet
+const hre = require("hardhat");
+const address = require('../helper/address');
+
+async function main() {
+ const {deployments} = hre;
+ const allowTokensProxyAddress = await address.getAllowTokensProxyAddress(hre);
+
+ const allowedTokenAddr = "0xe700691da7b9851f2f35f8b8182c69c53ccad9db"
+
+ const AllowTokens = await deployments.getArtifact('AllowTokens');
+
+ const allowTokensContract = new web3.eth.Contract(AllowTokens.abi, allowTokensProxyAddress);
+
+ console.log("\nAllowTokens Proxy Contract", allowTokensProxyAddress);
+
+ const infoAndLimits = await allowTokensContract.methods.getInfoAndLimits(allowedTokenAddr).call();
+ const info = infoAndLimits.info;
+ const limit = infoAndLimits.limit;
+ console.log("isTokenAllowed", allowedTokenAddr, ":", info.allowed);
+ console.log("info", info);
+ console.log("limit", limit);
+
+ console.log("finish");
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
diff --git a/bridge/hardhat/script/removeAllowToken.js b/bridge/hardhat/script/removeAllowToken.js
new file mode 100644
index 000000000..dd81daff9
--- /dev/null
+++ b/bridge/hardhat/script/removeAllowToken.js
@@ -0,0 +1,45 @@
+// How to run the script: npx hardhat run ./hardhat/script/removeAllowToken.js --network bsctestnet
+const hre = require("hardhat");
+
+async function main() {
+ const {getNamedAccounts, deployments} = hre;
+ const {deployer} = await getNamedAccounts();
+
+ const tokenToRemove = "0x00....."
+
+ const AllowTokens = await deployments.get('AllowTokens');
+ const AllowTokensProxy = await deployments.get('AllowTokensProxy');
+ const MultiSigWallet = await deployments.get('MultiSigWallet');
+
+ const allowTokens = new web3.eth.Contract(AllowTokens.abi, AllowTokensProxy.address);
+ const multiSigContract = new web3.eth.Contract(MultiSigWallet.abi, MultiSigWallet.address);
+
+ console.log("\nAllowTokens", AllowTokens.address);
+ console.log("\nAllowTokensProxy", AllowTokensProxy.address);
+ console.log("\nMultiSigWallet", MultiSigWallet.address);
+
+ const methodCallSetToken = allowTokens.methods.removeAllowedToken(tokenToRemove);
+ const result = await methodCallSetToken.call({ from: MultiSigWallet.address});
+ console.log("Method call result", result);
+
+ const receipt = await multiSigContract.methods.submitTransaction(
+ AllowTokensProxy.address,
+ 0,
+ methodCallSetToken.encodeABI()
+ ).send({
+ from: deployer,
+ gasLimit: 3000000
+ });
+ console.log("Transaction worked", receipt.transactionHash);
+
+ console.log("finish");
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
diff --git a/bridge/hardhat/script/setAllowToken.js b/bridge/hardhat/script/setAllowToken.js
new file mode 100644
index 000000000..f1e62f9fc
--- /dev/null
+++ b/bridge/hardhat/script/setAllowToken.js
@@ -0,0 +1,45 @@
+// How to run the script: npx hardhat run ./hardhat/script/setAllowToken.js --network bsctestnet
+const hre = require("hardhat");
+
+async function main() {
+ const {getNamedAccounts, deployments} = hre;
+ const {deployer} = await getNamedAccounts();
+
+ const tokenToList = '0x00.....';
+ const tokenToListType = '0';
+ const AllowTokens = await deployments.get('AllowTokens');
+ const AllowTokensProxy = await deployments.get('AllowTokensProxy');
+ const MultiSigWallet = await deployments.get('MultiSigWallet');
+
+ const allowTokens = new web3.eth.Contract(AllowTokens.abi, AllowTokensProxy.address);
+ const multiSigContract = new web3.eth.Contract(MultiSigWallet.abi, MultiSigWallet.address);
+
+ console.log("\nAllowTokens", AllowTokens.address);
+ console.log("\nAllowTokensProxy", AllowTokensProxy.address);
+ console.log("\nMultiSigWallet", MultiSigWallet.address);
+
+ const methodCallSetToken = allowTokens.methods.setToken(tokenToList, tokenToListType);
+ const result = await methodCallSetToken.call({ from: MultiSigWallet.address});
+ console.log("Method call result", result);
+
+ const receipt = await multiSigContract.methods.submitTransaction(
+ AllowTokensProxy.address,
+ 0,
+ methodCallSetToken.encodeABI()
+ ).send({
+ from: deployer,
+ gasLimit: 3000000
+ });
+ console.log("Transaction worked", receipt.transactionHash);
+
+ console.log("finish");
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
diff --git a/bridge/hardhat/script/tryTxCall.js b/bridge/hardhat/script/tryTxCall.js
new file mode 100644
index 000000000..2e0ba373d
--- /dev/null
+++ b/bridge/hardhat/script/tryTxCall.js
@@ -0,0 +1,29 @@
+
+// How to run the script: npx hardhat run ./hardhat/script/getFeeConfig.js --network rsktestnetbsc
+const hre = require("hardhat");
+
+async function main() {
+
+ // Use the from, to and data sent in the transaction to see what is the revert reason
+ // In this example we use https://explorer.rsk.co/tx/0xddcdc5e6917b1f92069fe67585d288b42f1ee11f195597b73e00b206a42d20a3
+
+ const to = "0x9d11937E2179dC5270Aa86A3f8143232D6DA0E69";
+ const data = "0x7813bea2000000000000000000000000e700691da7b9851f2f35f8b8182c69c53ccad9db000000000000000000000000ad0eca47df3c9a226daaa62b1d8a1986c9e1a64b0000000000000000000000000000000000000000000000056bc75e2d63100000";
+ const from = "0xad0EcA47DF3C9a226dAAA62B1D8A1986c9e1A64b";
+
+ const result = await web3.eth.call({
+ to:to.toLowerCase(), // contract address
+ data: data,
+ from: from.toLowerCase()
+ });
+ console.log('Call successfull', result);
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
\ No newline at end of file
diff --git a/bridge/maindeploy.js b/bridge/maindeploy.js
deleted file mode 100644
index 196d32aba..000000000
--- a/bridge/maindeploy.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const fs = require('fs');
-const promisify = require('./test/utils').promisify;
-
-const FederatedManager = artifacts.require('./FederatedManager');
-const MainToken = artifacts.require('./MainToken');
-const Bridge = artifacts.require('./Bridge');
-
-async function run() {
- const accounts = await promisify(cb => web3.eth.getAccounts(cb));
-
- const members = [ accounts[1], accounts[2], accounts[3], accounts[4], accounts[5] ];
-
- const manager = await FederatedManager.new(members);
- console.log('Manager deployed at', manager.address);
-
- const token = await MainToken.new("MAIN", "MAIN", 18, 10000000);
- console.log('MainToken deployed at', token.address);
-
- const bridge = await Bridge.new(manager.address, token.address);
- console.log('Bridge deployed at', bridge.address);
-
- await manager.setTransferable(bridge.address);
- console.log('Bridge controlled by Manager');
-
- const config = {
- host: web3.currentProvider.host,
- accounts: accounts,
- bridge: bridge.address,
- token: token.address,
- manager: manager.address,
- members: members
- };
-
- fs.writeFileSync('mainconf.json', JSON.stringify(config, null, 4));
-}
-
-module.exports = function (cb) {
- run().then(function () {
- console.log('done');
- cb(null, null);
- });
-}
\ No newline at end of file
diff --git a/bridge/migrations/1_initial_migration.js b/bridge/migrations/1_initial_migration.js
deleted file mode 100644
index 4d5f3f9b0..000000000
--- a/bridge/migrations/1_initial_migration.js
+++ /dev/null
@@ -1,5 +0,0 @@
-var Migrations = artifacts.require("./Migrations.sol");
-
-module.exports = function(deployer) {
- deployer.deploy(Migrations);
-};
diff --git a/bridge/niamdeploy.js b/bridge/niamdeploy.js
deleted file mode 100644
index 31145659b..000000000
--- a/bridge/niamdeploy.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const fs = require('fs');
-const promisify = require('./test/utils').promisify;
-
-const FederatedManager = artifacts.require('./FederatedManager');
-const MainToken = artifacts.require('./MainToken');
-const Bridge = artifacts.require('./Bridge');
-
-async function run() {
- const accounts = await promisify(cb => web3.eth.getAccounts(cb));
-
- const members = [ accounts[1], accounts[2], accounts[3], accounts[4], accounts[5] ];
-
- const manager = await FederatedManager.new(members);
- console.log('Manager deployed at', manager.address);
-
- const token = await MainToken.new("NIAM", "NIAM", 18, 10000000);
- console.log('MainToken deployed at', token.address);
-
- const bridge = await Bridge.new(manager.address, token.address);
- console.log('Bridge deployed at', bridge.address);
-
- await manager.setTransferable(bridge.address);
- console.log('Bridge controlled by Manager');
-
- await token.transfer(bridge.address, 10000000);
- console.log('Bridge has token total supply');
-
- const config = {
- host: web3.currentProvider.host,
- accounts: accounts,
- bridge: bridge.address,
- token: token.address,
- manager: manager.address,
- members: members
- };
-
- fs.writeFileSync('sideconf.json', JSON.stringify(config, null, 4));
-}
-
-module.exports = function (cb) {
- run().then(function () {
- console.log('done');
- cb(null, null);
- });
-}
\ No newline at end of file
diff --git a/bridge/package-lock.json b/bridge/package-lock.json
new file mode 100644
index 000000000..9f20807c2
--- /dev/null
+++ b/bridge/package-lock.json
@@ -0,0 +1,39176 @@
+{
+ "name": "bridge",
+ "version": "3.0.0",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "bridge",
+ "version": "3.0.0",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@nomiclabs/hardhat-etherscan": "^3.0.1",
+ "@nomiclabs/hardhat-truffle5": "^2.0.0",
+ "@nomiclabs/hardhat-web3": "^2.0.0",
+ "@thinkanddev/deploy-eip-1820-web3-rsk": "^1.0.2",
+ "@thinkanddev/hardhat-erc1820-rsk": "^0.1.2",
+ "@truffle/compile-common": "^0.7.15",
+ "chalk": "^4.1.0",
+ "hardhat-contract-sizer": "^2.3.0",
+ "hardhat-deploy": "^0.9.24",
+ "hardhat-gas-reporter": "^1.0.6",
+ "npm-force-resolutions": "0.0.10",
+ "resolve": "^1.21.0",
+ "solhint": "^3.3.6",
+ "solidity-coverage": "^0.7.20",
+ "truffle-assertions": "^0.9.2"
+ },
+ "devDependencies": {
+ "coveralls": "^3.1.1",
+ "ethereum-waffle": "^3.4.0",
+ "hardhat": "^2.9.3",
+ "hardhat-abi-exporter": "^2.2.1",
+ "prettier": "^2.3.2",
+ "prettier-plugin-solidity": "^1.0.0-beta.17"
+ },
+ "engines": {
+ "node": "16"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/whatwg-fetch": {
+ "version": "2.0.4",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/ganache-core/node_modules/browserify-rsa": {
+ "version": "4.1.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bn.js": "^5.0.0",
+ "randombytes": "^2.0.1"
+ }
+ },
+ "node_modules/solhint/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/address": {
+ "version": "5.0.9",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.0.13",
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/keccak256": "^5.0.7",
+ "@ethersproject/logger": "^5.0.8",
+ "@ethersproject/rlp": "^5.0.7"
+ }
+ },
+ "node_modules/browserify-rsa": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
+ "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
+ "dependencies": {
+ "bn.js": "^5.0.0",
+ "randombytes": "^2.0.1"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
+ "optional": true,
+ "peer": true,
+ "bin": {
+ "detect-libc": "bin/detect-libc.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/then-request/node_modules/@types/node": {
+ "version": "8.10.66",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz",
+ "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw=="
+ },
+ "node_modules/ganache-core/node_modules/wrappy": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@trufflesuite/chromafi/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/mkdirp-promise": {
+ "version": "5.0.1",
+ "dev": true,
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "mkdirp": "*"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/web3-eth-contract": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.6.1.tgz",
+ "integrity": "sha512-GXqTe3mF6kpbOAakiNc7wtJ120/gpuKMTZjuGFKeeY8aobRLfbfgKzM9IpyqVZV2v5RLuGXDuurVN2KPgtu3hQ==",
+ "dependencies": {
+ "@types/bn.js": "^4.11.5",
+ "web3-core": "1.6.1",
+ "web3-core-helpers": "1.6.1",
+ "web3-core-method": "1.6.1",
+ "web3-core-promievent": "1.6.1",
+ "web3-core-subscriptions": "1.6.1",
+ "web3-eth-abi": "1.6.1",
+ "web3-utils": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/prr": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/body-parser/node_modules/qs": {
+ "version": "6.9.6",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz",
+ "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==",
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/resumer": {
+ "version": "0.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "through": "~2.3.4"
+ }
+ },
+ "node_modules/websocket": {
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz",
+ "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==",
+ "dependencies": {
+ "bufferutil": "^4.0.1",
+ "debug": "^2.2.0",
+ "es5-ext": "^0.10.50",
+ "typedarray-to-buffer": "^3.1.5",
+ "utf-8-validate": "^5.0.2",
+ "yaeti": "^0.0.6"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/abstract-signer": {
+ "version": "5.0.10",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/abstract-provider": "^5.0.8",
+ "@ethersproject/bignumber": "^5.0.13",
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/logger": "^5.0.8",
+ "@ethersproject/properties": "^5.0.7"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-amd": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/level-errors": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "errno": "~0.1.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/url-parse-lax": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+ "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+ "dependencies": {
+ "prepend-http": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ltgt": {
+ "version": "2.2.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@sentry/core": {
+ "version": "5.30.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz",
+ "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==",
+ "dependencies": {
+ "@sentry/hub": "5.30.0",
+ "@sentry/minimal": "5.30.0",
+ "@sentry/types": "5.30.0",
+ "@sentry/utils": "5.30.0",
+ "tslib": "^1.9.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
+ },
+ "node_modules/invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/yaeti": {
+ "version": "0.0.6",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.32"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dependencies": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/body-parser/node_modules/qs": {
+ "version": "6.7.0",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/randombytes": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/web3-core": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.6.1.tgz",
+ "integrity": "sha512-m+b7UfYvU5cQUAh6NRfxRzH/5B3to1AdEQi1HIQt570cDWlObOOmoO9tY6iJnI5w4acxIO19LqjDMqEJGBYyRQ==",
+ "dependencies": {
+ "@types/bn.js": "^4.11.5",
+ "@types/node": "^12.12.6",
+ "bignumber.js": "^9.0.0",
+ "web3-core-helpers": "1.6.1",
+ "web3-core-method": "1.6.1",
+ "web3-core-requestmanager": "1.6.1",
+ "web3-utils": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/browserify-cipher": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "browserify-aes": "^1.0.4",
+ "browserify-des": "^1.0.0",
+ "evp_bytestokey": "^1.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-helper-define-map": {
+ "version": "6.26.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "node_modules/ts-essentials": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz",
+ "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==",
+ "dev": true
+ },
+ "node_modules/@truffle/provider/node_modules/web3-providers-ipc": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz",
+ "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==",
+ "dependencies": {
+ "oboe": "2.1.5",
+ "web3-core-helpers": "1.5.3"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block/node_modules/ethereum-common": {
+ "version": "0.2.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/finalhandler/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/express/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/enquirer": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+ "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+ "dependencies": {
+ "ansi-colors": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/workerpool": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
+ "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A=="
+ },
+ "node_modules/ganache-core/node_modules/es5-ext": {
+ "version": "0.10.53",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "es6-iterator": "~2.0.3",
+ "es6-symbol": "~3.1.3",
+ "next-tick": "~1.0.0"
+ }
+ },
+ "node_modules/inquirer/node_modules/ansi-escapes": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+ "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eth-ens-namehash": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz",
+ "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=",
+ "dependencies": {
+ "idna-uts46-hx": "^2.3.1",
+ "js-sha3": "^0.5.7"
+ }
+ },
+ "node_modules/swarm-js/node_modules/get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dependencies": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/regex-not": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/content-disposition/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/@types/pbkdf2": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/scryptsy": {
+ "version": "1.2.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "pbkdf2": "^3.0.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/object-keys": {
+ "version": "0.4.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/gauge": {
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ }
+ },
+ "node_modules/mocha/node_modules/debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/patch-package/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-utils/node_modules/eth-lib": {
+ "version": "0.2.8",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bn.js": "^4.11.6",
+ "elliptic": "^6.4.0",
+ "xhr-request-promise": "^0.1.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/deferred-leveldown": {
+ "version": "1.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abstract-leveldown": "~2.6.0"
+ }
+ },
+ "node_modules/internal-slot": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
+ "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
+ "dependencies": {
+ "get-intrinsic": "^1.1.0",
+ "has": "^1.0.3",
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/patch-package/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/multicodec": {
+ "version": "0.5.7",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "varint": "^5.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/array-flatten": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+ },
+ "node_modules/get-port": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz",
+ "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/yargs-parser/node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/methods": {
+ "version": "1.1.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-typeof-symbol": {
+ "version": "6.23.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/fmix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz",
+ "integrity": "sha1-x7vxJN7ELJ0ZHPuUfQqXeN2YbAw=",
+ "dependencies": {
+ "imul": "^1.0.0"
+ }
+ },
+ "node_modules/test-value/node_modules/array-back": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+ "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+ "dev": true,
+ "dependencies": {
+ "typical": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree/node_modules/async": {
+ "version": "1.5.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/is-accessor-descriptor": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/encoding-down/node_modules/abstract-leveldown": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@yarnpkg/lockfile": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/ganache-core/node_modules/web3-bzz/node_modules/@types/node": {
+ "version": "12.19.12",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-tx": {
+ "version": "2.1.2",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-util": "^6.0.0"
+ }
+ },
+ "node_modules/flat": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz",
+ "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==",
+ "dependencies": {
+ "is-buffer": "~2.0.3"
+ },
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/@resolver-engine/imports-fs/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/node-emoji": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz",
+ "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==",
+ "dependencies": {
+ "lodash": "^4.17.21"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": {
+ "version": "6.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "0.1.6",
+ "rlp": "^2.2.3"
+ }
+ },
+ "node_modules/caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "node_modules/ganache-core/node_modules/extglob/node_modules/is-extendable": {
+ "version": "0.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-account": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "ethereumjs-util": "^6.0.0",
+ "rlp": "^2.2.1",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/cliui/node_modules/strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dependencies": {
+ "ansi-regex": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cli-table3": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz",
+ "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==",
+ "dependencies": {
+ "string-width": "^4.2.0"
+ },
+ "engines": {
+ "node": "10.* || >= 12.*"
+ },
+ "optionalDependencies": {
+ "colors": "1.4.0"
+ }
+ },
+ "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/node-hid": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-2.1.1.tgz",
+ "integrity": "sha512-Skzhqow7hyLZU93eIPthM9yjot9lszg9xrKxESleEs05V2NcbUptZc5HFqzjOkSmL0sFlZFr3kmvaYebx06wrw==",
+ "hasInstallScript": true,
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "bindings": "^1.5.0",
+ "node-addon-api": "^3.0.2",
+ "prebuild-install": "^6.0.0"
+ },
+ "bin": {
+ "hid-showdevices": "src/show-devices.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/path-starts-with": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-starts-with/-/path-starts-with-2.0.0.tgz",
+ "integrity": "sha512-3UHTHbJz5+NLkPafFR+2ycJOjoc4WV2e9qCZCnm71zHiWaFrm1XniLVTkZXvaRgxr1xFh9JsTdicpH2yM03nLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/web3-core-requestmanager": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz",
+ "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==",
+ "dependencies": {
+ "util": "^0.12.0",
+ "web3-core-helpers": "1.5.3",
+ "web3-providers-http": "1.5.3",
+ "web3-providers-ipc": "1.5.3",
+ "web3-providers-ws": "1.5.3"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/mkdirp-promise": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz",
+ "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=",
+ "deprecated": "This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.",
+ "dependencies": {
+ "mkdirp": "*"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/defer-to-connect": {
+ "version": "1.1.3",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/raw-body": {
+ "version": "2.4.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bytes": "3.1.0",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/escodegen/node_modules/estraverse": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
+ "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/min-document": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
+ "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
+ "dependencies": {
+ "dom-walk": "^0.1.0"
+ }
+ },
+ "node_modules/@ethereumjs/common": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.0.tgz",
+ "integrity": "sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA==",
+ "dependencies": {
+ "crc-32": "^1.2.0",
+ "ethereumjs-util": "^7.1.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-codec": {
+ "version": "7.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core": {
+ "version": "2.13.2",
+ "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz",
+ "integrity": "sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==",
+ "bundleDependencies": [
+ "keccak"
+ ],
+ "dev": true,
+ "hasShrinkwrap": true,
+ "dependencies": {
+ "cachedown": "1.0.0",
+ "websocket": "1.0.32",
+ "lodash": "4.17.20",
+ "ethereumjs-abi": "0.6.8",
+ "eth-sig-util": "3.0.0",
+ "ethereumjs-tx": "2.1.2",
+ "ethereumjs-util": "6.2.1",
+ "lru-cache": "5.1.1",
+ "ethereumjs-vm": "4.2.0",
+ "seedrandom": "3.0.1",
+ "patch-package": "6.2.2",
+ "async": "2.6.2",
+ "source-map-support": "0.5.12",
+ "ethereumjs-block": "2.2.2",
+ "keccak": "3.0.1",
+ "debug": "3.2.6",
+ "bip39": "2.5.0",
+ "ethereumjs-account": "3.0.0",
+ "heap": "0.2.6",
+ "encoding-down": "5.0.4",
+ "levelup": "3.1.1",
+ "level-sublevel": "6.6.4",
+ "merkle-patricia-tree": "3.0.0",
+ "clone": "2.1.2",
+ "web3-provider-engine": "14.2.1",
+ "ethereumjs-common": "1.5.0",
+ "abstract-leveldown": "3.0.0",
+ "tmp": "0.1.0"
+ },
+ "engines": {
+ "node": ">=8.9.0"
+ },
+ "optionalDependencies": {
+ "ethereumjs-wallet": "0.6.5",
+ "web3": "1.2.11"
+ }
+ },
+ "node_modules/ganache-core/node_modules/core-util-is": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/destroy": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-common": {
+ "version": "1.5.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/table": {
+ "version": "5.4.6",
+ "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
+ "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
+ "dependencies": {
+ "ajv": "^6.10.2",
+ "lodash": "^4.17.14",
+ "slice-ansi": "^2.1.0",
+ "string-width": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/miller-rabin": {
+ "version": "4.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bn.js": "^4.0.0",
+ "brorand": "^1.0.1"
+ },
+ "bin": {
+ "miller-rabin": "bin/miller-rabin"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/jsonify": {
+ "version": "0.0.0",
+ "dev": true,
+ "license": "Public Domain"
+ },
+ "node_modules/yargs/node_modules/locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dependencies": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/web3-core-subscriptions": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz",
+ "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==",
+ "dependencies": {
+ "eventemitter3": "4.0.4",
+ "web3-core-helpers": "1.5.3"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-types": {
+ "version": "6.26.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.26.0",
+ "esutils": "^2.0.2",
+ "lodash": "^4.17.4",
+ "to-fast-properties": "^1.0.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/atob": {
+ "version": "2.1.2",
+ "dev": true,
+ "license": "(MIT OR Apache-2.0)",
+ "bin": {
+ "atob": "bin/atob.js"
+ },
+ "engines": {
+ "node": ">= 4.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/debug": {
+ "version": "3.2.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
+ },
+ "node_modules/eslint-utils": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
+ "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
+ "dependencies": {
+ "eslint-visitor-keys": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/create-hmac": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+ "dependencies": {
+ "cipher-base": "^1.0.3",
+ "create-hash": "^1.1.0",
+ "inherits": "^2.0.1",
+ "ripemd160": "^2.0.0",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/once": {
+ "version": "1.4.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/solhint": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.3.6.tgz",
+ "integrity": "sha512-HWUxTAv2h7hx3s3hAab3ifnlwb02ZWhwFU/wSudUHqteMS3ll9c+m1FlGn9V8ztE2rf3Z82fQZA005Wv7KpcFA==",
+ "dependencies": {
+ "@solidity-parser/parser": "^0.13.2",
+ "ajv": "^6.6.1",
+ "antlr4": "4.7.1",
+ "ast-parents": "0.0.1",
+ "chalk": "^2.4.2",
+ "commander": "2.18.0",
+ "cosmiconfig": "^5.0.7",
+ "eslint": "^5.6.0",
+ "fast-diff": "^1.1.2",
+ "glob": "^7.1.3",
+ "ignore": "^4.0.6",
+ "js-yaml": "^3.12.0",
+ "lodash": "^4.17.11",
+ "semver": "^6.3.0"
+ },
+ "bin": {
+ "solhint": "solhint.js"
+ },
+ "optionalDependencies": {
+ "prettier": "^1.14.3"
+ }
+ },
+ "node_modules/@ethereumjs/vm/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/exit-on-epipe": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
+ "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/@types/resolve": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
+ "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/handlebars": {
+ "version": "4.7.7",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
+ "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
+ "dependencies": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.0",
+ "source-map": "^0.6.1",
+ "wordwrap": "^1.0.0"
+ },
+ "bin": {
+ "handlebars": "bin/handlebars"
+ },
+ "engines": {
+ "node": ">=0.4.7"
+ },
+ "optionalDependencies": {
+ "uglify-js": "^3.1.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/min-document": {
+ "version": "2.19.0",
+ "dev": true,
+ "dependencies": {
+ "dom-walk": "^0.1.0"
+ }
+ },
+ "node_modules/hardhat/node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babelify": {
+ "version": "7.3.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-core": "^6.0.14",
+ "object-assign": "^4.0.0"
+ }
+ },
+ "node_modules/prettier-plugin-solidity/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@truffle/contract-schema": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/@truffle/contract-schema/-/contract-schema-3.4.4.tgz",
+ "integrity": "sha512-xWgrm6WRM2jmT04w7dP7aVbS2qyP9XPmH/mybQtFXMjJ/8BZlp0yltC8QOs8sGl6q8Ws7acp19YtRkLdK6SsmQ==",
+ "dependencies": {
+ "ajv": "^6.10.0",
+ "debug": "^4.3.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/typewise": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "typewise-core": "^1.2.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/cachedown/node_modules/abstract-leveldown": {
+ "version": "2.7.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/@sentry/hub": {
+ "version": "5.30.0",
+ "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz",
+ "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==",
+ "dependencies": {
+ "@sentry/types": "5.30.0",
+ "@sentry/utils": "5.30.0",
+ "tslib": "^1.9.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/invariant": {
+ "version": "2.2.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-regex": {
+ "version": "2.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/precond": {
+ "version": "0.2.3",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-core-method": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/transactions": "^5.0.0-beta.135",
+ "underscore": "1.9.1",
+ "web3-core-helpers": "1.2.11",
+ "web3-core-promievent": "1.2.11",
+ "web3-core-subscriptions": "1.2.11",
+ "web3-utils": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-for-of": {
+ "version": "6.23.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/object-copy/node_modules/is-accessor-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/buffer-to-arraybuffer": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz",
+ "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo="
+ },
+ "node_modules/web3-eth": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.6.1.tgz",
+ "integrity": "sha512-kOV1ZgCKypSo5BQyltRArS7ZC3bRpIKAxSgzl7pUFinUb/MxfbM9KGeNxUXoCfTSErcCQJaDjcS6bSre5EMKuQ==",
+ "dependencies": {
+ "web3-core": "1.6.1",
+ "web3-core-helpers": "1.6.1",
+ "web3-core-method": "1.6.1",
+ "web3-core-subscriptions": "1.6.1",
+ "web3-eth-abi": "1.6.1",
+ "web3-eth-accounts": "1.6.1",
+ "web3-eth-contract": "1.6.1",
+ "web3-eth-ens": "1.6.1",
+ "web3-eth-iban": "1.6.1",
+ "web3-eth-personal": "1.6.1",
+ "web3-net": "1.6.1",
+ "web3-utils": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ajv": {
+ "version": "6.12.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
+ "node_modules/@ensdomains/ens/node_modules/fs-extra": {
+ "version": "0.30.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+ "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0",
+ "path-is-absolute": "^1.0.0",
+ "rimraf": "^2.2.8"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz",
+ "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dependencies": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@sentry/node": {
+ "version": "5.30.0",
+ "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz",
+ "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==",
+ "dependencies": {
+ "@sentry/core": "5.30.0",
+ "@sentry/hub": "5.30.0",
+ "@sentry/tracing": "5.30.0",
+ "@sentry/types": "5.30.0",
+ "@sentry/utils": "5.30.0",
+ "cookie": "^0.4.1",
+ "https-proxy-agent": "^5.0.0",
+ "lru_map": "^0.3.3",
+ "tslib": "^1.9.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/web3-core/node_modules/@types/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/are-we-there-yet": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz",
+ "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/utils-merge": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/sshpk/node_modules/tweetnacl": {
+ "version": "0.14.5",
+ "dev": true,
+ "license": "Unlicense"
+ },
+ "node_modules/@ethereumjs/blockchain/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/rxjs": {
+ "version": "6.6.7",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+ "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+ "dependencies": {
+ "tslib": "^1.9.0"
+ },
+ "engines": {
+ "npm": ">=2.0.0"
+ }
+ },
+ "node_modules/ultron": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
+ "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
+ },
+ "node_modules/@resolver-engine/imports": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz",
+ "integrity": "sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==",
+ "dev": true,
+ "dependencies": {
+ "@resolver-engine/core": "^0.3.3",
+ "debug": "^3.1.0",
+ "hosted-git-info": "^2.6.0",
+ "path-browserify": "^1.0.0",
+ "url": "^0.11.0"
+ }
+ },
+ "node_modules/cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/swarm-js/node_modules/url-parse-lax": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+ "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+ "dependencies": {
+ "prepend-http": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/snapdragon-node/node_modules/define-property": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/tape/node_modules/resolve": {
+ "version": "1.17.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-parse": "^1.0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+ "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+ "dependencies": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/core-js-pure": {
+ "version": "3.8.2",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-symbol": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/content-hash": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz",
+ "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==",
+ "dependencies": {
+ "cids": "^0.7.1",
+ "multicodec": "^0.5.5",
+ "multihashes": "^0.4.15"
+ }
+ },
+ "node_modules/ganache-core/node_modules/punycode": {
+ "version": "2.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/idna-uts46-hx/node_modules/punycode": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@truffle/codec/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/slice-ansi/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "node_modules/errno": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
+ "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
+ "dependencies": {
+ "prr": "~1.0.1"
+ },
+ "bin": {
+ "errno": "cli.js"
+ }
+ },
+ "node_modules/diff": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-sticky-regex": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-regex": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws": {
+ "version": "0.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "~1.0.15",
+ "xtend": "~2.1.1"
+ }
+ },
+ "node_modules/@ledgerhq/hw-transport": {
+ "version": "5.26.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.26.0.tgz",
+ "integrity": "sha512-NFeJOJmyEfAX8uuIBTpocWHcz630sqPcXbu864Q+OCBm4EK5UOKV1h/pX7e0xgNIKY8zhJ/O4p4cIZp9tnXLHQ==",
+ "peer": true,
+ "dependencies": {
+ "@ledgerhq/devices": "^5.26.0",
+ "@ledgerhq/errors": "^5.26.0",
+ "events": "^3.2.0"
+ }
+ },
+ "node_modules/varint": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
+ "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
+ },
+ "node_modules/decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/regjsparser/node_modules/jsesc": {
+ "version": "0.5.0",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ }
+ },
+ "node_modules/servify": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz",
+ "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==",
+ "dependencies": {
+ "body-parser": "^1.16.0",
+ "cors": "^2.8.1",
+ "express": "^4.14.0",
+ "request": "^2.79.0",
+ "xhr": "^2.3.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/eslint/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/async": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
+ "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
+ "dependencies": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
+ "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+ "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "node_modules/ganache-core/node_modules/urix": {
+ "version": "0.1.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/tar/node_modules/minipass": {
+ "version": "2.9.0",
+ "dev": true,
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.0"
+ }
+ },
+ "node_modules/then-request/node_modules/form-data": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
+ "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 0.12"
+ }
+ },
+ "node_modules/inquirer/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/os-homedir": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/js-sha3": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+ "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/arr-diff": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "5.16.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
+ "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
+ "dependencies": {
+ "ignore": "^4.0.6",
+ "table": "^5.2.3",
+ "eslint-scope": "^4.0.3",
+ "js-yaml": "^3.13.0",
+ "semver": "^5.5.1",
+ "natural-compare": "^1.4.0",
+ "doctrine": "^3.0.0",
+ "file-entry-cache": "^5.0.1",
+ "progress": "^2.0.0",
+ "functional-red-black-tree": "^1.0.1",
+ "eslint-visitor-keys": "^1.0.0",
+ "strip-ansi": "^4.0.0",
+ "text-table": "^0.2.0",
+ "import-fresh": "^3.0.0",
+ "lodash": "^4.17.11",
+ "path-is-inside": "^1.0.2",
+ "espree": "^5.0.1",
+ "imurmurhash": "^0.1.4",
+ "cross-spawn": "^6.0.5",
+ "regexpp": "^2.0.1",
+ "eslint-utils": "^1.3.1",
+ "inquirer": "^6.2.2",
+ "chalk": "^2.1.0",
+ "strip-json-comments": "^2.0.1",
+ "debug": "^4.0.1",
+ "ajv": "^6.9.1",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.3.0",
+ "esutils": "^2.0.2",
+ "globals": "^11.7.0",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "esquery": "^1.0.1",
+ "optionator": "^0.8.2",
+ "glob": "^7.1.2",
+ "@babel/code-frame": "^7.0.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^6.14.0 || ^8.10.0 || >=9.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-core-subscriptions": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "eventemitter3": "4.0.4",
+ "underscore": "1.9.1",
+ "web3-core-helpers": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/path-to-regexp": {
+ "version": "0.1.7",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+ "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true
+ },
+ "node_modules/hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "dev": true
+ },
+ "node_modules/ganache-core/node_modules/object-assign": {
+ "version": "4.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/randomfill": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "randombytes": "^2.0.5",
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/@ethersproject/abstract-signer": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz",
+ "integrity": "sha512-lj//7r250MXVLKI7sVarXAbZXbv9P50lgmJQGr2/is82EwEb8r7HrxsmMqAjTsztMYy7ohrIhGMIml+Gx4D3mA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/abstract-provider": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0"
+ }
+ },
+ "node_modules/hardhat/node_modules/mocha/node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/public-encrypt": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+ "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+ "dependencies": {
+ "bn.js": "^4.1.0",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "parse-asn1": "^5.0.0",
+ "randombytes": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-helper-remap-async-to-generator": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/eth-gas-reporter/node_modules/ethereumjs-util": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz",
+ "integrity": "sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ==",
+ "dependencies": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "ethjs-util": "0.1.6",
+ "keccak": "^2.0.0",
+ "rlp": "^2.2.3",
+ "secp256k1": "^3.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/caseless": {
+ "version": "0.12.0",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-errors": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "errno": "~0.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoping": {
+ "version": "6.26.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/split-string": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "dependencies": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/espree": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
+ "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
+ "dependencies": {
+ "acorn": "^6.0.7",
+ "acorn-jsx": "^5.0.0",
+ "eslint-visitor-keys": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-template": {
+ "version": "6.26.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/expand-brackets/node_modules/ms": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/regjsgen": {
+ "version": "0.2.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@ethersproject/constants": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.5.0.tgz",
+ "integrity": "sha512-2MsRRVChkvMWR+GyMGY4N1sAX9Mt3J9KykCsgUFd/1mwS0UH1qw+Bv9k1UJb3X3YJYFco9H20pjSlOIfCG5HYQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/tmp": {
+ "version": "0.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "rimraf": "^2.6.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.16.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz",
+ "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/has-values/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware": {
+ "version": "1.6.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "async": "^2.5.0",
+ "eth-query": "^2.1.2",
+ "eth-tx-summary": "^3.1.2",
+ "ethereumjs-block": "^1.6.0",
+ "ethereumjs-tx": "^1.3.3",
+ "ethereumjs-util": "^5.1.2",
+ "ethereumjs-vm": "^2.1.0",
+ "fetch-ponyfill": "^4.0.0",
+ "json-rpc-engine": "^3.6.0",
+ "json-rpc-error": "^2.0.0",
+ "json-stable-stringify": "^1.0.1",
+ "promise-to-callback": "^1.0.0",
+ "tape": "^4.6.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/cookiejar": {
+ "version": "2.1.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/@babel/highlight/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/uuid": {
+ "version": "3.3.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "bin": {
+ "uuid": "bin/uuid"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-block-tracker": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eth-query": "^2.1.0",
+ "ethereumjs-tx": "^1.3.3",
+ "ethereumjs-util": "^5.1.3",
+ "ethjs-util": "^0.1.3",
+ "json-rpc-engine": "^3.6.0",
+ "pify": "^2.3.0",
+ "tape": "^4.6.3"
+ }
+ },
+ "node_modules/sync-request": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz",
+ "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==",
+ "dependencies": {
+ "http-response-object": "^3.0.1",
+ "sync-rpc": "^1.2.1",
+ "then-request": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/concat-stream/node_modules/readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/for-each": {
+ "version": "0.3.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "node_modules/utf8": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz",
+ "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ=="
+ },
+ "node_modules/@ledgerhq/devices": {
+ "version": "5.51.1",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-5.51.1.tgz",
+ "integrity": "sha512-4w+P0VkbjzEXC7kv8T1GJ/9AVaP9I6uasMZ/JcdwZBS3qwvKo5A5z9uGhP5c7TvItzcmPb44b5Mw2kT+WjUuAA==",
+ "peer": true,
+ "dependencies": {
+ "@ledgerhq/errors": "^5.50.0",
+ "@ledgerhq/logs": "^5.50.0",
+ "rxjs": "6",
+ "semver": "^7.3.5"
+ }
+ },
+ "node_modules/web3-core-promievent": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.6.1.tgz",
+ "integrity": "sha512-byJ5s2MQxrWdXd27pWFmujfzsTZK4ik8rDgIV1RFDFc+rHZ2nZhq+VWk7t/Nkrj7EaVXncEgTdPEHc18nx+ocQ==",
+ "dependencies": {
+ "eventemitter3": "4.0.4"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/extglob/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/web3-shh": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.6.1.tgz",
+ "integrity": "sha512-oP00HbAtybLCGlLOZUYXOdeB9xq88k2l0TtStvKBtmFqRt+zVk5TxEeuOnVPRxNhcA2Un8RUw6FtvgZlWStu9A==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "web3-core": "1.6.1",
+ "web3-core-method": "1.6.1",
+ "web3-core-subscriptions": "1.6.1",
+ "web3-net": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@sentry/utils": {
+ "version": "5.30.0",
+ "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz",
+ "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==",
+ "dependencies": {
+ "@sentry/types": "5.30.0",
+ "tslib": "^1.9.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/mkdirp-classic": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/ganache-core/node_modules/color-convert": {
+ "version": "1.9.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-bzz": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "@types/node": "^12.12.6",
+ "got": "9.6.0",
+ "swarm-js": "^0.1.40",
+ "underscore": "1.9.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/hardhat/node_modules/yargs-parser": {
+ "version": "20.2.4",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+ "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/death": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz",
+ "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg="
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/ganache-core/node_modules/map-cache": {
+ "version": "0.2.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/flow-stoplight": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@truffle/interface-adapter/node_modules/bn.js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
+ },
+ "node_modules/ganache-core/node_modules/level-mem/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "node_modules/ganache-core/node_modules/level-mem/node_modules/ltgt": {
+ "version": "2.2.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/level-codec": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz",
+ "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==",
+ "dependencies": {
+ "buffer": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/encoding/node_modules/iconv-lite": {
+ "version": "0.6.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/statuses": {
+ "version": "1.5.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/bip39": {
+ "version": "2.5.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "create-hash": "^1.1.0",
+ "pbkdf2": "^3.0.9",
+ "randombytes": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "unorm": "^1.3.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block/node_modules/ethereum-common": {
+ "version": "0.2.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/swarm-js/node_modules/prepend-http": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/unset-value": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/tweetnacl-util": {
+ "version": "0.15.1",
+ "dev": true,
+ "license": "Unlicense"
+ },
+ "node_modules/@ethersproject/contracts": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.5.0.tgz",
+ "integrity": "sha512-2viY7NzyvJkh+Ug17v7g3/IJC8HqZBDcOjYARZLdzRxrfGlRgmYgl6xPRKVbEzy1dWKw/iv7chDcS83pg6cLxg==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/abi": "^5.5.0",
+ "@ethersproject/abstract-provider": "^5.5.0",
+ "@ethersproject/abstract-signer": "^5.5.0",
+ "@ethersproject/address": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/constants": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/transactions": "^5.5.0"
+ }
+ },
+ "node_modules/req-cwd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz",
+ "integrity": "sha1-1AgrTURZgDZkD7c93qAe1T20nrw=",
+ "dependencies": {
+ "req-from": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mocha/node_modules/js-yaml": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+ "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/node-fetch": {
+ "version": "1.7.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "encoding": "^0.1.11",
+ "is-stream": "^1.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/crypto-browserify": {
+ "version": "3.12.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "browserify-cipher": "^1.0.0",
+ "browserify-sign": "^4.0.0",
+ "create-ecdh": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.0",
+ "diffie-hellman": "^5.0.0",
+ "inherits": "^2.0.1",
+ "pbkdf2": "^3.0.3",
+ "public-encrypt": "^4.0.0",
+ "randombytes": "^2.0.0",
+ "randomfill": "^1.0.3"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/hardhat/node_modules/is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
+ },
+ "node_modules/@sentry/tracing/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/semver": {
+ "version": "5.4.1",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/hardhat/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-traverse/node_modules/debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/xhr2-cookies": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz",
+ "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=",
+ "dependencies": {
+ "cookiejar": "^2.1.1"
+ }
+ },
+ "node_modules/hardhat/node_modules/solc/node_modules/fs-extra": {
+ "version": "0.30.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+ "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0",
+ "path-is-absolute": "^1.0.0",
+ "rimraf": "^2.2.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/levelup": {
+ "version": "1.3.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deferred-leveldown": "~1.2.1",
+ "level-codec": "~7.0.0",
+ "level-errors": "~1.0.3",
+ "level-iterator-stream": "~1.3.0",
+ "prr": "~1.0.1",
+ "semver": "~5.4.1",
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/@truffle/compile-common/node_modules/@truffle/error": {
+ "version": "0.0.14",
+ "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.14.tgz",
+ "integrity": "sha512-utJx+SZYoMqk8wldQG4gCVKhV8GwMJbWY7sLXFT/D8wWZTnE2peX7URFJh/cxkjTRCO328z1s2qewkhyVsu2HA=="
+ },
+ "node_modules/entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
+ "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/solidity-comments-extractor": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz",
+ "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==",
+ "dev": true
+ },
+ "node_modules/ganache-core/node_modules/performance-now": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/log-symbols/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "2.6.6",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz",
+ "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ }
+ },
+ "node_modules/imul": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz",
+ "integrity": "sha1-nVhnFh6LPelsLDjV3HyxAvNeKsk=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/send": {
+ "version": "0.17.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.7.2",
+ "mime": "1.6.0",
+ "ms": "2.1.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/log-symbols/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/has-values/node_modules/kind-of": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ts-generator/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/array-back": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+ "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+ "dev": true,
+ "dependencies": {
+ "typical": "^2.6.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@resolver-engine/imports/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/@ethersproject/signing-key": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.5.0.tgz",
+ "integrity": "sha512-5VmseH7qjtNmDdZBswavhotYbWB0bOwKIlOTSlX14rKn5c11QmJwGt4GHeo7NrL/Ycl7uo9AHvEqs5xZgFBTng==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "bn.js": "^4.11.9",
+ "elliptic": "6.5.4",
+ "hash.js": "1.1.7"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-computed-properties": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "node_modules/request": {
+ "version": "2.88.2",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+ "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
+ "dependencies": {
+ "isstream": "~0.1.2",
+ "oauth-sign": "~0.9.0",
+ "safe-buffer": "^5.1.2",
+ "is-typedarray": "~1.0.0",
+ "json-stringify-safe": "~5.0.1",
+ "performance-now": "^2.1.0",
+ "http-signature": "~1.2.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2",
+ "har-validator": "~5.1.3",
+ "extend": "~3.0.2",
+ "mime-types": "~2.1.19",
+ "tough-cookie": "~2.5.0",
+ "aws-sign2": "~0.7.0",
+ "caseless": "~0.12.0",
+ "aws4": "^1.8.0",
+ "forever-agent": "~0.6.1",
+ "combined-stream": "~1.0.6",
+ "form-data": "~2.3.2",
+ "qs": "~6.5.2"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream/node_modules/readable-stream": {
+ "version": "1.1.14",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/got/node_modules/mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/printj": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
+ "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==",
+ "bin": {
+ "printj": "bin/printj.njs"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cids/node_modules/multicodec": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz",
+ "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==",
+ "deprecated": "This module has been superseded by the multiformats module",
+ "dependencies": {
+ "buffer": "^5.6.0",
+ "varint": "^5.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/util.promisify": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "for-each": "^0.3.3",
+ "has-symbols": "^1.0.1",
+ "object.getownpropertydescriptors": "^2.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+ "dependencies": {
+ "dom-serializer": "^1.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/murmur-128": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/murmur-128/-/murmur-128-0.2.1.tgz",
+ "integrity": "sha512-WseEgiRkI6aMFBbj8Cg9yBj/y+OdipwVC7zUo3W2W1JAJITwouUOtpqsmGSg67EQmwwSyod7hsVsWY5LsrfQVg==",
+ "dependencies": {
+ "encode-utf8": "^1.0.2",
+ "fmix": "^0.1.0",
+ "imul": "^1.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/qs": {
+ "version": "6.5.2",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/borc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/borc/-/borc-2.1.2.tgz",
+ "integrity": "sha512-Sy9eoUi4OiKzq7VovMn246iTo17kzuyHJKomCfpWMlI6RpfN1gk95w7d7gH264nApVLg0HZfcpz62/g4VH1Y4w==",
+ "dependencies": {
+ "bignumber.js": "^9.0.0",
+ "buffer": "^5.5.0",
+ "commander": "^2.15.0",
+ "ieee754": "^1.1.13",
+ "iso-url": "~0.4.7",
+ "json-text-sequence": "~0.1.0",
+ "readable-stream": "^3.6.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/xtend": {
+ "version": "2.1.2",
+ "dev": true,
+ "dependencies": {
+ "object-keys": "~0.4.0"
+ },
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-check-es2015-constants": {
+ "version": "6.22.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/forwarded": {
+ "version": "0.1.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/chalk": {
+ "version": "2.4.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-utils": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "bn.js": "^4.11.9",
+ "eth-lib": "0.2.8",
+ "ethereum-bloom-filters": "^1.0.6",
+ "ethjs-unit": "0.1.6",
+ "number-to-bn": "1.7.0",
+ "randombytes": "^2.1.0",
+ "underscore": "1.9.1",
+ "utf8": "3.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ghost-testrpc/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": {
+ "version": "2.2.2",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^2.0.1",
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-tx": "^2.1.1",
+ "ethereumjs-util": "^5.0.0",
+ "merkle-patricia-tree": "^2.1.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/readable-stream": {
+ "version": "1.0.34",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/@ethereumjs/blockchain": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.1.tgz",
+ "integrity": "sha512-JS2jeKxl3tlaa5oXrZ8mGoVBCz6YqsGG350XVNtHAtNZXKk7pU3rH4xzF2ru42fksMMqzFLzKh9l4EQzmNWDqA==",
+ "dependencies": {
+ "@ethereumjs/block": "^3.6.0",
+ "@ethereumjs/common": "^2.6.0",
+ "@ethereumjs/ethash": "^1.1.0",
+ "debug": "^2.2.0",
+ "ethereumjs-util": "^7.1.3",
+ "level-mem": "^5.0.1",
+ "lru-cache": "^5.1.1",
+ "semaphore-async-await": "^1.5.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/call-bind": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/web3-net": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.6.1.tgz",
+ "integrity": "sha512-gpnqKEIwfUHh5ik7wsQFlCje1DfcmGv+Sk7LCh1hCqn++HEDQxJ/mZCrMo11ZZpZHCH7c87imdxTg96GJnRxDw==",
+ "dependencies": {
+ "web3-core": "1.6.1",
+ "web3-core-method": "1.6.1",
+ "web3-utils": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@metamask/eth-sig-util": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz",
+ "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==",
+ "dependencies": {
+ "ethereumjs-abi": "^0.6.8",
+ "ethereumjs-util": "^6.2.1",
+ "ethjs-util": "^0.1.6",
+ "tweetnacl": "^1.0.3",
+ "tweetnacl-util": "^0.15.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "devOptional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "dependencies": {
+ "has-bigints": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@nomiclabs/hardhat-truffle5": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-truffle5/-/hardhat-truffle5-2.0.3.tgz",
+ "integrity": "sha512-KbRrFB4NwppzwR8XkYyOopOO6XWOSqtxIoavCIDQ5iIikuZC+WGGoFgeHxypipk5qfD0DWi031IZlXBjOOuYAQ==",
+ "dependencies": {
+ "@nomiclabs/truffle-contract": "^4.2.23",
+ "@types/chai": "^4.2.0",
+ "chai": "^4.2.0",
+ "ethereumjs-util": "^7.1.3",
+ "fs-extra": "^7.0.1"
+ },
+ "peerDependencies": {
+ "@nomiclabs/hardhat-web3": "^2.0.0",
+ "hardhat": "^2.6.4",
+ "web3": "^1.0.0-beta.36"
+ }
+ },
+ "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/get-func-name": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/is-function": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz",
+ "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ=="
+ },
+ "node_modules/lodash.assign": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
+ "dev": true
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/web": {
+ "version": "5.0.12",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/base64": "^5.0.7",
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/logger": "^5.0.8",
+ "@ethersproject/properties": "^5.0.7",
+ "@ethersproject/strings": "^5.0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ts-generator/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/fake-merkle-patricia-tree": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "checkpoint-store": "^1.1.0"
+ }
+ },
+ "node_modules/eth-gas-reporter/node_modules/@types/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/pbkdf2": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
+ "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
+ "dependencies": {
+ "create-hash": "^1.1.2",
+ "create-hmac": "^1.1.4",
+ "ripemd160": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ },
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
+ "node_modules/ganache-core/node_modules/timed-out": {
+ "version": "4.0.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/simple-get": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
+ "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "decompress-response": "^4.2.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
+ "node_modules/@types/minimatch": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
+ "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ=="
+ },
+ "node_modules/ganache-core/node_modules/extglob": {
+ "version": "2.0.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/concat-stream/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/yallist": {
+ "version": "3.1.1",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@truffle/provider/node_modules/@types/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-template-literals": {
+ "version": "6.22.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/body-parser/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/domhandler": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz",
+ "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==",
+ "dependencies": {
+ "domelementtype": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/base": {
+ "version": "0.11.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/strip-ansi": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/find-replace": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz",
+ "integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^1.0.4",
+ "test-value": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/request-promise-core": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
+ "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
+ "dependencies": {
+ "lodash": "^4.17.19"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "peerDependencies": {
+ "request": "^2.34"
+ }
+ },
+ "node_modules/decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+ "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block/node_modules/ethereum-common": {
+ "version": "0.2.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tough-cookie/node_modules/punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/class-utils": {
+ "version": "0.3.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/web3-eth-iban": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz",
+ "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==",
+ "dependencies": {
+ "bn.js": "^4.11.9",
+ "web3-utils": "1.5.3"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/hardhat/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/typedarray": {
+ "version": "0.0.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/ganache-core/node_modules/type": {
+ "version": "1.2.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ganache-core/node_modules/is-date-object": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string-width/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm": {
+ "version": "2.6.0",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^2.1.2",
+ "async-eventemitter": "^0.2.2",
+ "ethereumjs-account": "^2.0.3",
+ "ethereumjs-block": "~2.2.0",
+ "ethereumjs-common": "^1.1.0",
+ "ethereumjs-util": "^6.0.0",
+ "fake-merkle-patricia-tree": "^1.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "merkle-patricia-tree": "^2.3.2",
+ "rustbn.js": "~0.2.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/clone": {
+ "version": "2.1.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/diffie-hellman": {
+ "version": "5.0.3",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bn.js": "^4.1.0",
+ "miller-rabin": "^4.0.0",
+ "randombytes": "^2.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": {
+ "version": "5.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.34",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
+ "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
+ "dependencies": {
+ "mime-db": "1.51.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/table/node_modules/string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dependencies": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/logger": {
+ "version": "5.0.8",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/es-to-primitive": {
+ "version": "1.2.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hardhat-contract-sizer": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.3.1.tgz",
+ "integrity": "sha512-pW4DoJAgkP2ouLs7Fbg8rqNbFDQ2oz1sv2jkE9DWObzd0IG42YonXK4unQLCHvEUWzbp68sBjPCnrDMoc/JZfA==",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "cli-table3": "^0.6.0"
+ },
+ "peerDependencies": {
+ "hardhat": "^2.0.0"
+ }
+ },
+ "node_modules/inquirer/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/blakejs": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz",
+ "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg=="
+ },
+ "node_modules/ganache-core/node_modules/defined": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/swarm-js/node_modules/fs-minipass": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
+ "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
+ "dependencies": {
+ "minipass": "^2.6.0"
+ }
+ },
+ "node_modules/getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dependencies": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/minizlib": {
+ "version": "1.3.3",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "minipass": "^2.9.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/isarray": {
+ "version": "0.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/pascalcase": {
+ "version": "0.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@trufflesuite/chromafi/node_modules/highlight.js": {
+ "version": "10.7.3",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
+ "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/query-string": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+ "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+ "dependencies": {
+ "decode-uri-component": "^0.2.0",
+ "object-assign": "^4.1.0",
+ "strict-uri-encode": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/supports-color": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ext/node_modules/type": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-classes": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-define-map": "^6.24.1",
+ "babel-helper-function-name": "^6.24.1",
+ "babel-helper-optimise-call-expression": "^6.24.1",
+ "babel-helper-replace-supers": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree/node_modules/async": {
+ "version": "1.5.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@ethersproject/properties": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.5.0.tgz",
+ "integrity": "sha512-l3zRQg3JkD8EL3CPjNK5g7kMx4qSwiR60/uk5IVjd3oq1MZR5qUg40CNOoEJoX5wc3DyY5bt9EbMk86C7x0DNA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/logger": "^5.5.0"
+ }
+ },
+ "node_modules/@ethereum-waffle/compiler": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.4.0.tgz",
+ "integrity": "sha512-a2wxGOoB9F1QFRE+Om7Cz2wn+pxM/o7a0a6cbwhaS2lECJgFzeN9xEkVrKahRkF4gEfXGcuORg4msP0Asxezlw==",
+ "dev": true,
+ "dependencies": {
+ "@resolver-engine/imports": "^0.3.3",
+ "@resolver-engine/imports-fs": "^0.3.3",
+ "@typechain/ethers-v5": "^2.0.0",
+ "@types/mkdirp": "^0.5.2",
+ "@types/node-fetch": "^2.5.5",
+ "ethers": "^5.0.1",
+ "mkdirp": "^0.5.1",
+ "node-fetch": "^2.6.1",
+ "solc": "^0.6.3",
+ "ts-generator": "^0.1.1",
+ "typechain": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "node_modules/@babel/highlight/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/getpass": {
+ "version": "0.1.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "node_modules/solc/node_modules/fs-extra": {
+ "version": "0.30.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+ "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0",
+ "path-is-absolute": "^1.0.0",
+ "rimraf": "^2.2.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi": {
+ "version": "0.6.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bn.js": "^4.10.0",
+ "ethereumjs-util": "^4.3.0"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/web3-eth-iban/node_modules/bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
+ },
+ "node_modules/growl": {
+ "version": "1.10.5",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+ "engines": {
+ "node": ">=4.x"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
+ },
+ "node_modules/ganache-core/node_modules/mime": {
+ "version": "1.6.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/yaeti": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
+ "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=",
+ "engines": {
+ "node": ">=0.10.32"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-providers-http": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "web3-core-helpers": "1.2.11",
+ "xhr2-cookies": "1.1.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/eth-lib": {
+ "version": "0.1.29",
+ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz",
+ "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==",
+ "dependencies": {
+ "bn.js": "^4.11.6",
+ "elliptic": "^6.4.0",
+ "nano-json-stream-parser": "^0.1.2",
+ "servify": "^0.1.12",
+ "ws": "^3.0.0",
+ "xhr-request-promise": "^0.1.2"
+ }
+ },
+ "node_modules/axios": {
+ "version": "^0.21.2",
+ "dependencies": {
+ "follow-redirects": "^1.14.0"
+ }
+ },
+ "node_modules/interpret": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/ethjs-unit": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz",
+ "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=",
+ "dependencies": {
+ "bn.js": "4.11.6",
+ "number-to-bn": "1.7.0"
+ },
+ "engines": {
+ "node": ">=6.5.0",
+ "npm": ">=3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/prepend-http": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/cors": {
+ "version": "2.8.5",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/ethereum-bloom-filters": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz",
+ "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==",
+ "dependencies": {
+ "js-sha3": "^0.8.0"
+ }
+ },
+ "node_modules/external-editor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+ "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+ "dependencies": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/astral-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz",
+ "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==",
+ "dependencies": {
+ "bytes": "3.1.1",
+ "http-errors": "1.8.1",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/url-to-options": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/markdown-table": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz",
+ "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q=="
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/xtend": {
+ "version": "2.1.2",
+ "dev": true,
+ "dependencies": {
+ "object-keys": "~0.4.0"
+ },
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/base64-js": {
+ "version": "1.5.1",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/deferred-leveldown": {
+ "version": "1.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abstract-leveldown": "~2.6.0"
+ }
+ },
+ "node_modules/bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
+ },
+ "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/micromatch": {
+ "version": "3.1.10",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dependencies": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "engines": {
+ "node": ">=4.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/pseudomap": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/request/node_modules/uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
+ "bin": {
+ "uuid": "bin/uuid"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz",
+ "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ=="
+ },
+ "node_modules/ganache-core/node_modules/stream-to-pull-stream/node_modules/looper": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ },
+ "node_modules/io-ts": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz",
+ "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==",
+ "dependencies": {
+ "fp-ts": "^1.0.0"
+ }
+ },
+ "node_modules/eth-lib/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "node_modules/lodash.sum": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/lodash.sum/-/lodash.sum-4.0.2.tgz",
+ "integrity": "sha1-rZDjl5ZdgD1PH/eqWy0Bl/O0Y3s="
+ },
+ "node_modules/ganache-core/node_modules/bignumber.js": {
+ "version": "9.0.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/http-response-object/node_modules/@types/node": {
+ "version": "10.17.60",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
+ "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="
+ },
+ "node_modules/ganache-core/node_modules/babel-helper-explode-assignable-expression": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/es6-iterator": {
+ "version": "2.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "node_modules/@nomiclabs/hardhat-etherscan/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@ethersproject/abi": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.5.0.tgz",
+ "integrity": "sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/address": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/constants": "^5.5.0",
+ "@ethersproject/hash": "^5.5.0",
+ "@ethersproject/keccak256": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0"
+ }
+ },
+ "node_modules/concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "engines": [
+ "node >= 0.8"
+ ],
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+ "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint/node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/eth-lib": {
+ "version": "0.2.8",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bn.js": "^4.11.6",
+ "elliptic": "^6.4.0",
+ "xhr-request-promise": "^0.1.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block": {
+ "version": "1.7.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^2.0.1",
+ "ethereum-common": "0.2.0",
+ "ethereumjs-tx": "^1.2.2",
+ "ethereumjs-util": "^5.0.0",
+ "merkle-patricia-tree": "^2.1.2"
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
+ "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "mimic-response": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
+ "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@ethersproject/pbkdf2": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz",
+ "integrity": "sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/sha2": "^5.5.0"
+ }
+ },
+ "node_modules/eslint/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dependencies": {
+ "locate-path": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eth-gas-reporter/node_modules/cli-table3": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz",
+ "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==",
+ "dependencies": {
+ "object-assign": "^4.1.0",
+ "string-width": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "optionalDependencies": {
+ "colors": "^1.1.2"
+ }
+ },
+ "node_modules/randomfill": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+ "dependencies": {
+ "randombytes": "^2.0.5",
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/eslint/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
+ "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/union-value/node_modules/is-extendable": {
+ "version": "0.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
+ "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "node_modules/@sentry/node/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ },
+ "node_modules/ganache-core/node_modules/set-immediate-shim": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/networks": {
+ "version": "5.0.7",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/logger": "^5.0.8"
+ }
+ },
+ "node_modules/mcl-wasm": {
+ "version": "0.7.9",
+ "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz",
+ "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==",
+ "engines": {
+ "node": ">=8.9.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/escape-html": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ts-generator": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz",
+ "integrity": "sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/mkdirp": "^0.5.2",
+ "@types/prettier": "^2.1.1",
+ "@types/resolve": "^0.0.8",
+ "chalk": "^2.4.1",
+ "glob": "^7.1.2",
+ "mkdirp": "^0.5.1",
+ "prettier": "^2.1.2",
+ "resolve": "^1.8.1",
+ "ts-essentials": "^1.0.0"
+ },
+ "bin": {
+ "ts-generator": "dist/cli/run.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/mixin-deep": {
+ "version": "1.3.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-eth": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "underscore": "1.9.1",
+ "web3-core": "1.2.11",
+ "web3-core-helpers": "1.2.11",
+ "web3-core-method": "1.2.11",
+ "web3-core-subscriptions": "1.2.11",
+ "web3-eth-abi": "1.2.11",
+ "web3-eth-accounts": "1.2.11",
+ "web3-eth-contract": "1.2.11",
+ "web3-eth-ens": "1.2.11",
+ "web3-eth-iban": "1.2.11",
+ "web3-eth-personal": "1.2.11",
+ "web3-net": "1.2.11",
+ "web3-utils": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/responselike": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+ "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+ "dependencies": {
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/chalk": {
+ "version": "1.1.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/balanced-match": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
+ },
+ "node_modules/ganache-core/node_modules/nanomatch": {
+ "version": "1.2.13",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/delimit-stream": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz",
+ "integrity": "sha1-m4MZR3wOX4rrPONXrjBfwl6hzSs="
+ },
+ "node_modules/ganache-core/node_modules/encodeurl": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/@ensdomains/ens/node_modules/ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/asn1": {
+ "version": "0.2.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/unpipe": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/hardhat/node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/http-signature": {
+ "version": "1.2.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ },
+ "engines": {
+ "node": ">=0.8",
+ "npm": ">=1.3.7"
+ }
+ },
+ "node_modules/bech32": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
+ "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ=="
+ },
+ "node_modules/ganache-core/node_modules/patch-package/node_modules/tmp": {
+ "version": "0.0.33",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "os-tmpdir": "~1.0.2"
+ },
+ "engines": {
+ "node": ">=0.6.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/object-inspect": {
+ "version": "1.9.0",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/swarm-js/node_modules/minipass": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
+ "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+ "dependencies": {
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/immediate": {
+ "version": "3.2.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-environment-flags/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/@types/chai": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz",
+ "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw=="
+ },
+ "node_modules/ganache-core/node_modules/patch-package/node_modules/slash": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/xtend": {
+ "version": "2.1.2",
+ "dev": true,
+ "dependencies": {
+ "object-keys": "~0.4.0"
+ },
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/which-pm-runs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
+ "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/@ethereumjs/blockchain/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "node_modules/ganache-core/node_modules/send/node_modules/ms": {
+ "version": "2.1.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/browserify-sign/node_modules/readable-stream": {
+ "version": "3.6.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/node-environment-flags": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
+ "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
+ "dependencies": {
+ "object.getownpropertydescriptors": "^2.0.3",
+ "semver": "^5.7.0"
+ }
+ },
+ "node_modules/level-errors": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz",
+ "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==",
+ "dependencies": {
+ "errno": "~0.1.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/cacheable-request": {
+ "version": "6.1.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^3.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^4.1.0",
+ "responselike": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@ethersproject/logger": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz",
+ "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ]
+ },
+ "node_modules/flat-cache/node_modules/rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbol-support-x": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz",
+ "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/clone-response/node_modules/mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/prebuild-install": {
+ "version": "5.3.6",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz",
+ "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "detect-libc": "^1.0.3",
+ "expand-template": "^2.0.3",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.3",
+ "mkdirp-classic": "^0.5.3",
+ "napi-build-utils": "^1.0.1",
+ "node-abi": "^2.7.0",
+ "noop-logger": "^0.1.1",
+ "npmlog": "^4.0.1",
+ "pump": "^3.0.0",
+ "rc": "^1.2.7",
+ "simple-get": "^3.0.3",
+ "tar-fs": "^2.0.0",
+ "tunnel-agent": "^0.6.0",
+ "which-pm-runs": "^1.0.0"
+ },
+ "bin": {
+ "prebuild-install": "bin.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/deferred-leveldown/node_modules/abstract-leveldown": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz",
+ "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==",
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "immediate": "^3.2.3",
+ "level-concat-iterator": "~2.0.0",
+ "level-supports": "~1.0.0",
+ "xtend": "~4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@sentry/minimal": {
+ "version": "5.30.0",
+ "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz",
+ "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==",
+ "dependencies": {
+ "@sentry/hub": "5.30.0",
+ "@sentry/types": "5.30.0",
+ "tslib": "^1.9.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/solc/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/@trufflesuite/chromafi": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@trufflesuite/chromafi/-/chromafi-2.2.2.tgz",
+ "integrity": "sha512-mItQwVBsb8qP/vaYHQ1kDt2vJLhjoEXJptT6y6fJGvFophMFhOI/NsTVUa0nJL1nyMeFiS6hSYuNVdpQZzB1gA==",
+ "dependencies": {
+ "ansi-mark": "^1.0.0",
+ "ansi-regex": "^3.0.0",
+ "array-uniq": "^1.0.3",
+ "camelcase": "^4.1.0",
+ "chalk": "^2.3.2",
+ "cheerio": "^1.0.0-rc.2",
+ "detect-indent": "^5.0.0",
+ "he": "^1.1.1",
+ "highlight.js": "^10.4.1",
+ "lodash.merge": "^4.6.2",
+ "min-indent": "^1.0.0",
+ "strip-ansi": "^4.0.0",
+ "strip-indent": "^2.0.0",
+ "super-split": "^1.1.0"
+ }
+ },
+ "node_modules/swarm-js/node_modules/mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/jsprim": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+ "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
+ "dependencies": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.4.0",
+ "verror": "1.10.0"
+ },
+ "engines": {
+ "node": ">=0.6.0"
+ }
+ },
+ "node_modules/hardhat/node_modules/decamelize": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
+ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
+ },
+ "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/to-readable-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+ "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
+ },
+ "node_modules/@ledgerhq/hw-transport-u2f": {
+ "version": "5.26.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-u2f/-/hw-transport-u2f-5.26.0.tgz",
+ "integrity": "sha512-QTxP1Rsh+WZ184LUOelYVLeaQl3++V3I2jFik+l9JZtakwEHjD0XqOT750xpYNL/vfHsy31Wlz+oicdxGzFk+w==",
+ "deprecated": "@ledgerhq/hw-transport-u2f is deprecated. Please use @ledgerhq/hw-transport-webusb or @ledgerhq/hw-transport-webhid. https://github.com/LedgerHQ/ledgerjs/blob/master/docs/migrate_webusb.md",
+ "peer": true,
+ "dependencies": {
+ "@ledgerhq/errors": "^5.26.0",
+ "@ledgerhq/hw-transport": "^5.26.0",
+ "@ledgerhq/logs": "^5.26.0",
+ "u2f-api": "0.2.7"
+ }
+ },
+ "node_modules/@sentry/core/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ },
+ "node_modules/table/node_modules/is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@nomiclabs/truffle-contract/node_modules/scrypt-js": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz",
+ "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw=="
+ },
+ "node_modules/bignumber.js": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz",
+ "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
+ },
+ "node_modules/ganache-core/node_modules/object-keys": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/set-value/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/sshpk": {
+ "version": "1.16.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/home-or-tmp": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/node-fetch": {
+ "version": "2.1.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-arguments": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-eth-iban": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "bn.js": "^4.11.9",
+ "web3-utils": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/utf-8-validate": {
+ "version": "5.0.4",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "node-gyp-build": "^4.2.0"
+ }
+ },
+ "node_modules/fastq": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
+ "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/string.prototype.trim": {
+ "version": "1.2.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-buffer": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+ "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/create-ecdh": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
+ "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
+ "dependencies": {
+ "bn.js": "^4.1.0",
+ "elliptic": "^6.5.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/hash-base/node_modules/readable-stream": {
+ "version": "3.6.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/aws4": {
+ "version": "1.11.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/antlr4ts": {
+ "version": "0.5.0-alpha.4",
+ "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz",
+ "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ=="
+ },
+ "node_modules/ganache-core/node_modules/tough-cookie": {
+ "version": "2.5.0",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/delete-empty": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/delete-empty/-/delete-empty-3.0.0.tgz",
+ "integrity": "sha512-ZUyiwo76W+DYnKsL3Kim6M/UOavPdBJgDYWOmuQhYaZvJH0AXAHbUNyEDtRbBra8wqqr686+63/0azfEk1ebUQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-colors": "^4.1.0",
+ "minimist": "^1.2.0",
+ "path-starts-with": "^2.0.0",
+ "rimraf": "^2.6.2"
+ },
+ "bin": {
+ "delete-empty": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ganache-core/node_modules/esutils": {
+ "version": "2.0.3",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/concat-map": {
+ "version": "0.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/dom-walk": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
+ "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
+ },
+ "node_modules/ganache-core/node_modules/url-set-query": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/brorand": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown/node_modules/abstract-leveldown": {
+ "version": "2.7.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/read-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+ "dev": true,
+ "dependencies": {
+ "load-json-file": "^1.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@types/mkdirp": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz",
+ "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/log-driver": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz",
+ "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-syntax-exponentiation-operator": {
+ "version": "6.13.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/es6-symbol": {
+ "version": "3.1.3",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "d": "^1.0.1",
+ "ext": "^1.1.2"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "node_modules/req-from": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz",
+ "integrity": "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA=",
+ "dependencies": {
+ "resolve-from": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3": {
+ "version": "1.2.11",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "web3-bzz": "1.2.11",
+ "web3-core": "1.2.11",
+ "web3-eth": "1.2.11",
+ "web3-eth-personal": "1.2.11",
+ "web3-net": "1.2.11",
+ "web3-shh": "1.2.11",
+ "web3-utils": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-duplicate-keys": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/xhr-request/node_modules/decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/repeat-element": {
+ "version": "1.1.3",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/http-cache-semantics": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ=="
+ },
+ "node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+ },
+ "node_modules/@ethersproject/hardware-wallets": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/hardware-wallets/-/hardware-wallets-5.5.0.tgz",
+ "integrity": "sha512-oZh/Ps/ohxFQdKVeMw8wpw0xZpL+ndsRlQwNE3Eki2vLeH2to14de6fNrgETZtAbAhzglH6ES9Nlx1+UuqvvYg==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "peer": true,
+ "dependencies": {
+ "@ledgerhq/hw-app-eth": "5.27.2",
+ "@ledgerhq/hw-transport": "5.26.0",
+ "@ledgerhq/hw-transport-u2f": "5.26.0",
+ "ethers": "^5.5.0"
+ },
+ "optionalDependencies": {
+ "@ledgerhq/hw-transport-node-hid": "5.26.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eventemitter3": {
+ "version": "4.0.4",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/patch-package/node_modules/slash": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ultron": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-codec": {
+ "version": "7.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/tape": {
+ "version": "4.13.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-equal": "~1.1.1",
+ "defined": "~1.0.0",
+ "dotignore": "~0.1.2",
+ "for-each": "~0.3.3",
+ "function-bind": "~1.1.1",
+ "glob": "~7.1.6",
+ "has": "~1.0.3",
+ "inherits": "~2.0.4",
+ "is-regex": "~1.0.5",
+ "minimist": "~1.2.5",
+ "object-inspect": "~1.7.0",
+ "resolve": "~1.17.0",
+ "resumer": "~0.0.0",
+ "string.prototype.trim": "~1.2.1",
+ "through": "~2.3.8"
+ },
+ "bin": {
+ "tape": "bin/tape"
+ }
+ },
+ "node_modules/level-concat-iterator": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz",
+ "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/min-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/get-value": {
+ "version": "2.0.6",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/responselike": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "node_modules/amdefine": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+ "optional": true,
+ "engines": {
+ "node": ">=0.4.2"
+ }
+ },
+ "node_modules/browserify-cipher": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+ "dependencies": {
+ "browserify-aes": "^1.0.4",
+ "browserify-des": "^1.0.0",
+ "evp_bytestokey": "^1.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/convert-source-map/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/ganache-core/node_modules/tape/node_modules/is-regex": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/web3-eth-accounts": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.6.1.tgz",
+ "integrity": "sha512-rGn3jwnuOKwaQRu4SiShz0YAQ87aVDBKs4HO43+XTCI1q1Y1jn3NOsG3BW9ZHaOckev4+zEyxze/Bsh2oEk24w==",
+ "dependencies": {
+ "@ethereumjs/common": "^2.5.0",
+ "@ethereumjs/tx": "^3.3.2",
+ "crypto-browserify": "3.12.0",
+ "eth-lib": "0.2.8",
+ "ethereumjs-util": "^7.0.10",
+ "scrypt-js": "^3.0.1",
+ "uuid": "3.3.2",
+ "web3-core": "1.6.1",
+ "web3-core-helpers": "1.6.1",
+ "web3-core-method": "1.6.1",
+ "web3-utils": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-helper-hoist-variables": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
+ "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/swarm-js/node_modules/p-cancelable": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
+ "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/assign-symbols": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm": {
+ "version": "2.6.0",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^2.1.2",
+ "async-eventemitter": "^0.2.2",
+ "ethereumjs-account": "^2.0.3",
+ "ethereumjs-block": "~2.2.0",
+ "ethereumjs-common": "^1.1.0",
+ "ethereumjs-util": "^6.0.0",
+ "fake-merkle-patricia-tree": "^1.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "merkle-patricia-tree": "^2.3.2",
+ "rustbn.js": "~0.2.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/hash.js": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+ "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.1"
+ }
+ },
+ "node_modules/strip-indent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
+ "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.16.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz",
+ "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==",
+ "dependencies": {
+ "@babel/highlight": "^7.16.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/assertion-error": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/base-x": {
+ "version": "3.0.8",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/@ethereum-waffle/provider": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.4.1.tgz",
+ "integrity": "sha512-5iDte7c9g9N1rTRE/P4npwk1Hus/wA2yH850X6sP30mr1IrwSG9NKn6/2SOQkAVJnh9jqyLVg2X9xCODWL8G4A==",
+ "dev": true,
+ "dependencies": {
+ "@ethereum-waffle/ens": "^3.3.1",
+ "ethers": "^5.5.2",
+ "ganache-core": "^2.13.2",
+ "patch-package": "^6.2.2",
+ "postinstall-postinstall": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.16.7",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz",
+ "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.16.7",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/resolve-url": {
+ "version": "0.2.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/on-finished": {
+ "version": "2.3.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/expand-brackets/node_modules/kind-of": {
+ "version": "5.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/async-limiter": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown": {
+ "version": "1.4.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abstract-leveldown": "~2.7.1",
+ "functional-red-black-tree": "^1.0.1",
+ "immediate": "^3.2.3",
+ "inherits": "~2.0.1",
+ "ltgt": "~2.2.0",
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "node_modules/fs-readdir-recursive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
+ "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA=="
+ },
+ "node_modules/ganache-core/node_modules/encoding": {
+ "version": "0.1.13",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "^0.6.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/cids": {
+ "version": "0.7.5",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "class-is": "^1.1.0",
+ "multibase": "~0.6.0",
+ "multicodec": "^1.0.0",
+ "multihashes": "~0.4.15"
+ },
+ "engines": {
+ "node": ">=4.0.0",
+ "npm": ">=3.0.0"
+ }
+ },
+ "node_modules/@truffle/interface-adapter/node_modules/ethers/node_modules/bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
+ },
+ "node_modules/got/node_modules/decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/string.prototype.trimstart": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/sshpk/node_modules/tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+ },
+ "node_modules/aws4": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
+ },
+ "node_modules/ganache-core/node_modules/regenerator-transform": {
+ "version": "0.10.1",
+ "dev": true,
+ "license": "BSD",
+ "dependencies": {
+ "babel-runtime": "^6.18.0",
+ "babel-types": "^6.19.0",
+ "private": "^0.1.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/oboe": {
+ "version": "2.1.4",
+ "dev": true,
+ "license": "BSD",
+ "optional": true,
+ "dependencies": {
+ "http-https": "^1.0.0"
+ }
+ },
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+ },
+ "node_modules/@ethersproject/strings": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.5.0.tgz",
+ "integrity": "sha512-9fy3TtF5LrX/wTrBaT8FGE6TDJyVjOvXynXJz5MT5azq+E6D92zuKNx7i29sWW2FjVOaWjAsiZ1ZWznuduTIIQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/constants": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces": {
+ "version": "2.3.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/object.pick": {
+ "version": "1.3.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/inflight": {
+ "version": "1.0.6",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz",
+ "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==",
+ "dependencies": {
+ "css-select": "^4.1.3",
+ "css-what": "^5.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.2.0",
+ "domutils": "^2.7.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/swarm-js/node_modules/fs-extra": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
+ "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-helper-replace-supers": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-optimise-call-expression": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/json-text-sequence": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/json-text-sequence/-/json-text-sequence-0.1.1.tgz",
+ "integrity": "sha1-py8hfcSvxGKf/1/rME3BvVGi89I=",
+ "dependencies": {
+ "delimit-stream": "0.1.0"
+ }
+ },
+ "node_modules/@types/bignumber.js": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/bignumber.js/-/bignumber.js-5.0.0.tgz",
+ "integrity": "sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA==",
+ "deprecated": "This is a stub types definition for bignumber.js (https://github.com/MikeMcl/bignumber.js/). bignumber.js provides its own type definitions, so you don't need @types/bignumber.js installed!",
+ "dependencies": {
+ "bignumber.js": "*"
+ }
+ },
+ "node_modules/set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+ },
+ "node_modules/lcid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "dev": true,
+ "dependencies": {
+ "invert-kv": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@ethersproject/bignumber": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.5.0.tgz",
+ "integrity": "sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "bn.js": "^4.11.9"
+ }
+ },
+ "node_modules/send/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/request-promise-native": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
+ "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
+ "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142",
+ "dependencies": {
+ "request-promise-core": "1.1.4",
+ "stealthy-require": "^1.1.1",
+ "tough-cookie": "^2.3.3"
+ },
+ "engines": {
+ "node": ">=0.12.0"
+ },
+ "peerDependencies": {
+ "request": "^2.34"
+ }
+ },
+ "node_modules/got": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+ "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+ "dependencies": {
+ "@sindresorhus/is": "^0.14.0",
+ "@szmarczak/http-timer": "^1.1.2",
+ "cacheable-request": "^6.0.0",
+ "decompress-response": "^3.3.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^4.1.0",
+ "lowercase-keys": "^1.0.1",
+ "mimic-response": "^1.0.1",
+ "p-cancelable": "^1.0.0",
+ "to-readable-stream": "^1.0.0",
+ "url-parse-lax": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mocha/node_modules/find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dependencies": {
+ "locate-path": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/minimatch": {
+ "version": "3.0.4",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@ensdomains/ens/node_modules/which-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
+ "dev": true
+ },
+ "node_modules/ganache-core/node_modules/pull-level": {
+ "version": "2.0.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "level-post": "^1.0.7",
+ "pull-cat": "^1.1.9",
+ "pull-live": "^1.0.1",
+ "pull-pushable": "^2.0.0",
+ "pull-stream": "^3.4.0",
+ "pull-window": "^2.1.4",
+ "stream-to-pull-stream": "^1.7.1"
+ }
+ },
+ "node_modules/path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM="
+ },
+ "node_modules/psl": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+ "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
+ },
+ "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ghost-testrpc/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/through": {
+ "version": "2.3.8",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cheerio": {
+ "version": "1.0.0-rc.10",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
+ "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
+ "dependencies": {
+ "cheerio-select": "^1.5.0",
+ "dom-serializer": "^1.3.2",
+ "domhandler": "^4.2.0",
+ "htmlparser2": "^6.1.0",
+ "parse5": "^6.0.1",
+ "parse5-htmlparser2-tree-adapter": "^6.0.1",
+ "tslib": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/asn1.js": {
+ "version": "5.4.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bn.js": "^4.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "node_modules/hardhat/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ansi-mark/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/bs58check": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
+ "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
+ "dependencies": {
+ "bs58": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "node_modules/@ethersproject/base64": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.5.0.tgz",
+ "integrity": "sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bytes": "^5.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-helper-get-function-arity": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethashjs/node_modules/buffer-xor": {
+ "version": "2.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/cachedown": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abstract-leveldown": "^2.4.1",
+ "lru-cache": "^3.2.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ws/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/browserify-aes": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+ "dependencies": {
+ "buffer-xor": "^1.0.3",
+ "cipher-base": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.3",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-core/node_modules/slash": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/p-timeout": {
+ "version": "1.2.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "p-finally": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chai": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz",
+ "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==",
+ "dependencies": {
+ "assertion-error": "^1.1.0",
+ "check-error": "^1.0.2",
+ "deep-eql": "^3.0.1",
+ "get-func-name": "^2.0.0",
+ "pathval": "^1.1.1",
+ "type-detect": "^4.0.5"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/looper": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/keccak": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz",
+ "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "node-addon-api": "^2.0.0",
+ "node-gyp-build": "^4.2.0",
+ "readable-stream": "^3.6.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/node-addon-api": {
+ "version": "2.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/prr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY="
+ },
+ "node_modules/ganache-core/node_modules/lodash": {
+ "version": "4.17.20",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lru_map": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
+ "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0="
+ },
+ "node_modules/url-set-query": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz",
+ "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk="
+ },
+ "node_modules/ganache-core/node_modules/babel-helper-optimise-call-expression": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "dependencies": {
+ "ci-info": "^2.0.0"
+ },
+ "bin": {
+ "is-ci": "bin.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ci-info": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "dependencies": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dependencies": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/gauge/node_modules/ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/evp_bytestokey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+ "dependencies": {
+ "md5.js": "^1.3.4",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+ "dependencies": {
+ "minimist": "^1.2.5"
+ },
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/class-utils/node_modules/kind-of": {
+ "version": "5.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/static-extend/node_modules/kind-of": {
+ "version": "5.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wide-align/node_modules/string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dependencies": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/global": {
+ "version": "4.4.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "min-document": "^2.19.0",
+ "process": "^0.11.10"
+ }
+ },
+ "node_modules/hardhat/node_modules/resolve": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
+ "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+ "dependencies": {
+ "path-parse": "^1.0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/cacheable-request/node_modules/get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/web3-utils/node_modules/bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
+ },
+ "node_modules/ganache-core/node_modules/babel-register/node_modules/source-map-support": {
+ "version": "0.4.18",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "source-map": "^0.5.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/extend": {
+ "version": "3.0.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/global": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
+ "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
+ "dependencies": {
+ "min-document": "^2.19.0",
+ "process": "^0.11.10"
+ }
+ },
+ "node_modules/deferred-leveldown": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz",
+ "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==",
+ "dependencies": {
+ "abstract-leveldown": "~6.2.1",
+ "inherits": "^2.0.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-messages": {
+ "version": "6.23.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/sc-istanbul/node_modules/glob": {
+ "version": "5.0.15",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+ "dependencies": {
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "2 || 3",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/http-https": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz",
+ "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs="
+ },
+ "node_modules/encode-utf8": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz",
+ "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "node_modules/level-ws": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-2.0.0.tgz",
+ "integrity": "sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.0",
+ "xtend": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/lcov-parse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz",
+ "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=",
+ "dev": true,
+ "bin": {
+ "lcov-parse": "bin/cli.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/minimist": {
+ "version": "1.2.5",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/expand-brackets/node_modules/define-property": {
+ "version": "0.2.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/bytes": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/obliterator": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.1.tgz",
+ "integrity": "sha512-XnkiCrrBcIZQitJPAI36mrrpEUvatbte8hLcTcQwKA1v9NkCKasSi+UAguLsLDs/out7MoRzAlmz7VXvY6ph6w=="
+ },
+ "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/node-addon-api": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz",
+ "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/ganache-core/node_modules/express/node_modules/ms": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/@trufflesuite/chromafi/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/browserify-sign/node_modules/bn.js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
+ },
+ "node_modules/ext/node_modules/type": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz",
+ "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw=="
+ },
+ "node_modules/ganache-core/node_modules/levelup/node_modules/level-iterator-stream": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.3.6",
+ "xtend": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-hex-prefixed": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.5.0",
+ "npm": ">=3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ltgt": {
+ "version": "2.2.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/levelup": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.3.tgz",
+ "integrity": "sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA==",
+ "dependencies": {
+ "@types/abstract-leveldown": "*",
+ "@types/level-errors": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/snapdragon/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/deferred-leveldown": {
+ "version": "4.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abstract-leveldown": "~5.0.0",
+ "inherits": "^2.0.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/simple-concat": {
+ "version": "1.0.1",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ltgt": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+ "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU="
+ },
+ "node_modules/ganache-core/node_modules/http-errors/node_modules/inherits": {
+ "version": "2.0.3",
+ "dev": true,
+ "license": "ISC",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/got": {
+ "version": "9.6.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@sindresorhus/is": "^0.14.0",
+ "@szmarczak/http-timer": "^1.1.2",
+ "cacheable-request": "^6.0.0",
+ "decompress-response": "^3.3.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^4.1.0",
+ "lowercase-keys": "^1.0.1",
+ "mimic-response": "^1.0.1",
+ "p-cancelable": "^1.0.0",
+ "to-readable-stream": "^1.0.0",
+ "url-parse-lax": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/parse-headers": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.4.tgz",
+ "integrity": "sha512-psZ9iZoCNFLrgRjZ1d8mn0h9WRqJwFxM9q3x7iUjN/YT2OksthDJ5TiPCu2F38kS4zutqfW+YdVVkBZZx3/1aw=="
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws": {
+ "version": "0.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "~1.0.15",
+ "xtend": "~2.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/has-flag": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dependencies": {
+ "ansi-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream/node_modules/readable-stream": {
+ "version": "1.1.14",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/has-to-string-tag-x": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
+ "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
+ "dependencies": {
+ "has-symbol-support-x": "^1.4.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@ensdomains/ens/node_modules/strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/patch-package/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/tar-stream": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "bl": "^4.0.3",
+ "end-of-stream": "^1.4.1",
+ "fs-constants": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/xhr-request": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz",
+ "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==",
+ "dependencies": {
+ "buffer-to-arraybuffer": "^0.0.5",
+ "object-assign": "^4.1.1",
+ "query-string": "^5.0.1",
+ "simple-get": "^2.7.0",
+ "timed-out": "^4.0.1",
+ "url-set-query": "^1.0.0",
+ "xhr": "^2.0.4"
+ }
+ },
+ "node_modules/@nomiclabs/truffle-contract/node_modules/ethers": {
+ "version": "4.0.49",
+ "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz",
+ "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==",
+ "dependencies": {
+ "aes-js": "3.0.0",
+ "bn.js": "^4.11.9",
+ "elliptic": "6.5.4",
+ "hash.js": "1.1.3",
+ "js-sha3": "0.5.7",
+ "scrypt-js": "2.0.4",
+ "setimmediate": "1.0.4",
+ "uuid": "2.0.1",
+ "xmlhttprequest": "1.8.0"
+ }
+ },
+ "node_modules/tweetnacl": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
+ "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw=="
+ },
+ "node_modules/ganache-core/node_modules/patch-package/node_modules/path-key": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ws": {
+ "version": "5.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-limiter": "~1.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-descriptor": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/highlightjs-solidity": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-1.2.2.tgz",
+ "integrity": "sha512-+cZ+1+nAO5Pi6c70TKuMcPmwqLECxiYhnQc1MxdXckK94zyWFMNZADzu98ECNlf5xCRdNh+XKp+eklmRU+Dniw=="
+ },
+ "node_modules/ganache-core/node_modules/snapdragon/node_modules/kind-of": {
+ "version": "5.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/web3-providers-ws": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.6.1.tgz",
+ "integrity": "sha512-FWMEFYb4rYFYRgSFBf/O1Ex4p/YKSlN+JydCtdlJwRimd89qm95CTfs4xGjCskwvXMjV2sarH+f1NPwJXicYpg==",
+ "dependencies": {
+ "eventemitter3": "4.0.4",
+ "web3-core-helpers": "1.6.1",
+ "websocket": "^1.0.32"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "1.14.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz",
+ "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==",
+ "dependencies": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/isurl": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
+ "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
+ "dependencies": {
+ "has-to-string-tag-x": "^1.2.0",
+ "is-object": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/get-stream": {
+ "version": "5.2.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/level-supports": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz",
+ "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==",
+ "dependencies": {
+ "xtend": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@truffle/debug-utils/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-hex-prefix": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
+ "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
+ "dependencies": {
+ "is-hex-prefixed": "1.0.0"
+ },
+ "engines": {
+ "node": ">=6.5.0",
+ "npm": ">=3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@types/node": {
+ "version": "14.14.20",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/hardhat/node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cacheable-request": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+ "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+ "dependencies": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^3.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^4.1.0",
+ "responselike": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown/node_modules/abstract-leveldown": {
+ "version": "2.7.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dev": true,
+ "dependencies": {
+ "pinkie": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/object-copy/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/swarm-js/node_modules/got": {
+ "version": "7.1.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "decompress-response": "^3.2.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^3.0.0",
+ "is-plain-obj": "^1.1.0",
+ "is-retry-allowed": "^1.0.0",
+ "is-stream": "^1.0.0",
+ "isurl": "^1.0.0-alpha5",
+ "lowercase-keys": "^1.0.0",
+ "p-cancelable": "^0.3.0",
+ "p-timeout": "^1.1.1",
+ "safe-buffer": "^5.0.1",
+ "timed-out": "^4.0.0",
+ "url-parse-lax": "^1.0.0",
+ "url-to-options": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@truffle/compile-common": {
+ "version": "0.7.24",
+ "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.7.24.tgz",
+ "integrity": "sha512-iF3zjXhxcFVAYEZfQA6Rh2vxQ4xSuk/7pKm7yKlLh3p9WjFaPE+dF8wbgQoehftUnBh6SY91uZI6XiD4QDuxYQ==",
+ "dependencies": {
+ "@truffle/error": "^0.0.14",
+ "colors": "1.4.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/hash": {
+ "version": "5.0.10",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/abstract-signer": "^5.0.10",
+ "@ethersproject/address": "^5.0.9",
+ "@ethersproject/bignumber": "^5.0.13",
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/keccak256": "^5.0.7",
+ "@ethersproject/logger": "^5.0.8",
+ "@ethersproject/properties": "^5.0.7",
+ "@ethersproject/strings": "^5.0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/fs-extra": {
+ "version": "7.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz",
+ "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "es-abstract": "^1.18.5",
+ "foreach": "^2.0.5",
+ "has-tostringtag": "^1.0.0",
+ "is-typed-array": "^1.1.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/web3-eth-accounts/node_modules/uuid": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+ "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
+ "bin": {
+ "uuid": "bin/uuid"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree/node_modules/async": {
+ "version": "1.5.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/bcrypt-pbkdf/node_modules/tweetnacl": {
+ "version": "0.14.5",
+ "dev": true,
+ "license": "Unlicense"
+ },
+ "node_modules/nofilter": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz",
+ "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/snapdragon/node_modules/define-property": {
+ "version": "0.2.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@ethereum-waffle/mock-contract": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.3.1.tgz",
+ "integrity": "sha512-h9yChF7IkpJLODg/o9/jlwKwTcXJLSEIq3gewgwUJuBHnhPkJGekcZvsTbximYc+e42QUZrDUATSuTCIryeCEA==",
+ "dev": true,
+ "dependencies": {
+ "@ethersproject/abi": "^5.5.0",
+ "ethers": "^5.5.2"
+ },
+ "engines": {
+ "node": ">=10.0"
+ }
+ },
+ "node_modules/hardhat/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/minimalistic-assert": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
+ },
+ "node_modules/match-all": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/match-all/-/match-all-1.2.6.tgz",
+ "integrity": "sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ=="
+ },
+ "node_modules/ganache-core/node_modules/ethashjs/node_modules/ethereumjs-util": {
+ "version": "7.0.7",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^5.1.2",
+ "create-hash": "^1.1.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "0.1.6",
+ "rlp": "^2.2.4"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/spdx-correct": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "dev": true,
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/static-extend/node_modules/define-property": {
+ "version": "0.2.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/idna-uts46-hx": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz",
+ "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==",
+ "dependencies": {
+ "punycode": "2.1.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/idna-uts46-hx": {
+ "version": "2.3.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "punycode": "2.1.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethjs-util": {
+ "version": "0.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-hex-prefixed": "1.0.0",
+ "strip-hex-prefix": "1.0.0"
+ },
+ "engines": {
+ "node": ">=6.5.0",
+ "npm": ">=3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/json-buffer": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ts-generator/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "node_modules/ganache-core/node_modules/create-ecdh": {
+ "version": "4.0.4",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bn.js": "^4.1.0",
+ "elliptic": "^6.5.3"
+ }
+ },
+ "node_modules/hmac-drbg": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+ "dependencies": {
+ "hash.js": "^1.0.3",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number/node_modules/kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-tx": {
+ "version": "1.3.7",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "ethereum-common": "^0.0.18",
+ "ethereumjs-util": "^5.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-extendable": {
+ "version": "0.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/has-values/node_modules/is-number/node_modules/kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gauge/node_modules/is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "number-is-nan": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@truffle/blockchain-utils": {
+ "version": "0.0.25",
+ "resolved": "https://registry.npmjs.org/@truffle/blockchain-utils/-/blockchain-utils-0.0.25.tgz",
+ "integrity": "sha512-XA5m0BfAWtysy5ChHyiAf1fXbJxJXphKk+eZ9Rb9Twi6fn3Jg4gnHNwYXJacYFEydqT5vr2s4Ou812JHlautpw==",
+ "dependencies": {
+ "source-map-support": "^0.5.19"
+ }
+ },
+ "node_modules/ganache-core/node_modules/des.js": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/slice-ansi/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/xtend": {
+ "version": "4.0.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/secp256k1": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz",
+ "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "elliptic": "^6.5.4",
+ "node-addon-api": "^2.0.0",
+ "node-gyp-build": "^4.2.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dependencies": {
+ "p-try": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+ },
+ "node_modules/ganache-core/node_modules/safe-regex": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ret": "~0.1.10"
+ }
+ },
+ "node_modules/mute-stream": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
+ },
+ "node_modules/@ungap/promise-all-settled": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
+ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q=="
+ },
+ "node_modules/@szmarczak/http-timer": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+ "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+ "dependencies": {
+ "defer-to-connect": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ethereumjs-util": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz",
+ "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==",
+ "dependencies": {
+ "@types/bn.js": "^5.1.0",
+ "bn.js": "^5.1.2",
+ "create-hash": "^1.1.2",
+ "ethereum-cryptography": "^0.1.3",
+ "rlp": "^2.2.4"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/regenerate": {
+ "version": "1.4.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/aproba": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/inquirer/node_modules/string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dependencies": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+ "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+ "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/ganache-core/node_modules/content-hash": {
+ "version": "2.5.2",
+ "dev": true,
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "cids": "^0.7.1",
+ "multicodec": "^0.5.5",
+ "multihashes": "^0.4.15"
+ }
+ },
+ "node_modules/hardhat-deploy/node_modules/universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/abstract-leveldown": {
+ "version": "2.6.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+ },
+ "node_modules/ganache-core/node_modules/proxy-addr": {
+ "version": "2.0.6",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
+ "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
+ "dev": true,
+ "peer": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/get-intrinsic": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/normalize-url": {
+ "version": "4.5.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/content-type": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "13.3.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+ "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+ "dependencies": {
+ "cliui": "^5.0.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^3.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^13.1.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/dashdash": {
+ "version": "1.14.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree": {
+ "version": "2.3.2",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^1.4.2",
+ "ethereumjs-util": "^5.0.0",
+ "level-ws": "0.0.0",
+ "levelup": "^1.2.1",
+ "memdown": "^1.0.0",
+ "readable-stream": "^2.0.0",
+ "rlp": "^2.0.0",
+ "semaphore": ">=1.0.1"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/mock-fs": {
+ "version": "4.13.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "node_modules/p-timeout": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
+ "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
+ "dependencies": {
+ "p-finally": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/cids/node_modules/multicodec": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "buffer": "^5.6.0",
+ "varint": "^5.0.0"
+ }
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/ganache-core/node_modules/mime-types": {
+ "version": "2.1.28",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.45.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/typewise-core": {
+ "version": "1.2.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown/node_modules/abstract-leveldown": {
+ "version": "2.7.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/http-errors": {
+ "version": "1.7.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-callable": {
+ "version": "1.2.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+ "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "dependencies": {
+ "parse5": "^6.0.1"
+ }
+ },
+ "node_modules/stacktrace-parser/node_modules/type-fest": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz",
+ "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-shorthand-properties": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-runtime": {
+ "version": "6.26.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.11.0"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/regexpu-core": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regenerate": "^1.2.1",
+ "regjsgen": "^0.2.0",
+ "regjsparser": "^0.1.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/strict-uri-encode": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/regexp.prototype.flags/node_modules/es-abstract": {
+ "version": "1.17.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.2",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.1",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@nomiclabs/hardhat-web3": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-web3/-/hardhat-web3-2.0.0.tgz",
+ "integrity": "sha512-zt4xN+D+fKl3wW2YlTX3k9APR3XZgPkxJYf36AcliJn3oujnKEVRZaHu0PhgLjO+gR+F/kiYayo9fgd2L8970Q==",
+ "dependencies": {
+ "@types/bignumber.js": "^5.0.0"
+ },
+ "peerDependencies": {
+ "hardhat": "^2.0.0",
+ "web3": "^1.0.0-beta.36"
+ }
+ },
+ "node_modules/ganache-core/node_modules/expand-brackets/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/web3-eth-abi": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.6.1.tgz",
+ "integrity": "sha512-svhYrAlXP9XQtV7poWKydwDJq2CaNLMtmKydNXoOBLcQec6yGMP+v20pgrxF2H6wyTK+Qy0E3/5ciPOqC/VuoQ==",
+ "dependencies": {
+ "@ethersproject/abi": "5.0.7",
+ "web3-utils": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/promise-to-callback": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-fn": "^1.0.0",
+ "set-immediate-shim": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-lib": {
+ "version": "0.1.29",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bn.js": "^4.11.6",
+ "elliptic": "^6.4.0",
+ "nano-json-stream-parser": "^0.1.2",
+ "servify": "^0.1.12",
+ "ws": "^3.0.0",
+ "xhr-request-promise": "^0.1.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/servify": {
+ "version": "0.1.12",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "body-parser": "^1.16.0",
+ "cors": "^2.8.1",
+ "express": "^4.14.0",
+ "request": "^2.79.0",
+ "xhr": "^2.3.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/hmac-drbg": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hash.js": "^1.0.3",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+ "dev": true,
+ "dependencies": {
+ "is-utf8": "^0.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ganache-core/node_modules/unorm": {
+ "version": "1.6.0",
+ "dev": true,
+ "license": "MIT or GPL-2.0",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dependencies": {
+ "os-tmpdir": "~1.0.2"
+ },
+ "engines": {
+ "node": ">=0.6.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/swarm-js/node_modules/get-stream": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@thinkanddev/hardhat-erc1820-rsk": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/@thinkanddev/hardhat-erc1820-rsk/-/hardhat-erc1820-rsk-0.1.2.tgz",
+ "integrity": "sha512-9tGj8U9pFpP6Zgi896xIrG9DuIZMXcqxDA6n+s9wGKogWu400T+hMShDpR7Bx/pwMu8DsxplQanJAUIj0joRDA==",
+ "peerDependencies": {
+ "hardhat": "^2.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/has-ansi/node_modules/ansi-regex": {
+ "version": "2.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/isarray": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/hardhat-deploy/node_modules/fs-extra": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
+ "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "node_modules/yargs/node_modules/ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
+ "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
+ "dependencies": {
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/hardhat/node_modules/mocha/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/express": {
+ "version": "4.17.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "type-is": "~1.6.18",
+ "safe-buffer": "5.1.2",
+ "finalhandler": "~1.1.2",
+ "fresh": "0.5.2",
+ "body-parser": "1.19.0",
+ "content-type": "~1.0.4",
+ "send": "0.17.1",
+ "cookie": "0.4.0",
+ "methods": "~1.1.2",
+ "proxy-addr": "~2.0.5",
+ "accepts": "~1.3.7",
+ "range-parser": "~1.2.1",
+ "on-finished": "~2.3.0",
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "etag": "~1.8.1",
+ "path-to-regexp": "0.1.7",
+ "statuses": "~1.5.0",
+ "parseurl": "~1.3.3",
+ "setprototypeof": "1.1.1",
+ "merge-descriptors": "1.0.1",
+ "vary": "~1.1.2",
+ "serve-static": "1.14.1",
+ "content-disposition": "0.5.3",
+ "escape-html": "~1.0.3",
+ "cookie-signature": "1.0.6",
+ "utils-merge": "1.0.1",
+ "array-flatten": "1.1.1",
+ "depd": "~1.1.2",
+ "qs": "6.7.0"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/abstract-provider": {
+ "version": "5.0.8",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.0.13",
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/logger": "^5.0.8",
+ "@ethersproject/networks": "^5.0.7",
+ "@ethersproject/properties": "^5.0.7",
+ "@ethersproject/transactions": "^5.0.9",
+ "@ethersproject/web": "^5.0.12"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@ensdomains/ens/node_modules/cliui": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wrap-ansi": "^2.0.0"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dependencies": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/merkle-patricia-tree": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.2.2.tgz",
+ "integrity": "sha512-eqZYNTshcYx9aESkSPr71EqwsR/QmpnObDEV4iLxkt/x/IoLYZYjJvKY72voP/27Vy61iMOrfOG6jrn7ttXD+Q==",
+ "dependencies": {
+ "@types/levelup": "^4.3.0",
+ "ethereumjs-util": "^7.1.2",
+ "level-mem": "^5.0.1",
+ "level-ws": "^2.0.0",
+ "readable-stream": "^3.6.0",
+ "rlp": "^2.2.4",
+ "semaphore-async-await": "^1.5.1"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/vary": {
+ "version": "1.1.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-traverse/node_modules/ms": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown/node_modules/abstract-leveldown": {
+ "version": "2.7.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "node_modules/ganache-core/node_modules/class-utils/node_modules/define-property": {
+ "version": "0.2.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
+ },
+ "node_modules/web3": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3/-/web3-1.6.1.tgz",
+ "integrity": "sha512-c299lLiyb2/WOcxh7TinwvbATaMmrgNIeAzbLbmOKHI0LcwyfsB1eu2ReOIrfrCYDYRW2KAjYr7J7gHawqDNPQ==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "web3-bzz": "1.6.1",
+ "web3-core": "1.6.1",
+ "web3-eth": "1.6.1",
+ "web3-eth-personal": "1.6.1",
+ "web3-net": "1.6.1",
+ "web3-shh": "1.6.1",
+ "web3-utils": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@sentry/utils/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ },
+ "node_modules/body-parser": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz",
+ "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==",
+ "dependencies": {
+ "bytes": "3.1.1",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.8.1",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.9.6",
+ "raw-body": "2.4.2",
+ "type-is": "~1.6.18"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/@ethersproject/wallet": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.5.0.tgz",
+ "integrity": "sha512-Mlu13hIctSYaZmUOo7r2PhNSd8eaMPVXe1wxrz4w4FCE4tDYBywDH+bAR1Xz2ADyXGwqYMwstzTrtUVIsKDO0Q==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/abstract-provider": "^5.5.0",
+ "@ethersproject/abstract-signer": "^5.5.0",
+ "@ethersproject/address": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/hash": "^5.5.0",
+ "@ethersproject/hdnode": "^5.5.0",
+ "@ethersproject/json-wallets": "^5.5.0",
+ "@ethersproject/keccak256": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/random": "^5.5.0",
+ "@ethersproject/signing-key": "^5.5.0",
+ "@ethersproject/transactions": "^5.5.0",
+ "@ethersproject/wordlists": "^5.5.0"
+ }
+ },
+ "node_modules/handlebars/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/level-mem": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "level-packager": "~4.0.0",
+ "memdown": "~3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/semver/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-util": {
+ "version": "6.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "0.1.6",
+ "rlp": "^2.2.3"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/abbrev": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
+ "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU="
+ },
+ "node_modules/@ensdomains/ens/node_modules/yargs": {
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz",
+ "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "lodash.assign": "^4.0.3",
+ "os-locale": "^1.4.0",
+ "read-pkg-up": "^1.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^1.0.1",
+ "which-module": "^1.0.0",
+ "window-size": "^0.2.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^2.4.1"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz",
+ "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^5.1.0",
+ "domhandler": "^4.3.0",
+ "domutils": "^2.8.0",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/ganache-core/node_modules/accepts": {
+ "version": "1.3.7",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "mime-types": "~2.1.24",
+ "negotiator": "0.6.2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/expand-brackets": {
+ "version": "2.1.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/http-errors": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
+ "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
+ "dependencies": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/mkdirp": {
+ "version": "0.5.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.5"
+ },
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ }
+ },
+ "node_modules/inquirer/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/log-symbols": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+ "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+ "dependencies": {
+ "chalk": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/crypto-browserify": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+ "dependencies": {
+ "browserify-cipher": "^1.0.0",
+ "browserify-sign": "^4.0.0",
+ "create-ecdh": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.0",
+ "diffie-hellman": "^5.0.0",
+ "inherits": "^2.0.1",
+ "pbkdf2": "^3.0.3",
+ "public-encrypt": "^4.0.0",
+ "randombytes": "^2.0.0",
+ "randomfill": "^1.0.3"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/source-map-support": {
+ "version": "0.5.12",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/patch-package": {
+ "version": "6.4.7",
+ "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz",
+ "integrity": "sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==",
+ "dev": true,
+ "dependencies": {
+ "@yarnpkg/lockfile": "^1.1.0",
+ "chalk": "^2.4.2",
+ "cross-spawn": "^6.0.5",
+ "find-yarn-workspace-root": "^2.0.0",
+ "fs-extra": "^7.0.1",
+ "is-ci": "^2.0.0",
+ "klaw-sync": "^6.0.0",
+ "minimist": "^1.2.0",
+ "open": "^7.4.2",
+ "rimraf": "^2.6.3",
+ "semver": "^5.6.0",
+ "slash": "^2.0.0",
+ "tmp": "^0.0.33"
+ },
+ "bin": {
+ "patch-package": "index.js"
+ },
+ "engines": {
+ "npm": ">5"
+ }
+ },
+ "node_modules/ganache-core/node_modules/inherits": {
+ "version": "2.0.4",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": {
+ "version": "2.2.2",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^2.0.1",
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-tx": "^2.1.1",
+ "ethereumjs-util": "^5.0.0",
+ "merkle-patricia-tree": "^2.1.2"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
+ "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
+ "optional": true,
+ "dependencies": {
+ "amdefine": ">=0.0.4"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/hardhat/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dependencies": {
+ "assert-plus": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/log-symbols/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/yargs/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg="
+ },
+ "node_modules/is-hex-prefixed": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz",
+ "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=",
+ "engines": {
+ "node": ">=6.5.0",
+ "npm": ">=3"
+ }
+ },
+ "node_modules/solhint/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/has-symbols": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree": {
+ "version": "2.3.2",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^1.4.2",
+ "ethereumjs-util": "^5.0.0",
+ "level-ws": "0.0.0",
+ "levelup": "^1.2.1",
+ "memdown": "^1.0.0",
+ "readable-stream": "^2.0.0",
+ "rlp": "^2.0.0",
+ "semaphore": ">=1.0.1"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
+ },
+ "node_modules/globby": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
+ "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
+ "dependencies": {
+ "@types/glob": "^7.1.1",
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.0.3",
+ "glob": "^7.1.3",
+ "ignore": "^5.1.1",
+ "merge2": "^1.2.3",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown/node_modules/abstract-leveldown": {
+ "version": "2.7.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/@truffle/debug-utils/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dependencies": {
+ "ansi-regex": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@ethersproject/solidity": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.5.0.tgz",
+ "integrity": "sha512-9NgZs9LhGMj6aCtHXhtmFQ4AN4sth5HuFXVvAQtzmm0jpSCNOTGtrHZJAeYTh7MBjRR8brylWZxBZR9zDStXbw==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/keccak256": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/sha2": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "node_modules/ethereum-waffle": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.4.0.tgz",
+ "integrity": "sha512-ADBqZCkoSA5Isk486ntKJVjFEawIiC+3HxNqpJqONvh3YXBTNiRfXvJtGuAFLXPG91QaqkGqILEHANAo7j/olQ==",
+ "dev": true,
+ "dependencies": {
+ "@ethereum-waffle/chai": "^3.4.0",
+ "@ethereum-waffle/compiler": "^3.4.0",
+ "@ethereum-waffle/mock-contract": "^3.3.0",
+ "@ethereum-waffle/provider": "^3.4.0",
+ "ethers": "^5.0.1"
+ },
+ "bin": {
+ "waffle": "bin/waffle"
+ },
+ "engines": {
+ "node": ">=10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-helper-function-name": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-get-function-arity": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
+ "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-traverse": {
+ "version": "6.26.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-code-frame": "^6.26.0",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "debug": "^2.6.8",
+ "globals": "^9.18.0",
+ "invariant": "^2.2.2",
+ "lodash": "^4.17.4"
+ }
+ },
+ "node_modules/load-json-file/node_modules/parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "dev": true,
+ "dependencies": {
+ "error-ex": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/expand-brackets/node_modules/debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/fast-diff": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w=="
+ },
+ "node_modules/@ethersproject/abstract-provider": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz",
+ "integrity": "sha512-m+MA/ful6eKbxpr99xUYeRvLkfnlqzrF8SZ46d/xFB1A7ZVknYc/sXJG0RcufF52Qn2jeFj1hhcoQ7IXjNKUqg==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/networks": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/transactions": "^5.5.0",
+ "@ethersproject/web": "^5.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereum-cryptography": {
+ "version": "0.1.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/pbkdf2": "^3.0.0",
+ "@types/secp256k1": "^4.0.1",
+ "blakejs": "^1.1.0",
+ "browserify-aes": "^1.2.0",
+ "bs58check": "^2.1.2",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "hash.js": "^1.1.7",
+ "keccak": "^3.0.0",
+ "pbkdf2": "^3.0.17",
+ "randombytes": "^2.1.0",
+ "safe-buffer": "^5.1.2",
+ "scrypt-js": "^3.0.0",
+ "secp256k1": "^4.0.1",
+ "setimmediate": "^1.0.5"
+ }
+ },
+ "node_modules/ganache-core/node_modules/sha.js": {
+ "version": "2.4.11",
+ "dev": true,
+ "license": "(MIT AND BSD-3-Clause)",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ },
+ "bin": {
+ "sha.js": "bin.js"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "17.0.8",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.8.tgz",
+ "integrity": "sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg=="
+ },
+ "node_modules/ganache-core/node_modules/web3-core-requestmanager": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "underscore": "1.9.1",
+ "web3-core-helpers": "1.2.11",
+ "web3-providers-http": "1.2.11",
+ "web3-providers-ipc": "1.2.11",
+ "web3-providers-ws": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/combined-stream": {
+ "version": "1.0.8",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-tx": {
+ "version": "1.3.7",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "ethereum-common": "^0.0.18",
+ "ethereumjs-util": "^5.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@types/bn.js": {
+ "version": "4.11.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/etag": {
+ "version": "1.8.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/detect-port/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ethereum-ens/node_modules/js-sha3": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz",
+ "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc="
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/swarm-js": {
+ "version": "0.1.40",
+ "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz",
+ "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==",
+ "dependencies": {
+ "bluebird": "^3.5.0",
+ "buffer": "^5.0.5",
+ "eth-lib": "^0.1.26",
+ "fs-extra": "^4.0.2",
+ "got": "^7.1.0",
+ "mime-types": "^2.1.16",
+ "mkdirp-promise": "^5.0.1",
+ "mock-fs": "^4.1.0",
+ "setimmediate": "^1.0.5",
+ "tar": "^4.0.2",
+ "xhr-request": "^1.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/object-copy/node_modules/kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+ "dependencies": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-codec": {
+ "version": "7.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-systemjs": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-hoist-variables": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "node_modules/xhr-request/node_modules/mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-errors": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "errno": "~0.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/fresh": {
+ "version": "0.5.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@resolver-engine/fs/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/uglify-js": {
+ "version": "3.14.5",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.5.tgz",
+ "integrity": "sha512-qZukoSxOG0urUTvjc2ERMTcAy+BiFh3weWAkeurLwjrCba73poHmG3E36XEjd/JGukMzwTL7uCxZiAexj8ppvQ==",
+ "optional": true,
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/xhr": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz",
+ "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==",
+ "dependencies": {
+ "global": "~4.4.0",
+ "is-function": "^1.0.1",
+ "parse-headers": "^2.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "node_modules/bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
+ },
+ "node_modules/browserify-rsa/node_modules/bn.js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/isarray": {
+ "version": "0.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/true-case-path": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz",
+ "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q=="
+ },
+ "node_modules/web3-core/node_modules/@types/node": {
+ "version": "12.20.41",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz",
+ "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q=="
+ },
+ "node_modules/aes-js": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz",
+ "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0="
+ },
+ "node_modules/ganache-core/node_modules/body-parser": {
+ "version": "1.19.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bytes": "3.1.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.7.0",
+ "raw-body": "2.4.0",
+ "type-is": "~1.6.17"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.51.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
+ "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
+ "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ecc-jsbn": {
+ "version": "0.1.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "node_modules/hardhat-deploy/node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@types/qs": {
+ "version": "6.9.7",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
+ "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw=="
+ },
+ "node_modules/wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream": {
+ "version": "1.3.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "level-errors": "^1.0.3",
+ "readable-stream": "^1.0.33",
+ "xtend": "^4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/loose-envify": {
+ "version": "1.4.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/hardhat-gas-reporter": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.7.tgz",
+ "integrity": "sha512-calJH1rbhUFwCnw0odJb3Cw+mDmBIsHdVyutsHhA3RY6JELyFVaVxCnITYGr/crkmHqt4tQCYROy7ty6DTLkuA==",
+ "dependencies": {
+ "array-uniq": "1.0.3",
+ "eth-gas-reporter": "^0.2.24",
+ "sha1": "^1.1.1"
+ },
+ "peerDependencies": {
+ "hardhat": "^2.0.2"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
+ "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/object.getownpropertydescriptors": {
+ "version": "2.1.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/log-symbols/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/aes-js": {
+ "version": "3.1.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/sc-istanbul/node_modules/async": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
+ },
+ "node_modules/parse-cache-control": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz",
+ "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104="
+ },
+ "node_modules/resolve": {
+ "version": "1.21.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz",
+ "integrity": "sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==",
+ "dependencies": {
+ "is-core-module": "^2.8.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/websocket/node_modules/ms": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/for-in": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/finalhandler/node_modules/ms": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/url/node_modules/punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+ "dev": true
+ },
+ "node_modules/ganache-core/node_modules/static-extend/node_modules/is-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stacktrace-parser": {
+ "version": "0.1.10",
+ "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz",
+ "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==",
+ "dependencies": {
+ "type-fest": "^0.7.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/hardhat/node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+ },
+ "node_modules/fs-extra": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+ "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
+ "node_modules/read-pkg-up/node_modules/find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+ "dev": true,
+ "dependencies": {
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+ "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "dependencies": {
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/charenc": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
+ "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@ensdomains/ens": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz",
+ "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==",
+ "deprecated": "Please use @ensdomains/ens-contracts",
+ "dev": true,
+ "dependencies": {
+ "bluebird": "^3.5.2",
+ "eth-ens-namehash": "^2.0.8",
+ "solc": "^0.4.20",
+ "testrpc": "0.0.1",
+ "web3-utils": "^1.0.0-beta.31"
+ }
+ },
+ "node_modules/node-hid": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-1.3.0.tgz",
+ "integrity": "sha512-BA6G4V84kiNd1uAChub/Z/5s/xS3EHBCxotQ0nyYrUG65mXewUDHE1tWOSqA2dp3N+mV0Ffq9wo2AW9t4p/G7g==",
+ "hasInstallScript": true,
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "bindings": "^1.5.0",
+ "nan": "^2.14.0",
+ "node-abi": "^2.18.0",
+ "prebuild-install": "^5.3.4"
+ },
+ "bin": {
+ "hid-showdevices": "src/show-devices.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/mocha/node_modules/ansi-colors": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
+ "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/nano-json-stream-parser": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz",
+ "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18="
+ },
+ "node_modules/ganache-core/node_modules/class-is": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/pump": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/mock-fs": {
+ "version": "4.14.0",
+ "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz",
+ "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw=="
+ },
+ "node_modules/@types/prettier": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz",
+ "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==",
+ "dev": true
+ },
+ "node_modules/ganache-core/node_modules/function-bind": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@ledgerhq/hw-transport-node-hid": {
+ "version": "5.26.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-5.26.0.tgz",
+ "integrity": "sha512-qhaefZVZatJ6UuK8Wb6WSFNOLWc2mxcv/xgsfKi5HJCIr4bPF/ecIeN+7fRcEaycxj4XykY6Z4A7zDVulfFH4w==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "@ledgerhq/devices": "^5.26.0",
+ "@ledgerhq/errors": "^5.26.0",
+ "@ledgerhq/hw-transport": "^5.26.0",
+ "@ledgerhq/hw-transport-node-hid-noevents": "^5.26.0",
+ "@ledgerhq/logs": "^5.26.0",
+ "lodash": "^4.17.20",
+ "node-hid": "1.3.0",
+ "usb": "^1.6.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/ltgt": {
+ "version": "2.2.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown": {
+ "version": "1.4.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abstract-leveldown": "~2.7.1",
+ "functional-red-black-tree": "^1.0.1",
+ "immediate": "^3.2.3",
+ "inherits": "~2.0.1",
+ "ltgt": "~2.2.0",
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "node_modules/which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-account": {
+ "version": "2.0.5",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "ethereumjs-util": "^5.0.0",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/isexe": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ganache-core/node_modules/create-hash": {
+ "version": "1.2.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cipher-base": "^1.0.1",
+ "inherits": "^2.0.1",
+ "md5.js": "^1.3.4",
+ "ripemd160": "^2.0.1",
+ "sha.js": "^2.4.0"
+ }
+ },
+ "node_modules/minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/crypt": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
+ "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+ "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+ "dependencies": {
+ "flatted": "^2.0.0",
+ "rimraf": "2.6.3",
+ "write": "1.0.3"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/rustbn.js": {
+ "version": "0.2.0",
+ "dev": true,
+ "license": "(MIT OR Apache-2.0)"
+ },
+ "node_modules/camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+ "engines": [
+ "node >=0.6.0"
+ ]
+ },
+ "node_modules/tweetnacl-util": {
+ "version": "0.15.1",
+ "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz",
+ "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw=="
+ },
+ "node_modules/ganache-core/node_modules/pull-window": {
+ "version": "2.1.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "looper": "^2.0.0"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
+ },
+ "node_modules/command-line-args": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz",
+ "integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^2.0.0",
+ "find-replace": "^1.0.3",
+ "typical": "^2.6.1"
+ },
+ "bin": {
+ "command-line-args": "bin/cli.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/varint": {
+ "version": "5.0.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/yargs/node_modules/emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
+ },
+ "node_modules/@ledgerhq/hw-transport-node-hid-noevents": {
+ "version": "5.51.1",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-5.51.1.tgz",
+ "integrity": "sha512-9wFf1L8ZQplF7XOY2sQGEeOhpmBRzrn+4X43kghZ7FBDoltrcK+s/D7S+7ffg3j2OySyP6vIIIgloXylao5Scg==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "@ledgerhq/devices": "^5.51.1",
+ "@ledgerhq/errors": "^5.50.0",
+ "@ledgerhq/hw-transport": "^5.51.1",
+ "@ledgerhq/logs": "^5.50.0",
+ "node-hid": "2.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethjs-unit": {
+ "version": "0.1.6",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bn.js": "4.11.6",
+ "number-to-bn": "1.7.0"
+ },
+ "engines": {
+ "node": ">=6.5.0",
+ "npm": ">=3"
+ }
+ },
+ "node_modules/@ethersproject/hash": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.5.0.tgz",
+ "integrity": "sha512-dnGVpK1WtBjmnp3mUT0PlU2MpapnwWI0PibldQEq1408tQBAbZpPidkWoVVuNMOl/lISO3+4hXZWCL3YV7qzfg==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/abstract-signer": "^5.5.0",
+ "@ethersproject/address": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/keccak256": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/snapdragon/node_modules/debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/prepend-http": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/string_decoder": {
+ "version": "0.10.31",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dependencies": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/multihashes": {
+ "version": "0.4.21",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "multibase": "^0.7.0",
+ "varint": "^5.0.0"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/secp256k1": {
+ "version": "4.0.2",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "elliptic": "^6.5.2",
+ "node-addon-api": "^2.0.0",
+ "node-gyp-build": "^4.2.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/lodash.partition": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.partition/-/lodash.partition-4.6.0.tgz",
+ "integrity": "sha1-o45GtzRp4EILDaEhLmbUFL42S6Q="
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/cookiejar": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz",
+ "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ=="
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/levelup": {
+ "version": "1.3.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deferred-leveldown": "~1.2.1",
+ "level-codec": "~7.0.0",
+ "level-errors": "~1.0.3",
+ "level-iterator-stream": "~1.3.0",
+ "prr": "~1.0.1",
+ "semver": "~5.4.1",
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/source-map-support/node_modules/source-map": {
+ "version": "0.6.1",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream/node_modules/readable-stream": {
+ "version": "1.1.14",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/@ethersproject/keccak256": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.5.0.tgz",
+ "integrity": "sha512-5VoFCTjo2rYbBe1l2f4mccaRFN/4VQEYFwwn04aJV2h7qf4ZvI2wFxUE1XOX+snbwCLRzIeikOqtAoPwMza9kg==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bytes": "^5.5.0",
+ "js-sha3": "0.8.0"
+ }
+ },
+ "node_modules/web3-eth-personal": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.6.1.tgz",
+ "integrity": "sha512-ItsC89Ln02+irzJjK6ALcLrMZfbVUCqVbmb/ieDKJ+eLW3pNkBNwoUzaydh92d5NzxNZgNxuQWVdlFyYX2hkEw==",
+ "dependencies": {
+ "@types/node": "^12.12.6",
+ "web3-core": "1.6.1",
+ "web3-core-helpers": "1.6.1",
+ "web3-core-method": "1.6.1",
+ "web3-net": "1.6.1",
+ "web3-utils": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ieee754": {
+ "version": "1.2.1",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/semaphore-async-await": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz",
+ "integrity": "sha1-hXvvXjZEYBykuVcLh+nfXKEpdPo=",
+ "engines": {
+ "node": ">=4.1"
+ }
+ },
+ "node_modules/core-js-pure": {
+ "version": "3.20.2",
+ "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.20.2.tgz",
+ "integrity": "sha512-CmWHvSKn2vNL6p6StNp1EmMIfVY/pqn3JLAjfZQ8WZGPOlGoO92EkX9/Mk81i6GxvoPXjUqEQnpM3rJ5QxxIOg==",
+ "hasInstallScript": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mocha/node_modules/chokidar": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz",
+ "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==",
+ "dependencies": {
+ "anymatch": "~3.1.1",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.0",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.2.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/keccak": {
+ "version": "3.0.1",
+ "dev": true,
+ "hasInstallScript": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "node-addon-api": "^2.0.0",
+ "node-gyp-build": "^4.2.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws": {
+ "version": "0.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "~1.0.15",
+ "xtend": "~2.1.1"
+ }
+ },
+ "node_modules/web3-core-helpers": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.6.1.tgz",
+ "integrity": "sha512-om2PZvK1uoWcgMq6JfcSx3241LEIVF6qi2JuHz2SLKiKEW5UsBUaVx0mNCmcZaiuYQCyOsLS3r33q5AdM+v8ng==",
+ "dependencies": {
+ "web3-eth-iban": "1.6.1",
+ "web3-utils": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/ganache-core/node_modules/ethashjs/node_modules/bn.js": {
+ "version": "5.1.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@resolver-engine/fs": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz",
+ "integrity": "sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==",
+ "dev": true,
+ "dependencies": {
+ "@resolver-engine/core": "^0.3.3",
+ "debug": "^3.1.0"
+ }
+ },
+ "node_modules/@types/form-data": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz",
+ "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/table/node_modules/strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dependencies": {
+ "ansi-regex": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/load-json-file/node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/levelup": {
+ "version": "3.1.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deferred-leveldown": "~4.0.0",
+ "level-errors": "~2.0.0",
+ "level-iterator-stream": "~3.0.0",
+ "xtend": "~4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/solc/node_modules/commander": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz",
+ "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==",
+ "dev": true
+ },
+ "node_modules/node-addon-api": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
+ "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA=="
+ },
+ "node_modules/websocket/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/source-map-url": {
+ "version": "0.4.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/babel-code-frame": {
+ "version": "6.26.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^1.1.3",
+ "esutils": "^2.0.2",
+ "js-tokens": "^3.0.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/graceful-fs": {
+ "version": "4.2.4",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ganache-core/node_modules/typedarray-to-buffer": {
+ "version": "3.1.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/@ethersproject/address": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.5.0.tgz",
+ "integrity": "sha512-l4Nj0eWlTUh6ro5IbPTgbpT4wRbdH5l8CQf7icF7sb/SI3Nhd9Y9HzhonTSTi6CefI0necIw7LJqQPopPLZyWw==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/keccak256": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/rlp": "^5.5.0"
+ }
+ },
+ "node_modules/@ledgerhq/logs": {
+ "version": "5.50.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-5.50.0.tgz",
+ "integrity": "sha512-swKHYCOZUGyVt4ge0u8a7AwNcA//h4nx5wIi0sruGye1IJ5Cva0GyK9L2/WdX+kWVTKp92ZiEo1df31lrWGPgA==",
+ "peer": true
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@truffle/debug-utils/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "node_modules/ganache-core/node_modules/extsprintf": {
+ "version": "1.3.0",
+ "dev": true,
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "license": "MIT"
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-arrow-functions": {
+ "version": "6.22.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/sync-rpc": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz",
+ "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==",
+ "dependencies": {
+ "get-port": "^3.1.0"
+ }
+ },
+ "node_modules/typechain": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/typechain/-/typechain-3.0.0.tgz",
+ "integrity": "sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg==",
+ "dev": true,
+ "dependencies": {
+ "command-line-args": "^4.0.7",
+ "debug": "^4.1.1",
+ "fs-extra": "^7.0.0",
+ "js-sha3": "^0.8.0",
+ "lodash": "^4.17.15",
+ "ts-essentials": "^6.0.3",
+ "ts-generator": "^0.1.1"
+ },
+ "bin": {
+ "typechain": "dist/cli/cli.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/levelup": {
+ "version": "1.3.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deferred-leveldown": "~1.2.1",
+ "level-codec": "~7.0.0",
+ "level-errors": "~1.0.3",
+ "level-iterator-stream": "~1.3.0",
+ "prr": "~1.0.1",
+ "semver": "~5.4.1",
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/number-to-bn/node_modules/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
+ },
+ "node_modules/rxjs/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ },
+ "node_modules/ganache-core/node_modules/ethereum-bloom-filters": {
+ "version": "1.0.7",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "js-sha3": "^0.8.0"
+ }
+ },
+ "node_modules/json-format": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-format/-/json-format-1.0.1.tgz",
+ "integrity": "sha1-FD9n5irxKda//tKIpGJl6iPQ3ww="
+ },
+ "node_modules/es-abstract": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz",
+ "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==",
+ "dependencies": {
+ "object-keys": "^1.1.1",
+ "internal-slot": "^1.0.3",
+ "function-bind": "^1.1.1",
+ "es-to-primitive": "^1.2.1",
+ "get-intrinsic": "^1.1.1",
+ "is-weakref": "^1.0.1",
+ "is-callable": "^1.2.4",
+ "string.prototype.trimend": "^1.0.4",
+ "is-shared-array-buffer": "^1.0.1",
+ "object.assign": "^4.1.2",
+ "is-regex": "^1.1.4",
+ "has-symbols": "^1.0.2",
+ "get-symbol-description": "^1.0.0",
+ "unbox-primitive": "^1.0.1",
+ "is-string": "^1.0.7",
+ "call-bind": "^1.0.2",
+ "object-inspect": "^1.11.0",
+ "has": "^1.0.3",
+ "string.prototype.trimstart": "^1.0.4",
+ "is-negative-zero": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/static-extend": {
+ "version": "0.1.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/inquirer/node_modules/string-width/node_modules/strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dependencies": {
+ "ansi-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/highlight.js": {
+ "version": "9.18.5",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.5.tgz",
+ "integrity": "sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==",
+ "deprecated": "Support has ended for 9.x series. Upgrade to @latest",
+ "hasInstallScript": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/readable-stream": {
+ "version": "1.0.34",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/hardhat/node_modules/solc": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz",
+ "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==",
+ "dependencies": {
+ "command-exists": "^1.2.8",
+ "commander": "3.0.2",
+ "follow-redirects": "^1.12.1",
+ "fs-extra": "^0.30.0",
+ "js-sha3": "0.8.0",
+ "memorystream": "^0.3.1",
+ "require-from-string": "^2.0.0",
+ "semver": "^5.5.0",
+ "tmp": "0.0.33"
+ },
+ "bin": {
+ "solcjs": "solcjs"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "dependencies": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+ "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/multihashes/node_modules/multibase": {
+ "version": "0.7.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "node_modules/ganache-core/node_modules/serve-static": {
+ "version": "1.14.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/table/node_modules/emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
+ },
+ "node_modules/ganache-core/node_modules/web3-core-promievent": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "eventemitter3": "4.0.4"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "dependencies": {
+ "object-keys": "^1.0.12"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/patch-package/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/solhint/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/global-prefix": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
+ "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
+ "dependencies": {
+ "ini": "^1.3.5",
+ "kind-of": "^6.0.2",
+ "which": "^1.3.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/eslint/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "node_modules/pathval": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
+ "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/psl": {
+ "version": "1.8.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-umd": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-plugin-transform-es2015-modules-amd": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/eth-lib": {
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
+ "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
+ "dependencies": {
+ "bn.js": "^4.11.6",
+ "elliptic": "^6.4.0",
+ "xhr-request-promise": "^0.1.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/pull-pushable": {
+ "version": "2.2.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/address": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz",
+ "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==",
+ "engines": {
+ "node": ">= 0.12.0"
+ }
+ },
+ "node_modules/@nomiclabs/truffle-contract/node_modules/bignumber.js": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz",
+ "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/deferred-leveldown": {
+ "version": "1.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abstract-leveldown": "~2.6.0"
+ }
+ },
+ "node_modules/window-size": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
+ "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=",
+ "dev": true,
+ "bin": {
+ "window-size": "cli.js"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/isarray": {
+ "version": "0.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/path-browserify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
+ "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+ "dev": true
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/browserify-sign/node_modules/bn.js": {
+ "version": "5.1.3",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ }
+ },
+ "node_modules/oboe": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz",
+ "integrity": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=",
+ "dependencies": {
+ "http-https": "^1.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/patch-package/node_modules/shebang-command": {
+ "version": "1.2.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/parse-asn1": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
+ "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
+ "dependencies": {
+ "asn1.js": "^5.2.0",
+ "browserify-aes": "^1.0.0",
+ "evp_bytestokey": "^1.0.0",
+ "pbkdf2": "^3.0.3",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/@ethereumjs/vm": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.6.0.tgz",
+ "integrity": "sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ==",
+ "dependencies": {
+ "@ethereumjs/block": "^3.6.0",
+ "@ethereumjs/blockchain": "^5.5.0",
+ "@ethereumjs/common": "^2.6.0",
+ "@ethereumjs/tx": "^3.4.0",
+ "async-eventemitter": "^0.2.4",
+ "core-js-pure": "^3.0.1",
+ "debug": "^2.2.0",
+ "ethereumjs-util": "^7.1.3",
+ "functional-red-black-tree": "^1.0.1",
+ "mcl-wasm": "^0.7.1",
+ "merkle-patricia-tree": "^4.2.2",
+ "rustbn.js": "~0.2.0"
+ }
+ },
+ "node_modules/inquirer/node_modules/strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dependencies": {
+ "ansi-regex": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/solhint/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-object-super": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-replace-supers": "^6.24.1",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@types/secp256k1": {
+ "version": "4.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/level-codec": {
+ "version": "9.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown": {
+ "version": "1.4.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abstract-leveldown": "~2.7.1",
+ "functional-red-black-tree": "^1.0.1",
+ "immediate": "^3.2.3",
+ "inherits": "~2.0.1",
+ "ltgt": "~2.2.0",
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "node_modules/@ethersproject/transactions": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.5.0.tgz",
+ "integrity": "sha512-9RZYSKX26KfzEd/1eqvv8pLauCKzDTub0Ko4LfIgaERvRuwyaNV78mJs7cpIgZaDl6RJui4o49lHwwCM0526zA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/address": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/constants": "^5.5.0",
+ "@ethersproject/keccak256": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/rlp": "^5.5.0",
+ "@ethersproject/signing-key": "^5.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/set-value": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/hardhat/node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ganache-core/node_modules/xhr-request-promise": {
+ "version": "0.1.3",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "xhr-request": "^1.1.0"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/web3-bzz": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz",
+ "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@types/node": "^12.12.6",
+ "got": "9.6.0",
+ "swarm-js": "^0.1.40"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/hardhat/node_modules/mocha/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eth-ens-namehash/node_modules/js-sha3": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz",
+ "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc="
+ },
+ "node_modules/ganache-core/node_modules/string_decoder/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/regjsparser": {
+ "version": "0.1.5",
+ "dev": true,
+ "license": "BSD",
+ "dependencies": {
+ "jsesc": "~0.5.0"
+ },
+ "bin": {
+ "regjsparser": "bin/parser"
+ }
+ },
+ "node_modules/browserify-sign": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
+ "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
+ "dependencies": {
+ "bn.js": "^5.1.1",
+ "browserify-rsa": "^4.0.1",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "elliptic": "^6.5.3",
+ "inherits": "^2.0.4",
+ "parse-asn1": "^5.1.5",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/browserify-des": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "cipher-base": "^1.0.1",
+ "des.js": "^1.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "node_modules/aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ansi-mark/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/safe-event-emitter": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "events": "^3.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/object-is": {
+ "version": "1.1.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/http-https": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "ISC",
+ "optional": true
+ },
+ "node_modules/log-symbols/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "node_modules/ganache-core/node_modules/ee-first": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/sshpk": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
+ "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
+ "dependencies": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ },
+ "bin": {
+ "sshpk-conv": "bin/sshpk-conv",
+ "sshpk-sign": "bin/sshpk-sign",
+ "sshpk-verify": "bin/sshpk-verify"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/encoding-down": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz",
+ "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==",
+ "dependencies": {
+ "abstract-leveldown": "^6.2.1",
+ "inherits": "^2.0.3",
+ "level-codec": "^9.0.0",
+ "level-errors": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/underscore": {
+ "version": "1.9.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/electron-to-chromium": {
+ "version": "1.3.636",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
+ "node_modules/coveralls": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz",
+ "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==",
+ "dev": true,
+ "dependencies": {
+ "js-yaml": "^3.13.1",
+ "lcov-parse": "^1.0.0",
+ "log-driver": "^1.2.7",
+ "minimist": "^1.2.5",
+ "request": "^2.88.2"
+ },
+ "bin": {
+ "coveralls": "bin/coveralls.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@trufflesuite/chromafi/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/keccak256": {
+ "version": "5.0.7",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/bytes": "^5.0.9",
+ "js-sha3": "0.5.7"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ltgt": {
+ "version": "2.1.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
+ "version": "4.5.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "bn.js": "^4.8.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "rlp": "^2.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/lru-cache": {
+ "version": "5.1.1",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/patch-package": {
+ "version": "6.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@yarnpkg/lockfile": "^1.1.0",
+ "chalk": "^2.4.2",
+ "cross-spawn": "^6.0.5",
+ "find-yarn-workspace-root": "^1.2.1",
+ "fs-extra": "^7.0.1",
+ "is-ci": "^2.0.0",
+ "klaw-sync": "^6.0.0",
+ "minimist": "^1.2.0",
+ "rimraf": "^2.6.3",
+ "semver": "^5.6.0",
+ "slash": "^2.0.0",
+ "tmp": "^0.0.33"
+ },
+ "bin": {
+ "patch-package": "index.js"
+ },
+ "engines": {
+ "npm": ">5"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ltgt": {
+ "version": "2.2.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-parameters": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-call-delegate": "^6.24.1",
+ "babel-helper-get-function-arity": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz",
+ "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-arguments": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
+ "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/web3-eth-ens": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.6.1.tgz",
+ "integrity": "sha512-ngprtbnoRgxg8s1wXt9nXpD3h1P+p7XnKXrp/8GdFI9uDmrbSQPRfzBw86jdZgOmy78hAnWmrHI6pBInmgi2qQ==",
+ "dependencies": {
+ "content-hash": "^2.5.2",
+ "eth-ens-namehash": "2.0.8",
+ "web3-core": "1.6.1",
+ "web3-core-helpers": "1.6.1",
+ "web3-core-promievent": "1.6.1",
+ "web3-eth-abi": "1.6.1",
+ "web3-eth-contract": "1.6.1",
+ "web3-utils": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz",
+ "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==",
+ "dev": true
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/eth-lib/node_modules/bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
+ },
+ "node_modules/ganache-core/node_modules/jsonfile": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/semver": {
+ "version": "5.4.1",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/ganache-core/node_modules/strip-hex-prefix": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-hex-prefixed": "1.0.0"
+ },
+ "engines": {
+ "node": ">=6.5.0",
+ "npm": ">=3"
+ }
+ },
+ "node_modules/hardhat/node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "node_modules/hardhat/node_modules/mocha": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz",
+ "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==",
+ "dependencies": {
+ "serialize-javascript": "6.0.0",
+ "yargs-unparser": "2.0.0",
+ "js-yaml": "4.1.0",
+ "yargs": "16.2.0",
+ "which": "2.0.2",
+ "ansi-colors": "4.1.1",
+ "log-symbols": "4.1.0",
+ "@ungap/promise-all-settled": "1.1.2",
+ "growl": "1.10.5",
+ "diff": "5.0.0",
+ "nanoid": "3.3.1",
+ "yargs-parser": "20.2.4",
+ "ms": "2.1.3",
+ "supports-color": "8.1.1",
+ "chokidar": "3.5.3",
+ "strip-json-comments": "3.1.1",
+ "debug": "4.3.3",
+ "minimatch": "4.2.1",
+ "find-up": "5.0.0",
+ "browser-stdout": "1.3.1",
+ "escape-string-regexp": "4.0.0",
+ "glob": "7.2.0",
+ "workerpool": "6.2.0",
+ "he": "1.2.0"
+ },
+ "bin": {
+ "_mocha": "bin/_mocha",
+ "mocha": "bin/mocha"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mochajs"
+ }
+ },
+ "node_modules/ganache-core/node_modules/async": {
+ "version": "2.6.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash": "^4.17.11"
+ }
+ },
+ "node_modules/ganache-core/node_modules/asynckit": {
+ "version": "0.4.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/md5.js": {
+ "version": "1.3.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "node_modules/log-symbols/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/web3-core-method": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz",
+ "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==",
+ "dependencies": {
+ "@ethereumjs/common": "^2.4.0",
+ "@ethersproject/transactions": "^5.0.0-beta.135",
+ "web3-core-helpers": "1.5.3",
+ "web3-core-promievent": "1.5.3",
+ "web3-core-subscriptions": "1.5.3",
+ "web3-utils": "1.5.3"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/deep-eql": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
+ "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+ "dependencies": {
+ "type-detect": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/readable-stream": {
+ "version": "1.0.34",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": {
+ "version": "6.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "0.1.6",
+ "rlp": "^2.2.3"
+ }
+ },
+ "node_modules/regexpp": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
+ "engines": {
+ "node": ">=6.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/snapdragon": {
+ "version": "0.8.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+ "dependencies": {
+ "mimic-fn": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+ "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+ "dependencies": {
+ "flat-cache": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-tx": {
+ "version": "1.3.7",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "ethereum-common": "^0.0.18",
+ "ethereumjs-util": "^5.0.0"
+ }
+ },
+ "node_modules/ts-generator/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "node_modules/ganache-core/node_modules/map-visit": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "object-visit": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-windows": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-wallet": {
+ "version": "0.6.5",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "aes-js": "^3.1.1",
+ "bs58check": "^2.1.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethereumjs-util": "^6.0.0",
+ "randombytes": "^2.0.6",
+ "safe-buffer": "^5.1.2",
+ "scryptsy": "^1.2.1",
+ "utf8": "^3.0.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "node_modules/level-mem": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-5.0.1.tgz",
+ "integrity": "sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg==",
+ "dependencies": {
+ "level-packager": "^5.0.3",
+ "memdown": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/type-is": {
+ "version": "1.6.18",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/repeat-string": {
+ "version": "1.6.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/shelljs": {
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
+ "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
+ "dependencies": {
+ "glob": "^7.0.0",
+ "interpret": "^1.0.0",
+ "rechoir": "^0.6.2"
+ },
+ "bin": {
+ "shjs": "bin/shjs"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/run-async": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/hardhat/node_modules/mocha/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ },
+ "node_modules/@nomiclabs/truffle-contract": {
+ "version": "4.2.23",
+ "resolved": "https://registry.npmjs.org/@nomiclabs/truffle-contract/-/truffle-contract-4.2.23.tgz",
+ "integrity": "sha512-Khj/Ts9r0LqEpGYhISbc+8WTOd6qJ4aFnDR+Ew+neqcjGnhwrIvuihNwPFWU6hDepW3Xod6Y+rTo90N8sLRDjw==",
+ "dependencies": {
+ "@truffle/blockchain-utils": "^0.0.25",
+ "@truffle/contract-schema": "^3.2.5",
+ "@truffle/debug-utils": "^4.2.9",
+ "@truffle/error": "^0.0.11",
+ "@truffle/interface-adapter": "^0.4.16",
+ "bignumber.js": "^7.2.1",
+ "ethereum-ens": "^0.8.0",
+ "ethers": "^4.0.0-beta.1",
+ "source-map-support": "^0.5.19"
+ },
+ "peerDependencies": {
+ "web3": "^1.2.1",
+ "web3-core-helpers": "^1.2.1",
+ "web3-core-promievent": "^1.2.1",
+ "web3-eth-abi": "^1.2.1",
+ "web3-utils": "^1.2.1"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@ethersproject/random": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.1.tgz",
+ "integrity": "sha512-YaU2dQ7DuhL5Au7KbcQLHxcRHfgyNgvFV4sQOo0HrtW3Zkrc9ctWNz8wXQ4uCSfSDsqX2vcjhroxU5RQRV0nqA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/readable-stream": {
+ "version": "1.0.34",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": {
+ "version": "6.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "0.1.6",
+ "rlp": "^2.2.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/has-values/node_modules/is-number": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/file-uri-to-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/ganache-core/node_modules/node-gyp-build": {
+ "version": "4.2.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "bin": {
+ "node-gyp-build": "bin.js",
+ "node-gyp-build-optional": "optional.js",
+ "node-gyp-build-test": "build-test.js"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "node_modules/ganache-core/node_modules/minizlib/node_modules/minipass": {
+ "version": "2.9.0",
+ "dev": true,
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.0"
+ }
+ },
+ "node_modules/hardhat/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/find-yarn-workspace-root": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz",
+ "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==",
+ "dev": true,
+ "dependencies": {
+ "micromatch": "^4.0.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/mime-db": {
+ "version": "1.45.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/truffle-assertions": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/truffle-assertions/-/truffle-assertions-0.9.2.tgz",
+ "integrity": "sha512-9g2RhaxU2F8DeWhqoGQvL/bV8QVoSnQ6PY+ZPvYRP5eF7+/8LExb4mjLx/FeliLTjc3Tv1SABG05Gu5qQ/ErmA==",
+ "dependencies": {
+ "assertion-error": "^1.1.0",
+ "lodash.isequal": "^4.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-strict-mode": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/ethereum-ens": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/ethereum-ens/-/ethereum-ens-0.8.0.tgz",
+ "integrity": "sha512-a8cBTF4AWw1Q1Y37V1LSCS9pRY4Mh3f8vCg5cbXCCEJ3eno1hbI/+Ccv9SZLISYpqQhaglP3Bxb/34lS4Qf7Bg==",
+ "dependencies": {
+ "bluebird": "^3.4.7",
+ "eth-ens-namehash": "^2.0.0",
+ "js-sha3": "^0.5.7",
+ "pako": "^1.0.4",
+ "underscore": "^1.8.3",
+ "web3": "^1.0.0-beta.34"
+ }
+ },
+ "node_modules/ganache-core/node_modules/har-validator": {
+ "version": "5.1.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.3",
+ "har-schema": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/cachedown/node_modules/lru-cache": {
+ "version": "3.2.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "pseudomap": "^1.0.1"
+ }
+ },
+ "node_modules/global-modules": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
+ "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
+ "dependencies": {
+ "global-prefix": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/node-abi/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "optional": true,
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/level-iterator-stream": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz",
+ "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==",
+ "dependencies": {
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0",
+ "xtend": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@ensdomains/resolver": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz",
+ "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==",
+ "deprecated": "Please use @ensdomains/ens-contracts",
+ "dev": true
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/functional-red-black-tree": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/url-to-options": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
+ "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@ethersproject/rlp": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.5.0.tgz",
+ "integrity": "sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/has": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+ "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+ "dependencies": {
+ "is-bigint": "^1.0.1",
+ "is-boolean-object": "^1.1.0",
+ "is-number-object": "^1.0.4",
+ "is-string": "^1.0.5",
+ "is-symbol": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "node_modules/eventemitter3": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz",
+ "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ=="
+ },
+ "node_modules/@ethersproject/web": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.1.tgz",
+ "integrity": "sha512-olvLvc1CB12sREc1ROPSHTdFCdvMh0J5GSJYiQg2D0hdD4QmJDy8QYDb1CvoqD/bF1c++aeKv2sR5uduuG9dQg==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/base64": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0"
+ }
+ },
+ "node_modules/immediate": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz",
+ "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q=="
+ },
+ "node_modules/ganache-core/node_modules/blakejs": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/test-value": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz",
+ "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^1.0.3",
+ "typical": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rustbn.js": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz",
+ "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA=="
+ },
+ "node_modules/ganache-core/node_modules/web3-providers-ws": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "eventemitter3": "4.0.4",
+ "underscore": "1.9.1",
+ "web3-core-helpers": "1.2.11",
+ "websocket": "^1.0.31"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/properties": {
+ "version": "5.0.7",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/logger": "^5.0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-abi": {
+ "version": "0.6.8",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bn.js": "^4.11.8",
+ "ethereumjs-util": "^6.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/string_decoder": {
+ "version": "0.10.31",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/swarm-js/node_modules/chownr": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
+ },
+ "node_modules/write": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+ "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
+ "dependencies": {
+ "mkdirp": "^0.5.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/expand-template": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree": {
+ "version": "2.3.2",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^1.4.2",
+ "ethereumjs-util": "^5.0.0",
+ "level-ws": "0.0.0",
+ "levelup": "^1.2.1",
+ "memdown": "^1.0.0",
+ "readable-stream": "^2.0.0",
+ "rlp": "^2.0.0",
+ "semaphore": ">=1.0.1"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/@truffle/error": {
+ "version": "0.0.14",
+ "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.14.tgz",
+ "integrity": "sha512-utJx+SZYoMqk8wldQG4gCVKhV8GwMJbWY7sLXFT/D8wWZTnE2peX7URFJh/cxkjTRCO328z1s2qewkhyVsu2HA=="
+ },
+ "node_modules/@nomiclabs/hardhat-etherscan": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.0.1.tgz",
+ "integrity": "sha512-ZeDMqUvbmWGSpsCkyD7QOsJ3lytNgmoOPpglOtgCfoIewb1o2Nz1PgofWYsSdIiWBtIN9rBF8ldU2jVpgsNhHg==",
+ "dependencies": {
+ "@ethersproject/abi": "^5.1.2",
+ "@ethersproject/address": "^5.0.2",
+ "cbor": "^5.0.2",
+ "debug": "^4.1.1",
+ "fs-extra": "^7.0.1",
+ "node-fetch": "^2.6.0",
+ "semver": "^6.3.0"
+ },
+ "peerDependencies": {
+ "hardhat": "^2.0.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/decompress-response": {
+ "version": "3.3.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/globby/node_modules/ignore": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
+ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/xtend": {
+ "version": "2.1.2",
+ "dev": true,
+ "dependencies": {
+ "object-keys": "~0.4.0"
+ },
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/levelup": {
+ "version": "1.3.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deferred-leveldown": "~1.2.1",
+ "level-codec": "~7.0.0",
+ "level-errors": "~1.0.3",
+ "level-iterator-stream": "~1.3.0",
+ "prr": "~1.0.1",
+ "semver": "~5.4.1",
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/hash-base": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
+ "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
+ "dependencies": {
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor": {
+ "version": "0.1.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-net": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "web3-core": "1.2.11",
+ "web3-core-method": "1.2.11",
+ "web3-utils": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/cacheable-request/node_modules/lowercase-keys": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/esquery/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/yargs/node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/web3-eth-iban": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.6.1.tgz",
+ "integrity": "sha512-91H0jXZnWlOoXmc13O9NuQzcjThnWyAHyDn5Yf7u6mmKOhpJSGF/OHlkbpXt1Y4v2eJdEPaVFa+6i8aRyagE7Q==",
+ "dependencies": {
+ "bn.js": "^4.11.9",
+ "web3-utils": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ghost-testrpc": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz",
+ "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==",
+ "dependencies": {
+ "chalk": "^2.4.2",
+ "node-emoji": "^1.10.0"
+ },
+ "bin": {
+ "testrpc-sc": "index.js"
+ }
+ },
+ "node_modules/@ensdomains/ens/node_modules/string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "dependencies": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@ensdomains/ens/node_modules/y18n": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
+ "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
+ "dev": true
+ },
+ "node_modules/ganache-core/node_modules/swarm-js/node_modules/url-parse-lax": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "prepend-http": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/through2": {
+ "version": "2.0.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/elliptic": {
+ "version": "6.5.4",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
+ "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
+ "dependencies": {
+ "bn.js": "^4.11.9",
+ "brorand": "^1.1.0",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.1",
+ "inherits": "^2.0.4",
+ "minimalistic-assert": "^1.0.1",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/source-map": {
+ "version": "0.5.7",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/rlp": {
+ "version": "5.0.7",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/logger": "^5.0.8"
+ }
+ },
+ "node_modules/ethers": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.3.tgz",
+ "integrity": "sha512-fTT4WT8/hTe/BLwRUtl7I5zlpF3XC3P/Xwqxc5AIP2HGlH15qpmjs0Ou78az93b1rLITzXLFxoNX63B8ZbUd7g==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/wordlists": "5.5.0",
+ "@ethersproject/abi": "5.5.0",
+ "@ethersproject/networks": "5.5.2",
+ "@ethersproject/hash": "5.5.0",
+ "@ethersproject/sha2": "5.5.0",
+ "@ethersproject/bignumber": "5.5.0",
+ "@ethersproject/bytes": "5.5.0",
+ "@ethersproject/properties": "5.5.0",
+ "@ethersproject/transactions": "5.5.0",
+ "@ethersproject/base64": "5.5.0",
+ "@ethersproject/signing-key": "5.5.0",
+ "@ethersproject/constants": "5.5.0",
+ "@ethersproject/solidity": "5.5.0",
+ "@ethersproject/logger": "5.5.0",
+ "@ethersproject/abstract-signer": "5.5.0",
+ "@ethersproject/address": "5.5.0",
+ "@ethersproject/web": "5.5.1",
+ "@ethersproject/abstract-provider": "5.5.1",
+ "@ethersproject/pbkdf2": "5.5.0",
+ "@ethersproject/wallet": "5.5.0",
+ "@ethersproject/providers": "5.5.2",
+ "@ethersproject/basex": "5.5.0",
+ "@ethersproject/strings": "5.5.0",
+ "@ethersproject/json-wallets": "5.5.0",
+ "@ethersproject/units": "5.5.0",
+ "@ethersproject/keccak256": "5.5.0",
+ "@ethersproject/hdnode": "5.5.0",
+ "@ethersproject/rlp": "5.5.0",
+ "@ethersproject/contracts": "5.5.0",
+ "@ethersproject/random": "5.5.1"
+ }
+ },
+ "node_modules/sc-istanbul/node_modules/esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/merkle-patricia-tree": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^2.6.1",
+ "ethereumjs-util": "^5.2.0",
+ "level-mem": "^3.0.1",
+ "level-ws": "^1.0.0",
+ "readable-stream": "^3.0.6",
+ "rlp": "^2.0.0",
+ "semaphore": ">=1.0.1"
+ }
+ },
+ "node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+ },
+ "node_modules/ganache-core/node_modules/tar/node_modules/fs-minipass": {
+ "version": "1.2.7",
+ "dev": true,
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "minipass": "^2.6.0"
+ }
+ },
+ "node_modules/recursive-readdir": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
+ "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==",
+ "dependencies": {
+ "minimatch": "3.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-core/node_modules/debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/hardhat/node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
+ "node_modules/jsonschema": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.0.tgz",
+ "integrity": "sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/xmlhttprequest": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
+ "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/xhr2-cookies": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "cookiejar": "^2.1.1"
+ }
+ },
+ "node_modules/xhr-request-promise": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz",
+ "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==",
+ "dependencies": {
+ "xhr-request": "^1.1.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/semver": {
+ "version": "5.4.1",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-generator": {
+ "version": "6.26.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "detect-indent": "^4.0.0",
+ "jsesc": "^1.3.0",
+ "lodash": "^4.17.4",
+ "source-map": "^0.5.7",
+ "trim-right": "^1.0.1"
+ }
+ },
+ "node_modules/check-error": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+ "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-errors": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "errno": "~0.1.1"
+ }
+ },
+ "node_modules/@ethereumjs/ethash": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@ethereumjs/ethash/-/ethash-1.1.0.tgz",
+ "integrity": "sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA==",
+ "dependencies": {
+ "@ethereumjs/block": "^3.5.0",
+ "@types/levelup": "^4.3.0",
+ "buffer-xor": "^2.0.1",
+ "ethereumjs-util": "^7.1.1",
+ "miller-rabin": "^4.0.0"
+ }
+ },
+ "node_modules/eth-gas-reporter/node_modules/ethers": {
+ "version": "4.0.49",
+ "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz",
+ "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==",
+ "dependencies": {
+ "aes-js": "3.0.0",
+ "bn.js": "^4.11.9",
+ "elliptic": "6.5.4",
+ "hash.js": "1.1.3",
+ "js-sha3": "0.5.7",
+ "scrypt-js": "2.0.4",
+ "setimmediate": "1.0.4",
+ "uuid": "2.0.1",
+ "xmlhttprequest": "1.8.0"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/cipher-base": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/semver": {
+ "version": "5.4.1",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/abort-controller": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+ "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+ "dependencies": {
+ "event-target-shim": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=6.5"
+ }
+ },
+ "node_modules/@ethereumjs/tx": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.4.0.tgz",
+ "integrity": "sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw==",
+ "dependencies": {
+ "@ethereumjs/common": "^2.6.0",
+ "ethereumjs-util": "^7.1.3"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
+ "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ganache-core/node_modules/pull-defer": {
+ "version": "0.2.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/detect-port": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz",
+ "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==",
+ "dependencies": {
+ "address": "^1.0.1",
+ "debug": "^2.6.0"
+ },
+ "bin": {
+ "detect": "bin/detect-port",
+ "detect-port": "bin/detect-port"
+ },
+ "engines": {
+ "node": ">= 4.2.1"
+ }
+ },
+ "node_modules/promise": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz",
+ "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==",
+ "dependencies": {
+ "asap": "~2.0.6"
+ }
+ },
+ "node_modules/cbor": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz",
+ "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==",
+ "dependencies": {
+ "bignumber.js": "^9.0.1",
+ "nofilter": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/scrypt-js": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",
+ "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA=="
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-syntax-async-functions": {
+ "version": "6.13.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-eth-personal/node_modules/@types/node": {
+ "version": "12.19.12",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/snapdragon-util": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/web3-eth-accounts/node_modules/eth-lib": {
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
+ "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
+ "dependencies": {
+ "bn.js": "^4.11.6",
+ "elliptic": "^6.4.0",
+ "xhr-request-promise": "^0.1.2"
+ }
+ },
+ "node_modules/stealthy-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+ "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/decode-uri-component": {
+ "version": "0.2.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/ganache-core/node_modules/define-property": {
+ "version": "2.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
+ },
+ "node_modules/source-map-support/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value": {
+ "version": "0.3.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/websocket/node_modules/debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "node_modules/ganache-core/node_modules/isobject": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
+ "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/xhr": {
+ "version": "2.6.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "global": "~4.4.0",
+ "is-function": "^1.0.1",
+ "parse-headers": "^2.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown": {
+ "version": "1.4.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abstract-leveldown": "~2.7.1",
+ "functional-red-black-tree": "^1.0.1",
+ "immediate": "^3.2.3",
+ "inherits": "~2.0.1",
+ "ltgt": "~2.2.0",
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "node_modules/hardhat/node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream": {
+ "version": "1.3.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "level-errors": "^1.0.3",
+ "readable-stream": "^1.0.33",
+ "xtend": "^4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/table/node_modules/ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
+ "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
+ "dependencies": {
+ "json-buffer": "3.0.0"
+ }
+ },
+ "node_modules/@truffle/interface-adapter/node_modules/web3": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/web3/-/web3-1.3.6.tgz",
+ "integrity": "sha512-jEpPhnL6GDteifdVh7ulzlPrtVQeA30V9vnki9liYlUvLV82ZM7BNOQJiuzlDePuE+jZETZSP/0G/JlUVt6pOA==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "web3-bzz": "1.3.6",
+ "web3-core": "1.3.6",
+ "web3-eth": "1.3.6",
+ "web3-eth-personal": "1.3.6",
+ "web3-net": "1.3.6",
+ "web3-shh": "1.3.6",
+ "web3-utils": "1.3.6"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/find-yarn-workspace-root": {
+ "version": "1.2.1",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "fs-extra": "^4.0.3",
+ "micromatch": "^3.1.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws": {
+ "version": "0.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "~1.0.15",
+ "xtend": "~2.1.1"
+ }
+ },
+ "node_modules/inquirer": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
+ "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
+ "dependencies": {
+ "ansi-escapes": "^3.2.0",
+ "chalk": "^2.4.2",
+ "cli-cursor": "^2.1.0",
+ "cli-width": "^2.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^2.0.0",
+ "lodash": "^4.17.12",
+ "mute-stream": "0.0.7",
+ "run-async": "^2.2.0",
+ "rxjs": "^6.4.0",
+ "string-width": "^2.1.0",
+ "strip-ansi": "^5.1.0",
+ "through": "^2.3.6"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/cosmiconfig": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+ "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+ "dependencies": {
+ "import-fresh": "^2.0.0",
+ "is-directory": "^0.3.1",
+ "js-yaml": "^3.13.1",
+ "parse-json": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereum-bloom-filters/node_modules/js-sha3": {
+ "version": "0.8.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/@truffle/provider/node_modules/web3": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz",
+ "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "web3-bzz": "1.5.3",
+ "web3-core": "1.5.3",
+ "web3-eth": "1.5.3",
+ "web3-eth-personal": "1.5.3",
+ "web3-net": "1.5.3",
+ "web3-shh": "1.5.3",
+ "web3-utils": "1.5.3"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@ledgerhq/cryptoassets": {
+ "version": "5.53.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/cryptoassets/-/cryptoassets-5.53.0.tgz",
+ "integrity": "sha512-M3ibc3LRuHid5UtL7FI3IC6nMEppvly98QHFoSa7lJU0HDzQxY6zHec/SPM4uuJUC8sXoGVAiRJDkgny54damw==",
+ "peer": true,
+ "dependencies": {
+ "invariant": "2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/patch-package/node_modules/shebang-regex": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-core/node_modules/@types/node": {
+ "version": "12.19.12",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/npmlog": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+ "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
+ }
+ },
+ "node_modules/string-width/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/oauth-sign": {
+ "version": "0.9.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/tar-fs": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+ "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "chownr": "^1.1.1",
+ "mkdirp-classic": "^0.5.2",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.1.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/browserslist": {
+ "version": "3.2.8",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "caniuse-lite": "^1.0.30000844",
+ "electron-to-chromium": "^1.3.47"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/string_decoder": {
+ "version": "0.10.31",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/hash.js": {
+ "version": "1.1.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/abstract-leveldown": {
+ "version": "2.6.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/bn.js": {
+ "version": "4.11.9",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/multibase": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz",
+ "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==",
+ "deprecated": "This module has been superseded by the multiformats module",
+ "dependencies": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/send/node_modules/debug/node_modules/ms": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/hardhat/node_modules/solc/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/sha.js": {
+ "version": "2.4.11",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ },
+ "bin": {
+ "sha.js": "bin.js"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/bn.js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
+ },
+ "node_modules/ganache-core/node_modules/pull-stream": {
+ "version": "3.6.14",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/cacheable-request/node_modules/lowercase-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@sindresorhus/is": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/web3-core-requestmanager": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.6.1.tgz",
+ "integrity": "sha512-4y7etYEUtkfflyYVBfN1oJtCbVFNhNX1omlEYzezhTnPj3/dT7n+dhUXcqvIhx9iKA13unGfpFge80XNFfcB8A==",
+ "dependencies": {
+ "util": "^0.12.0",
+ "web3-core-helpers": "1.6.1",
+ "web3-providers-http": "1.6.1",
+ "web3-providers-ipc": "1.6.1",
+ "web3-providers-ws": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/minimalistic-assert": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ganache-core/node_modules/cache-base": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/super-split": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/super-split/-/super-split-1.1.0.tgz",
+ "integrity": "sha512-I4bA5mgcb6Fw5UJ+EkpzqXfiuvVGS/7MuND+oBxNFmxu3ugLNrdIatzBLfhFRMVMLxgSsRy+TjIktgkF9RFSNQ=="
+ },
+ "node_modules/ghost-testrpc/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@types/secp256k1": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz",
+ "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babylon": {
+ "version": "6.18.0",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "babylon": "bin/babylon.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/buffer-xor": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/concat-stream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "node_modules/object.getownpropertydescriptors": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz",
+ "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.19.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/regenerator-runtime": {
+ "version": "0.11.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/concat-stream": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz",
+ "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/abstract-leveldown": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz",
+ "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==",
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "immediate": "^3.2.3",
+ "level-concat-iterator": "~2.0.0",
+ "level-supports": "~1.0.0",
+ "xtend": "~4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@resolver-engine/imports-fs": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz",
+ "integrity": "sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==",
+ "dev": true,
+ "dependencies": {
+ "@resolver-engine/fs": "^0.3.3",
+ "@resolver-engine/imports": "^0.3.3",
+ "debug": "^3.1.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-register": {
+ "version": "6.26.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-core": "^6.26.0",
+ "babel-runtime": "^6.26.0",
+ "core-js": "^2.5.0",
+ "home-or-tmp": "^2.0.0",
+ "lodash": "^4.17.4",
+ "mkdirp": "^0.5.1",
+ "source-map-support": "^0.4.15"
+ }
+ },
+ "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/@ledgerhq/hw-transport": {
+ "version": "5.51.1",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.51.1.tgz",
+ "integrity": "sha512-6wDYdbWrw9VwHIcoDnqWBaDFyviyjZWv6H9vz9Vyhe4Qd7TIFmbTl/eWs6hZvtZBza9K8y7zD8ChHwRI4s9tSw==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "@ledgerhq/devices": "^5.51.1",
+ "@ledgerhq/errors": "^5.50.0",
+ "events": "^3.3.0"
+ }
+ },
+ "node_modules/levelup": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz",
+ "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==",
+ "dependencies": {
+ "deferred-leveldown": "~5.3.0",
+ "level-errors": "~2.0.0",
+ "level-iterator-stream": "~4.0.0",
+ "level-supports": "~1.0.0",
+ "xtend": "~4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+ "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.x"
+ }
+ },
+ "node_modules/util": {
+ "version": "0.12.4",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz",
+ "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "is-arguments": "^1.0.4",
+ "is-generator-function": "^1.0.7",
+ "is-typed-array": "^1.1.3",
+ "safe-buffer": "^5.1.2",
+ "which-typed-array": "^1.1.2"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
+ "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.0.0",
+ "domutils": "^2.5.2",
+ "entities": "^2.0.0"
+ }
+ },
+ "node_modules/ethjs-unit/node_modules/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/duplexer3": {
+ "version": "0.1.4",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "optional": true
+ },
+ "node_modules/@types/pbkdf2": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz",
+ "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/http-response-object": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz",
+ "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==",
+ "dependencies": {
+ "@types/node": "^10.0.3"
+ }
+ },
+ "node_modules/har-validator": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+ "deprecated": "this library is no longer supported",
+ "dependencies": {
+ "ajv": "^6.12.3",
+ "har-schema": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/patch-package/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/semver/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/usb": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/usb/-/usb-1.9.2.tgz",
+ "integrity": "sha512-dryNz030LWBPAf6gj8vyq0Iev3vPbCLHCT8dBw3gQRXRzVNsIdeuU+VjPp3ksmSPkeMAl1k+kQ14Ij0QHyeiAg==",
+ "hasInstallScript": true,
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "node-addon-api": "^4.2.0",
+ "node-gyp-build": "^4.3.0"
+ },
+ "engines": {
+ "node": ">=10.16.0"
+ }
+ },
+ "node_modules/typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "dependencies": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "node_modules/es5-ext": {
+ "version": "0.10.53",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
+ "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+ "dependencies": {
+ "es6-iterator": "~2.0.3",
+ "es6-symbol": "~3.1.3",
+ "next-tick": "~1.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-data-descriptor": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-providers-ipc": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "oboe": "2.1.4",
+ "underscore": "1.9.1",
+ "web3-core-helpers": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/detect-port/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ganache-core/node_modules/level-packager": {
+ "version": "4.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "encoding-down": "~5.0.0",
+ "levelup": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/hardhat": {
+ "version": "2.9.3",
+ "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.9.3.tgz",
+ "integrity": "sha512-7Vw99RbYbMZ15UzegOR/nqIYIqddZXvLwJGaX5sX4G5bydILnbjmDU6g3jMKJSiArEixS3vHAEaOs5CW1JQ3hg==",
+ "dependencies": {
+ "@ethersproject/abi": "^5.1.2",
+ "semver": "^6.3.0",
+ "mocha": "^9.2.0",
+ "@ethereumjs/vm": "^5.6.0",
+ "fp-ts": "1.19.3",
+ "undici": "^4.14.1",
+ "resolve": "1.17.0",
+ "true-case-path": "^2.2.1",
+ "@ethereumjs/tx": "^3.4.0",
+ "solc": "0.7.3",
+ "ethereum-cryptography": "^0.1.2",
+ "@sentry/node": "^5.18.1",
+ "lodash": "^4.17.11",
+ "immutable": "^4.0.0-rc.12",
+ "ethereumjs-abi": "^0.6.8",
+ "adm-zip": "^0.4.16",
+ "abort-controller": "^3.0.0",
+ "mnemonist": "^0.38.0",
+ "ethereumjs-util": "^7.1.3",
+ "fs-extra": "^7.0.1",
+ "@ethereumjs/block": "^3.6.0",
+ "source-map-support": "^0.5.13",
+ "@types/lru-cache": "^5.1.0",
+ "uuid": "^8.3.2",
+ "io-ts": "1.10.4",
+ "tsort": "0.0.1",
+ "chalk": "^2.4.2",
+ "chokidar": "^3.4.0",
+ "stacktrace-parser": "^0.1.10",
+ "debug": "^4.1.1",
+ "slash": "^3.0.0",
+ "aggregate-error": "^3.0.0",
+ "raw-body": "^2.4.1",
+ "merkle-patricia-tree": "^4.2.2",
+ "enquirer": "^2.3.0",
+ "find-up": "^2.1.0",
+ "@ethereumjs/blockchain": "^5.5.0",
+ "p-map": "^4.0.0",
+ "@ethereumjs/common": "^2.6.0",
+ "@types/bn.js": "^5.1.0",
+ "glob": "^7.1.3",
+ "ws": "^7.4.6",
+ "env-paths": "^2.2.0",
+ "@solidity-parser/parser": "^0.14.1",
+ "@metamask/eth-sig-util": "^4.0.0",
+ "ci-info": "^2.0.0",
+ "ansi-escapes": "^4.3.0",
+ "qs": "^6.7.0"
+ },
+ "bin": {
+ "hardhat": "internal/cli/cli.js"
+ },
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || ^16.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-extendable": {
+ "version": "0.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
+ "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has-bigints": "^1.0.1",
+ "has-symbols": "^1.0.2",
+ "which-boxed-primitive": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/parent-module/node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/ethers": {
+ "version": "4.0.49",
+ "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz",
+ "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==",
+ "dependencies": {
+ "aes-js": "3.0.0",
+ "bn.js": "^4.11.9",
+ "elliptic": "6.5.4",
+ "hash.js": "1.1.3",
+ "js-sha3": "0.5.7",
+ "scrypt-js": "2.0.4",
+ "setimmediate": "1.0.4",
+ "uuid": "2.0.1",
+ "xmlhttprequest": "1.8.0"
+ }
+ },
+ "node_modules/inquirer/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/dom-walk": {
+ "version": "0.1.2",
+ "dev": true
+ },
+ "node_modules/@types/level-errors": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz",
+ "integrity": "sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ=="
+ },
+ "node_modules/ganache-core/node_modules/verror": {
+ "version": "1.10.0",
+ "dev": true,
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "node_modules/slice-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+ "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.0",
+ "astral-regex": "^1.0.0",
+ "is-fullwidth-code-point": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-extendable": {
+ "version": "0.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ },
+ "node_modules/ganache-core/node_modules/level-post": {
+ "version": "1.0.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ltgt": "^2.1.2"
+ }
+ },
+ "node_modules/web3-eth-abi/node_modules/@ethersproject/abi": {
+ "version": "5.0.7",
+ "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz",
+ "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==",
+ "dependencies": {
+ "@ethersproject/address": "^5.0.4",
+ "@ethersproject/bignumber": "^5.0.7",
+ "@ethersproject/bytes": "^5.0.4",
+ "@ethersproject/constants": "^5.0.4",
+ "@ethersproject/hash": "^5.0.4",
+ "@ethersproject/keccak256": "^5.0.3",
+ "@ethersproject/logger": "^5.0.5",
+ "@ethersproject/properties": "^5.0.3",
+ "@ethersproject/strings": "^5.0.4"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/@truffle/provider": {
+ "version": "0.2.42",
+ "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.42.tgz",
+ "integrity": "sha512-ZNoglPho4alYIjJR+sLTgX0x6ho7m4OAUWuJ50RAWmoEqYc4AM6htdrI+lTSoRrOHHbmgasv22a7rFPMnmDrTg==",
+ "dependencies": {
+ "@truffle/error": "^0.0.14",
+ "@truffle/interface-adapter": "^0.5.8",
+ "web3": "1.5.3"
+ }
+ },
+ "node_modules/tsort": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz",
+ "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y="
+ },
+ "node_modules/usb/node_modules/node-addon-api": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.2.0.tgz",
+ "integrity": "sha512-eazsqzwG2lskuzBqCGPi7Ac2UgOoMz8JVOXVhTvvPDYhthvNpefx8jWD8Np7Gv+2Sz0FlPWZk0nJV0z598Wn8Q==",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/ganache-core/node_modules/process": {
+ "version": "0.11.10",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/normalize-url": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
+ "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-mark/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/iso-url": {
+ "version": "0.4.7",
+ "resolved": "https://registry.npmjs.org/iso-url/-/iso-url-0.4.7.tgz",
+ "integrity": "sha512-27fFRDnPAMnHGLq36bWTpKET+eiXct3ENlCcdcMdk+mjXrb2kw3mhBUg1B7ewAC0kVzlOPhADzQgz1SE6Tglog==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@truffle/debug-utils": {
+ "version": "4.2.14",
+ "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-4.2.14.tgz",
+ "integrity": "sha512-g5UTX2DPTzrjRjBJkviGI2IrQRTTSvqjmNWCNZNXP+vgQKNxL9maLZhQ6oA3BuuByVW/kusgYeXt8+W1zynC8g==",
+ "dependencies": {
+ "@truffle/codec": "^0.7.1",
+ "@trufflesuite/chromafi": "^2.2.1",
+ "chalk": "^2.4.2",
+ "debug": "^4.1.0",
+ "highlight.js": "^9.15.8",
+ "highlightjs-solidity": "^1.0.18"
+ }
+ },
+ "node_modules/web3-utils": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.1.tgz",
+ "integrity": "sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w==",
+ "dependencies": {
+ "bn.js": "^4.11.9",
+ "ethereum-bloom-filters": "^1.0.6",
+ "ethereumjs-util": "^7.1.0",
+ "ethjs-unit": "0.1.6",
+ "number-to-bn": "1.7.0",
+ "randombytes": "^2.1.0",
+ "utf8": "3.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+ },
+ "node_modules/ganache-core/node_modules/request": {
+ "version": "2.88.2",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "isstream": "~0.1.2",
+ "oauth-sign": "~0.9.0",
+ "safe-buffer": "^5.1.2",
+ "is-typedarray": "~1.0.0",
+ "json-stringify-safe": "~5.0.1",
+ "performance-now": "^2.1.0",
+ "http-signature": "~1.2.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2",
+ "har-validator": "~5.1.3",
+ "extend": "~3.0.2",
+ "mime-types": "~2.1.19",
+ "tough-cookie": "~2.5.0",
+ "aws-sign2": "~0.7.0",
+ "caseless": "~0.12.0",
+ "aws4": "^1.8.0",
+ "forever-agent": "~0.6.1",
+ "combined-stream": "~1.0.6",
+ "form-data": "~2.3.2",
+ "qs": "~6.5.2"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz",
+ "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "es-abstract": "^1.18.5",
+ "foreach": "^2.0.5",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "node_modules/miller-rabin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+ "dependencies": {
+ "bn.js": "^4.0.0",
+ "brorand": "^1.0.1"
+ },
+ "bin": {
+ "miller-rabin": "bin/miller-rabin"
+ }
+ },
+ "node_modules/ganache-core/node_modules/nano-json-stream-parser": {
+ "version": "0.1.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+ "dev": true
+ },
+ "node_modules/ganache-core/node_modules/bluebird": {
+ "version": "3.7.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/jsprim": {
+ "version": "1.4.1",
+ "dev": true,
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "node_modules/@types/node-fetch": {
+ "version": "2.5.12",
+ "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz",
+ "integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "form-data": "^3.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/xhr-request": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "buffer-to-arraybuffer": "^0.0.5",
+ "object-assign": "^4.1.1",
+ "query-string": "^5.0.1",
+ "simple-get": "^2.7.0",
+ "timed-out": "^4.0.1",
+ "url-set-query": "^1.0.0",
+ "xhr": "^2.0.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/object-copy/node_modules/define-property": {
+ "version": "0.2.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/set-value/node_modules/is-extendable": {
+ "version": "0.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "peer": true,
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/transactions": {
+ "version": "5.0.9",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/address": "^5.0.9",
+ "@ethersproject/bignumber": "^5.0.13",
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/constants": "^5.0.8",
+ "@ethersproject/keccak256": "^5.0.7",
+ "@ethersproject/logger": "^5.0.8",
+ "@ethersproject/properties": "^5.0.7",
+ "@ethersproject/rlp": "^5.0.7",
+ "@ethersproject/signing-key": "^5.0.8"
+ }
+ },
+ "node_modules/hardhat/node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/web3-utils": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz",
+ "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==",
+ "dependencies": {
+ "bn.js": "^4.11.9",
+ "eth-lib": "0.2.8",
+ "ethereum-bloom-filters": "^1.0.6",
+ "ethjs-unit": "0.1.6",
+ "number-to-bn": "1.7.0",
+ "randombytes": "^2.1.0",
+ "utf8": "3.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-core": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "@types/bn.js": "^4.11.5",
+ "@types/node": "^12.12.6",
+ "bignumber.js": "^9.0.0",
+ "web3-core-helpers": "1.2.11",
+ "web3-core-method": "1.2.11",
+ "web3-core-requestmanager": "1.2.11",
+ "web3-utils": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
+ },
+ "node_modules/ganache-core/node_modules/tape/node_modules/object-inspect": {
+ "version": "1.7.0",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-async-to-generator": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-remap-async-to-generator": "^6.24.1",
+ "babel-plugin-syntax-async-functions": "^6.8.0",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-generator/node_modules/jsesc": {
+ "version": "1.3.0",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ }
+ },
+ "node_modules/cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+ "dependencies": {
+ "restore-cursor": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/uri-js": {
+ "version": "4.4.1",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/number-to-bn": {
+ "version": "1.7.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bn.js": "4.11.6",
+ "strip-hex-prefix": "1.0.0"
+ },
+ "engines": {
+ "node": ">=6.5.0",
+ "npm": ">=3"
+ }
+ },
+ "node_modules/rlp/node_modules/bn.js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
+ },
+ "node_modules/mocha": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz",
+ "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==",
+ "dependencies": {
+ "yargs-unparser": "1.6.0",
+ "js-yaml": "3.13.1",
+ "yargs": "13.3.2",
+ "which": "1.3.1",
+ "ansi-colors": "3.2.3",
+ "log-symbols": "3.0.0",
+ "wide-align": "1.1.3",
+ "growl": "1.10.5",
+ "diff": "3.5.0",
+ "object.assign": "4.1.0",
+ "node-environment-flags": "1.0.6",
+ "yargs-parser": "13.1.2",
+ "ms": "2.1.1",
+ "supports-color": "6.0.0",
+ "chokidar": "3.3.0",
+ "strip-json-comments": "2.0.1",
+ "debug": "3.2.6",
+ "minimatch": "3.0.4",
+ "mkdirp": "0.5.5",
+ "find-up": "3.0.0",
+ "browser-stdout": "1.3.1",
+ "escape-string-regexp": "1.0.5",
+ "glob": "7.1.3",
+ "he": "1.2.0"
+ },
+ "bin": {
+ "_mocha": "bin/_mocha",
+ "mocha": "bin/mocha"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mochajs"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-ci": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ci-info": "^2.0.0"
+ },
+ "bin": {
+ "is-ci": "bin.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/json-rpc-random-id": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ganache-core/node_modules/extglob/node_modules/define-property": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-query": {
+ "version": "2.1.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "json-rpc-random-id": "^1.0.0",
+ "xtend": "^4.0.1"
+ }
+ },
+ "node_modules/noop-logger": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
+ "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/undici": {
+ "version": "4.16.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-4.16.0.tgz",
+ "integrity": "sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw==",
+ "engines": {
+ "node": ">=12.18"
+ }
+ },
+ "node_modules/@truffle/debug-utils/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/bs58": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
+ "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
+ "dependencies": {
+ "base-x": "^3.0.2"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/stream-to-pull-stream": {
+ "version": "1.7.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "looper": "^3.0.0",
+ "pull-stream": "^3.2.3"
+ }
+ },
+ "node_modules/antlr4": {
+ "version": "4.7.1",
+ "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz",
+ "integrity": "sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ=="
+ },
+ "node_modules/@ethersproject/wordlists": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.5.0.tgz",
+ "integrity": "sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/hash": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-helper-regex": {
+ "version": "6.26.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+ "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": {
+ "version": "2.2.2",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^2.0.1",
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-tx": "^2.1.1",
+ "ethereumjs-util": "^5.0.0",
+ "merkle-patricia-tree": "^2.1.2"
+ }
+ },
+ "node_modules/tar-fs/node_modules/chownr": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/@ethersproject/bytes": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz",
+ "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/logger": "^5.5.0"
+ }
+ },
+ "node_modules/foreach": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
+ },
+ "node_modules/yargs/node_modules/string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dependencies": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/js-tokens": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/abstract-leveldown": {
+ "version": "2.6.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/eth-sig-util": {
+ "version": "1.4.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+ "ethereumjs-util": "^5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-helper-call-delegate": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-hoist-variables": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm": {
+ "version": "2.6.0",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^2.1.2",
+ "async-eventemitter": "^0.2.2",
+ "ethereumjs-account": "^2.0.3",
+ "ethereumjs-block": "~2.2.0",
+ "ethereumjs-common": "^1.1.0",
+ "ethereumjs-util": "^6.0.0",
+ "fake-merkle-patricia-tree": "^1.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "merkle-patricia-tree": "^2.3.2",
+ "rustbn.js": "~0.2.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/has-ansi": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/evp_bytestokey": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "md5.js": "^1.3.4",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
+ },
+ "node_modules/ganache-core/node_modules/jsbn": {
+ "version": "0.1.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/hardhat-deploy": {
+ "version": "0.9.24",
+ "resolved": "https://registry.npmjs.org/hardhat-deploy/-/hardhat-deploy-0.9.24.tgz",
+ "integrity": "sha512-fIIg6Wt7lV8h+6c6dFnINUKcJ/5Wfe5GYDaDsGGPqaK2b71DaeFHjsWRL+2ozaHkMZjdyYBOweY09wRu/KM1Qw==",
+ "dependencies": {
+ "@types/qs": "^6.9.7",
+ "@ethersproject/abi": "^5.4.0",
+ "axios": "^0.21.1",
+ "@ethersproject/bignumber": "^5.4.1",
+ "@ethersproject/bytes": "^5.4.0",
+ "murmur-128": "^0.2.1",
+ "@ethersproject/transactions": "^5.4.0",
+ "@ethersproject/constants": "^5.4.0",
+ "@ethersproject/solidity": "^5.4.0",
+ "@ethersproject/abstract-signer": "^5.4.1",
+ "@ethersproject/address": "^5.4.0",
+ "fs-extra": "^10.0.0",
+ "match-all": "^1.2.6",
+ "chalk": "^4.1.2",
+ "chokidar": "^3.5.2",
+ "debug": "^4.3.2",
+ "@ethersproject/wallet": "^5.4.0",
+ "@ethersproject/providers": "^5.4.4",
+ "enquirer": "^2.3.6",
+ "@ethersproject/contracts": "^5.4.1",
+ "form-data": "^4.0.0",
+ "qs": "^6.9.4"
+ },
+ "peerDependencies": {
+ "@ethersproject/hardware-wallets": "^5.0.14",
+ "hardhat": "^2.6.8"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/buffer-from": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nth-check": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
+ "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/@ethereum-waffle/ens": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.3.1.tgz",
+ "integrity": "sha512-xSjNWnT2Iwii3J3XGqD+F5yLEOzQzLHNLGfI5KIXdtQ4FHgReW/AMGRgPPLi+n+SP08oEQWJ3sEKrvbFlwJuaA==",
+ "dev": true,
+ "dependencies": {
+ "@ensdomains/ens": "^0.4.4",
+ "@ensdomains/resolver": "^0.2.4",
+ "ethers": "^5.5.2"
+ },
+ "engines": {
+ "node": ">=10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-function-name": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/klaw-sync": {
+ "version": "6.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.11"
+ }
+ },
+ "node_modules/ansi-mark": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/ansi-mark/-/ansi-mark-1.0.4.tgz",
+ "integrity": "sha1-HNS6jVfxXxCdaq9uycqXhsik7mw=",
+ "dependencies": {
+ "ansi-regex": "^3.0.0",
+ "array-uniq": "^1.0.3",
+ "chalk": "^2.3.2",
+ "strip-ansi": "^4.0.0",
+ "super-split": "^1.1.0"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/@types/node": {
+ "version": "12.20.41",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz",
+ "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q=="
+ },
+ "node_modules/has-bigints": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
+ "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hardhat/node_modules/yargs-unparser": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
+ "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
+ "dependencies": {
+ "camelcase": "^6.0.0",
+ "decamelize": "^4.0.0",
+ "flat": "^5.0.2",
+ "is-plain-obj": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/are-we-there-yet/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/ganache-core/node_modules/core-js": {
+ "version": "2.6.12",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/babel-types/node_modules/to-fast-properties": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/clone-response": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isarray": "1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/yargs/node_modules/strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dependencies": {
+ "ansi-regex": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/mocha/node_modules/ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/sha1": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz",
+ "integrity": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=",
+ "dependencies": {
+ "charenc": ">= 0.0.1",
+ "crypt": ">= 0.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ts-generator/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/setimmediate": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@truffle/error": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.11.tgz",
+ "integrity": "sha512-ju6TucjlJkfYMmdraYY/IBJaFb+Sa+huhYtOoyOJ+G29KcgytUVnDzKGwC7Kgk6IsxQMm62Mc1E0GZzFbGGipw=="
+ },
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/isurl": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "has-to-string-tag-x": "^1.2.0",
+ "is-object": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-blockchain": {
+ "version": "4.0.4",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^2.6.1",
+ "ethashjs": "~0.0.7",
+ "ethereumjs-block": "~2.2.2",
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-util": "^6.1.0",
+ "flow-stoplight": "^1.0.0",
+ "level-mem": "^3.0.1",
+ "lru-cache": "^5.1.1",
+ "rlp": "^2.2.2",
+ "semaphore": "^1.1.0"
+ }
+ },
+ "node_modules/yargs/node_modules/p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dependencies": {
+ "p-limit": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/semaphore": {
+ "version": "1.1.0",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream": {
+ "version": "1.3.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "level-errors": "^1.0.3",
+ "readable-stream": "^1.0.33",
+ "xtend": "^4.0.0"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "node_modules/ganache-core/node_modules/bs58check": {
+ "version": "2.1.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bs58": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "node_modules/memorystream": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+ "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/solc": {
+ "version": "0.6.12",
+ "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz",
+ "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==",
+ "dev": true,
+ "dependencies": {
+ "command-exists": "^1.2.8",
+ "commander": "3.0.2",
+ "fs-extra": "^0.30.0",
+ "js-sha3": "0.8.0",
+ "memorystream": "^0.3.1",
+ "require-from-string": "^2.0.0",
+ "semver": "^5.5.0",
+ "tmp": "0.0.33"
+ },
+ "bin": {
+ "solcjs": "solcjs"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/fragment-cache": {
+ "version": "0.2.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "map-cache": "^0.2.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/nice-try": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/websocket": {
+ "version": "1.0.32",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "bufferutil": "^4.0.1",
+ "debug": "^2.2.0",
+ "es5-ext": "^0.10.50",
+ "typedarray-to-buffer": "^3.1.5",
+ "utf-8-validate": "^5.0.2",
+ "yaeti": "^0.0.6"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-preset-env/node_modules/semver": {
+ "version": "5.7.1",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/abstract-leveldown": {
+ "version": "2.6.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/elliptic": {
+ "version": "6.5.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bn.js": "^4.4.0",
+ "brorand": "^1.0.1",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.0"
+ }
+ },
+ "node_modules/solhint/node_modules/commander": {
+ "version": "2.18.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz",
+ "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ=="
+ },
+ "node_modules/ganache-core/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@ethersproject/units": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.5.0.tgz",
+ "integrity": "sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/constants": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/finalhandler/node_modules/debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/patch-package/node_modules/semver": {
+ "version": "5.7.1",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/@ensdomains/ens/node_modules/solc": {
+ "version": "0.4.26",
+ "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz",
+ "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==",
+ "dev": true,
+ "dependencies": {
+ "fs-extra": "^0.30.0",
+ "memorystream": "^0.3.1",
+ "require-from-string": "^1.1.0",
+ "semver": "^5.3.0",
+ "yargs": "^4.7.1"
+ },
+ "bin": {
+ "solcjs": "solcjs"
+ }
+ },
+ "node_modules/buffer-xor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
+ },
+ "node_modules/ganache-core/node_modules/p-cancelable": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/unset-value/node_modules/has-values": {
+ "version": "0.1.4",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/isarray": {
+ "version": "0.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/express/node_modules/qs": {
+ "version": "6.7.0",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-regenerator": {
+ "version": "6.26.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regenerator-transform": "^0.10.0"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-account": {
+ "version": "2.0.5",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "ethereumjs-util": "^5.0.0",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown": {
+ "version": "1.4.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abstract-leveldown": "~2.7.1",
+ "functional-red-black-tree": "^1.0.1",
+ "immediate": "^3.2.3",
+ "inherits": "~2.0.1",
+ "ltgt": "~2.2.0",
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "node_modules/browserify-des": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+ "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+ "dependencies": {
+ "cipher-base": "^1.0.1",
+ "des.js": "^1.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "node_modules/http-basic": {
+ "version": "8.1.3",
+ "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz",
+ "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==",
+ "dependencies": {
+ "caseless": "^0.12.0",
+ "concat-stream": "^1.6.2",
+ "http-response-object": "^3.0.1",
+ "parse-cache-control": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/semver": {
+ "version": "5.4.1",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
+ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA=="
+ },
+ "node_modules/ganache-core/node_modules/backoff": {
+ "version": "2.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "precond": "0.2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/type": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/deferred-leveldown": {
+ "version": "1.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abstract-leveldown": "~2.6.0"
+ }
+ },
+ "node_modules/accepts": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+ "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+ "dependencies": {
+ "mime-types": "~2.1.24",
+ "negotiator": "0.6.2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/read-pkg/node_modules/path-type": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eth-gas-reporter": {
+ "version": "0.2.24",
+ "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.24.tgz",
+ "integrity": "sha512-RbXLC2bnuPHzIMU/rnLXXlb6oiHEEKu7rq2UrAX/0mfo0Lzrr/kb9QTjWjfz8eNvc+uu6J8AuBwI++b+MLNI2w==",
+ "dependencies": {
+ "@ethersproject/abi": "^5.0.0-beta.146",
+ "@solidity-parser/parser": "^0.14.0",
+ "cli-table3": "^0.5.0",
+ "colors": "1.4.0",
+ "ethereumjs-util": "6.2.0",
+ "ethers": "^4.0.40",
+ "fs-readdir-recursive": "^1.1.0",
+ "lodash": "^4.17.14",
+ "markdown-table": "^1.1.3",
+ "mocha": "^7.1.1",
+ "req-cwd": "^2.0.0",
+ "request": "^2.88.0",
+ "request-promise-native": "^1.0.5",
+ "sha1": "^1.1.1",
+ "sync-request": "^6.0.0"
+ },
+ "peerDependencies": {
+ "@codechecks/client": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@codechecks/client": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@ethersproject/json-wallets": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.5.0.tgz",
+ "integrity": "sha512-9lA21XQnCdcS72xlBn1jfQdj2A1VUxZzOzi9UkNdnokNKke/9Ya2xA9aIK1SC3PQyBDLt4C+dfps7ULpkvKikQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/abstract-signer": "^5.5.0",
+ "@ethersproject/address": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/hdnode": "^5.5.0",
+ "@ethersproject/keccak256": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/pbkdf2": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/random": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0",
+ "@ethersproject/transactions": "^5.5.0",
+ "aes-js": "3.0.0",
+ "scrypt-js": "3.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/negotiator": {
+ "version": "0.6.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/assert-plus": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+ "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+ "dependencies": {
+ "string-width": "^3.1.0",
+ "strip-ansi": "^5.2.0",
+ "wrap-ansi": "^5.1.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/kind-of": {
+ "version": "6.0.3",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/multihashes": {
+ "version": "0.4.21",
+ "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz",
+ "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==",
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "multibase": "^0.7.0",
+ "varint": "^5.0.0"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz",
+ "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/web3-eth-personal/node_modules/@types/node": {
+ "version": "12.20.41",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz",
+ "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q=="
+ },
+ "node_modules/@types/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw=="
+ },
+ "node_modules/ganache-core/node_modules/to-object-path/node_modules/kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@nomiclabs/truffle-contract/node_modules/js-sha3": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz",
+ "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc="
+ },
+ "node_modules/nan": {
+ "version": "2.15.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
+ "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/ganache-core/node_modules/buffer-to-arraybuffer": {
+ "version": "0.0.5",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/repeating": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-finite": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/bignumber": {
+ "version": "5.0.13",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/logger": "^5.0.8",
+ "bn.js": "^4.4.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/json-rpc-error": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/tweetnacl": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "Unlicense"
+ },
+ "node_modules/eth-gas-reporter/node_modules/is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@ensdomains/ens/node_modules/wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/class-is": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz",
+ "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw=="
+ },
+ "node_modules/ganache-core/node_modules/d": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "es5-ext": "^0.10.50",
+ "type": "^1.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/pull-live": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pull-cat": "^1.1.9",
+ "pull-stream": "^3.4.0"
+ }
+ },
+ "node_modules/@sentry/types": {
+ "version": "5.30.0",
+ "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz",
+ "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+ },
+ "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/async-eventemitter": {
+ "version": "0.2.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async": "^2.4.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-plain-object": {
+ "version": "2.0.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inquirer/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/uuid": {
+ "version": "3.4.0",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "uuid": "bin/uuid"
+ }
+ },
+ "node_modules/ganache-core/node_modules/object-copy/node_modules/is-data-descriptor": {
+ "version": "0.1.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-core/node_modules/json5": {
+ "version": "0.5.1",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-eth-contract": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "@types/bn.js": "^4.11.5",
+ "underscore": "1.9.1",
+ "web3-core": "1.2.11",
+ "web3-core-helpers": "1.2.11",
+ "web3-core-method": "1.2.11",
+ "web3-core-promievent": "1.2.11",
+ "web3-core-subscriptions": "1.2.11",
+ "web3-eth-abi": "1.2.11",
+ "web3-utils": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/node-abi": {
+ "version": "2.30.1",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz",
+ "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "semver": "^5.4.1"
+ }
+ },
+ "node_modules/inquirer/node_modules/strip-ansi/node_modules/ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/body-parser/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "node_modules/clone-response": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+ "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "node_modules/eslint/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ripemd160": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+ "dependencies": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws": {
+ "version": "0.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "~1.0.15",
+ "xtend": "~2.1.1"
+ }
+ },
+ "node_modules/read-pkg-up": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^1.0.0",
+ "read-pkg": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/universalify": {
+ "version": "0.1.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/public-encrypt": {
+ "version": "4.0.3",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bn.js": "^4.1.0",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "parse-asn1": "^5.0.0",
+ "randombytes": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "node_modules/next-tick": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
+ },
+ "node_modules/ganache-core/node_modules/trim-right": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@sentry/tracing": {
+ "version": "5.30.0",
+ "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz",
+ "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==",
+ "dependencies": {
+ "@sentry/hub": "5.30.0",
+ "@sentry/minimal": "5.30.0",
+ "@sentry/types": "5.30.0",
+ "@sentry/utils": "5.30.0",
+ "tslib": "^1.9.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/request/node_modules/form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 0.12"
+ }
+ },
+ "node_modules/browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw=="
+ },
+ "node_modules/minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ },
+ "node_modules/ganache-core/node_modules/finalhandler": {
+ "version": "1.1.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/ethereumjs-abi/node_modules/@types/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ },
+ "node_modules/klaw": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.9"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary": {
+ "version": "3.2.4",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "async": "^2.1.2",
+ "clone": "^2.0.0",
+ "concat-stream": "^1.5.1",
+ "end-of-stream": "^1.1.0",
+ "eth-query": "^2.0.2",
+ "ethereumjs-block": "^1.4.1",
+ "ethereumjs-tx": "^1.1.1",
+ "ethereumjs-util": "^5.0.1",
+ "ethereumjs-vm": "^2.6.0",
+ "through2": "^2.0.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/has-to-string-tag-x": {
+ "version": "1.4.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "has-symbol-support-x": "^1.4.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/deferred-leveldown": {
+ "version": "1.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abstract-leveldown": "~2.6.0"
+ }
+ },
+ "node_modules/solhint/node_modules/@solidity-parser/parser": {
+ "version": "0.13.2",
+ "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.13.2.tgz",
+ "integrity": "sha512-RwHnpRnfrnD2MSPveYoPh8nhofEvX7fgjHk1Oq+NNvCcLx4r1js91CO9o+F/F3fBzOCyvm8kKRTriFICX/odWw==",
+ "dependencies": {
+ "antlr4ts": "^0.5.0-alpha.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree/node_modules/async": {
+ "version": "1.5.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/class-utils/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/object.assign": {
+ "version": "4.1.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "peer": true,
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/ganache-core/node_modules/fetch-ponyfill": {
+ "version": "4.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "node-fetch": "~1.7.1"
+ }
+ },
+ "node_modules/hardhat-abi-exporter": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/hardhat-abi-exporter/-/hardhat-abi-exporter-2.7.2.tgz",
+ "integrity": "sha512-/do2VgS/aqpyrB0P93Pc9flsW7d2nknVLU8rQCMUNjJNa3S7ZLbNaFwuwvieM1V9hejUu6AIm1o6p2Vw5dHlOg==",
+ "dev": true,
+ "dependencies": {
+ "@ethersproject/abi": "^5.5.0",
+ "delete-empty": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.14.0"
+ },
+ "peerDependencies": {
+ "hardhat": "^2.0.0"
+ }
+ },
+ "node_modules/lodash.escaperegexp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
+ "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c="
+ },
+ "node_modules/ts-generator/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ltgt": {
+ "version": "2.2.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-account": {
+ "version": "2.0.5",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "ethereumjs-util": "^5.0.0",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/solhint/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eth-lib/node_modules/ws": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
+ "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
+ "dependencies": {
+ "async-limiter": "~1.0.0",
+ "safe-buffer": "~5.1.0",
+ "ultron": "~1.1.0"
+ }
+ },
+ "node_modules/cipher-base": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/yargs/node_modules/find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dependencies": {
+ "locate-path": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/toidentifier": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/strict-uri-encode": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
+ },
+ "node_modules/gauge/node_modules/string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-plain-obj": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/to-object-path/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/@ensdomains/ens/node_modules/get-caller-file": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
+ "dev": true
+ },
+ "node_modules/os-locale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "dev": true,
+ "dependencies": {
+ "lcid": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/solhint/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/has-value": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": {
+ "version": "2.1.2",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-util": "^6.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/posix-character-classes": {
+ "version": "0.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block": {
+ "version": "2.2.2",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^2.0.1",
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-tx": "^2.1.1",
+ "ethereumjs-util": "^5.0.0",
+ "merkle-patricia-tree": "^2.1.2"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dependencies": {
+ "p-limit": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/object-keys": {
+ "version": "0.4.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/color-name": {
+ "version": "1.1.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/@ethereumjs/vm/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "node_modules/load-json-file": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0",
+ "strip-bom": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sc-istanbul/node_modules/supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "dependencies": {
+ "has-flag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-eth-ens": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "content-hash": "^2.5.2",
+ "eth-ens-namehash": "2.0.8",
+ "underscore": "1.9.1",
+ "web3-core": "1.2.11",
+ "web3-core-helpers": "1.2.11",
+ "web3-core-promievent": "1.2.11",
+ "web3-eth-abi": "1.2.11",
+ "web3-eth-contract": "1.2.11",
+ "web3-utils": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/eth-gas-reporter/node_modules/setimmediate": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
+ "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48="
+ },
+ "node_modules/web3-bzz": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.6.1.tgz",
+ "integrity": "sha512-JbnFNbRlwwHJZPtVuCxo7rC4U4OTg+mPsyhjgPQJJhS0a6Y54OgVWYk9UA/95HqbmTJwTtX329gJoSsseEfrng==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@types/node": "^12.12.6",
+ "got": "9.6.0",
+ "swarm-js": "^0.1.40"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ghost-testrpc/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/query-string": {
+ "version": "5.1.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "decode-uri-component": "^0.2.0",
+ "object-assign": "^4.1.0",
+ "strict-uri-encode": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream/node_modules/readable-stream": {
+ "version": "1.1.14",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/gauge/node_modules/strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/arr-flatten": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nopt": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+ "dependencies": {
+ "abbrev": "1"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/supports-color": {
+ "version": "5.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/json-stable-stringify": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jsonify": "~0.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/swarm-js/node_modules/fs-extra": {
+ "version": "4.0.3",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "node_modules/functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc="
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/string_decoder": {
+ "version": "0.10.31",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cli-width": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
+ "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw=="
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "node_modules/ganache-core/node_modules/eth-sig-util": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "buffer": "^5.2.1",
+ "elliptic": "^6.4.0",
+ "ethereumjs-abi": "0.6.5",
+ "ethereumjs-util": "^5.1.1",
+ "tweetnacl": "^1.0.0",
+ "tweetnacl-util": "^0.15.0"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/to-regex": {
+ "version": "3.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/readable-stream": {
+ "version": "2.3.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/are-we-there-yet/node_modules/readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/request/node_modules/qs": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
+ "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethashjs": {
+ "version": "0.0.8",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^2.1.2",
+ "buffer-xor": "^2.0.1",
+ "ethereumjs-util": "^7.0.2",
+ "miller-rabin": "^4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-literals": {
+ "version": "6.22.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/web3-core": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz",
+ "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==",
+ "dependencies": {
+ "@types/bn.js": "^4.11.5",
+ "@types/node": "^12.12.6",
+ "bignumber.js": "^9.0.0",
+ "web3-core-helpers": "1.5.3",
+ "web3-core-method": "1.5.3",
+ "web3-core-requestmanager": "1.5.3",
+ "web3-utils": "1.5.3"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-eth-accounts": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "crypto-browserify": "3.12.0",
+ "eth-lib": "0.2.8",
+ "ethereumjs-common": "^1.3.2",
+ "ethereumjs-tx": "^2.1.1",
+ "scrypt-js": "^3.0.1",
+ "underscore": "1.9.1",
+ "uuid": "3.3.2",
+ "web3-core": "1.2.11",
+ "web3-core-helpers": "1.2.11",
+ "web3-core-method": "1.2.11",
+ "web3-utils": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/chownr": {
+ "version": "1.1.4",
+ "dev": true,
+ "license": "ISC",
+ "optional": true
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/prettier-plugin-solidity": {
+ "version": "1.0.0-beta.19",
+ "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz",
+ "integrity": "sha512-xxRQ5ZiiZyUoMFLE9h7HnUDXI/daf1tnmL1msEdcKmyh7ZGQ4YklkYLC71bfBpYU2WruTb5/SFLUaEb3RApg5g==",
+ "dev": true,
+ "dependencies": {
+ "@solidity-parser/parser": "^0.14.0",
+ "emoji-regex": "^10.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "semver": "^7.3.5",
+ "solidity-comments-extractor": "^0.0.7",
+ "string-width": "^4.2.3"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "prettier": "^2.3.0"
+ }
+ },
+ "node_modules/express": {
+ "version": "4.17.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz",
+ "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==",
+ "dependencies": {
+ "type-is": "~1.6.18",
+ "safe-buffer": "5.2.1",
+ "finalhandler": "~1.1.2",
+ "fresh": "0.5.2",
+ "body-parser": "1.19.1",
+ "content-type": "~1.0.4",
+ "send": "0.17.2",
+ "cookie": "0.4.1",
+ "methods": "~1.1.2",
+ "proxy-addr": "~2.0.7",
+ "accepts": "~1.3.7",
+ "range-parser": "~1.2.1",
+ "on-finished": "~2.3.0",
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "etag": "~1.8.1",
+ "path-to-regexp": "0.1.7",
+ "statuses": "~1.5.0",
+ "parseurl": "~1.3.3",
+ "setprototypeof": "1.2.0",
+ "merge-descriptors": "1.0.1",
+ "vary": "~1.1.2",
+ "serve-static": "1.14.2",
+ "content-disposition": "0.5.4",
+ "escape-html": "~1.0.3",
+ "cookie-signature": "1.0.6",
+ "utils-merge": "1.0.1",
+ "array-flatten": "1.1.1",
+ "depd": "~1.1.2",
+ "qs": "6.9.6"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/simple-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+ "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+ "dependencies": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "0.1.6",
+ "rlp": "^2.2.3"
+ }
+ },
+ "node_modules/@nomiclabs/truffle-contract/node_modules/uuid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+ "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
+ "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details."
+ },
+ "node_modules/@truffle/debug-utils/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/aws-sign2": {
+ "version": "0.7.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/hardhat-deploy/node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/async": {
+ "version": "1.5.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@truffle/interface-adapter/node_modules/ethers": {
+ "version": "4.0.49",
+ "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz",
+ "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==",
+ "dependencies": {
+ "aes-js": "3.0.0",
+ "bn.js": "^4.11.9",
+ "elliptic": "6.5.4",
+ "hash.js": "1.1.3",
+ "js-sha3": "0.5.7",
+ "scrypt-js": "2.0.4",
+ "setimmediate": "1.0.4",
+ "uuid": "2.0.1",
+ "xmlhttprequest": "1.8.0"
+ }
+ },
+ "node_modules/web3-core-method": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.6.1.tgz",
+ "integrity": "sha512-szH5KyIWIaULQDBdDvevQUCHV9lsExJ/oV0ePqK+w015D2SdMPMuhii0WB+HCePaksWO+rr/GAypvV9g2T3N+w==",
+ "dependencies": {
+ "@ethersproject/transactions": "^5.0.0-beta.135",
+ "web3-core-helpers": "1.6.1",
+ "web3-core-promievent": "1.6.1",
+ "web3-core-subscriptions": "1.6.1",
+ "web3-utils": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": {
+ "version": "2.1.2",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-util": "^6.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/utf8": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/level-sublevel": {
+ "version": "6.6.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytewise": "~1.1.0",
+ "level-codec": "^9.0.0",
+ "level-errors": "^2.0.0",
+ "level-iterator-stream": "^2.0.3",
+ "ltgt": "~2.1.1",
+ "pull-defer": "^0.2.2",
+ "pull-level": "^2.0.3",
+ "pull-stream": "^3.6.8",
+ "typewiselite": "~1.0.0",
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/des.js": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+ "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/content-disposition": {
+ "version": "0.5.3",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "safe-buffer": "5.1.2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/command-exists": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz",
+ "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w=="
+ },
+ "node_modules/ganache-core/node_modules/to-object-path": {
+ "version": "0.3.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/scrypt-js": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/memdown/node_modules/abstract-leveldown": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz",
+ "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==",
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "immediate": "^3.2.3",
+ "level-concat-iterator": "~2.0.0",
+ "level-supports": "~1.0.0",
+ "xtend": "~4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "dev": true,
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ganache-core/node_modules/multibase": {
+ "version": "0.6.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/class-utils/node_modules/is-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/signing-key": {
+ "version": "5.0.8",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/logger": "^5.0.8",
+ "@ethersproject/properties": "^5.0.7",
+ "elliptic": "6.5.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/path-parse": {
+ "version": "1.0.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/js-tokens": {
+ "version": "3.0.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/babel-helper-builder-binary-assignment-operator-visitor": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-explode-assignable-expression": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/p-cancelable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@ensdomains/ens/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/mnemonist": {
+ "version": "0.38.5",
+ "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz",
+ "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==",
+ "dependencies": {
+ "obliterator": "^2.0.0"
+ }
+ },
+ "node_modules/ext": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz",
+ "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==",
+ "dependencies": {
+ "type": "^2.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream": {
+ "version": "1.3.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "level-errors": "^1.0.3",
+ "readable-stream": "^1.0.33",
+ "xtend": "^4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/form-data": {
+ "version": "2.3.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 0.12"
+ }
+ },
+ "node_modules/d": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+ "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+ "dependencies": {
+ "es5-ext": "^0.10.50",
+ "type": "^1.0.1"
+ }
+ },
+ "node_modules/patch-package/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/ganache-core/node_modules/static-extend/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/next-tick": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/eslint/node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cids": {
+ "version": "0.7.5",
+ "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz",
+ "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==",
+ "deprecated": "This module has been superseded by the multiformats module",
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "class-is": "^1.1.0",
+ "multibase": "~0.6.0",
+ "multicodec": "^1.0.0",
+ "multihashes": "~0.4.15"
+ },
+ "engines": {
+ "node": ">=4.0.0",
+ "npm": ">=3.0.0"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.0.0.tgz",
+ "integrity": "sha512-KmJa8l6uHi1HrBI34udwlzZY1jOEuID/ft4d8BSSEdRyap7PwBEt910453PJa5MuGvxkLqlt4Uvhu7tttFHViw=="
+ },
+ "node_modules/ganache-core/node_modules/json-schema": {
+ "version": "0.2.3",
+ "dev": true
+ },
+ "node_modules/ganache-core/node_modules/level-mem/node_modules/abstract-leveldown": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-ens-namehash": {
+ "version": "2.0.8",
+ "dev": true,
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "idna-uts46-hx": "^2.3.1",
+ "js-sha3": "^0.5.7"
+ }
+ },
+ "node_modules/ganache-core/node_modules/lowercase-keys": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@szmarczak/http-timer": {
+ "version": "1.1.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "defer-to-connect": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereum-common": {
+ "version": "0.0.18",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@resolver-engine/core/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor": {
+ "version": "0.1.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/setprototypeof": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "ISC",
+ "optional": true
+ },
+ "node_modules/caller-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
+ "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
+ "dependencies": {
+ "caller-callsite": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/pify": {
+ "version": "2.3.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/js-sha3": {
+ "version": "0.5.7",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/is-retry-allowed": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+ "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/collection-visit": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ethereum-cryptography": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz",
+ "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==",
+ "dependencies": {
+ "@types/pbkdf2": "^3.0.0",
+ "@types/secp256k1": "^4.0.1",
+ "blakejs": "^1.1.0",
+ "browserify-aes": "^1.2.0",
+ "bs58check": "^2.1.2",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "hash.js": "^1.1.7",
+ "keccak": "^3.0.0",
+ "pbkdf2": "^3.0.17",
+ "randombytes": "^2.1.0",
+ "safe-buffer": "^5.1.2",
+ "scrypt-js": "^3.0.0",
+ "secp256k1": "^4.0.1",
+ "setimmediate": "^1.0.5"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+ "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+ "dependencies": {
+ "ansi-styles": "^3.2.0",
+ "string-width": "^3.0.0",
+ "strip-ansi": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/es6-symbol": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+ "dependencies": {
+ "d": "^1.0.1",
+ "ext": "^1.1.2"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.9",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
+ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ=="
+ },
+ "node_modules/ganache-core/node_modules/parse-headers": {
+ "version": "2.0.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/hardhat/node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ganache-core/node_modules/has-values": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/bytes": {
+ "version": "5.0.9",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/logger": "^5.0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/to-regex-range": {
+ "version": "2.1.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/body-parser/node_modules/ms": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/create-hmac": {
+ "version": "1.1.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cipher-base": "^1.0.3",
+ "create-hash": "^1.1.0",
+ "inherits": "^2.0.1",
+ "ripemd160": "^2.0.0",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/eth-gas-reporter/node_modules/string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dependencies": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/levelup": {
+ "version": "1.3.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deferred-leveldown": "~1.2.1",
+ "level-codec": "~7.0.0",
+ "level-errors": "~1.0.3",
+ "level-iterator-stream": "~1.3.0",
+ "prr": "~1.0.1",
+ "semver": "~5.4.1",
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dependencies": {
+ "shebang-regex": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/tape/node_modules/glob": {
+ "version": "7.1.6",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@truffle/debug-utils/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@sentry/hub/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ },
+ "node_modules/swarm-js/node_modules/minizlib": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
+ "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
+ "dependencies": {
+ "minipass": "^2.9.0"
+ }
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.14.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
+ "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/solhint/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/level-ws": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.8",
+ "xtend": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
+ "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ]
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-exponentiation-operator": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1",
+ "babel-plugin-syntax-exponentiation-operator": "^6.8.0",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/bytewise": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytewise-core": "^1.2.2",
+ "typewise": "^1.0.3"
+ }
+ },
+ "node_modules/@trufflesuite/chromafi/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/glob": {
+ "version": "7.1.3",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-core-helpers": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "underscore": "1.9.1",
+ "web3-eth-iban": "1.2.11",
+ "web3-utils": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/rlp": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz",
+ "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==",
+ "dependencies": {
+ "bn.js": "^5.2.0"
+ },
+ "bin": {
+ "rlp": "bin/rlp"
+ }
+ },
+ "node_modules/solc/node_modules/jsonfile": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+ "dev": true,
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/forever-agent": {
+ "version": "0.6.1",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@ethereum-waffle/chai": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.1.tgz",
+ "integrity": "sha512-8mjgjWCe8XSCWuyJgVtJY8sm00VTczGBTDxBejgEBWN/J9x7QD8jdmWW8bfxdnqZbxiDCTvRFL58Wmd254BEqQ==",
+ "dev": true,
+ "dependencies": {
+ "@ethereum-waffle/provider": "^3.4.0",
+ "ethers": "^5.4.7"
+ },
+ "engines": {
+ "node": ">=10.0"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "node_modules/ganache-core/node_modules/mimic-response": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-typedarray": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/xhr-request/node_modules/simple-get": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
+ "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
+ "dependencies": {
+ "decompress-response": "^3.3.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream/node_modules/readable-stream": {
+ "version": "1.1.14",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/url": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+ "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+ "dev": true,
+ "dependencies": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/event-target-shim": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/send/node_modules/debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine": {
+ "version": "14.2.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-fetch": "^2.1.0",
+ "json-stable-stringify": "^1.0.1",
+ "semaphore": "^1.0.3",
+ "eth-sig-util": "3.0.0",
+ "eth-json-rpc-infura": "^3.1.0",
+ "ethereumjs-tx": "^1.2.0",
+ "xtend": "^4.0.1",
+ "backoff": "^2.5.0",
+ "ethereumjs-util": "^5.1.5",
+ "ethereumjs-vm": "^2.3.4",
+ "eth-block-tracker": "^3.0.0",
+ "json-rpc-error": "^2.0.0",
+ "promise-to-callback": "^1.0.0",
+ "async": "^2.5.0",
+ "ethereumjs-block": "^1.2.2",
+ "readable-stream": "^2.2.9",
+ "request": "^2.85.0",
+ "xhr": "^2.2.0",
+ "clone": "^2.0.0",
+ "ws": "^5.1.1"
+ }
+ },
+ "node_modules/@trufflesuite/chromafi/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dependencies": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/es-abstract": {
+ "version": "1.18.0-next.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.2",
+ "is-negative-zero": "^2.0.0",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.1",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/are-we-there-yet/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/convert-source-map": {
+ "version": "1.7.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/bufferutil": {
+ "version": "4.0.3",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "node-gyp-build": "^4.2.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": {
+ "version": "2.1.2",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-util": "^6.0.0"
+ }
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/errno": {
+ "version": "0.1.8",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prr": "~1.0.1"
+ },
+ "bin": {
+ "errno": "cli.js"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/eth-gas-reporter/node_modules/uuid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+ "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
+ "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details."
+ },
+ "node_modules/ganache-core/node_modules/express/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/typechain/node_modules/ts-essentials": {
+ "version": "6.0.7",
+ "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz",
+ "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==",
+ "dev": true,
+ "peerDependencies": {
+ "typescript": ">=3.7.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/caniuse-lite": {
+ "version": "1.0.30001174",
+ "dev": true,
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoped-functions": {
+ "version": "6.22.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/ansi-mark/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/private": {
+ "version": "0.1.8",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/send": {
+ "version": "0.17.2",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz",
+ "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "1.8.1",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/har-schema": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/merge-descriptors": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/object-copy": {
+ "version": "0.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/web3-providers-ipc": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.6.1.tgz",
+ "integrity": "sha512-anyoIZlpMzwEQI4lwylTzDrHsVp20v0QUtSTp2B5jInBinmQtyCE7vnbX20jEQ4j5uPwfJabKNtoJsk6a3O4WQ==",
+ "dependencies": {
+ "oboe": "2.1.5",
+ "web3-core-helpers": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/fast-glob": {
+ "version": "3.2.10",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.10.tgz",
+ "integrity": "sha512-s9nFhFnvR63wls6/kM88kQqDhMu0AfdjqouE2l5GVQPbqLgyFjjU5ry/r2yKsJxpb9Py1EYNqieFrmMaX4v++A==",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/browserify-aes": {
+ "version": "1.2.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-xor": "^1.0.3",
+ "cipher-base": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.3",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-object": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/solhint/node_modules/prettier": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
+ "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
+ "optional": true,
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE="
+ },
+ "node_modules/ganache-core/node_modules/ethjs-unit/node_modules/bn.js": {
+ "version": "4.11.6",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/pbkdf2": {
+ "version": "3.1.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "create-hash": "^1.1.2",
+ "create-hmac": "^1.1.4",
+ "ripemd160": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ },
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
+ "node_modules/string-width/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-destructuring": {
+ "version": "6.23.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/yargs/node_modules/is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@ledgerhq/errors": {
+ "version": "5.50.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-5.50.0.tgz",
+ "integrity": "sha512-gu6aJ/BHuRlpU7kgVpy2vcYk6atjB4iauP2ymF7Gk0ez0Y/6VSMVSJvubeEQN+IV60+OBK0JgeIZG7OiHaw8ow==",
+ "peer": true
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@ledgerhq/hw-app-eth": {
+ "version": "5.27.2",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-app-eth/-/hw-app-eth-5.27.2.tgz",
+ "integrity": "sha512-llNdrE894cCN8j6yxJEUniciyLVcLmu5N0UmIJLOObztG+5rOF4bX54h4SreTWK+E10Z0CzHSeyE5Lz/tVcqqQ==",
+ "peer": true,
+ "dependencies": {
+ "@ledgerhq/cryptoassets": "^5.27.2",
+ "@ledgerhq/errors": "^5.26.0",
+ "@ledgerhq/hw-transport": "^5.26.0",
+ "bignumber.js": "^9.0.1",
+ "rlp": "^2.2.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/rimraf": {
+ "version": "2.6.3",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ }
+ },
+ "node_modules/npm-force-resolutions": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/npm-force-resolutions/-/npm-force-resolutions-0.0.10.tgz",
+ "integrity": "sha512-Jscex+xIU6tw3VsyrwxM1TeT+dd9Fd3UOMAjy6J1TMpuYeEqg4LQZnATQO5vjPrsARm3und6zc6Dii/GUyRE5A==",
+ "dependencies": {
+ "json-format": "^1.0.1",
+ "source-map-support": "^0.5.5",
+ "xmlhttprequest": "^1.8.0"
+ },
+ "bin": {
+ "npm-force-resolutions": "index.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/define-properties": {
+ "version": "1.1.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "object-keys": "^1.0.12"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/union-value": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-codec": {
+ "version": "7.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/typical": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
+ "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
+ "dev": true
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/object-keys": {
+ "version": "0.4.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/hardhat/node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-spread": {
+ "version": "6.22.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/number-to-bn/node_modules/bn.js": {
+ "version": "4.11.6",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/range-parser": {
+ "version": "1.2.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@sindresorhus/is": {
+ "version": "0.14.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-infura": {
+ "version": "3.2.1",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-fetch": "^2.1.1",
+ "eth-json-rpc-middleware": "^1.5.0",
+ "json-rpc-engine": "^3.4.0",
+ "json-rpc-error": "^2.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/browserify-sign": {
+ "version": "4.2.1",
+ "dev": true,
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "bn.js": "^5.1.1",
+ "browserify-rsa": "^4.0.1",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "elliptic": "^6.5.3",
+ "inherits": "^2.0.4",
+ "parse-asn1": "^5.1.5",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/parseurl": {
+ "version": "1.3.3",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/concat-stream": {
+ "version": "1.6.2",
+ "dev": true,
+ "engines": [
+ "node >= 0.8"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
+ "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "dependencies": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "node_modules/timed-out": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/is-stream": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+ },
+ "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/immutable": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
+ "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw=="
+ },
+ "node_modules/adm-zip": {
+ "version": "0.4.16",
+ "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz",
+ "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==",
+ "engines": {
+ "node": ">=0.3.0"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+ "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/bytewise-core": {
+ "version": "1.2.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "typewise-core": "^1.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/strings": {
+ "version": "5.0.8",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/constants": "^5.0.8",
+ "@ethersproject/logger": "^5.0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ganache-core/node_modules/simple-get": {
+ "version": "2.8.1",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "decompress-response": "^3.3.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
+ "node_modules/express/node_modules/qs": {
+ "version": "6.9.6",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz",
+ "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==",
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-fn": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/multihashes/node_modules/multibase": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz",
+ "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==",
+ "deprecated": "This module has been superseded by the multiformats module",
+ "dependencies": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ },
+ "node_modules/@ethersproject/hdnode": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.5.0.tgz",
+ "integrity": "sha512-mcSOo9zeUg1L0CoJH7zmxwUG5ggQHU1UrRf8jyTYy6HxdZV+r0PBoL1bxr+JHIPXRzS6u/UW4mEn43y0tmyF8Q==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/abstract-signer": "^5.5.0",
+ "@ethersproject/basex": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/pbkdf2": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/sha2": "^5.5.0",
+ "@ethersproject/signing-key": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0",
+ "@ethersproject/transactions": "^5.5.0",
+ "@ethersproject/wordlists": "^5.5.0"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "dependencies": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/string_decoder": {
+ "version": "0.10.31",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/cross-fetch": {
+ "version": "2.2.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "node-fetch": "2.1.2",
+ "whatwg-fetch": "2.0.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ret": {
+ "version": "0.1.15",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
+ "node_modules/ganache-core/node_modules/cookie": {
+ "version": "0.4.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@ethersproject/basex": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.5.0.tgz",
+ "integrity": "sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0"
+ }
+ },
+ "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/prebuild-install": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz",
+ "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "detect-libc": "^1.0.3",
+ "expand-template": "^2.0.3",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.3",
+ "mkdirp-classic": "^0.5.3",
+ "napi-build-utils": "^1.0.1",
+ "node-abi": "^2.21.0",
+ "npmlog": "^4.0.1",
+ "pump": "^3.0.0",
+ "rc": "^1.2.7",
+ "simple-get": "^3.0.3",
+ "tar-fs": "^2.0.0",
+ "tunnel-agent": "^0.6.0"
+ },
+ "bin": {
+ "prebuild-install": "bin.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ripemd160": {
+ "version": "2.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ws": {
+ "version": "3.3.3",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "async-limiter": "~1.0.0",
+ "safe-buffer": "~5.1.0",
+ "ultron": "~1.1.0"
+ }
+ },
+ "node_modules/code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+ "devOptional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/component-emitter": {
+ "version": "1.3.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/defer-to-connect": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
+ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ=="
+ },
+ "node_modules/ganache-core/node_modules/got/node_modules/get-stream": {
+ "version": "4.1.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/abi": {
+ "version": "5.0.0-beta.153",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/address": ">=5.0.0-beta.128",
+ "@ethersproject/bignumber": ">=5.0.0-beta.130",
+ "@ethersproject/bytes": ">=5.0.0-beta.129",
+ "@ethersproject/constants": ">=5.0.0-beta.128",
+ "@ethersproject/hash": ">=5.0.0-beta.128",
+ "@ethersproject/keccak256": ">=5.0.0-beta.127",
+ "@ethersproject/logger": ">=5.0.0-beta.129",
+ "@ethersproject/properties": ">=5.0.0-beta.131",
+ "@ethersproject/strings": ">=5.0.0-beta.130"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-function": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/import-fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+ "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
+ "dependencies": {
+ "caller-path": "^2.0.0",
+ "resolve-from": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/web3-eth-contract/node_modules/@types/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-core": {
+ "version": "6.26.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "convert-source-map": "^1.5.1",
+ "babylon": "^6.18.0",
+ "babel-traverse": "^6.26.0",
+ "babel-code-frame": "^6.26.0",
+ "lodash": "^4.17.4",
+ "private": "^0.1.8",
+ "babel-register": "^6.26.0",
+ "source-map": "^0.5.7",
+ "babel-template": "^6.26.0",
+ "debug": "^2.6.9",
+ "babel-types": "^6.26.0",
+ "babel-generator": "^6.26.0",
+ "slash": "^1.0.0",
+ "babel-runtime": "^6.26.0",
+ "minimatch": "^3.0.4",
+ "json5": "^0.5.1",
+ "babel-messages": "^6.23.0",
+ "path-is-absolute": "^1.0.1",
+ "babel-helpers": "^6.24.1"
+ }
+ },
+ "node_modules/slice-ansi/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/browserify-rsa/node_modules/bn.js": {
+ "version": "5.1.3",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/is-object": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz",
+ "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/arr-union": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "file-uri-to-path": "1.0.0"
+ }
+ },
+ "node_modules/caller-callsite": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
+ "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
+ "dependencies": {
+ "callsites": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="
+ },
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/u2f-api": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/u2f-api/-/u2f-api-0.2.7.tgz",
+ "integrity": "sha512-fqLNg8vpvLOD5J/z4B6wpPg4Lvowz1nJ9xdHcCzdUPKcFE/qNCceV2gNZxSJd5vhAZemHr/K/hbzVA0zxB5mkg==",
+ "peer": true
+ },
+ "node_modules/jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-errors": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "errno": "~0.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/regexp.prototype.flags": {
+ "version": "1.3.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/ghost-testrpc/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor": {
+ "version": "0.1.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
+ "node_modules/web3-providers-http": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.6.1.tgz",
+ "integrity": "sha512-xBoKOJxu10+kO3ikamXmBfrWZ/xpQOGy0ocdp7Y81B17En5TXELwlmMXt1UlIgWiyYDhjq4OwlH/VODYqHXy3A==",
+ "dependencies": {
+ "web3-core-helpers": "1.6.1",
+ "xhr2-cookies": "1.1.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@ethersproject/networks": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.2.tgz",
+ "integrity": "sha512-NEqPxbGBfy6O3x4ZTISb90SjEDkWYDUbEeIFhJly0F7sZjoQMnj5KYzMSkMkLKZ+1fGpx00EDpHQCy6PrDupkQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/logger": "^5.5.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-codec": {
+ "version": "7.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "dependencies": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-styles": {
+ "version": "2.2.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/send/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
+ "node_modules/ganache-core/node_modules/web3-eth-abi": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/abi": "5.0.0-beta.153",
+ "underscore": "1.9.1",
+ "web3-utils": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@ethereumjs/block": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.0.tgz",
+ "integrity": "sha512-dqLo1LtsLG+Oelu5S5tWUDG0pah3QUwV5TJZy2cm19BXDr4ka/S9XBSgao0i09gTcuPlovlHgcs6d7EZ37urjQ==",
+ "dependencies": {
+ "@ethereumjs/common": "^2.6.0",
+ "@ethereumjs/tx": "^3.4.0",
+ "ethereumjs-util": "^7.1.3",
+ "merkle-patricia-tree": "^4.2.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/isarray": {
+ "version": "0.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "dependencies": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ },
+ "engines": {
+ "node": ">=0.8",
+ "npm": ">=1.3.7"
+ }
+ },
+ "node_modules/type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dependencies": {
+ "prelude-ls": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/ethereumjs-abi": {
+ "version": "0.6.8",
+ "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz",
+ "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==",
+ "dependencies": {
+ "bn.js": "^4.11.8",
+ "ethereumjs-util": "^6.0.0"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/hash.js": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
+ "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "node_modules/memdown/node_modules/immediate": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz",
+ "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw="
+ },
+ "node_modules/ganache-core/node_modules/seedrandom": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@thinkanddev/deploy-eip-1820-web3-rsk": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@thinkanddev/deploy-eip-1820-web3-rsk/-/deploy-eip-1820-web3-rsk-1.0.2.tgz",
+ "integrity": "sha512-rh3q3UYR017bv09hBhEn/7j+cIRIBNfYVWr2KZ7Bxo+K1FXToCAKOKzr7alWzBTZN5XP7OuC2xTgczkGqaIyJA==",
+ "peerDependencies": {
+ "web3": ">=1.3.5"
+ }
+ },
+ "node_modules/base-x": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz",
+ "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/typewiselite": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/encoding-down": {
+ "version": "5.0.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abstract-leveldown": "^5.0.0",
+ "inherits": "^2.0.3",
+ "level-codec": "^9.0.0",
+ "level-errors": "^2.0.0",
+ "xtend": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-negative-zero": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/send/node_modules/debug/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "node_modules/create-hash": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+ "dependencies": {
+ "cipher-base": "^1.0.1",
+ "inherits": "^2.0.1",
+ "md5.js": "^1.3.4",
+ "ripemd160": "^2.0.1",
+ "sha.js": "^2.4.0"
+ }
+ },
+ "node_modules/mocha/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-url": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
+ "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
+ "dev": true
+ },
+ "node_modules/@solidity-parser/parser": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.1.tgz",
+ "integrity": "sha512-eLjj2L6AuQjBB6s/ibwCAc0DwrR5Ge+ys+wgWo+bviU7fV2nTMQhU63CGaDKXg9iTmMxwhkyoggdIR7ZGRfMgw==",
+ "dependencies": {
+ "antlr4ts": "^0.5.0-alpha.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/detect-indent": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "repeating": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fp-ts": {
+ "version": "1.19.3",
+ "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz",
+ "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg=="
+ },
+ "node_modules/yargs-unparser": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
+ "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
+ "dependencies": {
+ "flat": "^4.1.0",
+ "lodash": "^4.17.15",
+ "yargs": "^13.3.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree": {
+ "version": "2.3.2",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^1.4.2",
+ "ethereumjs-util": "^5.0.0",
+ "level-ws": "0.0.0",
+ "levelup": "^1.2.1",
+ "memdown": "^1.0.0",
+ "readable-stream": "^2.0.0",
+ "rlp": "^2.0.0",
+ "semaphore": ">=1.0.1"
+ }
+ },
+ "node_modules/level-packager": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz",
+ "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==",
+ "dependencies": {
+ "encoding-down": "^6.3.0",
+ "levelup": "^4.3.2"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "dependencies": {
+ "is-docker": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/open": {
+ "version": "7.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
+ "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
+ "dev": true,
+ "dependencies": {
+ "is-docker": "^2.0.0",
+ "is-wsl": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/diffie-hellman": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+ "dependencies": {
+ "bn.js": "^4.1.0",
+ "miller-rabin": "^4.0.0",
+ "randombytes": "^2.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/snapdragon-node": {
+ "version": "2.1.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/swarm-js/node_modules/tar": {
+ "version": ">=4.4.18",
+ "dependencies": {
+ "chownr": "^1.1.4",
+ "fs-minipass": "^1.2.7",
+ "minipass": "^2.9.0",
+ "minizlib": "^1.3.3",
+ "mkdirp": "^0.5.5",
+ "safe-buffer": "^5.2.1",
+ "yallist": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=4.5"
+ }
+ },
+ "node_modules/ganache-core/node_modules/tar": {
+ "version": "4.4.13",
+ "dev": true,
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "chownr": "^1.1.1",
+ "fs-minipass": "^1.2.5",
+ "minipass": "^2.8.6",
+ "minizlib": "^1.2.1",
+ "mkdirp": "^0.5.0",
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=4.5"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
+ },
+ "node_modules/async-eventemitter": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz",
+ "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==",
+ "dependencies": {
+ "async": "^2.4.0"
+ }
+ },
+ "node_modules/ethereumjs-util/node_modules/bn.js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
+ },
+ "node_modules/mocha/node_modules/glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
+ "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==",
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/ethers/node_modules/bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
+ },
+ "node_modules/solidity-coverage/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/level-iterator-stream": {
+ "version": "2.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.5",
+ "xtend": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-retry-allowed": {
+ "version": "1.2.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ms": {
+ "version": "2.1.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-syntax-trailing-function-commas": {
+ "version": "6.22.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/escodegen": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
+ "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
+ "dependencies": {
+ "esprima": "^2.7.1",
+ "estraverse": "^1.9.1",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1"
+ },
+ "bin": {
+ "escodegen": "bin/escodegen.js",
+ "esgenerate": "bin/esgenerate.js"
+ },
+ "engines": {
+ "node": ">=0.12.0"
+ },
+ "optionalDependencies": {
+ "source-map": "~0.2.0"
+ }
+ },
+ "node_modules/@typechain/ethers-v5": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz",
+ "integrity": "sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==",
+ "dev": true,
+ "dependencies": {
+ "ethers": "^5.0.2"
+ },
+ "peerDependencies": {
+ "ethers": "^5.0.0",
+ "typechain": "^3.0.0"
+ }
+ },
+ "node_modules/ethjs-util": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
+ "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
+ "dependencies": {
+ "is-hex-prefixed": "1.0.0",
+ "strip-hex-prefix": "1.0.0"
+ },
+ "engines": {
+ "node": ">=6.5.0",
+ "npm": ">=3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/md5.js": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+ "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+ "dependencies": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "node_modules/utf-8-validate": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz",
+ "integrity": "sha512-k4dW/Qja1BYDl2qD4tOMB9PFVha/UJtxTc1cXYOe3WwA/2m0Yn4qB7wLMpJyLJ/7DR0XnTut3HsCSzDT4ZvKgA==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "node-gyp-build": "^4.3.0"
+ },
+ "engines": {
+ "node": ">=6.14.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/express/node_modules/debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ },
+ "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fs-extra": {
+ "version": "4.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/keyv": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "json-buffer": "3.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/string.prototype.trimend": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/finalhandler/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "node_modules/multicodec": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz",
+ "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==",
+ "deprecated": "This module has been superseded by the multiformats module",
+ "dependencies": {
+ "varint": "^5.0.0"
+ }
+ },
+ "node_modules/github-from-package": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+ "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/crc-32": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz",
+ "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==",
+ "dependencies": {
+ "exit-on-epipe": "~1.0.1",
+ "printj": "~1.1.0"
+ },
+ "bin": {
+ "crc32": "bin/crc32.njs"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/readable-stream": {
+ "version": "1.0.34",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
+ },
+ "node_modules/ganache-core/node_modules/isstream": {
+ "version": "0.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/level-mem/node_modules/memdown": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abstract-leveldown": "~5.0.0",
+ "functional-red-black-tree": "~1.0.1",
+ "immediate": "~3.2.3",
+ "inherits": "~2.0.1",
+ "ltgt": "~2.2.0",
+ "safe-buffer": "~5.1.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/brorand": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/mocha/node_modules/supports-color": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
+ "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-preset-env": {
+ "version": "1.7.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-plugin-transform-es2015-literals": "^6.22.0",
+ "babel-plugin-syntax-trailing-function-commas": "^6.22.0",
+ "semver": "^5.3.0",
+ "babel-plugin-transform-es2015-block-scoping": "^6.23.0",
+ "babel-plugin-transform-regenerator": "^6.22.0",
+ "babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
+ "babel-plugin-check-es2015-constants": "^6.22.0",
+ "babel-plugin-transform-es2015-modules-umd": "^6.23.0",
+ "babel-plugin-transform-es2015-function-name": "^6.22.0",
+ "babel-plugin-transform-es2015-sticky-regex": "^6.22.0",
+ "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0",
+ "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
+ "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0",
+ "babel-plugin-transform-es2015-classes": "^6.23.0",
+ "babel-plugin-transform-async-to-generator": "^6.22.0",
+ "babel-plugin-transform-es2015-destructuring": "^6.23.0",
+ "babel-plugin-transform-es2015-unicode-regex": "^6.22.0",
+ "babel-plugin-transform-es2015-for-of": "^6.23.0",
+ "babel-plugin-transform-exponentiation-operator": "^6.22.0",
+ "browserslist": "^3.2.6",
+ "babel-plugin-transform-es2015-computed-properties": "^6.22.0",
+ "babel-plugin-transform-es2015-parameters": "^6.23.0",
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0",
+ "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0",
+ "babel-plugin-transform-es2015-object-super": "^6.22.0",
+ "invariant": "^2.2.2",
+ "babel-plugin-transform-es2015-template-literals": "^6.22.0",
+ "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0",
+ "babel-plugin-transform-es2015-modules-amd": "^6.22.0",
+ "babel-plugin-transform-es2015-spread": "^6.22.0"
+ }
+ },
+ "node_modules/then-request": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz",
+ "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==",
+ "dependencies": {
+ "@types/concat-stream": "^1.6.0",
+ "@types/form-data": "0.0.33",
+ "@types/node": "^8.0.0",
+ "@types/qs": "^6.2.31",
+ "caseless": "~0.12.0",
+ "concat-stream": "^1.6.0",
+ "form-data": "^2.2.0",
+ "http-basic": "^8.1.1",
+ "http-response-object": "^3.0.1",
+ "promise": "^8.0.0",
+ "qs": "^6.4.0"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/number-to-bn": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz",
+ "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=",
+ "dependencies": {
+ "bn.js": "4.11.6",
+ "strip-hex-prefix": "1.0.0"
+ },
+ "engines": {
+ "node": ">=6.5.0",
+ "npm": ">=3"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/ganache-core/node_modules/deferred-leveldown/node_modules/abstract-leveldown": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/hardhat/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/swarm-js/node_modules/decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm": {
+ "version": "4.2.0",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^2.1.2",
+ "async-eventemitter": "^0.2.2",
+ "core-js-pure": "^3.0.1",
+ "ethereumjs-account": "^3.0.0",
+ "ethereumjs-block": "^2.2.2",
+ "ethereumjs-blockchain": "^4.0.3",
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-tx": "^2.1.2",
+ "ethereumjs-util": "^6.2.0",
+ "fake-merkle-patricia-tree": "^1.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "merkle-patricia-tree": "^2.3.2",
+ "rustbn.js": "~0.2.0",
+ "safe-buffer": "^5.1.1",
+ "util.promisify": "^1.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/url-parse-lax": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "prepend-http": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/escodegen/node_modules/esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/deep-equal": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-arguments": "^1.0.4",
+ "is-date-object": "^1.0.1",
+ "is-regex": "^1.0.4",
+ "object-is": "^1.0.1",
+ "object-keys": "^1.1.1",
+ "regexp.prototype.flags": "^1.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream": {
+ "version": "1.3.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "level-errors": "^1.0.3",
+ "readable-stream": "^1.0.33",
+ "xtend": "^4.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/use": {
+ "version": "3.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block": {
+ "version": "1.7.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^2.0.1",
+ "ethereum-common": "0.2.0",
+ "ethereumjs-tx": "^1.2.2",
+ "ethereumjs-util": "^5.0.0",
+ "merkle-patricia-tree": "^2.1.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/abstract-leveldown": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
+ },
+ "node_modules/form-data": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+ "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+ "dev": true,
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/postinstall-postinstall": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz",
+ "integrity": "sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==",
+ "dev": true,
+ "hasInstallScript": true
+ },
+ "node_modules/console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/inquirer/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
+ "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/copy-descriptor": {
+ "version": "0.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/bufferutil": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz",
+ "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "node-gyp-build": "^4.3.0"
+ },
+ "engines": {
+ "node": ">=6.14.2"
+ }
+ },
+ "node_modules/p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/klaw-sync": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz",
+ "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.11"
+ }
+ },
+ "node_modules/@types/abstract-leveldown": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz",
+ "integrity": "sha512-q5veSX6zjUy/DlDhR4Y4cU0k2Ar+DT2LUraP00T19WLmTO6Se1djepCCaqU6nQrwcJ5Hyo/CWqxTzrrFg8eqbQ=="
+ },
+ "node_modules/is-directory": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+ "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "node_modules/ganache-core/node_modules/babel-traverse/node_modules/globals": {
+ "version": "9.18.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
+ "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/swarm-js/node_modules/prepend-http": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/async-limiter": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
+ },
+ "node_modules/es-abstract/node_modules/object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/underscore": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz",
+ "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g=="
+ },
+ "node_modules/@truffle/codec/node_modules/web3-utils": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.9.tgz",
+ "integrity": "sha512-9hcpuis3n/LxFzEVjwnVgvJzTirS2S9/MiNAa7l4WOEoywY+BSNwnRX4MuHnjkh9NY25B6QOjuNG6FNnSjTw1w==",
+ "dependencies": {
+ "bn.js": "4.11.8",
+ "eth-lib": "0.2.7",
+ "ethereum-bloom-filters": "^1.0.6",
+ "ethjs-unit": "0.1.6",
+ "number-to-bn": "1.7.0",
+ "randombytes": "^2.1.0",
+ "underscore": "1.9.1",
+ "utf8": "3.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-helpers": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-finite": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ganache-core/node_modules/bs58": {
+ "version": "4.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "base-x": "^3.0.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/array-unique": {
+ "version": "0.3.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/depd": {
+ "version": "1.1.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/swarm-js/node_modules/got": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
+ "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
+ "dependencies": {
+ "decompress-response": "^3.2.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^3.0.0",
+ "is-plain-obj": "^1.1.0",
+ "is-retry-allowed": "^1.0.0",
+ "is-stream": "^1.0.0",
+ "isurl": "^1.0.0-alpha5",
+ "lowercase-keys": "^1.0.0",
+ "p-cancelable": "^0.3.0",
+ "p-timeout": "^1.1.1",
+ "safe-buffer": "^5.0.1",
+ "timed-out": "^4.0.0",
+ "url-parse-lax": "^1.0.0",
+ "url-to-options": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree": {
+ "version": "2.3.2",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^1.4.2",
+ "ethereumjs-util": "^5.0.0",
+ "level-ws": "0.0.0",
+ "levelup": "^1.2.1",
+ "memdown": "^1.0.0",
+ "readable-stream": "^2.0.0",
+ "rlp": "^2.0.0",
+ "semaphore": ">=1.0.1"
+ }
+ },
+ "node_modules/web3-core-subscriptions": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.6.1.tgz",
+ "integrity": "sha512-WZwxsYttIojyGQ5RqxuQcKg0IJdDCFpUe4EncS3QKZwxPqWzGmgyLwE0rm7tP+Ux1waJn5CUaaoSCBxWGSun1g==",
+ "dependencies": {
+ "eventemitter3": "4.0.4",
+ "web3-core-helpers": "1.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/os-tmpdir": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
+ },
+ "node_modules/@resolver-engine/core": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz",
+ "integrity": "sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^3.1.0",
+ "is-url": "^1.2.4",
+ "request": "^2.85.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-tx": {
+ "version": "1.3.7",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "ethereum-common": "^0.0.18",
+ "ethereumjs-util": "^5.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-core/node_modules/ms": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/heap": {
+ "version": "0.2.6",
+ "dev": true
+ },
+ "node_modules/cliui/node_modules/emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
+ },
+ "node_modules/ganache-core/node_modules/source-map-resolve": {
+ "version": "0.5.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "atob": "^2.1.2",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "node_modules/duplexer3": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
+ },
+ "node_modules/@truffle/codec": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.7.1.tgz",
+ "integrity": "sha512-mNd6KnW6J0UB1zafGBXDlTEbCMvWpmPAJmzv7aF/nAIaN/F8UePSCiQ1OTQP39Rprj6GFiCCaWVnBAwum6UGSg==",
+ "dependencies": {
+ "big.js": "^5.2.2",
+ "bn.js": "^4.11.8",
+ "borc": "^2.1.2",
+ "debug": "^4.1.0",
+ "lodash.clonedeep": "^4.5.0",
+ "lodash.escaperegexp": "^4.1.2",
+ "lodash.partition": "^4.6.0",
+ "lodash.sum": "^4.0.2",
+ "semver": "^6.3.0",
+ "source-map-support": "^0.5.19",
+ "utf8": "^3.0.0",
+ "web3-utils": "1.2.9"
+ }
+ },
+ "node_modules/ganache-core/node_modules/snapdragon/node_modules/ms": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/object-keys": {
+ "version": "0.4.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@ensdomains/ens/node_modules/is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "dependencies": {
+ "number-is-nan": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/patch-package/node_modules/which": {
+ "version": "1.3.1",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "node_modules/ganache-core/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
+ },
+ "node_modules/normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "dependencies": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-eth-personal": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "@types/node": "^12.12.6",
+ "web3-core": "1.2.11",
+ "web3-core-helpers": "1.2.11",
+ "web3-core-method": "1.2.11",
+ "web3-net": "1.2.11",
+ "web3-utils": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@ensdomains/ens/node_modules/require-from-string": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
+ "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ganache-core/node_modules/json-rpc-engine": {
+ "version": "3.8.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "async": "^2.0.1",
+ "babel-preset-env": "^1.7.0",
+ "babelify": "^7.3.0",
+ "json-rpc-error": "^2.0.0",
+ "promise-to-callback": "^1.0.0",
+ "safe-event-emitter": "^1.0.1"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/lowercase-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/base/node_modules/define-property": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/web3-providers-http": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz",
+ "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==",
+ "dependencies": {
+ "web3-core-helpers": "1.5.3",
+ "xhr2-cookies": "1.1.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block": {
+ "version": "1.7.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "async": "^2.0.1",
+ "ethereum-common": "0.2.0",
+ "ethereumjs-tx": "^1.2.2",
+ "ethereumjs-util": "^5.0.0",
+ "merkle-patricia-tree": "^2.1.2"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/abstract-leveldown": {
+ "version": "2.6.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "node_modules/asn1": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
+ "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+ "dependencies": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "node_modules/@trufflesuite/chromafi/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "node_modules/ganache-core/node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/has-symbol-support-x": {
+ "version": "1.4.2",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/solidity-coverage/node_modules/fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
+ "node_modules/asn1.js": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
+ "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
+ "dependencies": {
+ "bn.js": "^4.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "node_modules/@types/bn.js": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz",
+ "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/base64": {
+ "version": "5.0.7",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/bytes": "^5.0.9"
+ }
+ },
+ "node_modules/@types/glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
+ "dependencies": {
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/ganache-core/node_modules/@ethersproject/constants": {
+ "version": "5.0.8",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.0.13"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/@truffle/interface-adapter": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.4.24.tgz",
+ "integrity": "sha512-2Zho4dJbm/XGwNleY7FdxcjXiAR3SzdGklgrAW4N/YVmltaJv6bT56ACIbPNN6AdzkTSTO65OlsB/63sfSa/VA==",
+ "dependencies": {
+ "bn.js": "^5.1.3",
+ "ethers": "^4.0.32",
+ "web3": "1.3.6"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "dependencies": {
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/find-replace/node_modules/array-back": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+ "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+ "dev": true,
+ "dependencies": {
+ "typical": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/@truffle/provider/node_modules/@truffle/interface-adapter": {
+ "version": "0.5.8",
+ "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.8.tgz",
+ "integrity": "sha512-vvy3xpq36oLgjjy8KE9l2Jabg3WcGPOt18tIyMfTQX9MFnbHoQA2Ne2i8xsd4p6KfxIqSjAB53Q9/nScAqY0UQ==",
+ "dependencies": {
+ "bn.js": "^5.1.3",
+ "ethers": "^4.0.32",
+ "web3": "1.5.3"
+ }
+ },
+ "node_modules/@yarnpkg/lockfile": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
+ "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
+ "dev": true
+ },
+ "node_modules/solidity-coverage": {
+ "version": "0.7.20",
+ "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.20.tgz",
+ "integrity": "sha512-edOXTugUYdqxrtEnIn4vgrGjLPxdexcL0WD8LzAvVA3d1dwgcfRO3k8xQR02ZQnOnWMBi8Cqs0F+kAQQp3JW8g==",
+ "dependencies": {
+ "semver": "^7.3.4",
+ "globby": "^10.0.1",
+ "lodash": "^4.17.15",
+ "node-emoji": "^1.10.0",
+ "shelljs": "^0.8.3",
+ "fs-extra": "^8.1.0",
+ "ghost-testrpc": "^0.0.2",
+ "sc-istanbul": "^0.4.5",
+ "recursive-readdir": "^2.2.2",
+ "chalk": "^2.4.2",
+ "detect-port": "^1.3.0",
+ "death": "^1.1.0",
+ "pify": "^4.0.1",
+ "global-modules": "^2.0.0",
+ "web3-utils": "^1.3.0",
+ "@truffle/provider": "^0.2.24",
+ "jsonschema": "^1.2.4",
+ "@solidity-parser/parser": "^0.14.0"
+ },
+ "bin": {
+ "solidity-coverage": "plugins/bin.js"
+ }
+ },
+ "node_modules/web3-bzz/node_modules/@types/node": {
+ "version": "12.20.41",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz",
+ "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q=="
+ },
+ "node_modules/sc-istanbul": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz",
+ "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==",
+ "dependencies": {
+ "abbrev": "1.0.x",
+ "async": "1.x",
+ "escodegen": "1.8.x",
+ "esprima": "2.7.x",
+ "glob": "^5.0.15",
+ "handlebars": "^4.0.1",
+ "js-yaml": "3.x",
+ "mkdirp": "0.5.x",
+ "nopt": "3.x",
+ "once": "1.x",
+ "resolve": "1.1.x",
+ "supports-color": "^3.1.0",
+ "which": "^1.1.1",
+ "wordwrap": "^1.0.0"
+ },
+ "bin": {
+ "istanbul": "lib/cli.js"
+ }
+ },
+ "node_modules/colors": {
+ "version": "^1.4.0",
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/is-regex": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+ "dependencies": {
+ "resolve": "^1.1.6"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/ganache-core/node_modules/parse-asn1": {
+ "version": "5.1.6",
+ "dev": true,
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "asn1.js": "^5.2.0",
+ "browserify-aes": "^1.0.0",
+ "evp_bytestokey": "^1.0.0",
+ "pbkdf2": "^3.0.3",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/media-typer": {
+ "version": "0.3.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/object-keys": {
+ "version": "0.4.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/tunnel-agent": {
+ "version": "0.6.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@ethersproject/providers": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.2.tgz",
+ "integrity": "sha512-hkbx7x/MKcRjyrO4StKXCzCpWer6s97xnm34xkfPiarhtEUVAN4TBBpamM+z66WcTt7H5B53YwbRj1n7i8pZoQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/networks": "^5.5.0",
+ "@ethersproject/hash": "^5.5.0",
+ "@ethersproject/sha2": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/transactions": "^5.5.0",
+ "@ethersproject/constants": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/abstract-signer": "^5.5.0",
+ "@ethersproject/address": "^5.5.0",
+ "@ethersproject/web": "^5.5.0",
+ "@ethersproject/abstract-provider": "^5.5.0",
+ "@ethersproject/basex": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0",
+ "bech32": "1.1.4",
+ "ws": "7.4.6",
+ "@ethersproject/rlp": "^5.5.0",
+ "@ethersproject/random": "^5.5.0"
+ }
+ },
+ "node_modules/websocket/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "node_modules/ganache-core/node_modules/swarm-js": {
+ "version": "0.1.40",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bluebird": "^3.5.0",
+ "buffer": "^5.0.5",
+ "eth-lib": "^0.1.26",
+ "fs-extra": "^4.0.2",
+ "got": "^7.1.0",
+ "mime-types": "^2.1.16",
+ "mkdirp-promise": "^5.0.1",
+ "mock-fs": "^4.1.0",
+ "setimmediate": "^1.0.5",
+ "tar": "^4.0.2",
+ "xhr-request": "^1.0.1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/http-cache-semantics": {
+ "version": "4.1.0",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "optional": true
+ },
+ "node_modules/ganache-core/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/buffer": {
+ "version": "5.7.1",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/testrpc": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz",
+ "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==",
+ "deprecated": "testrpc has been renamed to ganache-cli, please use this package from now on.",
+ "dev": true
+ },
+ "node_modules/ganache-core/node_modules/web3-shh": {
+ "version": "1.2.11",
+ "dev": true,
+ "license": "LGPL-3.0",
+ "optional": true,
+ "dependencies": {
+ "web3-core": "1.2.11",
+ "web3-core-method": "1.2.11",
+ "web3-core-subscriptions": "1.2.11",
+ "web3-net": "1.2.11"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/p-timeout/node_modules/p-finally": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/read-pkg/node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-commonjs": {
+ "version": "6.26.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-plugin-transform-strict-mode": "^6.24.1",
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-types": "^6.26.0"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/node-gyp-build": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz",
+ "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==",
+ "bin": {
+ "node-gyp-build": "bin.js",
+ "node-gyp-build-optional": "optional.js",
+ "node-gyp-build-test": "build-test.js"
+ }
+ },
+ "node_modules/ganache-core/node_modules/swarm-js/node_modules/is-stream": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/readable-stream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ganache-core/node_modules/checkpoint-store": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "functional-red-black-tree": "^1.0.1"
+ }
+ },
+ "node_modules/memdown": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/memdown/-/memdown-5.1.0.tgz",
+ "integrity": "sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw==",
+ "dependencies": {
+ "abstract-leveldown": "~6.2.1",
+ "functional-red-black-tree": "~1.0.1",
+ "immediate": "~3.2.3",
+ "inherits": "~2.0.1",
+ "ltgt": "~2.2.0",
+ "safe-buffer": "~5.2.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@ethersproject/sha2": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz",
+ "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "dependencies": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "hash.js": "1.1.7"
+ }
+ },
+ "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-unicode-regex": {
+ "version": "6.24.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-helper-regex": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "regexpu-core": "^2.0.0"
+ }
+ },
+ "node_modules/normalize-package-data/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/ast-parents": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz",
+ "integrity": "sha1-UI/Q8F0MSHddnszaLhdEIyYejdM="
+ },
+ "node_modules/ganache-core/node_modules/swarm-js/node_modules/p-cancelable": {
+ "version": "0.3.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-errors": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "errno": "~0.1.1"
+ }
+ },
+ "node_modules/ws": {
+ "version": "7.4.6",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
+ "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ="
+ },
+ "node_modules/detect-indent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz",
+ "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor": {
+ "version": "0.1.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
+ "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.2.0",
+ "entities": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/ganache-core/node_modules/dotignore": {
+ "version": "0.1.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimatch": "^3.0.4"
+ },
+ "bin": {
+ "ignored": "bin/ignored"
+ }
+ },
+ "node_modules/ganache-core/node_modules/hash-base": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/body-parser/node_modules/debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/@sentry/minimal/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ },
+ "node_modules/@ethereumjs/ethash/node_modules/buffer-xor": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz",
+ "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==",
+ "dependencies": {
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/patch-package/node_modules/cross-spawn": {
+ "version": "6.0.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "engines": {
+ "node": ">=4.8"
+ }
+ },
+ "node_modules/hardhat/node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wide-align": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+ "dependencies": {
+ "string-width": "^1.0.2 || 2"
+ }
+ },
+ "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+ "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+ "dependencies": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "0.1.6",
+ "rlp": "^2.2.3"
+ }
+ },
+ "node_modules/ganache-core/node_modules/rlp": {
+ "version": "2.2.6",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "bn.js": "^4.11.1"
+ },
+ "bin": {
+ "rlp": "bin/rlp"
+ }
+ },
+ "node_modules/napi-build-utils": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
+ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/@truffle/provider/node_modules/web3-core-helpers": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz",
+ "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==",
+ "dependencies": {
+ "web3-eth-iban": "1.5.3",
+ "web3-utils": "1.5.3"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/xtend": {
+ "version": "2.1.2",
+ "dev": true,
+ "dependencies": {
+ "object-keys": "~0.4.0"
+ },
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/ganache-core/node_modules/to-readable-stream": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/patch-package/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "node_modules/ganache-core/node_modules/events": {
+ "version": "3.2.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/sc-istanbul/node_modules/resolve": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs="
+ },
+ "node_modules/qs": {
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
+ "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
+ "dependencies": {
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ganache-core/node_modules/object-visit": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/readable-stream": {
+ "version": "3.6.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/ganache-core/node_modules/ext": {
+ "version": "1.4.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "type": "^2.0.0"
+ }
+ },
+ "node_modules/ganache-core/node_modules/pull-cat": {
+ "version": "1.1.11",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+ "dependencies": {
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ }
+ },
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.16.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz",
+ "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==",
+ "requires": {
+ "@babel/highlight": "^7.16.7"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.16.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz",
+ "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw=="
+ },
+ "@babel/highlight": {
+ "version": "7.16.7",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz",
+ "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==",
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.16.7",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "@ensdomains/ens": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz",
+ "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==",
+ "dev": true,
+ "requires": {
+ "bluebird": "^3.5.2",
+ "eth-ens-namehash": "^2.0.8",
+ "solc": "^0.4.20",
+ "testrpc": "0.0.1",
+ "web3-utils": "^1.0.0-beta.31"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "cliui": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wrap-ansi": "^2.0.0"
+ }
+ },
+ "fs-extra": {
+ "version": "0.30.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+ "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0",
+ "path-is-absolute": "^1.0.0",
+ "rimraf": "^2.2.8"
+ }
+ },
+ "get-caller-file": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "require-from-string": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
+ "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ },
+ "solc": {
+ "version": "0.4.26",
+ "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz",
+ "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==",
+ "dev": true,
+ "requires": {
+ "fs-extra": "^0.30.0",
+ "memorystream": "^0.3.1",
+ "require-from-string": "^1.1.0",
+ "semver": "^5.3.0",
+ "yargs": "^4.7.1"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
+ "dev": true
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ }
+ },
+ "y18n": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
+ "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz",
+ "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=",
+ "dev": true,
+ "requires": {
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "lodash.assign": "^4.0.3",
+ "os-locale": "^1.4.0",
+ "read-pkg-up": "^1.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^1.0.1",
+ "which-module": "^1.0.0",
+ "window-size": "^0.2.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^2.4.1"
+ }
+ }
+ }
+ },
+ "@ensdomains/resolver": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz",
+ "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==",
+ "dev": true
+ },
+ "@ethereum-waffle/chai": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.1.tgz",
+ "integrity": "sha512-8mjgjWCe8XSCWuyJgVtJY8sm00VTczGBTDxBejgEBWN/J9x7QD8jdmWW8bfxdnqZbxiDCTvRFL58Wmd254BEqQ==",
+ "dev": true,
+ "requires": {
+ "@ethereum-waffle/provider": "^3.4.0",
+ "ethers": "^5.4.7"
+ }
+ },
+ "@ethereum-waffle/compiler": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.4.0.tgz",
+ "integrity": "sha512-a2wxGOoB9F1QFRE+Om7Cz2wn+pxM/o7a0a6cbwhaS2lECJgFzeN9xEkVrKahRkF4gEfXGcuORg4msP0Asxezlw==",
+ "dev": true,
+ "requires": {
+ "@resolver-engine/imports": "^0.3.3",
+ "@resolver-engine/imports-fs": "^0.3.3",
+ "@typechain/ethers-v5": "^2.0.0",
+ "@types/mkdirp": "^0.5.2",
+ "@types/node-fetch": "^2.5.5",
+ "ethers": "^5.0.1",
+ "mkdirp": "^0.5.1",
+ "node-fetch": "^2.6.1",
+ "solc": "^0.6.3",
+ "ts-generator": "^0.1.1",
+ "typechain": "^3.0.0"
+ }
+ },
+ "@ethereum-waffle/ens": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.3.1.tgz",
+ "integrity": "sha512-xSjNWnT2Iwii3J3XGqD+F5yLEOzQzLHNLGfI5KIXdtQ4FHgReW/AMGRgPPLi+n+SP08oEQWJ3sEKrvbFlwJuaA==",
+ "dev": true,
+ "requires": {
+ "@ensdomains/ens": "^0.4.4",
+ "@ensdomains/resolver": "^0.2.4",
+ "ethers": "^5.5.2"
+ }
+ },
+ "@ethereum-waffle/mock-contract": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.3.1.tgz",
+ "integrity": "sha512-h9yChF7IkpJLODg/o9/jlwKwTcXJLSEIq3gewgwUJuBHnhPkJGekcZvsTbximYc+e42QUZrDUATSuTCIryeCEA==",
+ "dev": true,
+ "requires": {
+ "@ethersproject/abi": "^5.5.0",
+ "ethers": "^5.5.2"
+ }
+ },
+ "@ethereum-waffle/provider": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.4.1.tgz",
+ "integrity": "sha512-5iDte7c9g9N1rTRE/P4npwk1Hus/wA2yH850X6sP30mr1IrwSG9NKn6/2SOQkAVJnh9jqyLVg2X9xCODWL8G4A==",
+ "dev": true,
+ "requires": {
+ "@ethereum-waffle/ens": "^3.3.1",
+ "ethers": "^5.5.2",
+ "ganache-core": "^2.13.2",
+ "patch-package": "^6.2.2",
+ "postinstall-postinstall": "^2.1.0"
+ }
+ },
+ "@ethereumjs/block": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.0.tgz",
+ "integrity": "sha512-dqLo1LtsLG+Oelu5S5tWUDG0pah3QUwV5TJZy2cm19BXDr4ka/S9XBSgao0i09gTcuPlovlHgcs6d7EZ37urjQ==",
+ "requires": {
+ "@ethereumjs/common": "^2.6.0",
+ "@ethereumjs/tx": "^3.4.0",
+ "ethereumjs-util": "^7.1.3",
+ "merkle-patricia-tree": "^4.2.2"
+ }
+ },
+ "@ethereumjs/blockchain": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.1.tgz",
+ "integrity": "sha512-JS2jeKxl3tlaa5oXrZ8mGoVBCz6YqsGG350XVNtHAtNZXKk7pU3rH4xzF2ru42fksMMqzFLzKh9l4EQzmNWDqA==",
+ "requires": {
+ "@ethereumjs/block": "^3.6.0",
+ "@ethereumjs/common": "^2.6.0",
+ "@ethereumjs/ethash": "^1.1.0",
+ "debug": "^2.2.0",
+ "ethereumjs-util": "^7.1.3",
+ "level-mem": "^5.0.1",
+ "lru-cache": "^5.1.1",
+ "semaphore-async-await": "^1.5.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "@ethereumjs/common": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.0.tgz",
+ "integrity": "sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA==",
+ "requires": {
+ "crc-32": "^1.2.0",
+ "ethereumjs-util": "^7.1.3"
+ }
+ },
+ "@ethereumjs/ethash": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@ethereumjs/ethash/-/ethash-1.1.0.tgz",
+ "integrity": "sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA==",
+ "requires": {
+ "@ethereumjs/block": "^3.5.0",
+ "@types/levelup": "^4.3.0",
+ "buffer-xor": "^2.0.1",
+ "ethereumjs-util": "^7.1.1",
+ "miller-rabin": "^4.0.0"
+ },
+ "dependencies": {
+ "buffer-xor": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz",
+ "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==",
+ "requires": {
+ "safe-buffer": "^5.1.1"
+ }
+ }
+ }
+ },
+ "@ethereumjs/tx": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.4.0.tgz",
+ "integrity": "sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw==",
+ "requires": {
+ "@ethereumjs/common": "^2.6.0",
+ "ethereumjs-util": "^7.1.3"
+ }
+ },
+ "@ethereumjs/vm": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.6.0.tgz",
+ "integrity": "sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ==",
+ "requires": {
+ "@ethereumjs/block": "^3.6.0",
+ "@ethereumjs/blockchain": "^5.5.0",
+ "@ethereumjs/common": "^2.6.0",
+ "@ethereumjs/tx": "^3.4.0",
+ "async-eventemitter": "^0.2.4",
+ "core-js-pure": "^3.0.1",
+ "debug": "^2.2.0",
+ "ethereumjs-util": "^7.1.3",
+ "functional-red-black-tree": "^1.0.1",
+ "mcl-wasm": "^0.7.1",
+ "merkle-patricia-tree": "^4.2.2",
+ "rustbn.js": "~0.2.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "@ethersproject/abi": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.5.0.tgz",
+ "integrity": "sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w==",
+ "requires": {
+ "@ethersproject/address": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/constants": "^5.5.0",
+ "@ethersproject/hash": "^5.5.0",
+ "@ethersproject/keccak256": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0"
+ }
+ },
+ "@ethersproject/abstract-provider": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz",
+ "integrity": "sha512-m+MA/ful6eKbxpr99xUYeRvLkfnlqzrF8SZ46d/xFB1A7ZVknYc/sXJG0RcufF52Qn2jeFj1hhcoQ7IXjNKUqg==",
+ "requires": {
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/networks": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/transactions": "^5.5.0",
+ "@ethersproject/web": "^5.5.0"
+ }
+ },
+ "@ethersproject/abstract-signer": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz",
+ "integrity": "sha512-lj//7r250MXVLKI7sVarXAbZXbv9P50lgmJQGr2/is82EwEb8r7HrxsmMqAjTsztMYy7ohrIhGMIml+Gx4D3mA==",
+ "requires": {
+ "@ethersproject/abstract-provider": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0"
+ }
+ },
+ "@ethersproject/address": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.5.0.tgz",
+ "integrity": "sha512-l4Nj0eWlTUh6ro5IbPTgbpT4wRbdH5l8CQf7icF7sb/SI3Nhd9Y9HzhonTSTi6CefI0necIw7LJqQPopPLZyWw==",
+ "requires": {
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/keccak256": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/rlp": "^5.5.0"
+ }
+ },
+ "@ethersproject/base64": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.5.0.tgz",
+ "integrity": "sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA==",
+ "requires": {
+ "@ethersproject/bytes": "^5.5.0"
+ }
+ },
+ "@ethersproject/basex": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.5.0.tgz",
+ "integrity": "sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ==",
+ "requires": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0"
+ }
+ },
+ "@ethersproject/bignumber": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.5.0.tgz",
+ "integrity": "sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg==",
+ "requires": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "bn.js": "^4.11.9"
+ }
+ },
+ "@ethersproject/bytes": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz",
+ "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==",
+ "requires": {
+ "@ethersproject/logger": "^5.5.0"
+ }
+ },
+ "@ethersproject/constants": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.5.0.tgz",
+ "integrity": "sha512-2MsRRVChkvMWR+GyMGY4N1sAX9Mt3J9KykCsgUFd/1mwS0UH1qw+Bv9k1UJb3X3YJYFco9H20pjSlOIfCG5HYQ==",
+ "requires": {
+ "@ethersproject/bignumber": "^5.5.0"
+ }
+ },
+ "@ethersproject/contracts": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.5.0.tgz",
+ "integrity": "sha512-2viY7NzyvJkh+Ug17v7g3/IJC8HqZBDcOjYARZLdzRxrfGlRgmYgl6xPRKVbEzy1dWKw/iv7chDcS83pg6cLxg==",
+ "requires": {
+ "@ethersproject/abi": "^5.5.0",
+ "@ethersproject/abstract-provider": "^5.5.0",
+ "@ethersproject/abstract-signer": "^5.5.0",
+ "@ethersproject/address": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/constants": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/transactions": "^5.5.0"
+ }
+ },
+ "@ethersproject/hardware-wallets": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/hardware-wallets/-/hardware-wallets-5.5.0.tgz",
+ "integrity": "sha512-oZh/Ps/ohxFQdKVeMw8wpw0xZpL+ndsRlQwNE3Eki2vLeH2to14de6fNrgETZtAbAhzglH6ES9Nlx1+UuqvvYg==",
+ "peer": true,
+ "requires": {
+ "@ledgerhq/hw-app-eth": "5.27.2",
+ "@ledgerhq/hw-transport": "5.26.0",
+ "@ledgerhq/hw-transport-node-hid": "5.26.0",
+ "@ledgerhq/hw-transport-u2f": "5.26.0",
+ "ethers": "^5.5.0"
+ }
+ },
+ "@ethersproject/hash": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.5.0.tgz",
+ "integrity": "sha512-dnGVpK1WtBjmnp3mUT0PlU2MpapnwWI0PibldQEq1408tQBAbZpPidkWoVVuNMOl/lISO3+4hXZWCL3YV7qzfg==",
+ "requires": {
+ "@ethersproject/abstract-signer": "^5.5.0",
+ "@ethersproject/address": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/keccak256": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0"
+ }
+ },
+ "@ethersproject/hdnode": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.5.0.tgz",
+ "integrity": "sha512-mcSOo9zeUg1L0CoJH7zmxwUG5ggQHU1UrRf8jyTYy6HxdZV+r0PBoL1bxr+JHIPXRzS6u/UW4mEn43y0tmyF8Q==",
+ "requires": {
+ "@ethersproject/abstract-signer": "^5.5.0",
+ "@ethersproject/basex": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/pbkdf2": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/sha2": "^5.5.0",
+ "@ethersproject/signing-key": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0",
+ "@ethersproject/transactions": "^5.5.0",
+ "@ethersproject/wordlists": "^5.5.0"
+ }
+ },
+ "@ethersproject/json-wallets": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.5.0.tgz",
+ "integrity": "sha512-9lA21XQnCdcS72xlBn1jfQdj2A1VUxZzOzi9UkNdnokNKke/9Ya2xA9aIK1SC3PQyBDLt4C+dfps7ULpkvKikQ==",
+ "requires": {
+ "@ethersproject/abstract-signer": "^5.5.0",
+ "@ethersproject/address": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/hdnode": "^5.5.0",
+ "@ethersproject/keccak256": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/pbkdf2": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/random": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0",
+ "@ethersproject/transactions": "^5.5.0",
+ "aes-js": "3.0.0",
+ "scrypt-js": "3.0.1"
+ }
+ },
+ "@ethersproject/keccak256": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.5.0.tgz",
+ "integrity": "sha512-5VoFCTjo2rYbBe1l2f4mccaRFN/4VQEYFwwn04aJV2h7qf4ZvI2wFxUE1XOX+snbwCLRzIeikOqtAoPwMza9kg==",
+ "requires": {
+ "@ethersproject/bytes": "^5.5.0",
+ "js-sha3": "0.8.0"
+ }
+ },
+ "@ethersproject/logger": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz",
+ "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg=="
+ },
+ "@ethersproject/networks": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.2.tgz",
+ "integrity": "sha512-NEqPxbGBfy6O3x4ZTISb90SjEDkWYDUbEeIFhJly0F7sZjoQMnj5KYzMSkMkLKZ+1fGpx00EDpHQCy6PrDupkQ==",
+ "requires": {
+ "@ethersproject/logger": "^5.5.0"
+ }
+ },
+ "@ethersproject/pbkdf2": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz",
+ "integrity": "sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg==",
+ "requires": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/sha2": "^5.5.0"
+ }
+ },
+ "@ethersproject/properties": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.5.0.tgz",
+ "integrity": "sha512-l3zRQg3JkD8EL3CPjNK5g7kMx4qSwiR60/uk5IVjd3oq1MZR5qUg40CNOoEJoX5wc3DyY5bt9EbMk86C7x0DNA==",
+ "requires": {
+ "@ethersproject/logger": "^5.5.0"
+ }
+ },
+ "@ethersproject/providers": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.2.tgz",
+ "integrity": "sha512-hkbx7x/MKcRjyrO4StKXCzCpWer6s97xnm34xkfPiarhtEUVAN4TBBpamM+z66WcTt7H5B53YwbRj1n7i8pZoQ==",
+ "requires": {
+ "@ethersproject/abstract-provider": "^5.5.0",
+ "@ethersproject/abstract-signer": "^5.5.0",
+ "@ethersproject/address": "^5.5.0",
+ "@ethersproject/basex": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/constants": "^5.5.0",
+ "@ethersproject/hash": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/networks": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/random": "^5.5.0",
+ "@ethersproject/rlp": "^5.5.0",
+ "@ethersproject/sha2": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0",
+ "@ethersproject/transactions": "^5.5.0",
+ "@ethersproject/web": "^5.5.0",
+ "bech32": "1.1.4",
+ "ws": "7.4.6"
+ }
+ },
+ "@ethersproject/random": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.1.tgz",
+ "integrity": "sha512-YaU2dQ7DuhL5Au7KbcQLHxcRHfgyNgvFV4sQOo0HrtW3Zkrc9ctWNz8wXQ4uCSfSDsqX2vcjhroxU5RQRV0nqA==",
+ "requires": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0"
+ }
+ },
+ "@ethersproject/rlp": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.5.0.tgz",
+ "integrity": "sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA==",
+ "requires": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0"
+ }
+ },
+ "@ethersproject/sha2": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz",
+ "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==",
+ "requires": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "hash.js": "1.1.7"
+ }
+ },
+ "@ethersproject/signing-key": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.5.0.tgz",
+ "integrity": "sha512-5VmseH7qjtNmDdZBswavhotYbWB0bOwKIlOTSlX14rKn5c11QmJwGt4GHeo7NrL/Ycl7uo9AHvEqs5xZgFBTng==",
+ "requires": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "bn.js": "^4.11.9",
+ "elliptic": "6.5.4",
+ "hash.js": "1.1.7"
+ }
+ },
+ "@ethersproject/solidity": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.5.0.tgz",
+ "integrity": "sha512-9NgZs9LhGMj6aCtHXhtmFQ4AN4sth5HuFXVvAQtzmm0jpSCNOTGtrHZJAeYTh7MBjRR8brylWZxBZR9zDStXbw==",
+ "requires": {
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/keccak256": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/sha2": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0"
+ }
+ },
+ "@ethersproject/strings": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.5.0.tgz",
+ "integrity": "sha512-9fy3TtF5LrX/wTrBaT8FGE6TDJyVjOvXynXJz5MT5azq+E6D92zuKNx7i29sWW2FjVOaWjAsiZ1ZWznuduTIIQ==",
+ "requires": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/constants": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0"
+ }
+ },
+ "@ethersproject/transactions": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.5.0.tgz",
+ "integrity": "sha512-9RZYSKX26KfzEd/1eqvv8pLauCKzDTub0Ko4LfIgaERvRuwyaNV78mJs7cpIgZaDl6RJui4o49lHwwCM0526zA==",
+ "requires": {
+ "@ethersproject/address": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/constants": "^5.5.0",
+ "@ethersproject/keccak256": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/rlp": "^5.5.0",
+ "@ethersproject/signing-key": "^5.5.0"
+ }
+ },
+ "@ethersproject/units": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.5.0.tgz",
+ "integrity": "sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==",
+ "requires": {
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/constants": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0"
+ }
+ },
+ "@ethersproject/wallet": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.5.0.tgz",
+ "integrity": "sha512-Mlu13hIctSYaZmUOo7r2PhNSd8eaMPVXe1wxrz4w4FCE4tDYBywDH+bAR1Xz2ADyXGwqYMwstzTrtUVIsKDO0Q==",
+ "requires": {
+ "@ethersproject/abstract-provider": "^5.5.0",
+ "@ethersproject/abstract-signer": "^5.5.0",
+ "@ethersproject/address": "^5.5.0",
+ "@ethersproject/bignumber": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/hash": "^5.5.0",
+ "@ethersproject/hdnode": "^5.5.0",
+ "@ethersproject/json-wallets": "^5.5.0",
+ "@ethersproject/keccak256": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/random": "^5.5.0",
+ "@ethersproject/signing-key": "^5.5.0",
+ "@ethersproject/transactions": "^5.5.0",
+ "@ethersproject/wordlists": "^5.5.0"
+ }
+ },
+ "@ethersproject/web": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.1.tgz",
+ "integrity": "sha512-olvLvc1CB12sREc1ROPSHTdFCdvMh0J5GSJYiQg2D0hdD4QmJDy8QYDb1CvoqD/bF1c++aeKv2sR5uduuG9dQg==",
+ "requires": {
+ "@ethersproject/base64": "^5.5.0",
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0"
+ }
+ },
+ "@ethersproject/wordlists": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.5.0.tgz",
+ "integrity": "sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q==",
+ "requires": {
+ "@ethersproject/bytes": "^5.5.0",
+ "@ethersproject/hash": "^5.5.0",
+ "@ethersproject/logger": "^5.5.0",
+ "@ethersproject/properties": "^5.5.0",
+ "@ethersproject/strings": "^5.5.0"
+ }
+ },
+ "@ledgerhq/cryptoassets": {
+ "version": "5.53.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/cryptoassets/-/cryptoassets-5.53.0.tgz",
+ "integrity": "sha512-M3ibc3LRuHid5UtL7FI3IC6nMEppvly98QHFoSa7lJU0HDzQxY6zHec/SPM4uuJUC8sXoGVAiRJDkgny54damw==",
+ "peer": true,
+ "requires": {
+ "invariant": "2"
+ }
+ },
+ "@ledgerhq/devices": {
+ "version": "5.51.1",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-5.51.1.tgz",
+ "integrity": "sha512-4w+P0VkbjzEXC7kv8T1GJ/9AVaP9I6uasMZ/JcdwZBS3qwvKo5A5z9uGhP5c7TvItzcmPb44b5Mw2kT+WjUuAA==",
+ "peer": true,
+ "requires": {
+ "@ledgerhq/errors": "^5.50.0",
+ "@ledgerhq/logs": "^5.50.0",
+ "rxjs": "6",
+ "semver": "^7.3.5"
+ }
+ },
+ "@ledgerhq/errors": {
+ "version": "5.50.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-5.50.0.tgz",
+ "integrity": "sha512-gu6aJ/BHuRlpU7kgVpy2vcYk6atjB4iauP2ymF7Gk0ez0Y/6VSMVSJvubeEQN+IV60+OBK0JgeIZG7OiHaw8ow==",
+ "peer": true
+ },
+ "@ledgerhq/hw-app-eth": {
+ "version": "5.27.2",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-app-eth/-/hw-app-eth-5.27.2.tgz",
+ "integrity": "sha512-llNdrE894cCN8j6yxJEUniciyLVcLmu5N0UmIJLOObztG+5rOF4bX54h4SreTWK+E10Z0CzHSeyE5Lz/tVcqqQ==",
+ "peer": true,
+ "requires": {
+ "@ledgerhq/cryptoassets": "^5.27.2",
+ "@ledgerhq/errors": "^5.26.0",
+ "@ledgerhq/hw-transport": "^5.26.0",
+ "bignumber.js": "^9.0.1",
+ "rlp": "^2.2.6"
+ }
+ },
+ "@ledgerhq/hw-transport": {
+ "version": "5.26.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.26.0.tgz",
+ "integrity": "sha512-NFeJOJmyEfAX8uuIBTpocWHcz630sqPcXbu864Q+OCBm4EK5UOKV1h/pX7e0xgNIKY8zhJ/O4p4cIZp9tnXLHQ==",
+ "peer": true,
+ "requires": {
+ "@ledgerhq/devices": "^5.26.0",
+ "@ledgerhq/errors": "^5.26.0",
+ "events": "^3.2.0"
+ }
+ },
+ "@ledgerhq/hw-transport-node-hid": {
+ "version": "5.26.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-5.26.0.tgz",
+ "integrity": "sha512-qhaefZVZatJ6UuK8Wb6WSFNOLWc2mxcv/xgsfKi5HJCIr4bPF/ecIeN+7fRcEaycxj4XykY6Z4A7zDVulfFH4w==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "@ledgerhq/devices": "^5.26.0",
+ "@ledgerhq/errors": "^5.26.0",
+ "@ledgerhq/hw-transport": "^5.26.0",
+ "@ledgerhq/hw-transport-node-hid-noevents": "^5.26.0",
+ "@ledgerhq/logs": "^5.26.0",
+ "lodash": "^4.17.20",
+ "node-hid": "1.3.0",
+ "usb": "^1.6.3"
+ }
+ },
+ "@ledgerhq/hw-transport-node-hid-noevents": {
+ "version": "5.51.1",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-5.51.1.tgz",
+ "integrity": "sha512-9wFf1L8ZQplF7XOY2sQGEeOhpmBRzrn+4X43kghZ7FBDoltrcK+s/D7S+7ffg3j2OySyP6vIIIgloXylao5Scg==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "@ledgerhq/devices": "^5.51.1",
+ "@ledgerhq/errors": "^5.50.0",
+ "@ledgerhq/hw-transport": "^5.51.1",
+ "@ledgerhq/logs": "^5.50.0",
+ "node-hid": "2.1.1"
+ },
+ "dependencies": {
+ "@ledgerhq/hw-transport": {
+ "version": "5.51.1",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.51.1.tgz",
+ "integrity": "sha512-6wDYdbWrw9VwHIcoDnqWBaDFyviyjZWv6H9vz9Vyhe4Qd7TIFmbTl/eWs6hZvtZBza9K8y7zD8ChHwRI4s9tSw==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "@ledgerhq/devices": "^5.51.1",
+ "@ledgerhq/errors": "^5.50.0",
+ "events": "^3.3.0"
+ }
+ },
+ "node-addon-api": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz",
+ "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==",
+ "optional": true,
+ "peer": true
+ },
+ "node-hid": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-2.1.1.tgz",
+ "integrity": "sha512-Skzhqow7hyLZU93eIPthM9yjot9lszg9xrKxESleEs05V2NcbUptZc5HFqzjOkSmL0sFlZFr3kmvaYebx06wrw==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "bindings": "^1.5.0",
+ "node-addon-api": "^3.0.2",
+ "prebuild-install": "^6.0.0"
+ }
+ },
+ "prebuild-install": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz",
+ "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "detect-libc": "^1.0.3",
+ "expand-template": "^2.0.3",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.3",
+ "mkdirp-classic": "^0.5.3",
+ "napi-build-utils": "^1.0.1",
+ "node-abi": "^2.21.0",
+ "npmlog": "^4.0.1",
+ "pump": "^3.0.0",
+ "rc": "^1.2.7",
+ "simple-get": "^3.0.3",
+ "tar-fs": "^2.0.0",
+ "tunnel-agent": "^0.6.0"
+ }
+ }
+ }
+ },
+ "@ledgerhq/hw-transport-u2f": {
+ "version": "5.26.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-u2f/-/hw-transport-u2f-5.26.0.tgz",
+ "integrity": "sha512-QTxP1Rsh+WZ184LUOelYVLeaQl3++V3I2jFik+l9JZtakwEHjD0XqOT750xpYNL/vfHsy31Wlz+oicdxGzFk+w==",
+ "peer": true,
+ "requires": {
+ "@ledgerhq/errors": "^5.26.0",
+ "@ledgerhq/hw-transport": "^5.26.0",
+ "@ledgerhq/logs": "^5.26.0",
+ "u2f-api": "0.2.7"
+ }
+ },
+ "@ledgerhq/logs": {
+ "version": "5.50.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-5.50.0.tgz",
+ "integrity": "sha512-swKHYCOZUGyVt4ge0u8a7AwNcA//h4nx5wIi0sruGye1IJ5Cva0GyK9L2/WdX+kWVTKp92ZiEo1df31lrWGPgA==",
+ "peer": true
+ },
+ "@metamask/eth-sig-util": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz",
+ "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==",
+ "requires": {
+ "ethereumjs-abi": "^0.6.8",
+ "ethereumjs-util": "^6.2.1",
+ "ethjs-util": "^0.1.6",
+ "tweetnacl": "^1.0.3",
+ "tweetnacl-util": "^0.15.1"
+ },
+ "dependencies": {
+ "@types/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "ethereumjs-util": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+ "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+ "requires": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "0.1.6",
+ "rlp": "^2.2.3"
+ }
+ }
+ }
+ },
+ "@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "requires": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="
+ },
+ "@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "requires": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ }
+ },
+ "@nomiclabs/hardhat-etherscan": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.0.1.tgz",
+ "integrity": "sha512-ZeDMqUvbmWGSpsCkyD7QOsJ3lytNgmoOPpglOtgCfoIewb1o2Nz1PgofWYsSdIiWBtIN9rBF8ldU2jVpgsNhHg==",
+ "requires": {
+ "@ethersproject/abi": "^5.1.2",
+ "@ethersproject/address": "^5.0.2",
+ "cbor": "^5.0.2",
+ "debug": "^4.1.1",
+ "fs-extra": "^7.0.1",
+ "node-fetch": "^2.6.0",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ }
+ }
+ },
+ "@nomiclabs/hardhat-truffle5": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-truffle5/-/hardhat-truffle5-2.0.3.tgz",
+ "integrity": "sha512-KbRrFB4NwppzwR8XkYyOopOO6XWOSqtxIoavCIDQ5iIikuZC+WGGoFgeHxypipk5qfD0DWi031IZlXBjOOuYAQ==",
+ "requires": {
+ "@nomiclabs/truffle-contract": "^4.2.23",
+ "@types/chai": "^4.2.0",
+ "chai": "^4.2.0",
+ "ethereumjs-util": "^7.1.3",
+ "fs-extra": "^7.0.1"
+ }
+ },
+ "@nomiclabs/hardhat-web3": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-web3/-/hardhat-web3-2.0.0.tgz",
+ "integrity": "sha512-zt4xN+D+fKl3wW2YlTX3k9APR3XZgPkxJYf36AcliJn3oujnKEVRZaHu0PhgLjO+gR+F/kiYayo9fgd2L8970Q==",
+ "requires": {
+ "@types/bignumber.js": "^5.0.0"
+ }
+ },
+ "@nomiclabs/truffle-contract": {
+ "version": "4.2.23",
+ "resolved": "https://registry.npmjs.org/@nomiclabs/truffle-contract/-/truffle-contract-4.2.23.tgz",
+ "integrity": "sha512-Khj/Ts9r0LqEpGYhISbc+8WTOd6qJ4aFnDR+Ew+neqcjGnhwrIvuihNwPFWU6hDepW3Xod6Y+rTo90N8sLRDjw==",
+ "requires": {
+ "@truffle/blockchain-utils": "^0.0.25",
+ "@truffle/contract-schema": "^3.2.5",
+ "@truffle/debug-utils": "^4.2.9",
+ "@truffle/error": "^0.0.11",
+ "@truffle/interface-adapter": "^0.4.16",
+ "bignumber.js": "^7.2.1",
+ "ethereum-ens": "^0.8.0",
+ "ethers": "^4.0.0-beta.1",
+ "source-map-support": "^0.5.19"
+ },
+ "dependencies": {
+ "bignumber.js": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz",
+ "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ=="
+ },
+ "ethers": {
+ "version": "4.0.49",
+ "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz",
+ "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==",
+ "requires": {
+ "aes-js": "3.0.0",
+ "bn.js": "^4.11.9",
+ "elliptic": "6.5.4",
+ "hash.js": "1.1.3",
+ "js-sha3": "0.5.7",
+ "scrypt-js": "2.0.4",
+ "setimmediate": "1.0.4",
+ "uuid": "2.0.1",
+ "xmlhttprequest": "1.8.0"
+ }
+ },
+ "js-sha3": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz",
+ "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc="
+ },
+ "scrypt-js": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz",
+ "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw=="
+ },
+ "uuid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+ "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w="
+ }
+ }
+ },
+ "@resolver-engine/core": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz",
+ "integrity": "sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.1.0",
+ "is-url": "^1.2.4",
+ "request": "^2.85.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "@resolver-engine/fs": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz",
+ "integrity": "sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==",
+ "dev": true,
+ "requires": {
+ "@resolver-engine/core": "^0.3.3",
+ "debug": "^3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "@resolver-engine/imports": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz",
+ "integrity": "sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==",
+ "dev": true,
+ "requires": {
+ "@resolver-engine/core": "^0.3.3",
+ "debug": "^3.1.0",
+ "hosted-git-info": "^2.6.0",
+ "path-browserify": "^1.0.0",
+ "url": "^0.11.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "@resolver-engine/imports-fs": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz",
+ "integrity": "sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==",
+ "dev": true,
+ "requires": {
+ "@resolver-engine/fs": "^0.3.3",
+ "@resolver-engine/imports": "^0.3.3",
+ "debug": "^3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "@sentry/core": {
+ "version": "5.30.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz",
+ "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==",
+ "requires": {
+ "@sentry/hub": "5.30.0",
+ "@sentry/minimal": "5.30.0",
+ "@sentry/types": "5.30.0",
+ "@sentry/utils": "5.30.0",
+ "tslib": "^1.9.3"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
+ "@sentry/hub": {
+ "version": "5.30.0",
+ "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz",
+ "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==",
+ "requires": {
+ "@sentry/types": "5.30.0",
+ "@sentry/utils": "5.30.0",
+ "tslib": "^1.9.3"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
+ "@sentry/minimal": {
+ "version": "5.30.0",
+ "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz",
+ "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==",
+ "requires": {
+ "@sentry/hub": "5.30.0",
+ "@sentry/types": "5.30.0",
+ "tslib": "^1.9.3"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
+ "@sentry/node": {
+ "version": "5.30.0",
+ "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz",
+ "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==",
+ "requires": {
+ "@sentry/core": "5.30.0",
+ "@sentry/hub": "5.30.0",
+ "@sentry/tracing": "5.30.0",
+ "@sentry/types": "5.30.0",
+ "@sentry/utils": "5.30.0",
+ "cookie": "^0.4.1",
+ "https-proxy-agent": "^5.0.0",
+ "lru_map": "^0.3.3",
+ "tslib": "^1.9.3"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
+ "@sentry/tracing": {
+ "version": "5.30.0",
+ "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz",
+ "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==",
+ "requires": {
+ "@sentry/hub": "5.30.0",
+ "@sentry/minimal": "5.30.0",
+ "@sentry/types": "5.30.0",
+ "@sentry/utils": "5.30.0",
+ "tslib": "^1.9.3"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
+ "@sentry/types": {
+ "version": "5.30.0",
+ "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz",
+ "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw=="
+ },
+ "@sentry/utils": {
+ "version": "5.30.0",
+ "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz",
+ "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==",
+ "requires": {
+ "@sentry/types": "5.30.0",
+ "tslib": "^1.9.3"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
+ "@sindresorhus/is": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ=="
+ },
+ "@solidity-parser/parser": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.1.tgz",
+ "integrity": "sha512-eLjj2L6AuQjBB6s/ibwCAc0DwrR5Ge+ys+wgWo+bviU7fV2nTMQhU63CGaDKXg9iTmMxwhkyoggdIR7ZGRfMgw==",
+ "requires": {
+ "antlr4ts": "^0.5.0-alpha.4"
+ }
+ },
+ "@szmarczak/http-timer": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+ "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+ "requires": {
+ "defer-to-connect": "^1.0.1"
+ }
+ },
+ "@thinkanddev/deploy-eip-1820-web3-rsk": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@thinkanddev/deploy-eip-1820-web3-rsk/-/deploy-eip-1820-web3-rsk-1.0.2.tgz",
+ "integrity": "sha512-rh3q3UYR017bv09hBhEn/7j+cIRIBNfYVWr2KZ7Bxo+K1FXToCAKOKzr7alWzBTZN5XP7OuC2xTgczkGqaIyJA=="
+ },
+ "@thinkanddev/hardhat-erc1820-rsk": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/@thinkanddev/hardhat-erc1820-rsk/-/hardhat-erc1820-rsk-0.1.2.tgz",
+ "integrity": "sha512-9tGj8U9pFpP6Zgi896xIrG9DuIZMXcqxDA6n+s9wGKogWu400T+hMShDpR7Bx/pwMu8DsxplQanJAUIj0joRDA=="
+ },
+ "@truffle/blockchain-utils": {
+ "version": "0.0.25",
+ "resolved": "https://registry.npmjs.org/@truffle/blockchain-utils/-/blockchain-utils-0.0.25.tgz",
+ "integrity": "sha512-XA5m0BfAWtysy5ChHyiAf1fXbJxJXphKk+eZ9Rb9Twi6fn3Jg4gnHNwYXJacYFEydqT5vr2s4Ou812JHlautpw==",
+ "requires": {
+ "source-map-support": "^0.5.19"
+ }
+ },
+ "@truffle/codec": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.7.1.tgz",
+ "integrity": "sha512-mNd6KnW6J0UB1zafGBXDlTEbCMvWpmPAJmzv7aF/nAIaN/F8UePSCiQ1OTQP39Rprj6GFiCCaWVnBAwum6UGSg==",
+ "requires": {
+ "big.js": "^5.2.2",
+ "bn.js": "^4.11.8",
+ "borc": "^2.1.2",
+ "debug": "^4.1.0",
+ "lodash.clonedeep": "^4.5.0",
+ "lodash.escaperegexp": "^4.1.2",
+ "lodash.partition": "^4.6.0",
+ "lodash.sum": "^4.0.2",
+ "semver": "^6.3.0",
+ "source-map-support": "^0.5.19",
+ "utf8": "^3.0.0",
+ "web3-utils": "1.2.9"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ },
+ "web3-utils": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.9.tgz",
+ "integrity": "sha512-9hcpuis3n/LxFzEVjwnVgvJzTirS2S9/MiNAa7l4WOEoywY+BSNwnRX4MuHnjkh9NY25B6QOjuNG6FNnSjTw1w==",
+ "requires": {
+ "bn.js": "4.11.8",
+ "eth-lib": "0.2.7",
+ "ethereum-bloom-filters": "^1.0.6",
+ "ethjs-unit": "0.1.6",
+ "number-to-bn": "1.7.0",
+ "randombytes": "^2.1.0",
+ "underscore": "1.9.1",
+ "utf8": "3.0.0"
+ }
+ }
+ }
+ },
+ "@truffle/compile-common": {
+ "version": "0.7.24",
+ "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.7.24.tgz",
+ "integrity": "sha512-iF3zjXhxcFVAYEZfQA6Rh2vxQ4xSuk/7pKm7yKlLh3p9WjFaPE+dF8wbgQoehftUnBh6SY91uZI6XiD4QDuxYQ==",
+ "requires": {
+ "@truffle/error": "^0.0.14",
+ "colors": "1.4.0"
+ },
+ "dependencies": {
+ "@truffle/error": {
+ "version": "0.0.14",
+ "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.14.tgz",
+ "integrity": "sha512-utJx+SZYoMqk8wldQG4gCVKhV8GwMJbWY7sLXFT/D8wWZTnE2peX7URFJh/cxkjTRCO328z1s2qewkhyVsu2HA=="
+ }
+ }
+ },
+ "@truffle/contract-schema": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/@truffle/contract-schema/-/contract-schema-3.4.4.tgz",
+ "integrity": "sha512-xWgrm6WRM2jmT04w7dP7aVbS2qyP9XPmH/mybQtFXMjJ/8BZlp0yltC8QOs8sGl6q8Ws7acp19YtRkLdK6SsmQ==",
+ "requires": {
+ "ajv": "^6.10.0",
+ "debug": "^4.3.1"
+ }
+ },
+ "@truffle/debug-utils": {
+ "version": "4.2.14",
+ "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-4.2.14.tgz",
+ "integrity": "sha512-g5UTX2DPTzrjRjBJkviGI2IrQRTTSvqjmNWCNZNXP+vgQKNxL9maLZhQ6oA3BuuByVW/kusgYeXt8+W1zynC8g==",
+ "requires": {
+ "@truffle/codec": "^0.7.1",
+ "@trufflesuite/chromafi": "^2.2.1",
+ "chalk": "^2.4.2",
+ "debug": "^4.1.0",
+ "highlight.js": "^9.15.8",
+ "highlightjs-solidity": "^1.0.18"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "@truffle/error": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.11.tgz",
+ "integrity": "sha512-ju6TucjlJkfYMmdraYY/IBJaFb+Sa+huhYtOoyOJ+G29KcgytUVnDzKGwC7Kgk6IsxQMm62Mc1E0GZzFbGGipw=="
+ },
+ "@truffle/interface-adapter": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.4.24.tgz",
+ "integrity": "sha512-2Zho4dJbm/XGwNleY7FdxcjXiAR3SzdGklgrAW4N/YVmltaJv6bT56ACIbPNN6AdzkTSTO65OlsB/63sfSa/VA==",
+ "requires": {
+ "bn.js": "^5.1.3",
+ "ethers": "^4.0.32",
+ "web3": "1.3.6"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
+ },
+ "ethers": {
+ "version": "4.0.49",
+ "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz",
+ "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==",
+ "requires": {
+ "aes-js": "3.0.0",
+ "bn.js": "^4.11.9",
+ "elliptic": "6.5.4",
+ "hash.js": "1.1.3",
+ "js-sha3": "0.5.7",
+ "scrypt-js": "2.0.4",
+ "setimmediate": "1.0.4",
+ "uuid": "2.0.1",
+ "xmlhttprequest": "1.8.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
+ }
+ }
+ },
+ "web3": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/web3/-/web3-1.3.6.tgz",
+ "integrity": "sha512-jEpPhnL6GDteifdVh7ulzlPrtVQeA30V9vnki9liYlUvLV82ZM7BNOQJiuzlDePuE+jZETZSP/0G/JlUVt6pOA==",
+ "requires": {
+ "web3-bzz": "1.3.6",
+ "web3-core": "1.3.6",
+ "web3-eth": "1.3.6",
+ "web3-eth-personal": "1.3.6",
+ "web3-net": "1.3.6",
+ "web3-shh": "1.3.6",
+ "web3-utils": "1.3.6"
+ }
+ }
+ }
+ },
+ "@truffle/provider": {
+ "version": "0.2.42",
+ "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.42.tgz",
+ "integrity": "sha512-ZNoglPho4alYIjJR+sLTgX0x6ho7m4OAUWuJ50RAWmoEqYc4AM6htdrI+lTSoRrOHHbmgasv22a7rFPMnmDrTg==",
+ "requires": {
+ "@truffle/error": "^0.0.14",
+ "@truffle/interface-adapter": "^0.5.8",
+ "web3": "1.5.3"
+ },
+ "dependencies": {
+ "@truffle/error": {
+ "version": "0.0.14",
+ "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.14.tgz",
+ "integrity": "sha512-utJx+SZYoMqk8wldQG4gCVKhV8GwMJbWY7sLXFT/D8wWZTnE2peX7URFJh/cxkjTRCO328z1s2qewkhyVsu2HA=="
+ },
+ "@truffle/interface-adapter": {
+ "version": "0.5.8",
+ "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.8.tgz",
+ "integrity": "sha512-vvy3xpq36oLgjjy8KE9l2Jabg3WcGPOt18tIyMfTQX9MFnbHoQA2Ne2i8xsd4p6KfxIqSjAB53Q9/nScAqY0UQ==",
+ "requires": {
+ "bn.js": "^5.1.3",
+ "ethers": "^4.0.32",
+ "web3": "1.5.3"
+ }
+ },
+ "@types/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/node": {
+ "version": "12.20.41",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz",
+ "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q=="
+ },
+ "bn.js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
+ },
+ "eth-lib": {
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
+ "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
+ "requires": {
+ "bn.js": "^4.11.6",
+ "elliptic": "^6.4.0",
+ "xhr-request-promise": "^0.1.2"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
+ }
+ }
+ },
+ "ethers": {
+ "version": "4.0.49",
+ "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz",
+ "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==",
+ "requires": {
+ "aes-js": "3.0.0",
+ "bn.js": "^4.11.9",
+ "elliptic": "6.5.4",
+ "hash.js": "1.1.3",
+ "js-sha3": "0.5.7",
+ "scrypt-js": "2.0.4",
+ "setimmediate": "1.0.4",
+ "uuid": "2.0.1",
+ "xmlhttprequest": "1.8.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
+ }
+ }
+ },
+ "hash.js": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
+ "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "web3": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz",
+ "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==",
+ "requires": {
+ "web3-bzz": "1.5.3",
+ "web3-core": "1.5.3",
+ "web3-eth": "1.5.3",
+ "web3-eth-personal": "1.5.3",
+ "web3-net": "1.5.3",
+ "web3-shh": "1.5.3",
+ "web3-utils": "1.5.3"
+ }
+ },
+ "web3-bzz": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz",
+ "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==",
+ "requires": {
+ "@types/node": "^12.12.6",
+ "got": "9.6.0",
+ "swarm-js": "^0.1.40"
+ }
+ },
+ "web3-core": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz",
+ "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==",
+ "requires": {
+ "@types/bn.js": "^4.11.5",
+ "@types/node": "^12.12.6",
+ "bignumber.js": "^9.0.0",
+ "web3-core-helpers": "1.5.3",
+ "web3-core-method": "1.5.3",
+ "web3-core-requestmanager": "1.5.3",
+ "web3-utils": "1.5.3"
+ }
+ },
+ "web3-core-helpers": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz",
+ "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==",
+ "requires": {
+ "web3-eth-iban": "1.5.3",
+ "web3-utils": "1.5.3"
+ }
+ },
+ "web3-core-method": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz",
+ "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==",
+ "requires": {
+ "@ethereumjs/common": "^2.4.0",
+ "@ethersproject/transactions": "^5.0.0-beta.135",
+ "web3-core-helpers": "1.5.3",
+ "web3-core-promievent": "1.5.3",
+ "web3-core-subscriptions": "1.5.3",
+ "web3-utils": "1.5.3"
+ }
+ },
+ "web3-core-requestmanager": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz",
+ "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==",
+ "requires": {
+ "util": "^0.12.0",
+ "web3-core-helpers": "1.5.3",
+ "web3-providers-http": "1.5.3",
+ "web3-providers-ipc": "1.5.3",
+ "web3-providers-ws": "1.5.3"
+ }
+ },
+ "web3-core-subscriptions": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz",
+ "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==",
+ "requires": {
+ "eventemitter3": "4.0.4",
+ "web3-core-helpers": "1.5.3"
+ }
+ },
+ "web3-eth-iban": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz",
+ "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==",
+ "requires": {
+ "bn.js": "^4.11.9",
+ "web3-utils": "1.5.3"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
+ }
+ }
+ },
+ "web3-providers-http": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz",
+ "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==",
+ "requires": {
+ "web3-core-helpers": "1.5.3",
+ "xhr2-cookies": "1.1.0"
+ }
+ },
+ "web3-providers-ipc": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz",
+ "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==",
+ "requires": {
+ "oboe": "2.1.5",
+ "web3-core-helpers": "1.5.3"
+ }
+ },
+ "web3-utils": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz",
+ "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==",
+ "requires": {
+ "bn.js": "^4.11.9",
+ "eth-lib": "0.2.8",
+ "ethereum-bloom-filters": "^1.0.6",
+ "ethjs-unit": "0.1.6",
+ "number-to-bn": "1.7.0",
+ "randombytes": "^2.1.0",
+ "utf8": "3.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
+ }
+ }
+ }
+ }
+ },
+ "@trufflesuite/chromafi": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@trufflesuite/chromafi/-/chromafi-2.2.2.tgz",
+ "integrity": "sha512-mItQwVBsb8qP/vaYHQ1kDt2vJLhjoEXJptT6y6fJGvFophMFhOI/NsTVUa0nJL1nyMeFiS6hSYuNVdpQZzB1gA==",
+ "requires": {
+ "ansi-mark": "^1.0.0",
+ "ansi-regex": "^3.0.0",
+ "array-uniq": "^1.0.3",
+ "camelcase": "^4.1.0",
+ "chalk": "^2.3.2",
+ "cheerio": "^1.0.0-rc.2",
+ "detect-indent": "^5.0.0",
+ "he": "^1.1.1",
+ "highlight.js": "^10.4.1",
+ "lodash.merge": "^4.6.2",
+ "min-indent": "^1.0.0",
+ "strip-ansi": "^4.0.0",
+ "strip-indent": "^2.0.0",
+ "super-split": "^1.1.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "highlight.js": {
+ "version": "10.7.3",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
+ "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "@typechain/ethers-v5": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz",
+ "integrity": "sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==",
+ "dev": true,
+ "requires": {
+ "ethers": "^5.0.2"
+ }
+ },
+ "@types/abstract-leveldown": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz",
+ "integrity": "sha512-q5veSX6zjUy/DlDhR4Y4cU0k2Ar+DT2LUraP00T19WLmTO6Se1djepCCaqU6nQrwcJ5Hyo/CWqxTzrrFg8eqbQ=="
+ },
+ "@types/bignumber.js": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/bignumber.js/-/bignumber.js-5.0.0.tgz",
+ "integrity": "sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA==",
+ "requires": {
+ "bignumber.js": "*"
+ }
+ },
+ "@types/bn.js": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz",
+ "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/chai": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz",
+ "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw=="
+ },
+ "@types/concat-stream": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz",
+ "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/form-data": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz",
+ "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
+ "requires": {
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/level-errors": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz",
+ "integrity": "sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ=="
+ },
+ "@types/levelup": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.3.tgz",
+ "integrity": "sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA==",
+ "requires": {
+ "@types/abstract-leveldown": "*",
+ "@types/level-errors": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw=="
+ },
+ "@types/minimatch": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
+ "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ=="
+ },
+ "@types/mkdirp": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz",
+ "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/node": {
+ "version": "17.0.8",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.8.tgz",
+ "integrity": "sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg=="
+ },
+ "@types/node-fetch": {
+ "version": "2.5.12",
+ "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz",
+ "integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "form-data": "^3.0.0"
+ }
+ },
+ "@types/pbkdf2": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz",
+ "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/prettier": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz",
+ "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==",
+ "dev": true
+ },
+ "@types/qs": {
+ "version": "6.9.7",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
+ "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw=="
+ },
+ "@types/resolve": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
+ "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/secp256k1": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz",
+ "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@ungap/promise-all-settled": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
+ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q=="
+ },
+ "@yarnpkg/lockfile": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
+ "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
+ "dev": true
+ },
+ "abbrev": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
+ "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU="
+ },
+ "abort-controller": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+ "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+ "requires": {
+ "event-target-shim": "^5.0.0"
+ }
+ },
+ "abstract-leveldown": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz",
+ "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==",
+ "requires": {
+ "buffer": "^5.5.0",
+ "immediate": "^3.2.3",
+ "level-concat-iterator": "~2.0.0",
+ "level-supports": "~1.0.0",
+ "xtend": "~4.0.0"
+ }
+ },
+ "accepts": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+ "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+ "requires": {
+ "mime-types": "~2.1.24",
+ "negotiator": "0.6.2"
+ }
+ },
+ "acorn": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
+ "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ=="
+ },
+ "acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="
+ },
+ "address": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz",
+ "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA=="
+ },
+ "adm-zip": {
+ "version": "0.4.16",
+ "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz",
+ "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg=="
+ },
+ "aes-js": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz",
+ "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0="
+ },
+ "agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "requires": {
+ "debug": "4"
+ }
+ },
+ "aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "requires": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ }
+ },
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "amdefine": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+ "optional": true
+ },
+ "ansi-colors": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA=="
+ },
+ "ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "requires": {
+ "type-fest": "^0.21.3"
+ }
+ },
+ "ansi-mark": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/ansi-mark/-/ansi-mark-1.0.4.tgz",
+ "integrity": "sha1-HNS6jVfxXxCdaq9uycqXhsik7mw=",
+ "requires": {
+ "ansi-regex": "^3.0.0",
+ "array-uniq": "^1.0.3",
+ "chalk": "^2.3.2",
+ "strip-ansi": "^4.0.0",
+ "super-split": "^1.1.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "antlr4": {
+ "version": "4.7.1",
+ "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz",
+ "integrity": "sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ=="
+ },
+ "antlr4ts": {
+ "version": "0.5.0-alpha.4",
+ "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz",
+ "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ=="
+ },
+ "anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "aproba": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+ "optional": true,
+ "peer": true
+ },
+ "are-we-there-yet": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz",
+ "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.6"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "optional": true,
+ "peer": true
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "array-back": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+ "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+ "dev": true,
+ "requires": {
+ "typical": "^2.6.1"
+ }
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY="
+ },
+ "asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+ },
+ "asn1": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
+ "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "asn1.js": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
+ "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
+ "requires": {
+ "bn.js": "^4.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+ },
+ "assertion-error": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw=="
+ },
+ "ast-parents": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz",
+ "integrity": "sha1-UI/Q8F0MSHddnszaLhdEIyYejdM="
+ },
+ "astral-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg=="
+ },
+ "async": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
+ "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
+ "requires": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "async-eventemitter": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz",
+ "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==",
+ "requires": {
+ "async": "^2.4.0"
+ }
+ },
+ "async-limiter": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ },
+ "available-typed-arrays": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+ },
+ "aws4": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
+ },
+ "axios": {
+ "version": "^0.21.2",
+ "requires": {
+ "follow-redirects": "^1.14.0"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "base-x": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz",
+ "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==",
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ },
+ "dependencies": {
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+ }
+ }
+ },
+ "bech32": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
+ "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ=="
+ },
+ "big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ=="
+ },
+ "bignumber.js": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz",
+ "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw=="
+ },
+ "binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
+ },
+ "bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "file-uri-to-path": "1.0.0"
+ }
+ },
+ "bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "blakejs": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz",
+ "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg=="
+ },
+ "bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
+ },
+ "bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
+ },
+ "body-parser": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz",
+ "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==",
+ "requires": {
+ "bytes": "3.1.1",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.8.1",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.9.6",
+ "raw-body": "2.4.2",
+ "type-is": "~1.6.18"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "qs": {
+ "version": "6.9.6",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz",
+ "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ=="
+ }
+ }
+ },
+ "boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
+ },
+ "borc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/borc/-/borc-2.1.2.tgz",
+ "integrity": "sha512-Sy9eoUi4OiKzq7VovMn246iTo17kzuyHJKomCfpWMlI6RpfN1gk95w7d7gH264nApVLg0HZfcpz62/g4VH1Y4w==",
+ "requires": {
+ "bignumber.js": "^9.0.0",
+ "buffer": "^5.5.0",
+ "commander": "^2.15.0",
+ "ieee754": "^1.1.13",
+ "iso-url": "~0.4.7",
+ "json-text-sequence": "~0.1.0",
+ "readable-stream": "^3.6.0"
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "brorand": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
+ },
+ "browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw=="
+ },
+ "browserify-aes": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+ "requires": {
+ "buffer-xor": "^1.0.3",
+ "cipher-base": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.3",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "browserify-cipher": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+ "requires": {
+ "browserify-aes": "^1.0.4",
+ "browserify-des": "^1.0.0",
+ "evp_bytestokey": "^1.0.0"
+ }
+ },
+ "browserify-des": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+ "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "des.js": "^1.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "browserify-rsa": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
+ "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
+ "requires": {
+ "bn.js": "^5.0.0",
+ "randombytes": "^2.0.1"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
+ }
+ }
+ },
+ "browserify-sign": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
+ "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
+ "requires": {
+ "bn.js": "^5.1.1",
+ "browserify-rsa": "^4.0.1",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "elliptic": "^6.5.3",
+ "inherits": "^2.0.4",
+ "parse-asn1": "^5.1.5",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
+ }
+ }
+ },
+ "bs58": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
+ "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
+ "requires": {
+ "base-x": "^3.0.2"
+ }
+ },
+ "bs58check": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
+ "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
+ "requires": {
+ "bs58": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
+ },
+ "buffer-to-arraybuffer": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz",
+ "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo="
+ },
+ "buffer-xor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
+ },
+ "bufferutil": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz",
+ "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==",
+ "requires": {
+ "node-gyp-build": "^4.3.0"
+ }
+ },
+ "bytes": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz",
+ "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg=="
+ },
+ "cacheable-request": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+ "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+ "requires": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^3.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^4.1.0",
+ "responselike": "^1.0.2"
+ },
+ "dependencies": {
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "lowercase-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="
+ }
+ }
+ },
+ "call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ }
+ },
+ "caller-callsite": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
+ "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
+ "requires": {
+ "callsites": "^2.0.0"
+ }
+ },
+ "caller-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
+ "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
+ "requires": {
+ "caller-callsite": "^2.0.0"
+ }
+ },
+ "callsites": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+ "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA="
+ },
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "cbor": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz",
+ "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==",
+ "requires": {
+ "bignumber.js": "^9.0.1",
+ "nofilter": "^1.0.4"
+ }
+ },
+ "chai": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz",
+ "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==",
+ "requires": {
+ "assertion-error": "^1.1.0",
+ "check-error": "^1.0.2",
+ "deep-eql": "^3.0.1",
+ "get-func-name": "^2.0.0",
+ "pathval": "^1.1.1",
+ "type-detect": "^4.0.5"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
+ },
+ "charenc": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
+ "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
+ },
+ "check-error": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+ "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
+ },
+ "cheerio": {
+ "version": "1.0.0-rc.10",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
+ "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
+ "requires": {
+ "cheerio-select": "^1.5.0",
+ "dom-serializer": "^1.3.2",
+ "domhandler": "^4.2.0",
+ "htmlparser2": "^6.1.0",
+ "parse5": "^6.0.1",
+ "parse5-htmlparser2-tree-adapter": "^6.0.1",
+ "tslib": "^2.2.0"
+ }
+ },
+ "cheerio-select": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz",
+ "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==",
+ "requires": {
+ "css-select": "^4.1.3",
+ "css-what": "^5.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.2.0",
+ "domutils": "^2.7.0"
+ }
+ },
+ "chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "requires": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "fsevents": "~2.3.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ }
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="
+ },
+ "cids": {
+ "version": "0.7.5",
+ "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz",
+ "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==",
+ "requires": {
+ "buffer": "^5.5.0",
+ "class-is": "^1.1.0",
+ "multibase": "~0.6.0",
+ "multicodec": "^1.0.0",
+ "multihashes": "~0.4.15"
+ },
+ "dependencies": {
+ "multicodec": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz",
+ "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==",
+ "requires": {
+ "buffer": "^5.6.0",
+ "varint": "^5.0.0"
+ }
+ }
+ }
+ },
+ "cipher-base": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "class-is": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz",
+ "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw=="
+ },
+ "clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="
+ },
+ "cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+ "requires": {
+ "restore-cursor": "^2.0.0"
+ }
+ },
+ "cli-table3": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz",
+ "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==",
+ "requires": {
+ "colors": "1.4.0",
+ "string-width": "^4.2.0"
+ }
+ },
+ "cli-width": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
+ "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw=="
+ },
+ "cliui": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+ "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+ "requires": {
+ "string-width": "^3.1.0",
+ "strip-ansi": "^5.2.0",
+ "wrap-ansi": "^5.1.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "clone-response": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+ "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+ "requires": {
+ "mimic-response": "^1.0.0"
+ },
+ "dependencies": {
+ "mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="
+ }
+ }
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+ "devOptional": true
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "colors": {
+ "version": "^1.4.0"
+ },
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "command-exists": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz",
+ "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w=="
+ },
+ "command-line-args": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz",
+ "integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==",
+ "dev": true,
+ "requires": {
+ "array-back": "^2.0.0",
+ "find-replace": "^1.0.3",
+ "typical": "^2.6.1"
+ }
+ },
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+ "optional": true,
+ "peer": true
+ },
+ "content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "requires": {
+ "safe-buffer": "5.2.1"
+ }
+ },
+ "content-hash": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz",
+ "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==",
+ "requires": {
+ "cids": "^0.7.1",
+ "multicodec": "^0.5.5",
+ "multihashes": "^0.4.15"
+ }
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ },
+ "cookie": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
+ "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "cookiejar": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz",
+ "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ=="
+ },
+ "core-js-pure": {
+ "version": "3.20.2",
+ "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.20.2.tgz",
+ "integrity": "sha512-CmWHvSKn2vNL6p6StNp1EmMIfVY/pqn3JLAjfZQ8WZGPOlGoO92EkX9/Mk81i6GxvoPXjUqEQnpM3rJ5QxxIOg=="
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "requires": {
+ "object-assign": "^4",
+ "vary": "^1"
+ }
+ },
+ "cosmiconfig": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+ "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+ "requires": {
+ "import-fresh": "^2.0.0",
+ "is-directory": "^0.3.1",
+ "js-yaml": "^3.13.1",
+ "parse-json": "^4.0.0"
+ }
+ },
+ "coveralls": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz",
+ "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==",
+ "dev": true,
+ "requires": {
+ "js-yaml": "^3.13.1",
+ "lcov-parse": "^1.0.0",
+ "log-driver": "^1.2.7",
+ "minimist": "^1.2.5",
+ "request": "^2.88.2"
+ }
+ },
+ "crc-32": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz",
+ "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==",
+ "requires": {
+ "exit-on-epipe": "~1.0.1",
+ "printj": "~1.1.0"
+ }
+ },
+ "create-ecdh": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
+ "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
+ "requires": {
+ "bn.js": "^4.1.0",
+ "elliptic": "^6.5.3"
+ }
+ },
+ "create-hash": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "inherits": "^2.0.1",
+ "md5.js": "^1.3.4",
+ "ripemd160": "^2.0.1",
+ "sha.js": "^2.4.0"
+ }
+ },
+ "create-hmac": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+ "requires": {
+ "cipher-base": "^1.0.3",
+ "create-hash": "^1.1.0",
+ "inherits": "^2.0.1",
+ "ripemd160": "^2.0.0",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+ }
+ }
+ },
+ "crypt": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
+ "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs="
+ },
+ "crypto-browserify": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+ "requires": {
+ "browserify-cipher": "^1.0.0",
+ "browserify-sign": "^4.0.0",
+ "create-ecdh": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.0",
+ "diffie-hellman": "^5.0.0",
+ "inherits": "^2.0.1",
+ "pbkdf2": "^3.0.3",
+ "public-encrypt": "^4.0.0",
+ "randombytes": "^2.0.0",
+ "randomfill": "^1.0.3"
+ }
+ },
+ "css-select": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz",
+ "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==",
+ "requires": {
+ "boolbase": "^1.0.0",
+ "css-what": "^5.1.0",
+ "domhandler": "^4.3.0",
+ "domutils": "^2.8.0",
+ "nth-check": "^2.0.1"
+ }
+ },
+ "css-what": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz",
+ "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw=="
+ },
+ "d": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+ "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+ "requires": {
+ "es5-ext": "^0.10.50",
+ "type": "^1.0.1"
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "death": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz",
+ "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg="
+ },
+ "debug": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
+ "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+ },
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
+ },
+ "decompress-response": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
+ "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "mimic-response": "^2.0.0"
+ }
+ },
+ "deep-eql": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
+ "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+ "requires": {
+ "type-detect": "^4.0.0"
+ }
+ },
+ "deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "optional": true,
+ "peer": true
+ },
+ "deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
+ },
+ "defer-to-connect": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
+ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ=="
+ },
+ "deferred-leveldown": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz",
+ "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==",
+ "requires": {
+ "abstract-leveldown": "~6.2.1",
+ "inherits": "^2.0.3"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz",
+ "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==",
+ "requires": {
+ "buffer": "^5.5.0",
+ "immediate": "^3.2.3",
+ "level-concat-iterator": "~2.0.0",
+ "level-supports": "~1.0.0",
+ "xtend": "~4.0.0"
+ }
+ }
+ }
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+ "optional": true,
+ "peer": true
+ },
+ "delete-empty": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/delete-empty/-/delete-empty-3.0.0.tgz",
+ "integrity": "sha512-ZUyiwo76W+DYnKsL3Kim6M/UOavPdBJgDYWOmuQhYaZvJH0AXAHbUNyEDtRbBra8wqqr686+63/0azfEk1ebUQ==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "^4.1.0",
+ "minimist": "^1.2.0",
+ "path-starts-with": "^2.0.0",
+ "rimraf": "^2.6.2"
+ }
+ },
+ "delimit-stream": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz",
+ "integrity": "sha1-m4MZR3wOX4rrPONXrjBfwl6hzSs="
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "des.js": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+ "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+ "requires": {
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "detect-indent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz",
+ "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50="
+ },
+ "detect-libc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
+ "optional": true,
+ "peer": true
+ },
+ "detect-port": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz",
+ "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==",
+ "requires": {
+ "address": "^1.0.1",
+ "debug": "^2.6.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "diff": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA=="
+ },
+ "diffie-hellman": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+ "requires": {
+ "bn.js": "^4.1.0",
+ "miller-rabin": "^4.0.0",
+ "randombytes": "^2.0.0"
+ }
+ },
+ "dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "requires": {
+ "path-type": "^4.0.0"
+ }
+ },
+ "doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "dom-serializer": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
+ "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
+ "requires": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.2.0",
+ "entities": "^2.0.0"
+ }
+ },
+ "dom-walk": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
+ "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
+ },
+ "domelementtype": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
+ "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A=="
+ },
+ "domhandler": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz",
+ "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==",
+ "requires": {
+ "domelementtype": "^2.2.0"
+ }
+ },
+ "domutils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+ "requires": {
+ "dom-serializer": "^1.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.2.0"
+ }
+ },
+ "duplexer3": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
+ },
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "requires": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "elliptic": {
+ "version": "6.5.4",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
+ "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
+ "requires": {
+ "bn.js": "^4.11.9",
+ "brorand": "^1.1.0",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.1",
+ "inherits": "^2.0.4",
+ "minimalistic-assert": "^1.0.1",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "emoji-regex": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.0.0.tgz",
+ "integrity": "sha512-KmJa8l6uHi1HrBI34udwlzZY1jOEuID/ft4d8BSSEdRyap7PwBEt910453PJa5MuGvxkLqlt4Uvhu7tttFHViw=="
+ },
+ "encode-utf8": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz",
+ "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
+ },
+ "encoding-down": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz",
+ "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==",
+ "requires": {
+ "abstract-leveldown": "^6.2.1",
+ "inherits": "^2.0.3",
+ "level-codec": "^9.0.0",
+ "level-errors": "^2.0.0"
+ }
+ },
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "enquirer": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+ "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+ "requires": {
+ "ansi-colors": "^4.1.1"
+ }
+ },
+ "entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="
+ },
+ "env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="
+ },
+ "errno": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
+ "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
+ "requires": {
+ "prr": "~1.0.1"
+ }
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz",
+ "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==",
+ "requires": {
+ "call-bind": "^1.0.2",
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.1.1",
+ "get-symbol-description": "^1.0.0",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.2",
+ "internal-slot": "^1.0.3",
+ "is-callable": "^1.2.4",
+ "is-negative-zero": "^2.0.1",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.1",
+ "is-string": "^1.0.7",
+ "is-weakref": "^1.0.1",
+ "object-inspect": "^1.11.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.2",
+ "string.prototype.trimend": "^1.0.4",
+ "string.prototype.trimstart": "^1.0.4",
+ "unbox-primitive": "^1.0.1"
+ },
+ "dependencies": {
+ "object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ }
+ }
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.53",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
+ "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+ "requires": {
+ "es6-iterator": "~2.0.3",
+ "es6-symbol": "~3.1.3",
+ "next-tick": "~1.0.0"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+ "requires": {
+ "d": "^1.0.1",
+ "ext": "^1.1.2"
+ }
+ },
+ "escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "escodegen": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
+ "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
+ "requires": {
+ "esprima": "^2.7.1",
+ "estraverse": "^1.9.1",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1",
+ "source-map": "~0.2.0"
+ },
+ "dependencies": {
+ "esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE="
+ },
+ "estraverse": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
+ "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q="
+ }
+ }
+ },
+ "eslint": {
+ "version": "5.16.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
+ "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "ajv": "^6.9.1",
+ "chalk": "^2.1.0",
+ "cross-spawn": "^6.0.5",
+ "debug": "^4.0.1",
+ "doctrine": "^3.0.0",
+ "eslint-scope": "^4.0.3",
+ "eslint-utils": "^1.3.1",
+ "eslint-visitor-keys": "^1.0.0",
+ "espree": "^5.0.1",
+ "esquery": "^1.0.1",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^5.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "glob": "^7.1.2",
+ "globals": "^11.7.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^6.2.2",
+ "js-yaml": "^3.13.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.3.0",
+ "lodash": "^4.17.11",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.2",
+ "path-is-inside": "^1.0.2",
+ "progress": "^2.0.0",
+ "regexpp": "^2.0.1",
+ "semver": "^5.5.1",
+ "strip-ansi": "^4.0.0",
+ "strip-json-comments": "^2.0.1",
+ "table": "^5.2.3",
+ "text-table": "^0.2.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "eslint-scope": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
+ "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
+ "requires": {
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-utils": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
+ "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
+ "requires": {
+ "eslint-visitor-keys": "^1.1.0"
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ=="
+ },
+ "espree": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
+ "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
+ "requires": {
+ "acorn": "^6.0.7",
+ "acorn-jsx": "^5.0.0",
+ "eslint-visitor-keys": "^1.0.0"
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
+ },
+ "esquery": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+ "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "requires": {
+ "estraverse": "^5.1.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
+ }
+ }
+ },
+ "esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "requires": {
+ "estraverse": "^5.2.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
+ }
+ }
+ },
+ "estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+ },
+ "eth-ens-namehash": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz",
+ "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=",
+ "requires": {
+ "idna-uts46-hx": "^2.3.1",
+ "js-sha3": "^0.5.7"
+ },
+ "dependencies": {
+ "js-sha3": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz",
+ "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc="
+ }
+ }
+ },
+ "eth-gas-reporter": {
+ "version": "0.2.24",
+ "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.24.tgz",
+ "integrity": "sha512-RbXLC2bnuPHzIMU/rnLXXlb6oiHEEKu7rq2UrAX/0mfo0Lzrr/kb9QTjWjfz8eNvc+uu6J8AuBwI++b+MLNI2w==",
+ "requires": {
+ "@ethersproject/abi": "^5.0.0-beta.146",
+ "@solidity-parser/parser": "^0.14.0",
+ "cli-table3": "^0.5.0",
+ "colors": "1.4.0",
+ "ethereumjs-util": "6.2.0",
+ "ethers": "^4.0.40",
+ "fs-readdir-recursive": "^1.1.0",
+ "lodash": "^4.17.14",
+ "markdown-table": "^1.1.3",
+ "mocha": "^7.1.1",
+ "req-cwd": "^2.0.0",
+ "request": "^2.88.0",
+ "request-promise-native": "^1.0.5",
+ "sha1": "^1.1.1",
+ "sync-request": "^6.0.0"
+ },
+ "dependencies": {
+ "@types/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "cli-table3": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz",
+ "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==",
+ "requires": {
+ "colors": "^1.1.2",
+ "object-assign": "^4.1.0",
+ "string-width": "^2.1.1"
+ }
+ },
+ "ethereumjs-util": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz",
+ "integrity": "sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ==",
+ "requires": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "ethjs-util": "0.1.6",
+ "keccak": "^2.0.0",
+ "rlp": "^2.2.3",
+ "secp256k1": "^3.0.1"
+ }
+ },
+ "ethers": {
+ "version": "4.0.49",
+ "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz",
+ "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==",
+ "requires": {
+ "aes-js": "3.0.0",
+ "bn.js": "^4.11.9",
+ "elliptic": "6.5.4",
+ "hash.js": "1.1.3",
+ "js-sha3": "0.5.7",
+ "scrypt-js": "2.0.4",
+ "setimmediate": "1.0.4",
+ "uuid": "2.0.1",
+ "xmlhttprequest": "1.8.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
+ },
+ "setimmediate": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
+ "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48="
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "uuid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+ "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w="
+ }
+ }
+ },
+ "eth-lib": {
+ "version": "0.1.29",
+ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz",
+ "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==",
+ "requires": {
+ "bn.js": "^4.11.6",
+ "elliptic": "^6.4.0",
+ "nano-json-stream-parser": "^0.1.2",
+ "servify": "^0.1.12",
+ "ws": "^3.0.0",
+ "xhr-request-promise": "^0.1.2"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "ws": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
+ "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
+ "requires": {
+ "async-limiter": "~1.0.0",
+ "safe-buffer": "~5.1.0",
+ "ultron": "~1.1.0"
+ }
+ }
+ }
+ },
+ "ethereum-bloom-filters": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz",
+ "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==",
+ "requires": {
+ "js-sha3": "^0.8.0"
+ }
+ },
+ "ethereum-cryptography": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz",
+ "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==",
+ "requires": {
+ "@types/pbkdf2": "^3.0.0",
+ "@types/secp256k1": "^4.0.1",
+ "blakejs": "^1.1.0",
+ "browserify-aes": "^1.2.0",
+ "bs58check": "^2.1.2",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "hash.js": "^1.1.7",
+ "keccak": "^3.0.0",
+ "pbkdf2": "^3.0.17",
+ "randombytes": "^2.1.0",
+ "safe-buffer": "^5.1.2",
+ "scrypt-js": "^3.0.0",
+ "secp256k1": "^4.0.1",
+ "setimmediate": "^1.0.5"
+ }
+ },
+ "ethereum-ens": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/ethereum-ens/-/ethereum-ens-0.8.0.tgz",
+ "integrity": "sha512-a8cBTF4AWw1Q1Y37V1LSCS9pRY4Mh3f8vCg5cbXCCEJ3eno1hbI/+Ccv9SZLISYpqQhaglP3Bxb/34lS4Qf7Bg==",
+ "requires": {
+ "bluebird": "^3.4.7",
+ "eth-ens-namehash": "^2.0.0",
+ "js-sha3": "^0.5.7",
+ "pako": "^1.0.4",
+ "underscore": "^1.8.3",
+ "web3": "^1.0.0-beta.34"
+ },
+ "dependencies": {
+ "js-sha3": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz",
+ "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc="
+ }
+ }
+ },
+ "ethereum-waffle": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.4.0.tgz",
+ "integrity": "sha512-ADBqZCkoSA5Isk486ntKJVjFEawIiC+3HxNqpJqONvh3YXBTNiRfXvJtGuAFLXPG91QaqkGqILEHANAo7j/olQ==",
+ "dev": true,
+ "requires": {
+ "@ethereum-waffle/chai": "^3.4.0",
+ "@ethereum-waffle/compiler": "^3.4.0",
+ "@ethereum-waffle/mock-contract": "^3.3.0",
+ "@ethereum-waffle/provider": "^3.4.0",
+ "ethers": "^5.0.1"
+ }
+ },
+ "ethereumjs-abi": {
+ "version": "0.6.8",
+ "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz",
+ "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==",
+ "requires": {
+ "bn.js": "^4.11.8",
+ "ethereumjs-util": "^6.0.0"
+ },
+ "dependencies": {
+ "@types/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "ethereumjs-util": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+ "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+ "requires": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "0.1.6",
+ "rlp": "^2.2.3"
+ }
+ }
+ }
+ },
+ "ethereumjs-util": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz",
+ "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==",
+ "requires": {
+ "@types/bn.js": "^5.1.0",
+ "bn.js": "^5.1.2",
+ "create-hash": "^1.1.2",
+ "ethereum-cryptography": "^0.1.3",
+ "rlp": "^2.2.4"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
+ }
+ }
+ },
+ "ethers": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.3.tgz",
+ "integrity": "sha512-fTT4WT8/hTe/BLwRUtl7I5zlpF3XC3P/Xwqxc5AIP2HGlH15qpmjs0Ou78az93b1rLITzXLFxoNX63B8ZbUd7g==",
+ "requires": {
+ "@ethersproject/abi": "5.5.0",
+ "@ethersproject/abstract-provider": "5.5.1",
+ "@ethersproject/abstract-signer": "5.5.0",
+ "@ethersproject/address": "5.5.0",
+ "@ethersproject/base64": "5.5.0",
+ "@ethersproject/basex": "5.5.0",
+ "@ethersproject/bignumber": "5.5.0",
+ "@ethersproject/bytes": "5.5.0",
+ "@ethersproject/constants": "5.5.0",
+ "@ethersproject/contracts": "5.5.0",
+ "@ethersproject/hash": "5.5.0",
+ "@ethersproject/hdnode": "5.5.0",
+ "@ethersproject/json-wallets": "5.5.0",
+ "@ethersproject/keccak256": "5.5.0",
+ "@ethersproject/logger": "5.5.0",
+ "@ethersproject/networks": "5.5.2",
+ "@ethersproject/pbkdf2": "5.5.0",
+ "@ethersproject/properties": "5.5.0",
+ "@ethersproject/providers": "5.5.2",
+ "@ethersproject/random": "5.5.1",
+ "@ethersproject/rlp": "5.5.0",
+ "@ethersproject/sha2": "5.5.0",
+ "@ethersproject/signing-key": "5.5.0",
+ "@ethersproject/solidity": "5.5.0",
+ "@ethersproject/strings": "5.5.0",
+ "@ethersproject/transactions": "5.5.0",
+ "@ethersproject/units": "5.5.0",
+ "@ethersproject/wallet": "5.5.0",
+ "@ethersproject/web": "5.5.1",
+ "@ethersproject/wordlists": "5.5.0"
+ }
+ },
+ "ethjs-unit": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz",
+ "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=",
+ "requires": {
+ "bn.js": "4.11.6",
+ "number-to-bn": "1.7.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
+ }
+ }
+ },
+ "ethjs-util": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
+ "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
+ "requires": {
+ "is-hex-prefixed": "1.0.0",
+ "strip-hex-prefix": "1.0.0"
+ }
+ },
+ "event-target-shim": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
+ },
+ "eventemitter3": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz",
+ "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ=="
+ },
+ "events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "peer": true
+ },
+ "evp_bytestokey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+ "requires": {
+ "md5.js": "^1.3.4",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "exit-on-epipe": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
+ "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw=="
+ },
+ "expand-template": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+ "optional": true,
+ "peer": true
+ },
+ "express": {
+ "version": "4.17.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz",
+ "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==",
+ "requires": {
+ "accepts": "~1.3.7",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.19.1",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.4.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "~1.1.2",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.9.6",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.17.2",
+ "serve-static": "1.14.2",
+ "setprototypeof": "1.2.0",
+ "statuses": "~1.5.0",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "qs": {
+ "version": "6.9.6",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz",
+ "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ=="
+ }
+ }
+ },
+ "ext": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz",
+ "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==",
+ "requires": {
+ "type": "^2.5.0"
+ },
+ "dependencies": {
+ "type": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz",
+ "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw=="
+ }
+ }
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "external-editor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+ "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+ "requires": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "fast-diff": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w=="
+ },
+ "fast-glob": {
+ "version": "3.2.10",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.10.tgz",
+ "integrity": "sha512-s9nFhFnvR63wls6/kM88kQqDhMu0AfdjqouE2l5GVQPbqLgyFjjU5ry/r2yKsJxpb9Py1EYNqieFrmMaX4v++A==",
+ "requires": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ }
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
+ },
+ "fastq": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
+ "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+ "requires": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "file-entry-cache": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+ "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+ "requires": {
+ "flat-cache": "^2.0.1"
+ }
+ },
+ "file-uri-to-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+ "optional": true,
+ "peer": true
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "find-replace": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz",
+ "integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=",
+ "dev": true,
+ "requires": {
+ "array-back": "^1.0.4",
+ "test-value": "^2.1.0"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+ "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+ "dev": true,
+ "requires": {
+ "typical": "^2.6.0"
+ }
+ }
+ }
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ },
+ "find-yarn-workspace-root": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz",
+ "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==",
+ "dev": true,
+ "requires": {
+ "micromatch": "^4.0.2"
+ }
+ },
+ "flat": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz",
+ "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==",
+ "requires": {
+ "is-buffer": "~2.0.3"
+ }
+ },
+ "flat-cache": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+ "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+ "requires": {
+ "flatted": "^2.0.0",
+ "rimraf": "2.6.3",
+ "write": "1.0.3"
+ },
+ "dependencies": {
+ "rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "flatted": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
+ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA=="
+ },
+ "fmix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz",
+ "integrity": "sha1-x7vxJN7ELJ0ZHPuUfQqXeN2YbAw=",
+ "requires": {
+ "imul": "^1.0.0"
+ }
+ },
+ "follow-redirects": {
+ "version": "1.14.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
+ "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w=="
+ },
+ "foreach": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+ },
+ "form-data": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+ "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
+ },
+ "fp-ts": {
+ "version": "1.19.3",
+ "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz",
+ "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg=="
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+ },
+ "fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
+ "optional": true,
+ "peer": true
+ },
+ "fs-extra": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+ "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "fs-readdir-recursive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
+ "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA=="
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "optional": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc="
+ },
+ "ganache-core": {
+ "version": "2.13.2",
+ "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz",
+ "integrity": "sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "3.0.0",
+ "async": "2.6.2",
+ "bip39": "2.5.0",
+ "cachedown": "1.0.0",
+ "clone": "2.1.2",
+ "debug": "3.2.6",
+ "encoding-down": "5.0.4",
+ "eth-sig-util": "3.0.0",
+ "ethereumjs-abi": "0.6.8",
+ "ethereumjs-account": "3.0.0",
+ "ethereumjs-block": "2.2.2",
+ "ethereumjs-common": "1.5.0",
+ "ethereumjs-tx": "2.1.2",
+ "ethereumjs-util": "6.2.1",
+ "ethereumjs-vm": "4.2.0",
+ "ethereumjs-wallet": "0.6.5",
+ "heap": "0.2.6",
+ "keccak": "3.0.1",
+ "level-sublevel": "6.6.4",
+ "levelup": "3.1.1",
+ "lodash": "4.17.20",
+ "lru-cache": "5.1.1",
+ "merkle-patricia-tree": "3.0.0",
+ "patch-package": "6.2.2",
+ "seedrandom": "3.0.1",
+ "source-map-support": "0.5.12",
+ "tmp": "0.1.0",
+ "web3": "1.2.11",
+ "web3-provider-engine": "14.2.1",
+ "websocket": "1.0.32"
+ },
+ "dependencies": {
+ "@ethersproject/abi": {
+ "version": "5.0.0-beta.153",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/address": ">=5.0.0-beta.128",
+ "@ethersproject/bignumber": ">=5.0.0-beta.130",
+ "@ethersproject/bytes": ">=5.0.0-beta.129",
+ "@ethersproject/constants": ">=5.0.0-beta.128",
+ "@ethersproject/hash": ">=5.0.0-beta.128",
+ "@ethersproject/keccak256": ">=5.0.0-beta.127",
+ "@ethersproject/logger": ">=5.0.0-beta.129",
+ "@ethersproject/properties": ">=5.0.0-beta.131",
+ "@ethersproject/strings": ">=5.0.0-beta.130"
+ }
+ },
+ "@ethersproject/abstract-provider": {
+ "version": "5.0.8",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/bignumber": "^5.0.13",
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/logger": "^5.0.8",
+ "@ethersproject/networks": "^5.0.7",
+ "@ethersproject/properties": "^5.0.7",
+ "@ethersproject/transactions": "^5.0.9",
+ "@ethersproject/web": "^5.0.12"
+ }
+ },
+ "@ethersproject/abstract-signer": {
+ "version": "5.0.10",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/abstract-provider": "^5.0.8",
+ "@ethersproject/bignumber": "^5.0.13",
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/logger": "^5.0.8",
+ "@ethersproject/properties": "^5.0.7"
+ }
+ },
+ "@ethersproject/address": {
+ "version": "5.0.9",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/bignumber": "^5.0.13",
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/keccak256": "^5.0.7",
+ "@ethersproject/logger": "^5.0.8",
+ "@ethersproject/rlp": "^5.0.7"
+ }
+ },
+ "@ethersproject/base64": {
+ "version": "5.0.7",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/bytes": "^5.0.9"
+ }
+ },
+ "@ethersproject/bignumber": {
+ "version": "5.0.13",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/logger": "^5.0.8",
+ "bn.js": "^4.4.0"
+ }
+ },
+ "@ethersproject/bytes": {
+ "version": "5.0.9",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/logger": "^5.0.8"
+ }
+ },
+ "@ethersproject/constants": {
+ "version": "5.0.8",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/bignumber": "^5.0.13"
+ }
+ },
+ "@ethersproject/hash": {
+ "version": "5.0.10",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/abstract-signer": "^5.0.10",
+ "@ethersproject/address": "^5.0.9",
+ "@ethersproject/bignumber": "^5.0.13",
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/keccak256": "^5.0.7",
+ "@ethersproject/logger": "^5.0.8",
+ "@ethersproject/properties": "^5.0.7",
+ "@ethersproject/strings": "^5.0.8"
+ }
+ },
+ "@ethersproject/keccak256": {
+ "version": "5.0.7",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/bytes": "^5.0.9",
+ "js-sha3": "0.5.7"
+ }
+ },
+ "@ethersproject/logger": {
+ "version": "5.0.8",
+ "dev": true,
+ "optional": true
+ },
+ "@ethersproject/networks": {
+ "version": "5.0.7",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/logger": "^5.0.8"
+ }
+ },
+ "@ethersproject/properties": {
+ "version": "5.0.7",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/logger": "^5.0.8"
+ }
+ },
+ "@ethersproject/rlp": {
+ "version": "5.0.7",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/logger": "^5.0.8"
+ }
+ },
+ "@ethersproject/signing-key": {
+ "version": "5.0.8",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/logger": "^5.0.8",
+ "@ethersproject/properties": "^5.0.7",
+ "elliptic": "6.5.3"
+ }
+ },
+ "@ethersproject/strings": {
+ "version": "5.0.8",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/constants": "^5.0.8",
+ "@ethersproject/logger": "^5.0.8"
+ }
+ },
+ "@ethersproject/transactions": {
+ "version": "5.0.9",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/address": "^5.0.9",
+ "@ethersproject/bignumber": "^5.0.13",
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/constants": "^5.0.8",
+ "@ethersproject/keccak256": "^5.0.7",
+ "@ethersproject/logger": "^5.0.8",
+ "@ethersproject/properties": "^5.0.7",
+ "@ethersproject/rlp": "^5.0.7",
+ "@ethersproject/signing-key": "^5.0.8"
+ }
+ },
+ "@ethersproject/web": {
+ "version": "5.0.12",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/base64": "^5.0.7",
+ "@ethersproject/bytes": "^5.0.9",
+ "@ethersproject/logger": "^5.0.8",
+ "@ethersproject/properties": "^5.0.7",
+ "@ethersproject/strings": "^5.0.8"
+ }
+ },
+ "@sindresorhus/is": {
+ "version": "0.14.0",
+ "dev": true,
+ "optional": true
+ },
+ "@szmarczak/http-timer": {
+ "version": "1.1.2",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "defer-to-connect": "^1.0.1"
+ }
+ },
+ "@types/bn.js": {
+ "version": "4.11.6",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/node": {
+ "version": "14.14.20",
+ "dev": true
+ },
+ "@types/pbkdf2": {
+ "version": "3.1.0",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/secp256k1": {
+ "version": "4.0.1",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@yarnpkg/lockfile": {
+ "version": "1.1.0",
+ "dev": true
+ },
+ "abstract-leveldown": {
+ "version": "3.0.0",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "accepts": {
+ "version": "1.3.7",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "mime-types": "~2.1.24",
+ "negotiator": "0.6.2"
+ }
+ },
+ "aes-js": {
+ "version": "3.1.2",
+ "dev": true,
+ "optional": true
+ },
+ "ajv": {
+ "version": "6.12.6",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "dev": true
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "dev": true
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "dev": true
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "dev": true,
+ "optional": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.2.4",
+ "dev": true,
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "asn1.js": {
+ "version": "5.4.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bn.js": "^4.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "dev": true
+ },
+ "assign-symbols": {
+ "version": "1.0.0",
+ "dev": true
+ },
+ "async": {
+ "version": "2.6.2",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.11"
+ }
+ },
+ "async-eventemitter": {
+ "version": "0.2.4",
+ "dev": true,
+ "requires": {
+ "async": "^2.4.0"
+ }
+ },
+ "async-limiter": {
+ "version": "1.0.1",
+ "dev": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "dev": true
+ },
+ "atob": {
+ "version": "2.1.2",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.11.0",
+ "dev": true
+ },
+ "babel-code-frame": {
+ "version": "6.26.0",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3",
+ "esutils": "^2.0.2",
+ "js-tokens": "^3.0.2"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "js-tokens": {
+ "version": "3.0.2",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "dev": true
+ }
+ }
+ },
+ "babel-core": {
+ "version": "6.26.3",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "^6.26.0",
+ "babel-generator": "^6.26.0",
+ "babel-helpers": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-register": "^6.26.0",
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "convert-source-map": "^1.5.1",
+ "debug": "^2.6.9",
+ "json5": "^0.5.1",
+ "lodash": "^4.17.4",
+ "minimatch": "^3.0.4",
+ "path-is-absolute": "^1.0.1",
+ "private": "^0.1.8",
+ "slash": "^1.0.0",
+ "source-map": "^0.5.7"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "json5": {
+ "version": "0.5.1",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.0.0",
+ "dev": true
+ },
+ "slash": {
+ "version": "1.0.0",
+ "dev": true
+ }
+ }
+ },
+ "babel-generator": {
+ "version": "6.26.1",
+ "dev": true,
+ "requires": {
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "detect-indent": "^4.0.0",
+ "jsesc": "^1.3.0",
+ "lodash": "^4.17.4",
+ "source-map": "^0.5.7",
+ "trim-right": "^1.0.1"
+ },
+ "dependencies": {
+ "jsesc": {
+ "version": "1.3.0",
+ "dev": true
+ }
+ }
+ },
+ "babel-helper-builder-binary-assignment-operator-visitor": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-helper-explode-assignable-expression": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-call-delegate": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-helper-hoist-variables": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-define-map": {
+ "version": "6.26.0",
+ "dev": true,
+ "requires": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "babel-helper-explode-assignable-expression": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-function-name": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-helper-get-function-arity": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-get-function-arity": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-hoist-variables": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-optimise-call-expression": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-regex": {
+ "version": "6.26.0",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "babel-helper-remap-async-to-generator": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-replace-supers": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-helper-optimise-call-expression": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helpers": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-messages": {
+ "version": "6.23.0",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-check-es2015-constants": {
+ "version": "6.22.0",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-syntax-async-functions": {
+ "version": "6.13.0",
+ "dev": true
+ },
+ "babel-plugin-syntax-exponentiation-operator": {
+ "version": "6.13.0",
+ "dev": true
+ },
+ "babel-plugin-syntax-trailing-function-commas": {
+ "version": "6.22.0",
+ "dev": true
+ },
+ "babel-plugin-transform-async-to-generator": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-helper-remap-async-to-generator": "^6.24.1",
+ "babel-plugin-syntax-async-functions": "^6.8.0",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-arrow-functions": {
+ "version": "6.22.0",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-block-scoped-functions": {
+ "version": "6.22.0",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-block-scoping": {
+ "version": "6.26.0",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "babel-plugin-transform-es2015-classes": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-helper-define-map": "^6.24.1",
+ "babel-helper-function-name": "^6.24.1",
+ "babel-helper-optimise-call-expression": "^6.24.1",
+ "babel-helper-replace-supers": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-computed-properties": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-destructuring": {
+ "version": "6.23.0",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-duplicate-keys": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-for-of": {
+ "version": "6.23.0",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-function-name": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-literals": {
+ "version": "6.22.0",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-amd": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-commonjs": {
+ "version": "6.26.2",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-strict-mode": "^6.24.1",
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-types": "^6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-systemjs": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-helper-hoist-variables": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-umd": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-es2015-modules-amd": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-object-super": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-helper-replace-supers": "^6.24.1",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-parameters": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-helper-call-delegate": "^6.24.1",
+ "babel-helper-get-function-arity": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-shorthand-properties": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-spread": {
+ "version": "6.22.0",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-sticky-regex": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-helper-regex": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-template-literals": {
+ "version": "6.22.0",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-typeof-symbol": {
+ "version": "6.23.0",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-unicode-regex": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-helper-regex": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "regexpu-core": "^2.0.0"
+ }
+ },
+ "babel-plugin-transform-exponentiation-operator": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1",
+ "babel-plugin-syntax-exponentiation-operator": "^6.8.0",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-regenerator": {
+ "version": "6.26.0",
+ "dev": true,
+ "requires": {
+ "regenerator-transform": "^0.10.0"
+ }
+ },
+ "babel-plugin-transform-strict-mode": {
+ "version": "6.24.1",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-preset-env": {
+ "version": "1.7.0",
+ "dev": true,
+ "requires": {
+ "babel-plugin-check-es2015-constants": "^6.22.0",
+ "babel-plugin-syntax-trailing-function-commas": "^6.22.0",
+ "babel-plugin-transform-async-to-generator": "^6.22.0",
+ "babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
+ "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
+ "babel-plugin-transform-es2015-block-scoping": "^6.23.0",
+ "babel-plugin-transform-es2015-classes": "^6.23.0",
+ "babel-plugin-transform-es2015-computed-properties": "^6.22.0",
+ "babel-plugin-transform-es2015-destructuring": "^6.23.0",
+ "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0",
+ "babel-plugin-transform-es2015-for-of": "^6.23.0",
+ "babel-plugin-transform-es2015-function-name": "^6.22.0",
+ "babel-plugin-transform-es2015-literals": "^6.22.0",
+ "babel-plugin-transform-es2015-modules-amd": "^6.22.0",
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0",
+ "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0",
+ "babel-plugin-transform-es2015-modules-umd": "^6.23.0",
+ "babel-plugin-transform-es2015-object-super": "^6.22.0",
+ "babel-plugin-transform-es2015-parameters": "^6.23.0",
+ "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0",
+ "babel-plugin-transform-es2015-spread": "^6.22.0",
+ "babel-plugin-transform-es2015-sticky-regex": "^6.22.0",
+ "babel-plugin-transform-es2015-template-literals": "^6.22.0",
+ "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0",
+ "babel-plugin-transform-es2015-unicode-regex": "^6.22.0",
+ "babel-plugin-transform-exponentiation-operator": "^6.22.0",
+ "babel-plugin-transform-regenerator": "^6.22.0",
+ "browserslist": "^3.2.6",
+ "invariant": "^2.2.2",
+ "semver": "^5.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "dev": true
+ }
+ }
+ },
+ "babel-register": {
+ "version": "6.26.0",
+ "dev": true,
+ "requires": {
+ "babel-core": "^6.26.0",
+ "babel-runtime": "^6.26.0",
+ "core-js": "^2.5.0",
+ "home-or-tmp": "^2.0.0",
+ "lodash": "^4.17.4",
+ "mkdirp": "^0.5.1",
+ "source-map-support": "^0.4.15"
+ },
+ "dependencies": {
+ "source-map-support": {
+ "version": "0.4.18",
+ "dev": true,
+ "requires": {
+ "source-map": "^0.5.6"
+ }
+ }
+ }
+ },
+ "babel-runtime": {
+ "version": "6.26.0",
+ "dev": true,
+ "requires": {
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.11.0"
+ }
+ },
+ "babel-template": {
+ "version": "6.26.0",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "babel-traverse": {
+ "version": "6.26.0",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "^6.26.0",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "debug": "^2.6.8",
+ "globals": "^9.18.0",
+ "invariant": "^2.2.2",
+ "lodash": "^4.17.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "globals": {
+ "version": "9.18.0",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.0.0",
+ "dev": true
+ }
+ }
+ },
+ "babel-types": {
+ "version": "6.26.0",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "esutils": "^2.0.2",
+ "lodash": "^4.17.4",
+ "to-fast-properties": "^1.0.3"
+ },
+ "dependencies": {
+ "to-fast-properties": {
+ "version": "1.0.3",
+ "dev": true
+ }
+ }
+ },
+ "babelify": {
+ "version": "7.3.0",
+ "dev": true,
+ "requires": {
+ "babel-core": "^6.0.14",
+ "object-assign": "^4.0.0"
+ }
+ },
+ "babylon": {
+ "version": "6.18.0",
+ "dev": true
+ },
+ "backoff": {
+ "version": "2.5.0",
+ "dev": true,
+ "requires": {
+ "precond": "0.2"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "dev": true
+ },
+ "base": {
+ "version": "0.11.2",
+ "dev": true,
+ "requires": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ }
+ }
+ },
+ "base-x": {
+ "version": "3.0.8",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "base64-js": {
+ "version": "1.5.1",
+ "dev": true
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "dev": true,
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ },
+ "dependencies": {
+ "tweetnacl": {
+ "version": "0.14.5",
+ "dev": true
+ }
+ }
+ },
+ "bignumber.js": {
+ "version": "9.0.1",
+ "dev": true,
+ "optional": true
+ },
+ "bip39": {
+ "version": "2.5.0",
+ "dev": true,
+ "requires": {
+ "create-hash": "^1.1.0",
+ "pbkdf2": "^3.0.9",
+ "randombytes": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "unorm": "^1.3.3"
+ }
+ },
+ "blakejs": {
+ "version": "1.1.0",
+ "dev": true
+ },
+ "bluebird": {
+ "version": "3.7.2",
+ "dev": true,
+ "optional": true
+ },
+ "bn.js": {
+ "version": "4.11.9",
+ "dev": true
+ },
+ "body-parser": {
+ "version": "1.19.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bytes": "3.1.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.7.0",
+ "raw-body": "2.4.0",
+ "type-is": "~1.6.17"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "dev": true,
+ "optional": true
+ },
+ "qs": {
+ "version": "6.7.0",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "brorand": {
+ "version": "1.1.0",
+ "dev": true
+ },
+ "browserify-aes": {
+ "version": "1.2.0",
+ "dev": true,
+ "requires": {
+ "buffer-xor": "^1.0.3",
+ "cipher-base": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.3",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "browserify-cipher": {
+ "version": "1.0.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "browserify-aes": "^1.0.4",
+ "browserify-des": "^1.0.0",
+ "evp_bytestokey": "^1.0.0"
+ }
+ },
+ "browserify-des": {
+ "version": "1.0.2",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "des.js": "^1.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "browserify-rsa": {
+ "version": "4.1.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bn.js": "^5.0.0",
+ "randombytes": "^2.0.1"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "5.1.3",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "browserify-sign": {
+ "version": "4.2.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bn.js": "^5.1.1",
+ "browserify-rsa": "^4.0.1",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "elliptic": "^6.5.3",
+ "inherits": "^2.0.4",
+ "parse-asn1": "^5.1.5",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "5.1.3",
+ "dev": true,
+ "optional": true
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
+ "browserslist": {
+ "version": "3.2.8",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30000844",
+ "electron-to-chromium": "^1.3.47"
+ }
+ },
+ "bs58": {
+ "version": "4.0.1",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.2"
+ }
+ },
+ "bs58check": {
+ "version": "2.1.2",
+ "dev": true,
+ "requires": {
+ "bs58": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "buffer": {
+ "version": "5.7.1",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "buffer-from": {
+ "version": "1.1.1",
+ "dev": true
+ },
+ "buffer-to-arraybuffer": {
+ "version": "0.0.5",
+ "dev": true,
+ "optional": true
+ },
+ "buffer-xor": {
+ "version": "1.0.3",
+ "dev": true
+ },
+ "bufferutil": {
+ "version": "4.0.3",
+ "dev": true,
+ "requires": {
+ "node-gyp-build": "^4.2.0"
+ }
+ },
+ "bytes": {
+ "version": "3.1.0",
+ "dev": true,
+ "optional": true
+ },
+ "bytewise": {
+ "version": "1.1.0",
+ "dev": true,
+ "requires": {
+ "bytewise-core": "^1.2.2",
+ "typewise": "^1.0.3"
+ }
+ },
+ "bytewise-core": {
+ "version": "1.2.3",
+ "dev": true,
+ "requires": {
+ "typewise-core": "^1.2"
+ }
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "dev": true,
+ "requires": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ }
+ },
+ "cacheable-request": {
+ "version": "6.1.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^3.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^4.1.0",
+ "responselike": "^1.0.2"
+ },
+ "dependencies": {
+ "lowercase-keys": {
+ "version": "2.0.0",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "cachedown": {
+ "version": "1.0.0",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "^2.4.1",
+ "lru-cache": "^3.2.0"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "2.7.2",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "lru-cache": {
+ "version": "3.2.0",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.1"
+ }
+ }
+ }
+ },
+ "call-bind": {
+ "version": "1.0.2",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ }
+ },
+ "caniuse-lite": {
+ "version": "1.0.30001174",
+ "dev": true
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "checkpoint-store": {
+ "version": "1.1.0",
+ "dev": true,
+ "requires": {
+ "functional-red-black-tree": "^1.0.1"
+ }
+ },
+ "chownr": {
+ "version": "1.1.4",
+ "dev": true,
+ "optional": true
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "dev": true
+ },
+ "cids": {
+ "version": "0.7.5",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "buffer": "^5.5.0",
+ "class-is": "^1.1.0",
+ "multibase": "~0.6.0",
+ "multicodec": "^1.0.0",
+ "multihashes": "~0.4.15"
+ },
+ "dependencies": {
+ "multicodec": {
+ "version": "1.0.4",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "buffer": "^5.6.0",
+ "varint": "^5.0.0"
+ }
+ }
+ }
+ },
+ "cipher-base": {
+ "version": "1.0.4",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "class-is": {
+ "version": "1.1.0",
+ "dev": true,
+ "optional": true
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "dev": true
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "dev": true
+ }
+ }
+ },
+ "clone": {
+ "version": "2.1.2",
+ "dev": true
+ },
+ "clone-response": {
+ "version": "1.0.2",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "collection-visit": {
+ "version": "1.0.0",
+ "dev": true,
+ "requires": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.8",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "component-emitter": {
+ "version": "1.3.0",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "dev": true
+ },
+ "concat-stream": {
+ "version": "1.6.2",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "content-disposition": {
+ "version": "0.5.3",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "safe-buffer": "5.1.2"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "content-hash": {
+ "version": "2.5.2",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "cids": "^0.7.1",
+ "multicodec": "^0.5.5",
+ "multihashes": "^0.4.15"
+ }
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "dev": true,
+ "optional": true
+ },
+ "convert-source-map": {
+ "version": "1.7.0",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "dev": true
+ }
+ }
+ },
+ "cookie": {
+ "version": "0.4.0",
+ "dev": true,
+ "optional": true
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "dev": true,
+ "optional": true
+ },
+ "cookiejar": {
+ "version": "2.1.2",
+ "dev": true,
+ "optional": true
+ },
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "dev": true
+ },
+ "core-js": {
+ "version": "2.6.12",
+ "dev": true
+ },
+ "core-js-pure": {
+ "version": "3.8.2",
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "dev": true
+ },
+ "cors": {
+ "version": "2.8.5",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "object-assign": "^4",
+ "vary": "^1"
+ }
+ },
+ "create-ecdh": {
+ "version": "4.0.4",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "elliptic": "^6.5.3"
+ }
+ },
+ "create-hash": {
+ "version": "1.2.0",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "inherits": "^2.0.1",
+ "md5.js": "^1.3.4",
+ "ripemd160": "^2.0.1",
+ "sha.js": "^2.4.0"
+ }
+ },
+ "create-hmac": {
+ "version": "1.1.7",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.3",
+ "create-hash": "^1.1.0",
+ "inherits": "^2.0.1",
+ "ripemd160": "^2.0.0",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "cross-fetch": {
+ "version": "2.2.3",
+ "dev": true,
+ "requires": {
+ "node-fetch": "2.1.2",
+ "whatwg-fetch": "2.0.4"
+ }
+ },
+ "crypto-browserify": {
+ "version": "3.12.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "browserify-cipher": "^1.0.0",
+ "browserify-sign": "^4.0.0",
+ "create-ecdh": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.0",
+ "diffie-hellman": "^5.0.0",
+ "inherits": "^2.0.1",
+ "pbkdf2": "^3.0.3",
+ "public-encrypt": "^4.0.0",
+ "randombytes": "^2.0.0",
+ "randomfill": "^1.0.3"
+ }
+ },
+ "d": {
+ "version": "1.0.1",
+ "dev": true,
+ "requires": {
+ "es5-ext": "^0.10.50",
+ "type": "^1.0.1"
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "debug": {
+ "version": "3.2.6",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "dev": true
+ },
+ "decompress-response": {
+ "version": "3.3.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "deep-equal": {
+ "version": "1.1.1",
+ "dev": true,
+ "requires": {
+ "is-arguments": "^1.0.4",
+ "is-date-object": "^1.0.1",
+ "is-regex": "^1.0.4",
+ "object-is": "^1.0.1",
+ "object-keys": "^1.1.1",
+ "regexp.prototype.flags": "^1.2.0"
+ }
+ },
+ "defer-to-connect": {
+ "version": "1.1.3",
+ "dev": true,
+ "optional": true
+ },
+ "deferred-leveldown": {
+ "version": "4.0.2",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "~5.0.0",
+ "inherits": "^2.0.3"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "5.0.0",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ }
+ }
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "dev": true,
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
+ "define-property": {
+ "version": "2.0.2",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ }
+ },
+ "defined": {
+ "version": "1.0.0",
+ "dev": true
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "dev": true
+ },
+ "depd": {
+ "version": "1.1.2",
+ "dev": true,
+ "optional": true
+ },
+ "des.js": {
+ "version": "1.0.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "dev": true,
+ "optional": true
+ },
+ "detect-indent": {
+ "version": "4.0.0",
+ "dev": true,
+ "requires": {
+ "repeating": "^2.0.0"
+ }
+ },
+ "diffie-hellman": {
+ "version": "5.0.3",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "miller-rabin": "^4.0.0",
+ "randombytes": "^2.0.0"
+ }
+ },
+ "dom-walk": {
+ "version": "0.1.2",
+ "dev": true
+ },
+ "dotignore": {
+ "version": "0.1.2",
+ "dev": true,
+ "requires": {
+ "minimatch": "^3.0.4"
+ }
+ },
+ "duplexer3": {
+ "version": "0.1.4",
+ "dev": true,
+ "optional": true
+ },
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "dev": true,
+ "requires": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "dev": true,
+ "optional": true
+ },
+ "electron-to-chromium": {
+ "version": "1.3.636",
+ "dev": true
+ },
+ "elliptic": {
+ "version": "6.5.3",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.4.0",
+ "brorand": "^1.0.1",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.0"
+ }
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "dev": true,
+ "optional": true
+ },
+ "encoding": {
+ "version": "0.1.13",
+ "dev": true,
+ "requires": {
+ "iconv-lite": "^0.6.2"
+ },
+ "dependencies": {
+ "iconv-lite": {
+ "version": "0.6.2",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ }
+ }
+ }
+ },
+ "encoding-down": {
+ "version": "5.0.4",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "^5.0.0",
+ "inherits": "^2.0.3",
+ "level-codec": "^9.0.0",
+ "level-errors": "^2.0.0",
+ "xtend": "^4.0.1"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "5.0.0",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ }
+ }
+ },
+ "end-of-stream": {
+ "version": "1.4.4",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "errno": {
+ "version": "0.1.8",
+ "dev": true,
+ "requires": {
+ "prr": "~1.0.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.18.0-next.1",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.2",
+ "is-negative-zero": "^2.0.0",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.1",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.1",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.53",
+ "dev": true,
+ "requires": {
+ "es6-iterator": "~2.0.3",
+ "es6-symbol": "~3.1.3",
+ "next-tick": "~1.0.0"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.3",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.3",
+ "dev": true,
+ "requires": {
+ "d": "^1.0.1",
+ "ext": "^1.1.2"
+ }
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "dev": true,
+ "optional": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "dev": true
+ },
+ "etag": {
+ "version": "1.8.1",
+ "dev": true,
+ "optional": true
+ },
+ "eth-block-tracker": {
+ "version": "3.0.1",
+ "dev": true,
+ "requires": {
+ "eth-query": "^2.1.0",
+ "ethereumjs-tx": "^1.3.3",
+ "ethereumjs-util": "^5.1.3",
+ "ethjs-util": "^0.1.3",
+ "json-rpc-engine": "^3.6.0",
+ "pify": "^2.3.0",
+ "tape": "^4.6.3"
+ },
+ "dependencies": {
+ "ethereumjs-tx": {
+ "version": "1.3.7",
+ "dev": true,
+ "requires": {
+ "ethereum-common": "^0.0.18",
+ "ethereumjs-util": "^5.0.0"
+ }
+ },
+ "ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "dev": true
+ }
+ }
+ },
+ "eth-ens-namehash": {
+ "version": "2.0.8",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "idna-uts46-hx": "^2.3.1",
+ "js-sha3": "^0.5.7"
+ }
+ },
+ "eth-json-rpc-infura": {
+ "version": "3.2.1",
+ "dev": true,
+ "requires": {
+ "cross-fetch": "^2.1.1",
+ "eth-json-rpc-middleware": "^1.5.0",
+ "json-rpc-engine": "^3.4.0",
+ "json-rpc-error": "^2.0.0"
+ }
+ },
+ "eth-json-rpc-middleware": {
+ "version": "1.6.0",
+ "dev": true,
+ "requires": {
+ "async": "^2.5.0",
+ "eth-query": "^2.1.2",
+ "eth-tx-summary": "^3.1.2",
+ "ethereumjs-block": "^1.6.0",
+ "ethereumjs-tx": "^1.3.3",
+ "ethereumjs-util": "^5.1.2",
+ "ethereumjs-vm": "^2.1.0",
+ "fetch-ponyfill": "^4.0.0",
+ "json-rpc-engine": "^3.6.0",
+ "json-rpc-error": "^2.0.0",
+ "json-stable-stringify": "^1.0.1",
+ "promise-to-callback": "^1.0.0",
+ "tape": "^4.6.3"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "2.6.3",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "deferred-leveldown": {
+ "version": "1.2.2",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "~2.6.0"
+ }
+ },
+ "ethereumjs-account": {
+ "version": "2.0.5",
+ "dev": true,
+ "requires": {
+ "ethereumjs-util": "^5.0.0",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "ethereumjs-block": {
+ "version": "1.7.1",
+ "dev": true,
+ "requires": {
+ "async": "^2.0.1",
+ "ethereum-common": "0.2.0",
+ "ethereumjs-tx": "^1.2.2",
+ "ethereumjs-util": "^5.0.0",
+ "merkle-patricia-tree": "^2.1.2"
+ },
+ "dependencies": {
+ "ethereum-common": {
+ "version": "0.2.0",
+ "dev": true
+ }
+ }
+ },
+ "ethereumjs-tx": {
+ "version": "1.3.7",
+ "dev": true,
+ "requires": {
+ "ethereum-common": "^0.0.18",
+ "ethereumjs-util": "^5.0.0"
+ }
+ },
+ "ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "ethereumjs-vm": {
+ "version": "2.6.0",
+ "dev": true,
+ "requires": {
+ "async": "^2.1.2",
+ "async-eventemitter": "^0.2.2",
+ "ethereumjs-account": "^2.0.3",
+ "ethereumjs-block": "~2.2.0",
+ "ethereumjs-common": "^1.1.0",
+ "ethereumjs-util": "^6.0.0",
+ "fake-merkle-patricia-tree": "^1.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "merkle-patricia-tree": "^2.3.2",
+ "rustbn.js": "~0.2.0",
+ "safe-buffer": "^5.1.1"
+ },
+ "dependencies": {
+ "ethereumjs-block": {
+ "version": "2.2.2",
+ "dev": true,
+ "requires": {
+ "async": "^2.0.1",
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-tx": "^2.1.1",
+ "ethereumjs-util": "^5.0.0",
+ "merkle-patricia-tree": "^2.1.2"
+ },
+ "dependencies": {
+ "ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ }
+ }
+ },
+ "ethereumjs-tx": {
+ "version": "2.1.2",
+ "dev": true,
+ "requires": {
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-util": "^6.0.0"
+ }
+ },
+ "ethereumjs-util": {
+ "version": "6.2.1",
+ "dev": true,
+ "requires": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "0.1.6",
+ "rlp": "^2.2.3"
+ }
+ }
+ }
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "dev": true
+ },
+ "level-codec": {
+ "version": "7.0.1",
+ "dev": true
+ },
+ "level-errors": {
+ "version": "1.0.5",
+ "dev": true,
+ "requires": {
+ "errno": "~0.1.1"
+ }
+ },
+ "level-iterator-stream": {
+ "version": "1.3.1",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "level-errors": "^1.0.3",
+ "readable-stream": "^1.0.33",
+ "xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.1.14",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ }
+ }
+ },
+ "level-ws": {
+ "version": "0.0.0",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~1.0.15",
+ "xtend": "~2.1.1"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.0.34",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "xtend": {
+ "version": "2.1.2",
+ "dev": true,
+ "requires": {
+ "object-keys": "~0.4.0"
+ }
+ }
+ }
+ },
+ "levelup": {
+ "version": "1.3.9",
+ "dev": true,
+ "requires": {
+ "deferred-leveldown": "~1.2.1",
+ "level-codec": "~7.0.0",
+ "level-errors": "~1.0.3",
+ "level-iterator-stream": "~1.3.0",
+ "prr": "~1.0.1",
+ "semver": "~5.4.1",
+ "xtend": "~4.0.0"
+ }
+ },
+ "ltgt": {
+ "version": "2.2.1",
+ "dev": true
+ },
+ "memdown": {
+ "version": "1.4.1",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "~2.7.1",
+ "functional-red-black-tree": "^1.0.1",
+ "immediate": "^3.2.3",
+ "inherits": "~2.0.1",
+ "ltgt": "~2.2.0",
+ "safe-buffer": "~5.1.1"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "2.7.2",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ }
+ }
+ },
+ "merkle-patricia-tree": {
+ "version": "2.3.2",
+ "dev": true,
+ "requires": {
+ "async": "^1.4.2",
+ "ethereumjs-util": "^5.0.0",
+ "level-ws": "0.0.0",
+ "levelup": "^1.2.1",
+ "memdown": "^1.0.0",
+ "readable-stream": "^2.0.0",
+ "rlp": "^2.0.0",
+ "semaphore": ">=1.0.1"
+ },
+ "dependencies": {
+ "async": {
+ "version": "1.5.2",
+ "dev": true
+ }
+ }
+ },
+ "object-keys": {
+ "version": "0.4.0",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.4.1",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "dev": true
+ }
+ }
+ },
+ "eth-lib": {
+ "version": "0.1.29",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bn.js": "^4.11.6",
+ "elliptic": "^6.4.0",
+ "nano-json-stream-parser": "^0.1.2",
+ "servify": "^0.1.12",
+ "ws": "^3.0.0",
+ "xhr-request-promise": "^0.1.2"
+ }
+ },
+ "eth-query": {
+ "version": "2.1.2",
+ "dev": true,
+ "requires": {
+ "json-rpc-random-id": "^1.0.0",
+ "xtend": "^4.0.1"
+ }
+ },
+ "eth-sig-util": {
+ "version": "3.0.0",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.2.1",
+ "elliptic": "^6.4.0",
+ "ethereumjs-abi": "0.6.5",
+ "ethereumjs-util": "^5.1.1",
+ "tweetnacl": "^1.0.0",
+ "tweetnacl-util": "^0.15.0"
+ },
+ "dependencies": {
+ "ethereumjs-abi": {
+ "version": "0.6.5",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.10.0",
+ "ethereumjs-util": "^4.3.0"
+ },
+ "dependencies": {
+ "ethereumjs-util": {
+ "version": "4.5.1",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.8.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "rlp": "^2.0.0"
+ }
+ }
+ }
+ },
+ "ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ }
+ }
+ },
+ "eth-tx-summary": {
+ "version": "3.2.4",
+ "dev": true,
+ "requires": {
+ "async": "^2.1.2",
+ "clone": "^2.0.0",
+ "concat-stream": "^1.5.1",
+ "end-of-stream": "^1.1.0",
+ "eth-query": "^2.0.2",
+ "ethereumjs-block": "^1.4.1",
+ "ethereumjs-tx": "^1.1.1",
+ "ethereumjs-util": "^5.0.1",
+ "ethereumjs-vm": "^2.6.0",
+ "through2": "^2.0.3"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "2.6.3",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "deferred-leveldown": {
+ "version": "1.2.2",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "~2.6.0"
+ }
+ },
+ "ethereumjs-account": {
+ "version": "2.0.5",
+ "dev": true,
+ "requires": {
+ "ethereumjs-util": "^5.0.0",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "ethereumjs-block": {
+ "version": "1.7.1",
+ "dev": true,
+ "requires": {
+ "async": "^2.0.1",
+ "ethereum-common": "0.2.0",
+ "ethereumjs-tx": "^1.2.2",
+ "ethereumjs-util": "^5.0.0",
+ "merkle-patricia-tree": "^2.1.2"
+ },
+ "dependencies": {
+ "ethereum-common": {
+ "version": "0.2.0",
+ "dev": true
+ }
+ }
+ },
+ "ethereumjs-tx": {
+ "version": "1.3.7",
+ "dev": true,
+ "requires": {
+ "ethereum-common": "^0.0.18",
+ "ethereumjs-util": "^5.0.0"
+ }
+ },
+ "ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "ethereumjs-vm": {
+ "version": "2.6.0",
+ "dev": true,
+ "requires": {
+ "async": "^2.1.2",
+ "async-eventemitter": "^0.2.2",
+ "ethereumjs-account": "^2.0.3",
+ "ethereumjs-block": "~2.2.0",
+ "ethereumjs-common": "^1.1.0",
+ "ethereumjs-util": "^6.0.0",
+ "fake-merkle-patricia-tree": "^1.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "merkle-patricia-tree": "^2.3.2",
+ "rustbn.js": "~0.2.0",
+ "safe-buffer": "^5.1.1"
+ },
+ "dependencies": {
+ "ethereumjs-block": {
+ "version": "2.2.2",
+ "dev": true,
+ "requires": {
+ "async": "^2.0.1",
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-tx": "^2.1.1",
+ "ethereumjs-util": "^5.0.0",
+ "merkle-patricia-tree": "^2.1.2"
+ },
+ "dependencies": {
+ "ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ }
+ }
+ },
+ "ethereumjs-tx": {
+ "version": "2.1.2",
+ "dev": true,
+ "requires": {
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-util": "^6.0.0"
+ }
+ },
+ "ethereumjs-util": {
+ "version": "6.2.1",
+ "dev": true,
+ "requires": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "0.1.6",
+ "rlp": "^2.2.3"
+ }
+ }
+ }
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "dev": true
+ },
+ "level-codec": {
+ "version": "7.0.1",
+ "dev": true
+ },
+ "level-errors": {
+ "version": "1.0.5",
+ "dev": true,
+ "requires": {
+ "errno": "~0.1.1"
+ }
+ },
+ "level-iterator-stream": {
+ "version": "1.3.1",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "level-errors": "^1.0.3",
+ "readable-stream": "^1.0.33",
+ "xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.1.14",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ }
+ }
+ },
+ "level-ws": {
+ "version": "0.0.0",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~1.0.15",
+ "xtend": "~2.1.1"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.0.34",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "xtend": {
+ "version": "2.1.2",
+ "dev": true,
+ "requires": {
+ "object-keys": "~0.4.0"
+ }
+ }
+ }
+ },
+ "levelup": {
+ "version": "1.3.9",
+ "dev": true,
+ "requires": {
+ "deferred-leveldown": "~1.2.1",
+ "level-codec": "~7.0.0",
+ "level-errors": "~1.0.3",
+ "level-iterator-stream": "~1.3.0",
+ "prr": "~1.0.1",
+ "semver": "~5.4.1",
+ "xtend": "~4.0.0"
+ }
+ },
+ "ltgt": {
+ "version": "2.2.1",
+ "dev": true
+ },
+ "memdown": {
+ "version": "1.4.1",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "~2.7.1",
+ "functional-red-black-tree": "^1.0.1",
+ "immediate": "^3.2.3",
+ "inherits": "~2.0.1",
+ "ltgt": "~2.2.0",
+ "safe-buffer": "~5.1.1"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "2.7.2",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ }
+ }
+ },
+ "merkle-patricia-tree": {
+ "version": "2.3.2",
+ "dev": true,
+ "requires": {
+ "async": "^1.4.2",
+ "ethereumjs-util": "^5.0.0",
+ "level-ws": "0.0.0",
+ "levelup": "^1.2.1",
+ "memdown": "^1.0.0",
+ "readable-stream": "^2.0.0",
+ "rlp": "^2.0.0",
+ "semaphore": ">=1.0.1"
+ },
+ "dependencies": {
+ "async": {
+ "version": "1.5.2",
+ "dev": true
+ }
+ }
+ },
+ "object-keys": {
+ "version": "0.4.0",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.4.1",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "dev": true
+ }
+ }
+ },
+ "ethashjs": {
+ "version": "0.0.8",
+ "dev": true,
+ "requires": {
+ "async": "^2.1.2",
+ "buffer-xor": "^2.0.1",
+ "ethereumjs-util": "^7.0.2",
+ "miller-rabin": "^4.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "5.1.3",
+ "dev": true
+ },
+ "buffer-xor": {
+ "version": "2.0.2",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "ethereumjs-util": {
+ "version": "7.0.7",
+ "dev": true,
+ "requires": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^5.1.2",
+ "create-hash": "^1.1.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "0.1.6",
+ "rlp": "^2.2.4"
+ }
+ }
+ }
+ },
+ "ethereum-bloom-filters": {
+ "version": "1.0.7",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "js-sha3": "^0.8.0"
+ },
+ "dependencies": {
+ "js-sha3": {
+ "version": "0.8.0",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "ethereum-common": {
+ "version": "0.0.18",
+ "dev": true
+ },
+ "ethereum-cryptography": {
+ "version": "0.1.3",
+ "dev": true,
+ "requires": {
+ "@types/pbkdf2": "^3.0.0",
+ "@types/secp256k1": "^4.0.1",
+ "blakejs": "^1.1.0",
+ "browserify-aes": "^1.2.0",
+ "bs58check": "^2.1.2",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "hash.js": "^1.1.7",
+ "keccak": "^3.0.0",
+ "pbkdf2": "^3.0.17",
+ "randombytes": "^2.1.0",
+ "safe-buffer": "^5.1.2",
+ "scrypt-js": "^3.0.0",
+ "secp256k1": "^4.0.1",
+ "setimmediate": "^1.0.5"
+ }
+ },
+ "ethereumjs-abi": {
+ "version": "0.6.8",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.11.8",
+ "ethereumjs-util": "^6.0.0"
+ }
+ },
+ "ethereumjs-account": {
+ "version": "3.0.0",
+ "dev": true,
+ "requires": {
+ "ethereumjs-util": "^6.0.0",
+ "rlp": "^2.2.1",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "ethereumjs-block": {
+ "version": "2.2.2",
+ "dev": true,
+ "requires": {
+ "async": "^2.0.1",
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-tx": "^2.1.1",
+ "ethereumjs-util": "^5.0.0",
+ "merkle-patricia-tree": "^2.1.2"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "2.6.3",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "deferred-leveldown": {
+ "version": "1.2.2",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "~2.6.0"
+ }
+ },
+ "ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "dev": true
+ },
+ "level-codec": {
+ "version": "7.0.1",
+ "dev": true
+ },
+ "level-errors": {
+ "version": "1.0.5",
+ "dev": true,
+ "requires": {
+ "errno": "~0.1.1"
+ }
+ },
+ "level-iterator-stream": {
+ "version": "1.3.1",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "level-errors": "^1.0.3",
+ "readable-stream": "^1.0.33",
+ "xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.1.14",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ }
+ }
+ },
+ "level-ws": {
+ "version": "0.0.0",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~1.0.15",
+ "xtend": "~2.1.1"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.0.34",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "xtend": {
+ "version": "2.1.2",
+ "dev": true,
+ "requires": {
+ "object-keys": "~0.4.0"
+ }
+ }
+ }
+ },
+ "levelup": {
+ "version": "1.3.9",
+ "dev": true,
+ "requires": {
+ "deferred-leveldown": "~1.2.1",
+ "level-codec": "~7.0.0",
+ "level-errors": "~1.0.3",
+ "level-iterator-stream": "~1.3.0",
+ "prr": "~1.0.1",
+ "semver": "~5.4.1",
+ "xtend": "~4.0.0"
+ }
+ },
+ "ltgt": {
+ "version": "2.2.1",
+ "dev": true
+ },
+ "memdown": {
+ "version": "1.4.1",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "~2.7.1",
+ "functional-red-black-tree": "^1.0.1",
+ "immediate": "^3.2.3",
+ "inherits": "~2.0.1",
+ "ltgt": "~2.2.0",
+ "safe-buffer": "~5.1.1"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "2.7.2",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ }
+ }
+ },
+ "merkle-patricia-tree": {
+ "version": "2.3.2",
+ "dev": true,
+ "requires": {
+ "async": "^1.4.2",
+ "ethereumjs-util": "^5.0.0",
+ "level-ws": "0.0.0",
+ "levelup": "^1.2.1",
+ "memdown": "^1.0.0",
+ "readable-stream": "^2.0.0",
+ "rlp": "^2.0.0",
+ "semaphore": ">=1.0.1"
+ },
+ "dependencies": {
+ "async": {
+ "version": "1.5.2",
+ "dev": true
+ }
+ }
+ },
+ "object-keys": {
+ "version": "0.4.0",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.4.1",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "dev": true
+ }
+ }
+ },
+ "ethereumjs-blockchain": {
+ "version": "4.0.4",
+ "dev": true,
+ "requires": {
+ "async": "^2.6.1",
+ "ethashjs": "~0.0.7",
+ "ethereumjs-block": "~2.2.2",
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-util": "^6.1.0",
+ "flow-stoplight": "^1.0.0",
+ "level-mem": "^3.0.1",
+ "lru-cache": "^5.1.1",
+ "rlp": "^2.2.2",
+ "semaphore": "^1.1.0"
+ }
+ },
+ "ethereumjs-common": {
+ "version": "1.5.0",
+ "dev": true
+ },
+ "ethereumjs-tx": {
+ "version": "2.1.2",
+ "dev": true,
+ "requires": {
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-util": "^6.0.0"
+ }
+ },
+ "ethereumjs-util": {
+ "version": "6.2.1",
+ "dev": true,
+ "requires": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "0.1.6",
+ "rlp": "^2.2.3"
+ }
+ },
+ "ethereumjs-vm": {
+ "version": "4.2.0",
+ "dev": true,
+ "requires": {
+ "async": "^2.1.2",
+ "async-eventemitter": "^0.2.2",
+ "core-js-pure": "^3.0.1",
+ "ethereumjs-account": "^3.0.0",
+ "ethereumjs-block": "^2.2.2",
+ "ethereumjs-blockchain": "^4.0.3",
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-tx": "^2.1.2",
+ "ethereumjs-util": "^6.2.0",
+ "fake-merkle-patricia-tree": "^1.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "merkle-patricia-tree": "^2.3.2",
+ "rustbn.js": "~0.2.0",
+ "safe-buffer": "^5.1.1",
+ "util.promisify": "^1.0.0"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "2.6.3",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "deferred-leveldown": {
+ "version": "1.2.2",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "~2.6.0"
+ }
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "dev": true
+ },
+ "level-codec": {
+ "version": "7.0.1",
+ "dev": true
+ },
+ "level-errors": {
+ "version": "1.0.5",
+ "dev": true,
+ "requires": {
+ "errno": "~0.1.1"
+ }
+ },
+ "level-iterator-stream": {
+ "version": "1.3.1",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "level-errors": "^1.0.3",
+ "readable-stream": "^1.0.33",
+ "xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.1.14",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ }
+ }
+ },
+ "level-ws": {
+ "version": "0.0.0",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~1.0.15",
+ "xtend": "~2.1.1"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.0.34",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "xtend": {
+ "version": "2.1.2",
+ "dev": true,
+ "requires": {
+ "object-keys": "~0.4.0"
+ }
+ }
+ }
+ },
+ "levelup": {
+ "version": "1.3.9",
+ "dev": true,
+ "requires": {
+ "deferred-leveldown": "~1.2.1",
+ "level-codec": "~7.0.0",
+ "level-errors": "~1.0.3",
+ "level-iterator-stream": "~1.3.0",
+ "prr": "~1.0.1",
+ "semver": "~5.4.1",
+ "xtend": "~4.0.0"
+ }
+ },
+ "ltgt": {
+ "version": "2.2.1",
+ "dev": true
+ },
+ "memdown": {
+ "version": "1.4.1",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "~2.7.1",
+ "functional-red-black-tree": "^1.0.1",
+ "immediate": "^3.2.3",
+ "inherits": "~2.0.1",
+ "ltgt": "~2.2.0",
+ "safe-buffer": "~5.1.1"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "2.7.2",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ }
+ }
+ },
+ "merkle-patricia-tree": {
+ "version": "2.3.2",
+ "dev": true,
+ "requires": {
+ "async": "^1.4.2",
+ "ethereumjs-util": "^5.0.0",
+ "level-ws": "0.0.0",
+ "levelup": "^1.2.1",
+ "memdown": "^1.0.0",
+ "readable-stream": "^2.0.0",
+ "rlp": "^2.0.0",
+ "semaphore": ">=1.0.1"
+ },
+ "dependencies": {
+ "async": {
+ "version": "1.5.2",
+ "dev": true
+ },
+ "ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ }
+ }
+ },
+ "object-keys": {
+ "version": "0.4.0",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.4.1",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "dev": true
+ }
+ }
+ },
+ "ethereumjs-wallet": {
+ "version": "0.6.5",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "aes-js": "^3.1.1",
+ "bs58check": "^2.1.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethereumjs-util": "^6.0.0",
+ "randombytes": "^2.0.6",
+ "safe-buffer": "^5.1.2",
+ "scryptsy": "^1.2.1",
+ "utf8": "^3.0.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "ethjs-unit": {
+ "version": "0.1.6",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bn.js": "4.11.6",
+ "number-to-bn": "1.7.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.6",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "ethjs-util": {
+ "version": "0.1.6",
+ "dev": true,
+ "requires": {
+ "is-hex-prefixed": "1.0.0",
+ "strip-hex-prefix": "1.0.0"
+ }
+ },
+ "eventemitter3": {
+ "version": "4.0.4",
+ "dev": true,
+ "optional": true
+ },
+ "events": {
+ "version": "3.2.0",
+ "dev": true
+ },
+ "evp_bytestokey": {
+ "version": "1.0.3",
+ "dev": true,
+ "requires": {
+ "md5.js": "^1.3.4",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "dev": true
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.0.0",
+ "dev": true
+ }
+ }
+ },
+ "express": {
+ "version": "4.17.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "accepts": "~1.3.7",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.19.0",
+ "content-disposition": "0.5.3",
+ "content-type": "~1.0.4",
+ "cookie": "0.4.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "~1.1.2",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.5",
+ "qs": "6.7.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.1.2",
+ "send": "0.17.1",
+ "serve-static": "1.14.1",
+ "setprototypeof": "1.1.1",
+ "statuses": "~1.5.0",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "dev": true,
+ "optional": true
+ },
+ "qs": {
+ "version": "6.7.0",
+ "dev": true,
+ "optional": true
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "ext": {
+ "version": "1.4.0",
+ "dev": true,
+ "requires": {
+ "type": "^2.0.0"
+ },
+ "dependencies": {
+ "type": {
+ "version": "2.1.0",
+ "dev": true
+ }
+ }
+ },
+ "extend": {
+ "version": "3.0.2",
+ "dev": true
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "dev": true
+ }
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "dev": true
+ },
+ "fake-merkle-patricia-tree": {
+ "version": "1.0.1",
+ "dev": true,
+ "requires": {
+ "checkpoint-store": "^1.1.0"
+ }
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "dev": true
+ },
+ "fetch-ponyfill": {
+ "version": "4.1.0",
+ "dev": true,
+ "requires": {
+ "node-fetch": "~1.7.1"
+ },
+ "dependencies": {
+ "is-stream": {
+ "version": "1.1.0",
+ "dev": true
+ },
+ "node-fetch": {
+ "version": "1.7.3",
+ "dev": true,
+ "requires": {
+ "encoding": "^0.1.11",
+ "is-stream": "^1.0.1"
+ }
+ }
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.2",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "find-yarn-workspace-root": {
+ "version": "1.2.1",
+ "dev": true,
+ "requires": {
+ "fs-extra": "^4.0.3",
+ "micromatch": "^3.1.4"
+ },
+ "dependencies": {
+ "braces": {
+ "version": "2.3.2",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fs-extra": {
+ "version": "4.0.3",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "dev": true
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "dev": true
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ }
+ }
+ }
+ },
+ "flow-stoplight": {
+ "version": "1.0.0",
+ "dev": true
+ },
+ "for-each": {
+ "version": "0.3.3",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.3.3",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "dev": true,
+ "optional": true
+ },
+ "fragment-cache": {
+ "version": "0.2.1",
+ "dev": true,
+ "requires": {
+ "map-cache": "^0.2.2"
+ }
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "dev": true,
+ "optional": true
+ },
+ "fs-extra": {
+ "version": "7.0.1",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "dev": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "dev": true
+ },
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "dev": true
+ },
+ "get-intrinsic": {
+ "version": "1.0.2",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "get-stream": {
+ "version": "5.2.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "dev": true
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.3",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "global": {
+ "version": "4.4.0",
+ "dev": true,
+ "requires": {
+ "min-document": "^2.19.0",
+ "process": "^0.11.10"
+ }
+ },
+ "got": {
+ "version": "9.6.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@sindresorhus/is": "^0.14.0",
+ "@szmarczak/http-timer": "^1.1.2",
+ "cacheable-request": "^6.0.0",
+ "decompress-response": "^3.3.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^4.1.0",
+ "lowercase-keys": "^1.0.1",
+ "mimic-response": "^1.0.1",
+ "p-cancelable": "^1.0.0",
+ "to-readable-stream": "^1.0.0",
+ "url-parse-lax": "^3.0.0"
+ },
+ "dependencies": {
+ "get-stream": {
+ "version": "4.1.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ }
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.4",
+ "dev": true
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "dev": true
+ },
+ "har-validator": {
+ "version": "5.1.5",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.12.3",
+ "har-schema": "^2.0.0"
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "dev": true
+ }
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "dev": true
+ },
+ "has-symbol-support-x": {
+ "version": "1.4.2",
+ "dev": true,
+ "optional": true
+ },
+ "has-symbols": {
+ "version": "1.0.1",
+ "dev": true
+ },
+ "has-to-string-tag-x": {
+ "version": "1.4.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "has-symbol-support-x": "^1.4.1"
+ }
+ },
+ "has-value": {
+ "version": "1.0.0",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "1.1.6",
+ "dev": true
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "kind-of": {
+ "version": "4.0.0",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "hash-base": {
+ "version": "3.1.0",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.0",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
+ "hash.js": {
+ "version": "1.1.7",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.1"
+ }
+ },
+ "heap": {
+ "version": "0.2.6",
+ "dev": true
+ },
+ "hmac-drbg": {
+ "version": "1.0.1",
+ "dev": true,
+ "requires": {
+ "hash.js": "^1.0.3",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "home-or-tmp": {
+ "version": "2.0.0",
+ "dev": true,
+ "requires": {
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.1"
+ }
+ },
+ "http-cache-semantics": {
+ "version": "4.1.0",
+ "dev": true,
+ "optional": true
+ },
+ "http-errors": {
+ "version": "1.7.2",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.3",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "http-https": {
+ "version": "1.0.0",
+ "dev": true,
+ "optional": true
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "idna-uts46-hx": {
+ "version": "2.3.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "punycode": "2.1.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "2.1.0",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "ieee754": {
+ "version": "1.2.1",
+ "dev": true
+ },
+ "immediate": {
+ "version": "3.2.3",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "dev": true
+ },
+ "invariant": {
+ "version": "2.2.4",
+ "dev": true,
+ "requires": {
+ "loose-envify": "^1.0.0"
+ }
+ },
+ "ipaddr.js": {
+ "version": "1.9.1",
+ "dev": true,
+ "optional": true
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-arguments": {
+ "version": "1.1.0",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0"
+ }
+ },
+ "is-callable": {
+ "version": "1.2.2",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-date-object": {
+ "version": "1.0.2",
+ "dev": true
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ },
+ "is-finite": {
+ "version": "1.1.0",
+ "dev": true
+ },
+ "is-fn": {
+ "version": "1.0.0",
+ "dev": true
+ },
+ "is-function": {
+ "version": "1.0.2",
+ "dev": true
+ },
+ "is-hex-prefixed": {
+ "version": "1.0.0",
+ "dev": true
+ },
+ "is-negative-zero": {
+ "version": "2.0.1",
+ "dev": true
+ },
+ "is-object": {
+ "version": "1.0.2",
+ "dev": true,
+ "optional": true
+ },
+ "is-plain-obj": {
+ "version": "1.1.0",
+ "dev": true,
+ "optional": true
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "is-regex": {
+ "version": "1.1.1",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "is-retry-allowed": {
+ "version": "1.2.0",
+ "dev": true,
+ "optional": true
+ },
+ "is-symbol": {
+ "version": "1.0.3",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "dev": true
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "dev": true
+ },
+ "isurl": {
+ "version": "1.0.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "has-to-string-tag-x": "^1.2.0",
+ "is-object": "^1.0.1"
+ }
+ },
+ "js-sha3": {
+ "version": "0.5.7",
+ "dev": true,
+ "optional": true
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "dev": true
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "dev": true
+ },
+ "json-buffer": {
+ "version": "3.0.0",
+ "dev": true,
+ "optional": true
+ },
+ "json-rpc-engine": {
+ "version": "3.8.0",
+ "dev": true,
+ "requires": {
+ "async": "^2.0.1",
+ "babel-preset-env": "^1.7.0",
+ "babelify": "^7.3.0",
+ "json-rpc-error": "^2.0.0",
+ "promise-to-callback": "^1.0.0",
+ "safe-event-emitter": "^1.0.1"
+ }
+ },
+ "json-rpc-error": {
+ "version": "2.0.0",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1"
+ }
+ },
+ "json-rpc-random-id": {
+ "version": "1.0.1",
+ "dev": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "dev": true
+ },
+ "json-stable-stringify": {
+ "version": "1.0.1",
+ "dev": true,
+ "requires": {
+ "jsonify": "~0.0.0"
+ }
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "dev": true
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "jsonify": {
+ "version": "0.0.0",
+ "dev": true
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "keccak": {
+ "version": "3.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "node-addon-api": "^2.0.0",
+ "node-gyp-build": "^4.2.0"
+ }
+ },
+ "keyv": {
+ "version": "3.1.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "json-buffer": "3.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "dev": true
+ },
+ "klaw-sync": {
+ "version": "6.0.0",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.11"
+ }
+ },
+ "level-codec": {
+ "version": "9.0.2",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.6.0"
+ }
+ },
+ "level-errors": {
+ "version": "2.0.1",
+ "dev": true,
+ "requires": {
+ "errno": "~0.1.1"
+ }
+ },
+ "level-iterator-stream": {
+ "version": "2.0.3",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.5",
+ "xtend": "^4.0.0"
+ }
+ },
+ "level-mem": {
+ "version": "3.0.1",
+ "dev": true,
+ "requires": {
+ "level-packager": "~4.0.0",
+ "memdown": "~3.0.0"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "5.0.0",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "ltgt": {
+ "version": "2.2.1",
+ "dev": true
+ },
+ "memdown": {
+ "version": "3.0.0",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "~5.0.0",
+ "functional-red-black-tree": "~1.0.1",
+ "immediate": "~3.2.3",
+ "inherits": "~2.0.1",
+ "ltgt": "~2.2.0",
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "dev": true
+ }
+ }
+ },
+ "level-packager": {
+ "version": "4.0.1",
+ "dev": true,
+ "requires": {
+ "encoding-down": "~5.0.0",
+ "levelup": "^3.0.0"
+ }
+ },
+ "level-post": {
+ "version": "1.0.7",
+ "dev": true,
+ "requires": {
+ "ltgt": "^2.1.2"
+ }
+ },
+ "level-sublevel": {
+ "version": "6.6.4",
+ "dev": true,
+ "requires": {
+ "bytewise": "~1.1.0",
+ "level-codec": "^9.0.0",
+ "level-errors": "^2.0.0",
+ "level-iterator-stream": "^2.0.3",
+ "ltgt": "~2.1.1",
+ "pull-defer": "^0.2.2",
+ "pull-level": "^2.0.3",
+ "pull-stream": "^3.6.8",
+ "typewiselite": "~1.0.0",
+ "xtend": "~4.0.0"
+ }
+ },
+ "level-ws": {
+ "version": "1.0.0",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.8",
+ "xtend": "^4.0.1"
+ }
+ },
+ "levelup": {
+ "version": "3.1.1",
+ "dev": true,
+ "requires": {
+ "deferred-leveldown": "~4.0.0",
+ "level-errors": "~2.0.0",
+ "level-iterator-stream": "~3.0.0",
+ "xtend": "~4.0.0"
+ },
+ "dependencies": {
+ "level-iterator-stream": {
+ "version": "3.0.1",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.3.6",
+ "xtend": "^4.0.0"
+ }
+ }
+ }
+ },
+ "lodash": {
+ "version": "4.17.20",
+ "dev": true
+ },
+ "looper": {
+ "version": "2.0.0",
+ "dev": true
+ },
+ "loose-envify": {
+ "version": "1.4.0",
+ "dev": true,
+ "requires": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ }
+ },
+ "lowercase-keys": {
+ "version": "1.0.1",
+ "dev": true,
+ "optional": true
+ },
+ "lru-cache": {
+ "version": "5.1.1",
+ "dev": true,
+ "requires": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "ltgt": {
+ "version": "2.1.3",
+ "dev": true
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "dev": true
+ },
+ "map-visit": {
+ "version": "1.0.0",
+ "dev": true,
+ "requires": {
+ "object-visit": "^1.0.0"
+ }
+ },
+ "md5.js": {
+ "version": "1.3.5",
+ "dev": true,
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "dev": true,
+ "optional": true
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "dev": true,
+ "optional": true
+ },
+ "merkle-patricia-tree": {
+ "version": "3.0.0",
+ "dev": true,
+ "requires": {
+ "async": "^2.6.1",
+ "ethereumjs-util": "^5.2.0",
+ "level-mem": "^3.0.1",
+ "level-ws": "^1.0.0",
+ "readable-stream": "^3.0.6",
+ "rlp": "^2.0.0",
+ "semaphore": ">=1.0.1"
+ },
+ "dependencies": {
+ "ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
+ "methods": {
+ "version": "1.1.2",
+ "dev": true,
+ "optional": true
+ },
+ "miller-rabin": {
+ "version": "4.0.1",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.0.0",
+ "brorand": "^1.0.1"
+ }
+ },
+ "mime": {
+ "version": "1.6.0",
+ "dev": true,
+ "optional": true
+ },
+ "mime-db": {
+ "version": "1.45.0",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.28",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.45.0"
+ }
+ },
+ "mimic-response": {
+ "version": "1.0.1",
+ "dev": true,
+ "optional": true
+ },
+ "min-document": {
+ "version": "2.19.0",
+ "dev": true,
+ "requires": {
+ "dom-walk": "^0.1.0"
+ }
+ },
+ "minimalistic-assert": {
+ "version": "1.0.1",
+ "dev": true
+ },
+ "minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "dev": true
+ },
+ "minizlib": {
+ "version": "1.3.3",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "minipass": "^2.9.0"
+ },
+ "dependencies": {
+ "minipass": {
+ "version": "2.9.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.0"
+ }
+ }
+ }
+ },
+ "mixin-deep": {
+ "version": "1.3.2",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.5",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ },
+ "mkdirp-promise": {
+ "version": "5.0.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "mkdirp": "*"
+ }
+ },
+ "mock-fs": {
+ "version": "4.13.0",
+ "dev": true,
+ "optional": true
+ },
+ "ms": {
+ "version": "2.1.3",
+ "dev": true
+ },
+ "multibase": {
+ "version": "0.6.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ },
+ "multicodec": {
+ "version": "0.5.7",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "varint": "^5.0.0"
+ }
+ },
+ "multihashes": {
+ "version": "0.4.21",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "buffer": "^5.5.0",
+ "multibase": "^0.7.0",
+ "varint": "^5.0.0"
+ },
+ "dependencies": {
+ "multibase": {
+ "version": "0.7.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ }
+ }
+ },
+ "nano-json-stream-parser": {
+ "version": "0.1.2",
+ "dev": true,
+ "optional": true
+ },
+ "nanomatch": {
+ "version": "1.2.13",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ }
+ },
+ "negotiator": {
+ "version": "0.6.2",
+ "dev": true,
+ "optional": true
+ },
+ "next-tick": {
+ "version": "1.0.0",
+ "dev": true
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "dev": true
+ },
+ "node-addon-api": {
+ "version": "2.0.2",
+ "bundled": true,
+ "dev": true
+ },
+ "node-fetch": {
+ "version": "2.1.2",
+ "dev": true
+ },
+ "node-gyp-build": {
+ "version": "4.2.3",
+ "bundled": true,
+ "dev": true
+ },
+ "normalize-url": {
+ "version": "4.5.0",
+ "dev": true,
+ "optional": true
+ },
+ "number-to-bn": {
+ "version": "1.7.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bn.js": "4.11.6",
+ "strip-hex-prefix": "1.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.6",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "dev": true
+ },
+ "object-copy": {
+ "version": "0.1.0",
+ "dev": true,
+ "requires": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "dev": true
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "dev": true
+ }
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "object-inspect": {
+ "version": "1.9.0",
+ "dev": true
+ },
+ "object-is": {
+ "version": "1.1.4",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3"
+ }
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "dev": true
+ },
+ "object-visit": {
+ "version": "1.0.1",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.0"
+ }
+ },
+ "object.assign": {
+ "version": "4.1.2",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "object.getownpropertydescriptors": {
+ "version": "2.1.1",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.1"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "oboe": {
+ "version": "2.1.4",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "http-https": "^1.0.0"
+ }
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "dev": true
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "dev": true
+ },
+ "p-cancelable": {
+ "version": "1.1.0",
+ "dev": true,
+ "optional": true
+ },
+ "p-timeout": {
+ "version": "1.2.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "p-finally": "^1.0.0"
+ },
+ "dependencies": {
+ "p-finally": {
+ "version": "1.0.0",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "parse-asn1": {
+ "version": "5.1.6",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "asn1.js": "^5.2.0",
+ "browserify-aes": "^1.0.0",
+ "evp_bytestokey": "^1.0.0",
+ "pbkdf2": "^3.0.3",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "parse-headers": {
+ "version": "2.0.3",
+ "dev": true
+ },
+ "parseurl": {
+ "version": "1.3.3",
+ "dev": true,
+ "optional": true
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "dev": true
+ },
+ "patch-package": {
+ "version": "6.2.2",
+ "dev": true,
+ "requires": {
+ "@yarnpkg/lockfile": "^1.1.0",
+ "chalk": "^2.4.2",
+ "cross-spawn": "^6.0.5",
+ "find-yarn-workspace-root": "^1.2.1",
+ "fs-extra": "^7.0.1",
+ "is-ci": "^2.0.0",
+ "klaw-sync": "^6.0.0",
+ "minimist": "^1.2.0",
+ "rimraf": "^2.6.3",
+ "semver": "^5.6.0",
+ "slash": "^2.0.0",
+ "tmp": "^0.0.33"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "6.0.5",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.7.1",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "dev": true
+ },
+ "slash": {
+ "version": "2.0.0",
+ "dev": true
+ },
+ "tmp": {
+ "version": "0.0.33",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "~1.0.2"
+ }
+ },
+ "which": {
+ "version": "1.3.1",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.6",
+ "dev": true
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "dev": true,
+ "optional": true
+ },
+ "pbkdf2": {
+ "version": "3.1.1",
+ "dev": true,
+ "requires": {
+ "create-hash": "^1.1.2",
+ "create-hmac": "^1.1.4",
+ "ripemd160": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "dev": true
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "dev": true
+ },
+ "precond": {
+ "version": "0.2.3",
+ "dev": true
+ },
+ "prepend-http": {
+ "version": "2.0.0",
+ "dev": true,
+ "optional": true
+ },
+ "private": {
+ "version": "0.1.8",
+ "dev": true
+ },
+ "process": {
+ "version": "0.11.10",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "dev": true
+ },
+ "promise-to-callback": {
+ "version": "1.0.0",
+ "dev": true,
+ "requires": {
+ "is-fn": "^1.0.0",
+ "set-immediate-shim": "^1.0.1"
+ }
+ },
+ "proxy-addr": {
+ "version": "2.0.6",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.9.1"
+ }
+ },
+ "prr": {
+ "version": "1.0.1",
+ "dev": true
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "dev": true
+ },
+ "psl": {
+ "version": "1.8.0",
+ "dev": true
+ },
+ "public-encrypt": {
+ "version": "4.0.3",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "parse-asn1": "^5.0.0",
+ "randombytes": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "pull-cat": {
+ "version": "1.1.11",
+ "dev": true
+ },
+ "pull-defer": {
+ "version": "0.2.3",
+ "dev": true
+ },
+ "pull-level": {
+ "version": "2.0.4",
+ "dev": true,
+ "requires": {
+ "level-post": "^1.0.7",
+ "pull-cat": "^1.1.9",
+ "pull-live": "^1.0.1",
+ "pull-pushable": "^2.0.0",
+ "pull-stream": "^3.4.0",
+ "pull-window": "^2.1.4",
+ "stream-to-pull-stream": "^1.7.1"
+ }
+ },
+ "pull-live": {
+ "version": "1.0.1",
+ "dev": true,
+ "requires": {
+ "pull-cat": "^1.1.9",
+ "pull-stream": "^3.4.0"
+ }
+ },
+ "pull-pushable": {
+ "version": "2.2.0",
+ "dev": true
+ },
+ "pull-stream": {
+ "version": "3.6.14",
+ "dev": true
+ },
+ "pull-window": {
+ "version": "2.1.4",
+ "dev": true,
+ "requires": {
+ "looper": "^2.0.0"
+ }
+ },
+ "pump": {
+ "version": "3.0.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.5.2",
+ "dev": true
+ },
+ "query-string": {
+ "version": "5.1.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "decode-uri-component": "^0.2.0",
+ "object-assign": "^4.1.0",
+ "strict-uri-encode": "^1.0.0"
+ }
+ },
+ "randombytes": {
+ "version": "2.1.0",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "randomfill": {
+ "version": "1.0.4",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "randombytes": "^2.0.5",
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "range-parser": {
+ "version": "1.2.1",
+ "dev": true,
+ "optional": true
+ },
+ "raw-body": {
+ "version": "2.4.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bytes": "3.1.0",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "dev": true
+ }
+ }
+ },
+ "regenerate": {
+ "version": "1.4.2",
+ "dev": true
+ },
+ "regenerator-runtime": {
+ "version": "0.11.1",
+ "dev": true
+ },
+ "regenerator-transform": {
+ "version": "0.10.1",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.18.0",
+ "babel-types": "^6.19.0",
+ "private": "^0.1.6"
+ }
+ },
+ "regex-not": {
+ "version": "1.0.2",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "regexp.prototype.flags": {
+ "version": "1.3.0",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1"
+ },
+ "dependencies": {
+ "es-abstract": {
+ "version": "1.17.7",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.2",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.1",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ }
+ }
+ }
+ },
+ "regexpu-core": {
+ "version": "2.0.0",
+ "dev": true,
+ "requires": {
+ "regenerate": "^1.2.1",
+ "regjsgen": "^0.2.0",
+ "regjsparser": "^0.1.4"
+ }
+ },
+ "regjsgen": {
+ "version": "0.2.0",
+ "dev": true
+ },
+ "regjsparser": {
+ "version": "0.1.5",
+ "dev": true,
+ "requires": {
+ "jsesc": "~0.5.0"
+ },
+ "dependencies": {
+ "jsesc": {
+ "version": "0.5.0",
+ "dev": true
+ }
+ }
+ },
+ "repeat-element": {
+ "version": "1.1.3",
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "dev": true
+ },
+ "repeating": {
+ "version": "2.0.1",
+ "dev": true,
+ "requires": {
+ "is-finite": "^1.0.0"
+ }
+ },
+ "request": {
+ "version": "2.88.2",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.3",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.5.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "resolve-url": {
+ "version": "0.2.1",
+ "dev": true
+ },
+ "responselike": {
+ "version": "1.0.2",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "resumer": {
+ "version": "0.0.0",
+ "dev": true,
+ "requires": {
+ "through": "~2.3.4"
+ }
+ },
+ "ret": {
+ "version": "0.1.15",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "2.6.3",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "ripemd160": {
+ "version": "2.0.2",
+ "dev": true,
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
+ "rlp": {
+ "version": "2.2.6",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.11.1"
+ }
+ },
+ "rustbn.js": {
+ "version": "0.2.0",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "dev": true
+ },
+ "safe-event-emitter": {
+ "version": "1.0.1",
+ "dev": true,
+ "requires": {
+ "events": "^3.0.0"
+ }
+ },
+ "safe-regex": {
+ "version": "1.1.0",
+ "dev": true,
+ "requires": {
+ "ret": "~0.1.10"
+ }
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "dev": true
+ },
+ "scrypt-js": {
+ "version": "3.0.1",
+ "dev": true
+ },
+ "scryptsy": {
+ "version": "1.2.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "pbkdf2": "^3.0.3"
+ }
+ },
+ "secp256k1": {
+ "version": "4.0.2",
+ "dev": true,
+ "requires": {
+ "elliptic": "^6.5.2",
+ "node-addon-api": "^2.0.0",
+ "node-gyp-build": "^4.2.0"
+ }
+ },
+ "seedrandom": {
+ "version": "3.0.1",
+ "dev": true
+ },
+ "semaphore": {
+ "version": "1.1.0",
+ "dev": true
+ },
+ "send": {
+ "version": "0.17.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.7.2",
+ "mime": "1.6.0",
+ "ms": "2.1.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ms": "2.0.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.0.0",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "ms": {
+ "version": "2.1.1",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.14.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.1"
+ }
+ },
+ "servify": {
+ "version": "0.1.12",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "body-parser": "^1.16.0",
+ "cors": "^2.8.1",
+ "express": "^4.14.0",
+ "request": "^2.79.0",
+ "xhr": "^2.3.3"
+ }
+ },
+ "set-immediate-shim": {
+ "version": "1.0.1",
+ "dev": true
+ },
+ "set-value": {
+ "version": "2.0.1",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "dev": true
+ }
+ }
+ },
+ "setimmediate": {
+ "version": "1.0.5",
+ "dev": true
+ },
+ "setprototypeof": {
+ "version": "1.1.1",
+ "dev": true,
+ "optional": true
+ },
+ "sha.js": {
+ "version": "2.4.11",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "simple-concat": {
+ "version": "1.0.1",
+ "dev": true,
+ "optional": true
+ },
+ "simple-get": {
+ "version": "2.8.1",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "decompress-response": "^3.3.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
+ "snapdragon": {
+ "version": "0.8.2",
+ "dev": true,
+ "requires": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "dev": true
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.0.0",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "dev": true,
+ "requires": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.2.0"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "1.1.6",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "dev": true
+ },
+ "source-map-resolve": {
+ "version": "0.5.3",
+ "dev": true,
+ "requires": {
+ "atob": "^2.1.2",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "source-map-support": {
+ "version": "0.5.12",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "dev": true
+ }
+ }
+ },
+ "source-map-url": {
+ "version": "0.4.0",
+ "dev": true
+ },
+ "split-string": {
+ "version": "3.1.0",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.0"
+ }
+ },
+ "sshpk": {
+ "version": "1.16.1",
+ "dev": true,
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ },
+ "dependencies": {
+ "tweetnacl": {
+ "version": "0.14.5",
+ "dev": true
+ }
+ }
+ },
+ "static-extend": {
+ "version": "0.1.2",
+ "dev": true,
+ "requires": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "dev": true
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "dev": true
+ }
+ }
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "dev": true,
+ "optional": true
+ },
+ "stream-to-pull-stream": {
+ "version": "1.7.3",
+ "dev": true,
+ "requires": {
+ "looper": "^3.0.0",
+ "pull-stream": "^3.2.3"
+ },
+ "dependencies": {
+ "looper": {
+ "version": "3.0.0",
+ "dev": true
+ }
+ }
+ },
+ "strict-uri-encode": {
+ "version": "1.1.0",
+ "dev": true,
+ "optional": true
+ },
+ "string.prototype.trim": {
+ "version": "1.2.3",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.1"
+ }
+ },
+ "string.prototype.trimend": {
+ "version": "1.0.3",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3"
+ }
+ },
+ "string.prototype.trimstart": {
+ "version": "1.0.3",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "dev": true
+ }
+ }
+ },
+ "strip-hex-prefix": {
+ "version": "1.0.0",
+ "dev": true,
+ "requires": {
+ "is-hex-prefixed": "1.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "swarm-js": {
+ "version": "0.1.40",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bluebird": "^3.5.0",
+ "buffer": "^5.0.5",
+ "eth-lib": "^0.1.26",
+ "fs-extra": "^4.0.2",
+ "got": "^7.1.0",
+ "mime-types": "^2.1.16",
+ "mkdirp-promise": "^5.0.1",
+ "mock-fs": "^4.1.0",
+ "setimmediate": "^1.0.5",
+ "tar": "^4.0.2",
+ "xhr-request": "^1.0.1"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "4.0.3",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "get-stream": {
+ "version": "3.0.0",
+ "dev": true,
+ "optional": true
+ },
+ "got": {
+ "version": "7.1.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "decompress-response": "^3.2.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^3.0.0",
+ "is-plain-obj": "^1.1.0",
+ "is-retry-allowed": "^1.0.0",
+ "is-stream": "^1.0.0",
+ "isurl": "^1.0.0-alpha5",
+ "lowercase-keys": "^1.0.0",
+ "p-cancelable": "^0.3.0",
+ "p-timeout": "^1.1.1",
+ "safe-buffer": "^5.0.1",
+ "timed-out": "^4.0.0",
+ "url-parse-lax": "^1.0.0",
+ "url-to-options": "^1.0.1"
+ }
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "dev": true,
+ "optional": true
+ },
+ "p-cancelable": {
+ "version": "0.3.0",
+ "dev": true,
+ "optional": true
+ },
+ "prepend-http": {
+ "version": "1.0.4",
+ "dev": true,
+ "optional": true
+ },
+ "url-parse-lax": {
+ "version": "1.0.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "prepend-http": "^1.0.1"
+ }
+ }
+ }
+ },
+ "tape": {
+ "version": "4.13.3",
+ "dev": true,
+ "requires": {
+ "deep-equal": "~1.1.1",
+ "defined": "~1.0.0",
+ "dotignore": "~0.1.2",
+ "for-each": "~0.3.3",
+ "function-bind": "~1.1.1",
+ "glob": "~7.1.6",
+ "has": "~1.0.3",
+ "inherits": "~2.0.4",
+ "is-regex": "~1.0.5",
+ "minimist": "~1.2.5",
+ "object-inspect": "~1.7.0",
+ "resolve": "~1.17.0",
+ "resumer": "~0.0.0",
+ "string.prototype.trim": "~1.2.1",
+ "through": "~2.3.8"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.6",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "is-regex": {
+ "version": "1.0.5",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "object-inspect": {
+ "version": "1.7.0",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.17.0",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
+ }
+ }
+ },
+ "tar": {
+ "version": "4.4.13",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "chownr": "^1.1.1",
+ "fs-minipass": "^1.2.5",
+ "minipass": "^2.8.6",
+ "minizlib": "^1.2.1",
+ "mkdirp": "^0.5.0",
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.3"
+ },
+ "dependencies": {
+ "fs-minipass": {
+ "version": "1.2.7",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "minipass": "^2.6.0"
+ }
+ },
+ "minipass": {
+ "version": "2.9.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.0"
+ }
+ }
+ }
+ },
+ "through": {
+ "version": "2.3.8",
+ "dev": true
+ },
+ "through2": {
+ "version": "2.0.5",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ }
+ },
+ "timed-out": {
+ "version": "4.0.1",
+ "dev": true,
+ "optional": true
+ },
+ "tmp": {
+ "version": "0.1.0",
+ "dev": true,
+ "requires": {
+ "rimraf": "^2.6.3"
+ }
+ },
+ "to-object-path": {
+ "version": "0.3.0",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "1.1.6",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "to-readable-stream": {
+ "version": "1.0.0",
+ "dev": true,
+ "optional": true
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "dev": true,
+ "requires": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "toidentifier": {
+ "version": "1.0.0",
+ "dev": true,
+ "optional": true
+ },
+ "tough-cookie": {
+ "version": "2.5.0",
+ "dev": true,
+ "requires": {
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ }
+ },
+ "trim-right": {
+ "version": "1.0.1",
+ "dev": true
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "1.0.3",
+ "dev": true
+ },
+ "tweetnacl-util": {
+ "version": "0.15.1",
+ "dev": true
+ },
+ "type": {
+ "version": "1.2.0",
+ "dev": true
+ },
+ "type-is": {
+ "version": "1.6.18",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "dev": true
+ },
+ "typedarray-to-buffer": {
+ "version": "3.1.5",
+ "dev": true,
+ "requires": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "typewise": {
+ "version": "1.0.3",
+ "dev": true,
+ "requires": {
+ "typewise-core": "^1.2.0"
+ }
+ },
+ "typewise-core": {
+ "version": "1.2.0",
+ "dev": true
+ },
+ "typewiselite": {
+ "version": "1.0.0",
+ "dev": true
+ },
+ "ultron": {
+ "version": "1.1.1",
+ "dev": true,
+ "optional": true
+ },
+ "underscore": {
+ "version": "1.9.1",
+ "dev": true,
+ "optional": true
+ },
+ "union-value": {
+ "version": "1.0.1",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^2.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "0.1.1",
+ "dev": true
+ }
+ }
+ },
+ "universalify": {
+ "version": "0.1.2",
+ "dev": true
+ },
+ "unorm": {
+ "version": "1.6.0",
+ "dev": true
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "dev": true,
+ "optional": true
+ },
+ "unset-value": {
+ "version": "1.0.0",
+ "dev": true,
+ "requires": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "dev": true
+ }
+ }
+ },
+ "uri-js": {
+ "version": "4.4.1",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "urix": {
+ "version": "0.1.0",
+ "dev": true
+ },
+ "url-parse-lax": {
+ "version": "3.0.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "prepend-http": "^2.0.0"
+ }
+ },
+ "url-set-query": {
+ "version": "1.0.0",
+ "dev": true,
+ "optional": true
+ },
+ "url-to-options": {
+ "version": "1.0.1",
+ "dev": true,
+ "optional": true
+ },
+ "use": {
+ "version": "3.1.1",
+ "dev": true
+ },
+ "utf-8-validate": {
+ "version": "5.0.4",
+ "dev": true,
+ "requires": {
+ "node-gyp-build": "^4.2.0"
+ }
+ },
+ "utf8": {
+ "version": "3.0.0",
+ "dev": true,
+ "optional": true
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "dev": true
+ },
+ "util.promisify": {
+ "version": "1.1.1",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "for-each": "^0.3.3",
+ "has-symbols": "^1.0.1",
+ "object.getownpropertydescriptors": "^2.1.1"
+ }
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "dev": true,
+ "optional": true
+ },
+ "uuid": {
+ "version": "3.4.0",
+ "dev": true
+ },
+ "varint": {
+ "version": "5.0.2",
+ "dev": true,
+ "optional": true
+ },
+ "vary": {
+ "version": "1.1.2",
+ "dev": true,
+ "optional": true
+ },
+ "verror": {
+ "version": "1.10.0",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "web3": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "web3-bzz": "1.2.11",
+ "web3-core": "1.2.11",
+ "web3-eth": "1.2.11",
+ "web3-eth-personal": "1.2.11",
+ "web3-net": "1.2.11",
+ "web3-shh": "1.2.11",
+ "web3-utils": "1.2.11"
+ }
+ },
+ "web3-bzz": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@types/node": "^12.12.6",
+ "got": "9.6.0",
+ "swarm-js": "^0.1.40",
+ "underscore": "1.9.1"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "12.19.12",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "web3-core": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@types/bn.js": "^4.11.5",
+ "@types/node": "^12.12.6",
+ "bignumber.js": "^9.0.0",
+ "web3-core-helpers": "1.2.11",
+ "web3-core-method": "1.2.11",
+ "web3-core-requestmanager": "1.2.11",
+ "web3-utils": "1.2.11"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "12.19.12",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "web3-core-helpers": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "underscore": "1.9.1",
+ "web3-eth-iban": "1.2.11",
+ "web3-utils": "1.2.11"
+ }
+ },
+ "web3-core-method": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/transactions": "^5.0.0-beta.135",
+ "underscore": "1.9.1",
+ "web3-core-helpers": "1.2.11",
+ "web3-core-promievent": "1.2.11",
+ "web3-core-subscriptions": "1.2.11",
+ "web3-utils": "1.2.11"
+ }
+ },
+ "web3-core-promievent": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "eventemitter3": "4.0.4"
+ }
+ },
+ "web3-core-requestmanager": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "underscore": "1.9.1",
+ "web3-core-helpers": "1.2.11",
+ "web3-providers-http": "1.2.11",
+ "web3-providers-ipc": "1.2.11",
+ "web3-providers-ws": "1.2.11"
+ }
+ },
+ "web3-core-subscriptions": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "eventemitter3": "4.0.4",
+ "underscore": "1.9.1",
+ "web3-core-helpers": "1.2.11"
+ }
+ },
+ "web3-eth": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "underscore": "1.9.1",
+ "web3-core": "1.2.11",
+ "web3-core-helpers": "1.2.11",
+ "web3-core-method": "1.2.11",
+ "web3-core-subscriptions": "1.2.11",
+ "web3-eth-abi": "1.2.11",
+ "web3-eth-accounts": "1.2.11",
+ "web3-eth-contract": "1.2.11",
+ "web3-eth-ens": "1.2.11",
+ "web3-eth-iban": "1.2.11",
+ "web3-eth-personal": "1.2.11",
+ "web3-net": "1.2.11",
+ "web3-utils": "1.2.11"
+ }
+ },
+ "web3-eth-abi": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@ethersproject/abi": "5.0.0-beta.153",
+ "underscore": "1.9.1",
+ "web3-utils": "1.2.11"
+ }
+ },
+ "web3-eth-accounts": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "crypto-browserify": "3.12.0",
+ "eth-lib": "0.2.8",
+ "ethereumjs-common": "^1.3.2",
+ "ethereumjs-tx": "^2.1.1",
+ "scrypt-js": "^3.0.1",
+ "underscore": "1.9.1",
+ "uuid": "3.3.2",
+ "web3-core": "1.2.11",
+ "web3-core-helpers": "1.2.11",
+ "web3-core-method": "1.2.11",
+ "web3-utils": "1.2.11"
+ },
+ "dependencies": {
+ "eth-lib": {
+ "version": "0.2.8",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bn.js": "^4.11.6",
+ "elliptic": "^6.4.0",
+ "xhr-request-promise": "^0.1.2"
+ }
+ },
+ "uuid": {
+ "version": "3.3.2",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "web3-eth-contract": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@types/bn.js": "^4.11.5",
+ "underscore": "1.9.1",
+ "web3-core": "1.2.11",
+ "web3-core-helpers": "1.2.11",
+ "web3-core-method": "1.2.11",
+ "web3-core-promievent": "1.2.11",
+ "web3-core-subscriptions": "1.2.11",
+ "web3-eth-abi": "1.2.11",
+ "web3-utils": "1.2.11"
+ }
+ },
+ "web3-eth-ens": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "content-hash": "^2.5.2",
+ "eth-ens-namehash": "2.0.8",
+ "underscore": "1.9.1",
+ "web3-core": "1.2.11",
+ "web3-core-helpers": "1.2.11",
+ "web3-core-promievent": "1.2.11",
+ "web3-eth-abi": "1.2.11",
+ "web3-eth-contract": "1.2.11",
+ "web3-utils": "1.2.11"
+ }
+ },
+ "web3-eth-iban": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bn.js": "^4.11.9",
+ "web3-utils": "1.2.11"
+ }
+ },
+ "web3-eth-personal": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@types/node": "^12.12.6",
+ "web3-core": "1.2.11",
+ "web3-core-helpers": "1.2.11",
+ "web3-core-method": "1.2.11",
+ "web3-net": "1.2.11",
+ "web3-utils": "1.2.11"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "12.19.12",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "web3-net": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "web3-core": "1.2.11",
+ "web3-core-method": "1.2.11",
+ "web3-utils": "1.2.11"
+ }
+ },
+ "web3-provider-engine": {
+ "version": "14.2.1",
+ "dev": true,
+ "requires": {
+ "async": "^2.5.0",
+ "backoff": "^2.5.0",
+ "clone": "^2.0.0",
+ "cross-fetch": "^2.1.0",
+ "eth-block-tracker": "^3.0.0",
+ "eth-json-rpc-infura": "^3.1.0",
+ "eth-sig-util": "3.0.0",
+ "ethereumjs-block": "^1.2.2",
+ "ethereumjs-tx": "^1.2.0",
+ "ethereumjs-util": "^5.1.5",
+ "ethereumjs-vm": "^2.3.4",
+ "json-rpc-error": "^2.0.0",
+ "json-stable-stringify": "^1.0.1",
+ "promise-to-callback": "^1.0.0",
+ "readable-stream": "^2.2.9",
+ "request": "^2.85.0",
+ "semaphore": "^1.0.3",
+ "ws": "^5.1.1",
+ "xhr": "^2.2.0",
+ "xtend": "^4.0.1"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "2.6.3",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ },
+ "deferred-leveldown": {
+ "version": "1.2.2",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "~2.6.0"
+ }
+ },
+ "eth-sig-util": {
+ "version": "1.4.2",
+ "dev": true,
+ "requires": {
+ "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+ "ethereumjs-util": "^5.1.1"
+ }
+ },
+ "ethereumjs-account": {
+ "version": "2.0.5",
+ "dev": true,
+ "requires": {
+ "ethereumjs-util": "^5.0.0",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "ethereumjs-block": {
+ "version": "1.7.1",
+ "dev": true,
+ "requires": {
+ "async": "^2.0.1",
+ "ethereum-common": "0.2.0",
+ "ethereumjs-tx": "^1.2.2",
+ "ethereumjs-util": "^5.0.0",
+ "merkle-patricia-tree": "^2.1.2"
+ },
+ "dependencies": {
+ "ethereum-common": {
+ "version": "0.2.0",
+ "dev": true
+ }
+ }
+ },
+ "ethereumjs-tx": {
+ "version": "1.3.7",
+ "dev": true,
+ "requires": {
+ "ethereum-common": "^0.0.18",
+ "ethereumjs-util": "^5.0.0"
+ }
+ },
+ "ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "ethereumjs-vm": {
+ "version": "2.6.0",
+ "dev": true,
+ "requires": {
+ "async": "^2.1.2",
+ "async-eventemitter": "^0.2.2",
+ "ethereumjs-account": "^2.0.3",
+ "ethereumjs-block": "~2.2.0",
+ "ethereumjs-common": "^1.1.0",
+ "ethereumjs-util": "^6.0.0",
+ "fake-merkle-patricia-tree": "^1.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "merkle-patricia-tree": "^2.3.2",
+ "rustbn.js": "~0.2.0",
+ "safe-buffer": "^5.1.1"
+ },
+ "dependencies": {
+ "ethereumjs-block": {
+ "version": "2.2.2",
+ "dev": true,
+ "requires": {
+ "async": "^2.0.1",
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-tx": "^2.1.1",
+ "ethereumjs-util": "^5.0.0",
+ "merkle-patricia-tree": "^2.1.2"
+ },
+ "dependencies": {
+ "ethereumjs-util": {
+ "version": "5.2.1",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "^0.1.3",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1"
+ }
+ }
+ }
+ },
+ "ethereumjs-tx": {
+ "version": "2.1.2",
+ "dev": true,
+ "requires": {
+ "ethereumjs-common": "^1.5.0",
+ "ethereumjs-util": "^6.0.0"
+ }
+ },
+ "ethereumjs-util": {
+ "version": "6.2.1",
+ "dev": true,
+ "requires": {
+ "@types/bn.js": "^4.11.3",
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "elliptic": "^6.5.2",
+ "ethereum-cryptography": "^0.1.3",
+ "ethjs-util": "0.1.6",
+ "rlp": "^2.2.3"
+ }
+ }
+ }
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "dev": true
+ },
+ "level-codec": {
+ "version": "7.0.1",
+ "dev": true
+ },
+ "level-errors": {
+ "version": "1.0.5",
+ "dev": true,
+ "requires": {
+ "errno": "~0.1.1"
+ }
+ },
+ "level-iterator-stream": {
+ "version": "1.3.1",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "level-errors": "^1.0.3",
+ "readable-stream": "^1.0.33",
+ "xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.1.14",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ }
+ }
+ },
+ "level-ws": {
+ "version": "0.0.0",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~1.0.15",
+ "xtend": "~2.1.1"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.0.34",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "xtend": {
+ "version": "2.1.2",
+ "dev": true,
+ "requires": {
+ "object-keys": "~0.4.0"
+ }
+ }
+ }
+ },
+ "levelup": {
+ "version": "1.3.9",
+ "dev": true,
+ "requires": {
+ "deferred-leveldown": "~1.2.1",
+ "level-codec": "~7.0.0",
+ "level-errors": "~1.0.3",
+ "level-iterator-stream": "~1.3.0",
+ "prr": "~1.0.1",
+ "semver": "~5.4.1",
+ "xtend": "~4.0.0"
+ }
+ },
+ "ltgt": {
+ "version": "2.2.1",
+ "dev": true
+ },
+ "memdown": {
+ "version": "1.4.1",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "~2.7.1",
+ "functional-red-black-tree": "^1.0.1",
+ "immediate": "^3.2.3",
+ "inherits": "~2.0.1",
+ "ltgt": "~2.2.0",
+ "safe-buffer": "~5.1.1"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "2.7.2",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
+ }
+ }
+ },
+ "merkle-patricia-tree": {
+ "version": "2.3.2",
+ "dev": true,
+ "requires": {
+ "async": "^1.4.2",
+ "ethereumjs-util": "^5.0.0",
+ "level-ws": "0.0.0",
+ "levelup": "^1.2.1",
+ "memdown": "^1.0.0",
+ "readable-stream": "^2.0.0",
+ "rlp": "^2.0.0",
+ "semaphore": ">=1.0.1"
+ },
+ "dependencies": {
+ "async": {
+ "version": "1.5.2",
+ "dev": true
+ }
+ }
+ },
+ "object-keys": {
+ "version": "0.4.0",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.4.1",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "dev": true
+ },
+ "ws": {
+ "version": "5.2.2",
+ "dev": true,
+ "requires": {
+ "async-limiter": "~1.0.0"
+ }
+ }
+ }
+ },
+ "web3-providers-http": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "web3-core-helpers": "1.2.11",
+ "xhr2-cookies": "1.1.0"
+ }
+ },
+ "web3-providers-ipc": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "oboe": "2.1.4",
+ "underscore": "1.9.1",
+ "web3-core-helpers": "1.2.11"
+ }
+ },
+ "web3-providers-ws": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "eventemitter3": "4.0.4",
+ "underscore": "1.9.1",
+ "web3-core-helpers": "1.2.11",
+ "websocket": "^1.0.31"
+ }
+ },
+ "web3-shh": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "web3-core": "1.2.11",
+ "web3-core-method": "1.2.11",
+ "web3-core-subscriptions": "1.2.11",
+ "web3-net": "1.2.11"
+ }
+ },
+ "web3-utils": {
+ "version": "1.2.11",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bn.js": "^4.11.9",
+ "eth-lib": "0.2.8",
+ "ethereum-bloom-filters": "^1.0.6",
+ "ethjs-unit": "0.1.6",
+ "number-to-bn": "1.7.0",
+ "randombytes": "^2.1.0",
+ "underscore": "1.9.1",
+ "utf8": "3.0.0"
+ },
+ "dependencies": {
+ "eth-lib": {
+ "version": "0.2.8",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bn.js": "^4.11.6",
+ "elliptic": "^6.4.0",
+ "xhr-request-promise": "^0.1.2"
+ }
+ }
+ }
+ },
+ "websocket": {
+ "version": "1.0.32",
+ "dev": true,
+ "requires": {
+ "bufferutil": "^4.0.1",
+ "debug": "^2.2.0",
+ "es5-ext": "^0.10.50",
+ "typedarray-to-buffer": "^3.1.5",
+ "utf-8-validate": "^5.0.2",
+ "yaeti": "^0.0.6"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "dev": true
+ }
+ }
+ },
+ "whatwg-fetch": {
+ "version": "2.0.4",
+ "dev": true
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "dev": true
+ },
+ "ws": {
+ "version": "3.3.3",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "async-limiter": "~1.0.0",
+ "safe-buffer": "~5.1.0",
+ "ultron": "~1.1.0"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "xhr": {
+ "version": "2.6.0",
+ "dev": true,
+ "requires": {
+ "global": "~4.4.0",
+ "is-function": "^1.0.1",
+ "parse-headers": "^2.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "xhr-request": {
+ "version": "1.1.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "buffer-to-arraybuffer": "^0.0.5",
+ "object-assign": "^4.1.1",
+ "query-string": "^5.0.1",
+ "simple-get": "^2.7.0",
+ "timed-out": "^4.0.1",
+ "url-set-query": "^1.0.0",
+ "xhr": "^2.0.4"
+ }
+ },
+ "xhr-request-promise": {
+ "version": "0.1.3",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "xhr-request": "^1.1.0"
+ }
+ },
+ "xhr2-cookies": {
+ "version": "1.1.0",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "cookiejar": "^2.1.1"
+ }
+ },
+ "xtend": {
+ "version": "4.0.2",
+ "dev": true
+ },
+ "yaeti": {
+ "version": "0.0.6",
+ "dev": true
+ },
+ "yallist": {
+ "version": "3.1.1",
+ "dev": true
+ }
+ }
+ },
+ "gauge": {
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "optional": true,
+ "peer": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ }
+ }
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
+ },
+ "get-func-name": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE="
+ },
+ "get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "get-port": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz",
+ "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw="
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "get-symbol-description": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+ "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "requires": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.1"
+ }
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "ghost-testrpc": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz",
+ "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==",
+ "requires": {
+ "chalk": "^2.4.2",
+ "node-emoji": "^1.10.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "github-from-package": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+ "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=",
+ "optional": true,
+ "peer": true
+ },
+ "glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "global": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
+ "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
+ "requires": {
+ "min-document": "^2.19.0",
+ "process": "^0.11.10"
+ }
+ },
+ "global-modules": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
+ "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
+ "requires": {
+ "global-prefix": "^3.0.0"
+ }
+ },
+ "global-prefix": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
+ "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
+ "requires": {
+ "ini": "^1.3.5",
+ "kind-of": "^6.0.2",
+ "which": "^1.3.1"
+ }
+ },
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
+ },
+ "globby": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
+ "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
+ "requires": {
+ "@types/glob": "^7.1.1",
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.0.3",
+ "glob": "^7.1.3",
+ "ignore": "^5.1.1",
+ "merge2": "^1.2.3",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "ignore": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
+ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ=="
+ }
+ }
+ },
+ "got": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+ "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+ "requires": {
+ "@sindresorhus/is": "^0.14.0",
+ "@szmarczak/http-timer": "^1.1.2",
+ "cacheable-request": "^6.0.0",
+ "decompress-response": "^3.3.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^4.1.0",
+ "lowercase-keys": "^1.0.1",
+ "mimic-response": "^1.0.1",
+ "p-cancelable": "^1.0.0",
+ "to-readable-stream": "^1.0.0",
+ "url-parse-lax": "^3.0.0"
+ },
+ "dependencies": {
+ "decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="
+ }
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.9",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
+ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ=="
+ },
+ "growl": {
+ "version": "1.10.5",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA=="
+ },
+ "handlebars": {
+ "version": "4.7.7",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
+ "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
+ "requires": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.0",
+ "source-map": "^0.6.1",
+ "uglify-js": "^3.1.4",
+ "wordwrap": "^1.0.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ }
+ }
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+ },
+ "har-validator": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+ "requires": {
+ "ajv": "^6.12.3",
+ "har-schema": "^2.0.0"
+ }
+ },
+ "hardhat": {
+ "version": "2.9.3",
+ "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.9.3.tgz",
+ "integrity": "sha512-7Vw99RbYbMZ15UzegOR/nqIYIqddZXvLwJGaX5sX4G5bydILnbjmDU6g3jMKJSiArEixS3vHAEaOs5CW1JQ3hg==",
+ "requires": {
+ "@ethereumjs/block": "^3.6.0",
+ "@ethereumjs/blockchain": "^5.5.0",
+ "@ethereumjs/common": "^2.6.0",
+ "@ethereumjs/tx": "^3.4.0",
+ "@ethereumjs/vm": "^5.6.0",
+ "@ethersproject/abi": "^5.1.2",
+ "@metamask/eth-sig-util": "^4.0.0",
+ "@sentry/node": "^5.18.1",
+ "@solidity-parser/parser": "^0.14.1",
+ "@types/bn.js": "^5.1.0",
+ "@types/lru-cache": "^5.1.0",
+ "abort-controller": "^3.0.0",
+ "adm-zip": "^0.4.16",
+ "aggregate-error": "^3.0.0",
+ "ansi-escapes": "^4.3.0",
+ "chalk": "^2.4.2",
+ "chokidar": "^3.4.0",
+ "ci-info": "^2.0.0",
+ "debug": "^4.1.1",
+ "enquirer": "^2.3.0",
+ "env-paths": "^2.2.0",
+ "ethereum-cryptography": "^0.1.2",
+ "ethereumjs-abi": "^0.6.8",
+ "ethereumjs-util": "^7.1.3",
+ "find-up": "^2.1.0",
+ "fp-ts": "1.19.3",
+ "fs-extra": "^7.0.1",
+ "glob": "^7.1.3",
+ "immutable": "^4.0.0-rc.12",
+ "io-ts": "1.10.4",
+ "lodash": "^4.17.11",
+ "merkle-patricia-tree": "^4.2.2",
+ "mnemonist": "^0.38.0",
+ "mocha": "^9.2.0",
+ "p-map": "^4.0.0",
+ "qs": "^6.7.0",
+ "raw-body": "^2.4.1",
+ "resolve": "1.17.0",
+ "semver": "^6.3.0",
+ "slash": "^3.0.0",
+ "solc": "0.7.3",
+ "source-map-support": "^0.5.13",
+ "stacktrace-parser": "^0.1.10",
+ "true-case-path": "^2.2.1",
+ "tsort": "0.0.1",
+ "undici": "^4.14.1",
+ "uuid": "^8.3.2",
+ "ws": "^7.4.6"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+ },
+ "camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "decamelize": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
+ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ=="
+ },
+ "flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA=="
+ },
+ "js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "requires": {
+ "argparse": "^2.0.1"
+ }
+ },
+ "locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "requires": {
+ "p-locate": "^5.0.0"
+ }
+ },
+ "mocha": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz",
+ "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==",
+ "requires": {
+ "@ungap/promise-all-settled": "1.1.2",
+ "ansi-colors": "4.1.1",
+ "browser-stdout": "1.3.1",
+ "chokidar": "3.5.3",
+ "debug": "4.3.3",
+ "diff": "5.0.0",
+ "escape-string-regexp": "4.0.0",
+ "find-up": "5.0.0",
+ "glob": "7.2.0",
+ "growl": "1.10.5",
+ "he": "1.2.0",
+ "js-yaml": "4.1.0",
+ "log-symbols": "4.1.0",
+ "minimatch": "4.2.1",
+ "ms": "2.1.3",
+ "nanoid": "3.3.1",
+ "serialize-javascript": "6.0.0",
+ "strip-json-comments": "3.1.1",
+ "supports-color": "8.1.1",
+ "which": "2.0.2",
+ "workerpool": "6.2.0",
+ "yargs": "16.2.0",
+ "yargs-parser": "20.2.4",
+ "yargs-unparser": "2.0.0"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
+ },
+ "find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "requires": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+ },
+ "supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "requires": {
+ "yocto-queue": "^0.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "requires": {
+ "p-limit": "^3.0.2"
+ }
+ },
+ "resolve": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
+ "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ },
+ "solc": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz",
+ "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==",
+ "requires": {
+ "command-exists": "^1.2.8",
+ "commander": "3.0.2",
+ "follow-redirects": "^1.12.1",
+ "fs-extra": "^0.30.0",
+ "js-sha3": "0.8.0",
+ "memorystream": "^0.3.1",
+ "require-from-string": "^2.0.0",
+ "semver": "^5.5.0",
+ "tmp": "0.0.33"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "0.30.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+ "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0",
+ "path-is-absolute": "^1.0.0",
+ "rimraf": "^2.2.8"
+ }
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+ }
+ }
+ },
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ }
+ }
+ },
+ "y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="
+ },
+ "yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "requires": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "20.2.4",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+ "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA=="
+ },
+ "yargs-unparser": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
+ "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
+ "requires": {
+ "camelcase": "^6.0.0",
+ "decamelize": "^4.0.0",
+ "flat": "^5.0.2",
+ "is-plain-obj": "^2.1.0"
+ }
+ }
+ }
+ },
+ "hardhat-abi-exporter": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/hardhat-abi-exporter/-/hardhat-abi-exporter-2.7.2.tgz",
+ "integrity": "sha512-/do2VgS/aqpyrB0P93Pc9flsW7d2nknVLU8rQCMUNjJNa3S7ZLbNaFwuwvieM1V9hejUu6AIm1o6p2Vw5dHlOg==",
+ "dev": true,
+ "requires": {
+ "@ethersproject/abi": "^5.5.0",
+ "delete-empty": "^3.0.0"
+ }
+ },
+ "hardhat-contract-sizer": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.3.1.tgz",
+ "integrity": "sha512-pW4DoJAgkP2ouLs7Fbg8rqNbFDQ2oz1sv2jkE9DWObzd0IG42YonXK4unQLCHvEUWzbp68sBjPCnrDMoc/JZfA==",
+ "requires": {
+ "chalk": "^4.0.0",
+ "cli-table3": "^0.6.0"
+ }
+ },
+ "hardhat-deploy": {
+ "version": "0.9.24",
+ "resolved": "https://registry.npmjs.org/hardhat-deploy/-/hardhat-deploy-0.9.24.tgz",
+ "integrity": "sha512-fIIg6Wt7lV8h+6c6dFnINUKcJ/5Wfe5GYDaDsGGPqaK2b71DaeFHjsWRL+2ozaHkMZjdyYBOweY09wRu/KM1Qw==",
+ "requires": {
+ "@ethersproject/abi": "^5.4.0",
+ "@ethersproject/abstract-signer": "^5.4.1",
+ "@ethersproject/address": "^5.4.0",
+ "@ethersproject/bignumber": "^5.4.1",
+ "@ethersproject/bytes": "^5.4.0",
+ "@ethersproject/constants": "^5.4.0",
+ "@ethersproject/contracts": "^5.4.1",
+ "@ethersproject/providers": "^5.4.4",
+ "@ethersproject/solidity": "^5.4.0",
+ "@ethersproject/transactions": "^5.4.0",
+ "@ethersproject/wallet": "^5.4.0",
+ "@types/qs": "^6.9.7",
+ "axios": "^0.21.1",
+ "chalk": "^4.1.2",
+ "chokidar": "^3.5.2",
+ "debug": "^4.3.2",
+ "enquirer": "^2.3.6",
+ "form-data": "^4.0.0",
+ "fs-extra": "^10.0.0",
+ "match-all": "^1.2.6",
+ "murmur-128": "^0.2.1",
+ "qs": "^6.9.4"
+ },
+ "dependencies": {
+ "form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "fs-extra": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
+ "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ }
+ },
+ "jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "requires": {
+ "graceful-fs": "^4.1.6",
+ "universalify": "^2.0.0"
+ }
+ },
+ "universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
+ }
+ }
+ },
+ "hardhat-gas-reporter": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.7.tgz",
+ "integrity": "sha512-calJH1rbhUFwCnw0odJb3Cw+mDmBIsHdVyutsHhA3RY6JELyFVaVxCnITYGr/crkmHqt4tQCYROy7ty6DTLkuA==",
+ "requires": {
+ "array-uniq": "1.0.3",
+ "eth-gas-reporter": "^0.2.24",
+ "sha1": "^1.1.1"
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-bigints": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
+ "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA=="
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+ },
+ "has-symbol-support-x": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz",
+ "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw=="
+ },
+ "has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw=="
+ },
+ "has-to-string-tag-x": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
+ "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
+ "requires": {
+ "has-symbol-support-x": "^1.4.1"
+ }
+ },
+ "has-tostringtag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+ "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "requires": {
+ "has-symbols": "^1.0.2"
+ }
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+ "optional": true,
+ "peer": true
+ },
+ "hash-base": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
+ "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
+ "requires": {
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ }
+ },
+ "hash.js": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+ "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.1"
+ }
+ },
+ "he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
+ },
+ "highlight.js": {
+ "version": "9.18.5",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.5.tgz",
+ "integrity": "sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA=="
+ },
+ "highlightjs-solidity": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-1.2.2.tgz",
+ "integrity": "sha512-+cZ+1+nAO5Pi6c70TKuMcPmwqLECxiYhnQc1MxdXckK94zyWFMNZADzu98ECNlf5xCRdNh+XKp+eklmRU+Dniw=="
+ },
+ "hmac-drbg": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+ "requires": {
+ "hash.js": "^1.0.3",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "dev": true
+ },
+ "htmlparser2": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
+ "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
+ "requires": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.0.0",
+ "domutils": "^2.5.2",
+ "entities": "^2.0.0"
+ }
+ },
+ "http-basic": {
+ "version": "8.1.3",
+ "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz",
+ "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==",
+ "requires": {
+ "caseless": "^0.12.0",
+ "concat-stream": "^1.6.2",
+ "http-response-object": "^3.0.1",
+ "parse-cache-control": "^1.0.1"
+ }
+ },
+ "http-cache-semantics": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ=="
+ },
+ "http-errors": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
+ "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.1"
+ }
+ },
+ "http-https": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz",
+ "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs="
+ },
+ "http-response-object": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz",
+ "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==",
+ "requires": {
+ "@types/node": "^10.0.3"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "10.17.60",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
+ "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="
+ }
+ }
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "https-proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+ "requires": {
+ "agent-base": "6",
+ "debug": "4"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "idna-uts46-hx": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz",
+ "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==",
+ "requires": {
+ "punycode": "2.1.0"
+ }
+ },
+ "ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
+ },
+ "ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
+ },
+ "immediate": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz",
+ "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q=="
+ },
+ "immutable": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
+ "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw=="
+ },
+ "import-fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+ "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
+ "requires": {
+ "caller-path": "^2.0.0",
+ "resolve-from": "^3.0.0"
+ }
+ },
+ "imul": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz",
+ "integrity": "sha1-nVhnFh6LPelsLDjV3HyxAvNeKsk="
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
+ },
+ "indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+ },
+ "inquirer": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
+ "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
+ "requires": {
+ "ansi-escapes": "^3.2.0",
+ "chalk": "^2.4.2",
+ "cli-cursor": "^2.1.0",
+ "cli-width": "^2.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^2.0.0",
+ "lodash": "^4.17.12",
+ "mute-stream": "0.0.7",
+ "run-async": "^2.2.0",
+ "rxjs": "^6.4.0",
+ "string-width": "^2.1.0",
+ "strip-ansi": "^5.1.0",
+ "through": "^2.3.6"
+ },
+ "dependencies": {
+ "ansi-escapes": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+ "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ=="
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
+ }
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "internal-slot": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
+ "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
+ "requires": {
+ "get-intrinsic": "^1.1.0",
+ "has": "^1.0.3",
+ "side-channel": "^1.0.4"
+ }
+ },
+ "interpret": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA=="
+ },
+ "invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "peer": true,
+ "requires": {
+ "loose-envify": "^1.0.0"
+ }
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
+ "dev": true
+ },
+ "io-ts": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz",
+ "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==",
+ "requires": {
+ "fp-ts": "^1.0.0"
+ }
+ },
+ "ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
+ },
+ "is-arguments": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
+ "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
+ },
+ "is-bigint": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "requires": {
+ "has-bigints": "^1.0.1"
+ }
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-buffer": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+ "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ=="
+ },
+ "is-callable": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
+ "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w=="
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "is-core-module": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
+ "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==",
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-date-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+ "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-directory": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+ "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE="
+ },
+ "is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
+ },
+ "is-function": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz",
+ "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ=="
+ },
+ "is-generator-function": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
+ "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-hex-prefixed": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz",
+ "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ="
+ },
+ "is-negative-zero": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+ "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA=="
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
+ },
+ "is-number-object": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz",
+ "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==",
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-object": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz",
+ "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA=="
+ },
+ "is-plain-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
+ },
+ "is-regex": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+ "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-retry-allowed": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+ "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg=="
+ },
+ "is-shared-array-buffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
+ "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA=="
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+ },
+ "is-string": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+ "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-symbol": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+ "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "requires": {
+ "has-symbols": "^1.0.2"
+ }
+ },
+ "is-typed-array": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz",
+ "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==",
+ "requires": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "es-abstract": "^1.18.5",
+ "foreach": "^2.0.5",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+ },
+ "is-url": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
+ "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
+ "dev": true
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+ "dev": true
+ },
+ "is-weakref": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+ "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "requires": {
+ "call-bind": "^1.0.2"
+ }
+ },
+ "is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "requires": {
+ "is-docker": "^2.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+ },
+ "iso-url": {
+ "version": "0.4.7",
+ "resolved": "https://registry.npmjs.org/iso-url/-/iso-url-0.4.7.tgz",
+ "integrity": "sha512-27fFRDnPAMnHGLq36bWTpKET+eiXct3ENlCcdcMdk+mjXrb2kw3mhBUg1B7ewAC0kVzlOPhADzQgz1SE6Tglog=="
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ },
+ "isurl": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
+ "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
+ "requires": {
+ "has-to-string-tag-x": "^1.2.0",
+ "is-object": "^1.0.1"
+ }
+ },
+ "js-sha3": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+ "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
+ },
+ "json-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg="
+ },
+ "json-format": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-format/-/json-format-1.0.1.tgz",
+ "integrity": "sha1-FD9n5irxKda//tKIpGJl6iPQ3ww="
+ },
+ "json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
+ },
+ "json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE="
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ },
+ "json-text-sequence": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/json-text-sequence/-/json-text-sequence-0.1.1.tgz",
+ "integrity": "sha1-py8hfcSvxGKf/1/rME3BvVGi89I=",
+ "requires": {
+ "delimit-stream": "0.1.0"
+ }
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "jsonschema": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.0.tgz",
+ "integrity": "sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw=="
+ },
+ "jsprim": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+ "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.4.0",
+ "verror": "1.10.0"
+ }
+ },
+ "keccak": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz",
+ "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==",
+ "requires": {
+ "node-addon-api": "^2.0.0",
+ "node-gyp-build": "^4.2.0",
+ "readable-stream": "^3.6.0"
+ }
+ },
+ "keyv": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
+ "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
+ "requires": {
+ "json-buffer": "3.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
+ },
+ "klaw": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+ "requires": {
+ "graceful-fs": "^4.1.9"
+ }
+ },
+ "klaw-sync": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz",
+ "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.11"
+ }
+ },
+ "lcid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "dev": true,
+ "requires": {
+ "invert-kv": "^1.0.0"
+ }
+ },
+ "lcov-parse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz",
+ "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=",
+ "dev": true
+ },
+ "level-codec": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz",
+ "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==",
+ "requires": {
+ "buffer": "^5.6.0"
+ }
+ },
+ "level-concat-iterator": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz",
+ "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw=="
+ },
+ "level-errors": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz",
+ "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==",
+ "requires": {
+ "errno": "~0.1.1"
+ }
+ },
+ "level-iterator-stream": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz",
+ "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==",
+ "requires": {
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0",
+ "xtend": "^4.0.2"
+ }
+ },
+ "level-mem": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-5.0.1.tgz",
+ "integrity": "sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg==",
+ "requires": {
+ "level-packager": "^5.0.3",
+ "memdown": "^5.0.0"
+ }
+ },
+ "level-packager": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz",
+ "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==",
+ "requires": {
+ "encoding-down": "^6.3.0",
+ "levelup": "^4.3.2"
+ }
+ },
+ "level-supports": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz",
+ "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==",
+ "requires": {
+ "xtend": "^4.0.2"
+ }
+ },
+ "level-ws": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-2.0.0.tgz",
+ "integrity": "sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.0",
+ "xtend": "^4.0.1"
+ }
+ },
+ "levelup": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz",
+ "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==",
+ "requires": {
+ "deferred-leveldown": "~5.3.0",
+ "level-errors": "~2.0.0",
+ "level-iterator-stream": "~4.0.0",
+ "level-supports": "~1.0.0",
+ "xtend": "~4.0.0"
+ }
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
+ "load-json-file": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0",
+ "strip-bom": "^2.0.0"
+ },
+ "dependencies": {
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.2.0"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ }
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "requires": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
+ "lodash.assign": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
+ "dev": true
+ },
+ "lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
+ },
+ "lodash.escaperegexp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
+ "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c="
+ },
+ "lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
+ },
+ "lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
+ },
+ "lodash.partition": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.partition/-/lodash.partition-4.6.0.tgz",
+ "integrity": "sha1-o45GtzRp4EILDaEhLmbUFL42S6Q="
+ },
+ "lodash.sum": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/lodash.sum/-/lodash.sum-4.0.2.tgz",
+ "integrity": "sha1-rZDjl5ZdgD1PH/eqWy0Bl/O0Y3s="
+ },
+ "log-driver": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz",
+ "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==",
+ "dev": true
+ },
+ "log-symbols": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+ "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+ "requires": {
+ "chalk": "^2.4.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "peer": true,
+ "requires": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ }
+ },
+ "lowercase-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
+ },
+ "lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "requires": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "lru_map": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
+ "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0="
+ },
+ "ltgt": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+ "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU="
+ },
+ "markdown-table": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz",
+ "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q=="
+ },
+ "match-all": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/match-all/-/match-all-1.2.6.tgz",
+ "integrity": "sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ=="
+ },
+ "mcl-wasm": {
+ "version": "0.7.9",
+ "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz",
+ "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ=="
+ },
+ "md5.js": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+ "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ },
+ "memdown": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/memdown/-/memdown-5.1.0.tgz",
+ "integrity": "sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw==",
+ "requires": {
+ "abstract-leveldown": "~6.2.1",
+ "functional-red-black-tree": "~1.0.1",
+ "immediate": "~3.2.3",
+ "inherits": "~2.0.1",
+ "ltgt": "~2.2.0",
+ "safe-buffer": "~5.2.0"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz",
+ "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==",
+ "requires": {
+ "buffer": "^5.5.0",
+ "immediate": "^3.2.3",
+ "level-concat-iterator": "~2.0.0",
+ "level-supports": "~1.0.0",
+ "xtend": "~4.0.0"
+ }
+ },
+ "immediate": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz",
+ "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw="
+ }
+ }
+ },
+ "memorystream": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+ "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI="
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
+ "merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="
+ },
+ "merkle-patricia-tree": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.2.2.tgz",
+ "integrity": "sha512-eqZYNTshcYx9aESkSPr71EqwsR/QmpnObDEV4iLxkt/x/IoLYZYjJvKY72voP/27Vy61iMOrfOG6jrn7ttXD+Q==",
+ "requires": {
+ "@types/levelup": "^4.3.0",
+ "ethereumjs-util": "^7.1.2",
+ "level-mem": "^5.0.1",
+ "level-ws": "^2.0.0",
+ "readable-stream": "^3.6.0",
+ "rlp": "^2.2.4",
+ "semaphore-async-await": "^1.5.1"
+ }
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+ },
+ "micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ }
+ },
+ "miller-rabin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+ "requires": {
+ "bn.js": "^4.0.0",
+ "brorand": "^1.0.1"
+ }
+ },
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
+ },
+ "mime-db": {
+ "version": "1.51.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
+ "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g=="
+ },
+ "mime-types": {
+ "version": "2.1.34",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
+ "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
+ "requires": {
+ "mime-db": "1.51.0"
+ }
+ },
+ "mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
+ },
+ "mimic-response": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
+ "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
+ "optional": true,
+ "peer": true
+ },
+ "min-document": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
+ "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
+ "requires": {
+ "dom-walk": "^0.1.0"
+ }
+ },
+ "min-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="
+ },
+ "minimalistic-assert": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
+ },
+ "minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ },
+ "mkdirp": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ },
+ "mkdirp-classic": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
+ "optional": true,
+ "peer": true
+ },
+ "mkdirp-promise": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz",
+ "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=",
+ "requires": {
+ "mkdirp": "*"
+ }
+ },
+ "mnemonist": {
+ "version": "0.38.5",
+ "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz",
+ "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==",
+ "requires": {
+ "obliterator": "^2.0.0"
+ }
+ },
+ "mocha": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz",
+ "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==",
+ "requires": {
+ "ansi-colors": "3.2.3",
+ "browser-stdout": "1.3.1",
+ "chokidar": "3.3.0",
+ "debug": "3.2.6",
+ "diff": "3.5.0",
+ "escape-string-regexp": "1.0.5",
+ "find-up": "3.0.0",
+ "glob": "7.1.3",
+ "growl": "1.10.5",
+ "he": "1.2.0",
+ "js-yaml": "3.13.1",
+ "log-symbols": "3.0.0",
+ "minimatch": "3.0.4",
+ "mkdirp": "0.5.5",
+ "ms": "2.1.1",
+ "node-environment-flags": "1.0.6",
+ "object.assign": "4.1.0",
+ "strip-json-comments": "2.0.1",
+ "supports-color": "6.0.0",
+ "which": "1.3.1",
+ "wide-align": "1.1.3",
+ "yargs": "13.3.2",
+ "yargs-parser": "13.1.2",
+ "yargs-unparser": "1.6.0"
+ },
+ "dependencies": {
+ "ansi-colors": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
+ "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw=="
+ },
+ "chokidar": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz",
+ "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==",
+ "requires": {
+ "anymatch": "~3.1.1",
+ "braces": "~3.0.2",
+ "fsevents": "~2.1.1",
+ "glob-parent": "~5.1.0",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.2.0"
+ }
+ },
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "js-yaml": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+ },
+ "supports-color": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
+ "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "mock-fs": {
+ "version": "4.14.0",
+ "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz",
+ "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw=="
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "multibase": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz",
+ "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==",
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ },
+ "multicodec": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz",
+ "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==",
+ "requires": {
+ "varint": "^5.0.0"
+ }
+ },
+ "multihashes": {
+ "version": "0.4.21",
+ "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz",
+ "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==",
+ "requires": {
+ "buffer": "^5.5.0",
+ "multibase": "^0.7.0",
+ "varint": "^5.0.0"
+ },
+ "dependencies": {
+ "multibase": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz",
+ "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==",
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ }
+ }
+ },
+ "murmur-128": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/murmur-128/-/murmur-128-0.2.1.tgz",
+ "integrity": "sha512-WseEgiRkI6aMFBbj8Cg9yBj/y+OdipwVC7zUo3W2W1JAJITwouUOtpqsmGSg67EQmwwSyod7hsVsWY5LsrfQVg==",
+ "requires": {
+ "encode-utf8": "^1.0.2",
+ "fmix": "^0.1.0",
+ "imul": "^1.0.0"
+ }
+ },
+ "mute-stream": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
+ },
+ "nan": {
+ "version": "2.15.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
+ "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
+ "optional": true,
+ "peer": true
+ },
+ "nano-json-stream-parser": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz",
+ "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18="
+ },
+ "nanoid": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
+ "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw=="
+ },
+ "napi-build-utils": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
+ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
+ "optional": true,
+ "peer": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
+ },
+ "negotiator": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
+ },
+ "neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
+ },
+ "next-tick": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
+ },
+ "node-abi": {
+ "version": "2.30.1",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz",
+ "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "semver": "^5.4.1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "optional": true,
+ "peer": true
+ }
+ }
+ },
+ "node-addon-api": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
+ "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA=="
+ },
+ "node-emoji": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz",
+ "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==",
+ "requires": {
+ "lodash": "^4.17.21"
+ }
+ },
+ "node-environment-flags": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
+ "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
+ "requires": {
+ "object.getownpropertydescriptors": "^2.0.3",
+ "semver": "^5.7.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+ }
+ }
+ },
+ "node-fetch": {
+ "version": "2.6.6",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz",
+ "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==",
+ "requires": {
+ "whatwg-url": "^5.0.0"
+ }
+ },
+ "node-gyp-build": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz",
+ "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q=="
+ },
+ "node-hid": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-1.3.0.tgz",
+ "integrity": "sha512-BA6G4V84kiNd1uAChub/Z/5s/xS3EHBCxotQ0nyYrUG65mXewUDHE1tWOSqA2dp3N+mV0Ffq9wo2AW9t4p/G7g==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "bindings": "^1.5.0",
+ "nan": "^2.14.0",
+ "node-abi": "^2.18.0",
+ "prebuild-install": "^5.3.4"
+ }
+ },
+ "nofilter": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz",
+ "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA=="
+ },
+ "noop-logger": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
+ "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=",
+ "optional": true,
+ "peer": true
+ },
+ "nopt": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+ "requires": {
+ "abbrev": "1"
+ }
+ },
+ "normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ }
+ }
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
+ },
+ "normalize-url": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
+ "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA=="
+ },
+ "npm-force-resolutions": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/npm-force-resolutions/-/npm-force-resolutions-0.0.10.tgz",
+ "integrity": "sha512-Jscex+xIU6tw3VsyrwxM1TeT+dd9Fd3UOMAjy6J1TMpuYeEqg4LQZnATQO5vjPrsARm3und6zc6Dii/GUyRE5A==",
+ "requires": {
+ "json-format": "^1.0.1",
+ "source-map-support": "^0.5.5",
+ "xmlhttprequest": "^1.8.0"
+ }
+ },
+ "npmlog": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+ "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
+ }
+ },
+ "nth-check": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
+ "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
+ "requires": {
+ "boolbase": "^1.0.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "devOptional": true
+ },
+ "number-to-bn": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz",
+ "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=",
+ "requires": {
+ "bn.js": "4.11.6",
+ "strip-hex-prefix": "1.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
+ }
+ }
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ },
+ "object-inspect": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
+ "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g=="
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
+ },
+ "object.assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "requires": {
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
+ }
+ },
+ "object.getownpropertydescriptors": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz",
+ "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==",
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.19.1"
+ }
+ },
+ "obliterator": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.1.tgz",
+ "integrity": "sha512-XnkiCrrBcIZQitJPAI36mrrpEUvatbte8hLcTcQwKA1v9NkCKasSi+UAguLsLDs/out7MoRzAlmz7VXvY6ph6w=="
+ },
+ "oboe": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz",
+ "integrity": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=",
+ "requires": {
+ "http-https": "^1.0.0"
+ }
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+ "requires": {
+ "mimic-fn": "^1.0.0"
+ }
+ },
+ "open": {
+ "version": "7.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
+ "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
+ "dev": true,
+ "requires": {
+ "is-docker": "^2.0.0",
+ "is-wsl": "^2.1.1"
+ }
+ },
+ "optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ }
+ },
+ "os-locale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "dev": true,
+ "requires": {
+ "lcid": "^1.0.0"
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
+ },
+ "p-cancelable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw=="
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
+ },
+ "p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "requires": {
+ "p-try": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "requires": {
+ "p-limit": "^1.1.0"
+ }
+ },
+ "p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "requires": {
+ "aggregate-error": "^3.0.0"
+ }
+ },
+ "p-timeout": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
+ "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
+ "requires": {
+ "p-finally": "^1.0.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M="
+ },
+ "pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+ },
+ "parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "requires": {
+ "callsites": "^3.0.0"
+ },
+ "dependencies": {
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
+ }
+ }
+ },
+ "parse-asn1": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
+ "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
+ "requires": {
+ "asn1.js": "^5.2.0",
+ "browserify-aes": "^1.0.0",
+ "evp_bytestokey": "^1.0.0",
+ "pbkdf2": "^3.0.3",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "parse-cache-control": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz",
+ "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104="
+ },
+ "parse-headers": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.4.tgz",
+ "integrity": "sha512-psZ9iZoCNFLrgRjZ1d8mn0h9WRqJwFxM9q3x7iUjN/YT2OksthDJ5TiPCu2F38kS4zutqfW+YdVVkBZZx3/1aw=="
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
+ },
+ "parse5-htmlparser2-tree-adapter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+ "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "requires": {
+ "parse5": "^6.0.1"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
+ },
+ "patch-package": {
+ "version": "6.4.7",
+ "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz",
+ "integrity": "sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==",
+ "dev": true,
+ "requires": {
+ "@yarnpkg/lockfile": "^1.1.0",
+ "chalk": "^2.4.2",
+ "cross-spawn": "^6.0.5",
+ "find-yarn-workspace-root": "^2.0.0",
+ "fs-extra": "^7.0.1",
+ "is-ci": "^2.0.0",
+ "klaw-sync": "^6.0.0",
+ "minimist": "^1.2.0",
+ "open": "^7.4.2",
+ "rimraf": "^2.6.3",
+ "semver": "^5.6.0",
+ "slash": "^2.0.0",
+ "tmp": "^0.0.33"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ },
+ "slash": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "path-browserify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
+ "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM="
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ },
+ "path-starts-with": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-starts-with/-/path-starts-with-2.0.0.tgz",
+ "integrity": "sha512-3UHTHbJz5+NLkPafFR+2ycJOjoc4WV2e9qCZCnm71zHiWaFrm1XniLVTkZXvaRgxr1xFh9JsTdicpH2yM03nLA==",
+ "dev": true
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ },
+ "path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
+ },
+ "pathval": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
+ "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ=="
+ },
+ "pbkdf2": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
+ "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
+ "requires": {
+ "create-hash": "^1.1.2",
+ "create-hmac": "^1.1.4",
+ "ripemd160": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
+ },
+ "pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dev": true,
+ "requires": {
+ "pinkie": "^2.0.0"
+ }
+ },
+ "postinstall-postinstall": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz",
+ "integrity": "sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==",
+ "dev": true
+ },
+ "prebuild-install": {
+ "version": "5.3.6",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz",
+ "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "detect-libc": "^1.0.3",
+ "expand-template": "^2.0.3",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.3",
+ "mkdirp-classic": "^0.5.3",
+ "napi-build-utils": "^1.0.1",
+ "node-abi": "^2.7.0",
+ "noop-logger": "^0.1.1",
+ "npmlog": "^4.0.1",
+ "pump": "^3.0.0",
+ "rc": "^1.2.7",
+ "simple-get": "^3.0.3",
+ "tar-fs": "^2.0.0",
+ "tunnel-agent": "^0.6.0",
+ "which-pm-runs": "^1.0.0"
+ }
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
+ },
+ "prepend-http": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc="
+ },
+ "prettier": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
+ "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
+ "dev": true
+ },
+ "prettier-plugin-solidity": {
+ "version": "1.0.0-beta.19",
+ "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz",
+ "integrity": "sha512-xxRQ5ZiiZyUoMFLE9h7HnUDXI/daf1tnmL1msEdcKmyh7ZGQ4YklkYLC71bfBpYU2WruTb5/SFLUaEb3RApg5g==",
+ "dev": true,
+ "requires": {
+ "@solidity-parser/parser": "^0.14.0",
+ "emoji-regex": "^10.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "semver": "^7.3.5",
+ "solidity-comments-extractor": "^0.0.7",
+ "string-width": "^4.2.3"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true
+ }
+ }
+ },
+ "printj": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
+ "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ=="
+ },
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
+ },
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
+ },
+ "promise": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz",
+ "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==",
+ "requires": {
+ "asap": "~2.0.6"
+ }
+ },
+ "proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "requires": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ }
+ },
+ "prr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY="
+ },
+ "psl": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+ "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
+ },
+ "public-encrypt": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+ "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+ "requires": {
+ "bn.js": "^4.1.0",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "parse-asn1": "^5.0.0",
+ "randombytes": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "punycode": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
+ "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0="
+ },
+ "qs": {
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
+ "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
+ "requires": {
+ "side-channel": "^1.0.4"
+ }
+ },
+ "query-string": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+ "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+ "requires": {
+ "decode-uri-component": "^0.2.0",
+ "object-assign": "^4.1.0",
+ "strict-uri-encode": "^1.0.0"
+ }
+ },
+ "querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+ "dev": true
+ },
+ "queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="
+ },
+ "randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "requires": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "randomfill": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+ "requires": {
+ "randombytes": "^2.0.5",
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
+ },
+ "raw-body": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz",
+ "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==",
+ "requires": {
+ "bytes": "3.1.1",
+ "http-errors": "1.8.1",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
+ "rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ }
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^1.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^1.0.0"
+ },
+ "dependencies": {
+ "path-type": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ }
+ }
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+ "dev": true,
+ "requires": {
+ "find-up": "^1.0.0",
+ "read-pkg": "^1.0.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+ "dev": true,
+ "requires": {
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "requires": {
+ "picomatch": "^2.2.1"
+ }
+ },
+ "rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+ "requires": {
+ "resolve": "^1.1.6"
+ }
+ },
+ "recursive-readdir": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
+ "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==",
+ "requires": {
+ "minimatch": "3.0.4"
+ }
+ },
+ "regexpp": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw=="
+ },
+ "req-cwd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz",
+ "integrity": "sha1-1AgrTURZgDZkD7c93qAe1T20nrw=",
+ "requires": {
+ "req-from": "^2.0.0"
+ }
+ },
+ "req-from": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz",
+ "integrity": "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA=",
+ "requires": {
+ "resolve-from": "^3.0.0"
+ }
+ },
+ "request": {
+ "version": "2.88.2",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.3",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.5.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ },
+ "dependencies": {
+ "form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "qs": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
+ "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA=="
+ },
+ "uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
+ }
+ }
+ },
+ "request-promise-core": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
+ "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
+ "requires": {
+ "lodash": "^4.17.19"
+ }
+ },
+ "request-promise-native": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
+ "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
+ "requires": {
+ "request-promise-core": "1.1.4",
+ "stealthy-require": "^1.1.1",
+ "tough-cookie": "^2.3.3"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
+ },
+ "require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
+ },
+ "require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
+ },
+ "resolve": {
+ "version": "1.21.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz",
+ "integrity": "sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==",
+ "requires": {
+ "is-core-module": "^2.8.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
+ },
+ "responselike": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+ "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+ "requires": {
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+ "requires": {
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="
+ },
+ "rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "ripemd160": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
+ "rlp": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz",
+ "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==",
+ "requires": {
+ "bn.js": "^5.2.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
+ }
+ }
+ },
+ "run-async": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ=="
+ },
+ "run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "requires": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "rustbn.js": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz",
+ "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA=="
+ },
+ "rxjs": {
+ "version": "6.6.7",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+ "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+ "requires": {
+ "tslib": "^1.9.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "sc-istanbul": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz",
+ "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==",
+ "requires": {
+ "abbrev": "1.0.x",
+ "async": "1.x",
+ "escodegen": "1.8.x",
+ "esprima": "2.7.x",
+ "glob": "^5.0.15",
+ "handlebars": "^4.0.1",
+ "js-yaml": "3.x",
+ "mkdirp": "0.5.x",
+ "nopt": "3.x",
+ "once": "1.x",
+ "resolve": "1.1.x",
+ "supports-color": "^3.1.0",
+ "which": "^1.1.1",
+ "wordwrap": "^1.0.0"
+ },
+ "dependencies": {
+ "async": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
+ },
+ "esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE="
+ },
+ "glob": {
+ "version": "5.0.15",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+ "requires": {
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "2 || 3",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "^1.0.0"
+ }
+ }
+ }
+ },
+ "scrypt-js": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",
+ "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA=="
+ },
+ "secp256k1": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz",
+ "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==",
+ "requires": {
+ "elliptic": "^6.5.4",
+ "node-addon-api": "^2.0.0",
+ "node-gyp-build": "^4.2.0"
+ }
+ },
+ "semaphore-async-await": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz",
+ "integrity": "sha1-hXvvXjZEYBykuVcLh+nfXKEpdPo="
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "requires": {
+ "lru-cache": "^6.0.0"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ }
+ }
+ },
+ "send": {
+ "version": "0.17.2",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz",
+ "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==",
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "1.8.1",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ }
+ }
+ },
+ "serialize-javascript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
+ "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+ "requires": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "serve-static": {
+ "version": "1.14.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz",
+ "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==",
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.2"
+ }
+ },
+ "servify": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz",
+ "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==",
+ "requires": {
+ "body-parser": "^1.16.0",
+ "cors": "^2.8.1",
+ "express": "^4.14.0",
+ "request": "^2.79.0",
+ "xhr": "^2.3.3"
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+ },
+ "setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
+ },
+ "setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+ },
+ "sha.js": {
+ "version": "2.4.11",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "sha1": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz",
+ "integrity": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=",
+ "requires": {
+ "charenc": ">= 0.0.1",
+ "crypt": ">= 0.0.1"
+ }
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
+ },
+ "shelljs": {
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
+ "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
+ "requires": {
+ "glob": "^7.0.0",
+ "interpret": "^1.0.0",
+ "rechoir": "^0.6.2"
+ }
+ },
+ "side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "requires": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ }
+ },
+ "signal-exit": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz",
+ "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ=="
+ },
+ "simple-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="
+ },
+ "simple-get": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
+ "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "decompress-response": "^4.2.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
+ },
+ "slice-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+ "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "astral-regex": "^1.0.0",
+ "is-fullwidth-code-point": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
+ }
+ }
+ },
+ "solc": {
+ "version": "0.6.12",
+ "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz",
+ "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==",
+ "dev": true,
+ "requires": {
+ "command-exists": "^1.2.8",
+ "commander": "3.0.2",
+ "fs-extra": "^0.30.0",
+ "js-sha3": "0.8.0",
+ "memorystream": "^0.3.1",
+ "require-from-string": "^2.0.0",
+ "semver": "^5.5.0",
+ "tmp": "0.0.33"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz",
+ "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==",
+ "dev": true
+ },
+ "fs-extra": {
+ "version": "0.30.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+ "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0",
+ "path-is-absolute": "^1.0.0",
+ "rimraf": "^2.2.8"
+ }
+ },
+ "jsonfile": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ }
+ }
+ },
+ "solhint": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.3.6.tgz",
+ "integrity": "sha512-HWUxTAv2h7hx3s3hAab3ifnlwb02ZWhwFU/wSudUHqteMS3ll9c+m1FlGn9V8ztE2rf3Z82fQZA005Wv7KpcFA==",
+ "requires": {
+ "@solidity-parser/parser": "^0.13.2",
+ "ajv": "^6.6.1",
+ "antlr4": "4.7.1",
+ "ast-parents": "0.0.1",
+ "chalk": "^2.4.2",
+ "commander": "2.18.0",
+ "cosmiconfig": "^5.0.7",
+ "eslint": "^5.6.0",
+ "fast-diff": "^1.1.2",
+ "glob": "^7.1.3",
+ "ignore": "^4.0.6",
+ "js-yaml": "^3.12.0",
+ "lodash": "^4.17.11",
+ "prettier": "^1.14.3",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "@solidity-parser/parser": {
+ "version": "0.13.2",
+ "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.13.2.tgz",
+ "integrity": "sha512-RwHnpRnfrnD2MSPveYoPh8nhofEvX7fgjHk1Oq+NNvCcLx4r1js91CO9o+F/F3fBzOCyvm8kKRTriFICX/odWw==",
+ "requires": {
+ "antlr4ts": "^0.5.0-alpha.4"
+ }
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "commander": {
+ "version": "2.18.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz",
+ "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ=="
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "prettier": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
+ "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
+ "optional": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "solidity-comments-extractor": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz",
+ "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==",
+ "dev": true
+ },
+ "solidity-coverage": {
+ "version": "0.7.20",
+ "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.20.tgz",
+ "integrity": "sha512-edOXTugUYdqxrtEnIn4vgrGjLPxdexcL0WD8LzAvVA3d1dwgcfRO3k8xQR02ZQnOnWMBi8Cqs0F+kAQQp3JW8g==",
+ "requires": {
+ "@solidity-parser/parser": "^0.14.0",
+ "@truffle/provider": "^0.2.24",
+ "chalk": "^2.4.2",
+ "death": "^1.1.0",
+ "detect-port": "^1.3.0",
+ "fs-extra": "^8.1.0",
+ "ghost-testrpc": "^0.0.2",
+ "global-modules": "^2.0.0",
+ "globby": "^10.0.1",
+ "jsonschema": "^1.2.4",
+ "lodash": "^4.17.15",
+ "node-emoji": "^1.10.0",
+ "pify": "^4.0.1",
+ "recursive-readdir": "^2.2.2",
+ "sc-istanbul": "^0.4.5",
+ "semver": "^7.3.4",
+ "shelljs": "^0.8.3",
+ "web3-utils": "^1.3.0"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ }
+ }
+ },
+ "source-map": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
+ "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
+ "optional": true,
+ "requires": {
+ "amdefine": ">=0.0.4"
+ }
+ },
+ "source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ }
+ }
+ },
+ "spdx-correct": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "dev": true,
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz",
+ "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==",
+ "dev": true
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
+ },
+ "sshpk": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
+ "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ },
+ "dependencies": {
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+ }
+ }
+ },
+ "stacktrace-parser": {
+ "version": "0.1.10",
+ "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz",
+ "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==",
+ "requires": {
+ "type-fest": "^0.7.1"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz",
+ "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="
+ }
+ }
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
+ },
+ "stealthy-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+ "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
+ },
+ "strict-uri-encode": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
+ },
+ "string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ }
+ }
+ },
+ "string.prototype.trimend": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
+ "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ }
+ },
+ "string.prototype.trimstart": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
+ "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ }
+ },
+ "string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "requires": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+ "dev": true,
+ "requires": {
+ "is-utf8": "^0.2.0"
+ }
+ },
+ "strip-hex-prefix": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
+ "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
+ "requires": {
+ "is-hex-prefixed": "1.0.0"
+ }
+ },
+ "strip-indent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
+ "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g="
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
+ },
+ "super-split": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/super-split/-/super-split-1.1.0.tgz",
+ "integrity": "sha512-I4bA5mgcb6Fw5UJ+EkpzqXfiuvVGS/7MuND+oBxNFmxu3ugLNrdIatzBLfhFRMVMLxgSsRy+TjIktgkF9RFSNQ=="
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
+ },
+ "swarm-js": {
+ "version": "0.1.40",
+ "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz",
+ "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==",
+ "requires": {
+ "bluebird": "^3.5.0",
+ "buffer": "^5.0.5",
+ "eth-lib": "^0.1.26",
+ "fs-extra": "^4.0.2",
+ "got": "^7.1.0",
+ "mime-types": "^2.1.16",
+ "mkdirp-promise": "^5.0.1",
+ "mock-fs": "^4.1.0",
+ "setimmediate": "^1.0.5",
+ "tar": "^4.0.2",
+ "xhr-request": "^1.0.1"
+ },
+ "dependencies": {
+ "chownr": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
+ },
+ "decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "fs-extra": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
+ "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "fs-minipass": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
+ "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
+ "requires": {
+ "minipass": "^2.6.0"
+ }
+ },
+ "get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
+ },
+ "got": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
+ "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
+ "requires": {
+ "decompress-response": "^3.2.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^3.0.0",
+ "is-plain-obj": "^1.1.0",
+ "is-retry-allowed": "^1.0.0",
+ "is-stream": "^1.0.0",
+ "isurl": "^1.0.0-alpha5",
+ "lowercase-keys": "^1.0.0",
+ "p-cancelable": "^0.3.0",
+ "p-timeout": "^1.1.1",
+ "safe-buffer": "^5.0.1",
+ "timed-out": "^4.0.0",
+ "url-parse-lax": "^1.0.0",
+ "url-to-options": "^1.0.1"
+ }
+ },
+ "mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="
+ },
+ "minipass": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
+ "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+ "requires": {
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.0"
+ }
+ },
+ "minizlib": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
+ "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
+ "requires": {
+ "minipass": "^2.9.0"
+ }
+ },
+ "p-cancelable": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
+ "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw=="
+ },
+ "prepend-http": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
+ },
+ "tar": {
+ "version": ">=4.4.18",
+ "requires": {
+ "chownr": "^1.1.4",
+ "fs-minipass": "^1.2.7",
+ "minipass": "^2.9.0",
+ "minizlib": "^1.3.3",
+ "mkdirp": "^0.5.5",
+ "safe-buffer": "^5.2.1",
+ "yallist": "^3.1.1"
+ }
+ },
+ "url-parse-lax": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+ "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+ "requires": {
+ "prepend-http": "^1.0.1"
+ }
+ }
+ }
+ },
+ "sync-request": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz",
+ "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==",
+ "requires": {
+ "http-response-object": "^3.0.1",
+ "sync-rpc": "^1.2.1",
+ "then-request": "^6.0.0"
+ }
+ },
+ "sync-rpc": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz",
+ "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==",
+ "requires": {
+ "get-port": "^3.1.0"
+ }
+ },
+ "table": {
+ "version": "5.4.6",
+ "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
+ "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
+ "requires": {
+ "ajv": "^6.10.2",
+ "lodash": "^4.17.14",
+ "slice-ansi": "^2.1.0",
+ "string-width": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "tar-fs": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+ "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "chownr": "^1.1.1",
+ "mkdirp-classic": "^0.5.2",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.1.4"
+ },
+ "dependencies": {
+ "chownr": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+ "optional": true,
+ "peer": true
+ }
+ }
+ },
+ "tar-stream": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "bl": "^4.0.3",
+ "end-of-stream": "^1.4.1",
+ "fs-constants": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1"
+ }
+ },
+ "test-value": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz",
+ "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=",
+ "dev": true,
+ "requires": {
+ "array-back": "^1.0.3",
+ "typical": "^2.6.0"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+ "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+ "dev": true,
+ "requires": {
+ "typical": "^2.6.0"
+ }
+ }
+ }
+ },
+ "testrpc": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz",
+ "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==",
+ "dev": true
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ="
+ },
+ "then-request": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz",
+ "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==",
+ "requires": {
+ "@types/concat-stream": "^1.6.0",
+ "@types/form-data": "0.0.33",
+ "@types/node": "^8.0.0",
+ "@types/qs": "^6.2.31",
+ "caseless": "~0.12.0",
+ "concat-stream": "^1.6.0",
+ "form-data": "^2.2.0",
+ "http-basic": "^8.1.1",
+ "http-response-object": "^3.0.1",
+ "promise": "^8.0.0",
+ "qs": "^6.4.0"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "8.10.66",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz",
+ "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw=="
+ },
+ "form-data": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
+ "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ }
+ }
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
+ },
+ "timed-out": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8="
+ },
+ "tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "requires": {
+ "os-tmpdir": "~1.0.2"
+ }
+ },
+ "to-readable-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+ "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q=="
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
+ },
+ "tough-cookie": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+ "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "requires": {
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+ }
+ }
+ },
+ "tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
+ },
+ "true-case-path": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz",
+ "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q=="
+ },
+ "truffle-assertions": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/truffle-assertions/-/truffle-assertions-0.9.2.tgz",
+ "integrity": "sha512-9g2RhaxU2F8DeWhqoGQvL/bV8QVoSnQ6PY+ZPvYRP5eF7+/8LExb4mjLx/FeliLTjc3Tv1SABG05Gu5qQ/ErmA==",
+ "requires": {
+ "assertion-error": "^1.1.0",
+ "lodash.isequal": "^4.5.0"
+ }
+ },
+ "ts-essentials": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz",
+ "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==",
+ "dev": true
+ },
+ "ts-generator": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz",
+ "integrity": "sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==",
+ "dev": true,
+ "requires": {
+ "@types/mkdirp": "^0.5.2",
+ "@types/prettier": "^2.1.1",
+ "@types/resolve": "^0.0.8",
+ "chalk": "^2.4.1",
+ "glob": "^7.1.2",
+ "mkdirp": "^0.5.1",
+ "prettier": "^2.1.2",
+ "resolve": "^1.8.1",
+ "ts-essentials": "^1.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "tslib": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
+ },
+ "tsort": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz",
+ "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y="
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
+ "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw=="
+ },
+ "tweetnacl-util": {
+ "version": "0.15.1",
+ "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz",
+ "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw=="
+ },
+ "type": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ },
+ "type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="
+ },
+ "type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="
+ },
+ "type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ }
+ },
+ "typechain": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/typechain/-/typechain-3.0.0.tgz",
+ "integrity": "sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg==",
+ "dev": true,
+ "requires": {
+ "command-line-args": "^4.0.7",
+ "debug": "^4.1.1",
+ "fs-extra": "^7.0.0",
+ "js-sha3": "^0.8.0",
+ "lodash": "^4.17.15",
+ "ts-essentials": "^6.0.3",
+ "ts-generator": "^0.1.1"
+ },
+ "dependencies": {
+ "ts-essentials": {
+ "version": "6.0.7",
+ "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz",
+ "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==",
+ "dev": true
+ }
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
+ },
+ "typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "requires": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "typescript": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
+ "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
+ "dev": true,
+ "peer": true
+ },
+ "typical": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
+ "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
+ "dev": true
+ },
+ "u2f-api": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/u2f-api/-/u2f-api-0.2.7.tgz",
+ "integrity": "sha512-fqLNg8vpvLOD5J/z4B6wpPg4Lvowz1nJ9xdHcCzdUPKcFE/qNCceV2gNZxSJd5vhAZemHr/K/hbzVA0zxB5mkg==",
+ "peer": true
+ },
+ "uglify-js": {
+ "version": "3.14.5",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.5.tgz",
+ "integrity": "sha512-qZukoSxOG0urUTvjc2ERMTcAy+BiFh3weWAkeurLwjrCba73poHmG3E36XEjd/JGukMzwTL7uCxZiAexj8ppvQ==",
+ "optional": true
+ },
+ "ultron": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
+ "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
+ },
+ "unbox-primitive": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
+ "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has-bigints": "^1.0.1",
+ "has-symbols": "^1.0.2",
+ "which-boxed-primitive": "^1.0.2"
+ }
+ },
+ "underscore": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz",
+ "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g=="
+ },
+ "undici": {
+ "version": "4.16.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-4.16.0.tgz",
+ "integrity": "sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw=="
+ },
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ },
+ "uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "url": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+ "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+ "dev": true
+ }
+ }
+ },
+ "url-parse-lax": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+ "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+ "requires": {
+ "prepend-http": "^2.0.0"
+ }
+ },
+ "url-set-query": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz",
+ "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk="
+ },
+ "url-to-options": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
+ "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k="
+ },
+ "usb": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/usb/-/usb-1.9.2.tgz",
+ "integrity": "sha512-dryNz030LWBPAf6gj8vyq0Iev3vPbCLHCT8dBw3gQRXRzVNsIdeuU+VjPp3ksmSPkeMAl1k+kQ14Ij0QHyeiAg==",
+ "optional": true,
+ "peer": true,
+ "requires": {
+ "node-addon-api": "^4.2.0",
+ "node-gyp-build": "^4.3.0"
+ },
+ "dependencies": {
+ "node-addon-api": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.2.0.tgz",
+ "integrity": "sha512-eazsqzwG2lskuzBqCGPi7Ac2UgOoMz8JVOXVhTvvPDYhthvNpefx8jWD8Np7Gv+2Sz0FlPWZk0nJV0z598Wn8Q==",
+ "optional": true,
+ "peer": true
+ }
+ }
+ },
+ "utf-8-validate": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz",
+ "integrity": "sha512-k4dW/Qja1BYDl2qD4tOMB9PFVha/UJtxTc1cXYOe3WwA/2m0Yn4qB7wLMpJyLJ/7DR0XnTut3HsCSzDT4ZvKgA==",
+ "requires": {
+ "node-gyp-build": "^4.3.0"
+ }
+ },
+ "utf8": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz",
+ "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ=="
+ },
+ "util": {
+ "version": "0.12.4",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz",
+ "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "is-arguments": "^1.0.4",
+ "is-generator-function": "^1.0.7",
+ "is-typed-array": "^1.1.3",
+ "safe-buffer": "^5.1.2",
+ "which-typed-array": "^1.1.2"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
+ },
+ "uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "varint": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
+ "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "web3": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3/-/web3-1.6.1.tgz",
+ "integrity": "sha512-c299lLiyb2/WOcxh7TinwvbATaMmrgNIeAzbLbmOKHI0LcwyfsB1eu2ReOIrfrCYDYRW2KAjYr7J7gHawqDNPQ==",
+ "requires": {
+ "web3-bzz": "1.6.1",
+ "web3-core": "1.6.1",
+ "web3-eth": "1.6.1",
+ "web3-eth-personal": "1.6.1",
+ "web3-net": "1.6.1",
+ "web3-shh": "1.6.1",
+ "web3-utils": "1.6.1"
+ }
+ },
+ "web3-bzz": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.6.1.tgz",
+ "integrity": "sha512-JbnFNbRlwwHJZPtVuCxo7rC4U4OTg+mPsyhjgPQJJhS0a6Y54OgVWYk9UA/95HqbmTJwTtX329gJoSsseEfrng==",
+ "requires": {
+ "@types/node": "^12.12.6",
+ "got": "9.6.0",
+ "swarm-js": "^0.1.40"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "12.20.41",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz",
+ "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q=="
+ }
+ }
+ },
+ "web3-core": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.6.1.tgz",
+ "integrity": "sha512-m+b7UfYvU5cQUAh6NRfxRzH/5B3to1AdEQi1HIQt570cDWlObOOmoO9tY6iJnI5w4acxIO19LqjDMqEJGBYyRQ==",
+ "requires": {
+ "@types/bn.js": "^4.11.5",
+ "@types/node": "^12.12.6",
+ "bignumber.js": "^9.0.0",
+ "web3-core-helpers": "1.6.1",
+ "web3-core-method": "1.6.1",
+ "web3-core-requestmanager": "1.6.1",
+ "web3-utils": "1.6.1"
+ },
+ "dependencies": {
+ "@types/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/node": {
+ "version": "12.20.41",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz",
+ "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q=="
+ }
+ }
+ },
+ "web3-core-helpers": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.6.1.tgz",
+ "integrity": "sha512-om2PZvK1uoWcgMq6JfcSx3241LEIVF6qi2JuHz2SLKiKEW5UsBUaVx0mNCmcZaiuYQCyOsLS3r33q5AdM+v8ng==",
+ "requires": {
+ "web3-eth-iban": "1.6.1",
+ "web3-utils": "1.6.1"
+ }
+ },
+ "web3-core-method": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.6.1.tgz",
+ "integrity": "sha512-szH5KyIWIaULQDBdDvevQUCHV9lsExJ/oV0ePqK+w015D2SdMPMuhii0WB+HCePaksWO+rr/GAypvV9g2T3N+w==",
+ "requires": {
+ "@ethersproject/transactions": "^5.0.0-beta.135",
+ "web3-core-helpers": "1.6.1",
+ "web3-core-promievent": "1.6.1",
+ "web3-core-subscriptions": "1.6.1",
+ "web3-utils": "1.6.1"
+ }
+ },
+ "web3-core-promievent": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.6.1.tgz",
+ "integrity": "sha512-byJ5s2MQxrWdXd27pWFmujfzsTZK4ik8rDgIV1RFDFc+rHZ2nZhq+VWk7t/Nkrj7EaVXncEgTdPEHc18nx+ocQ==",
+ "requires": {
+ "eventemitter3": "4.0.4"
+ }
+ },
+ "web3-core-requestmanager": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.6.1.tgz",
+ "integrity": "sha512-4y7etYEUtkfflyYVBfN1oJtCbVFNhNX1omlEYzezhTnPj3/dT7n+dhUXcqvIhx9iKA13unGfpFge80XNFfcB8A==",
+ "requires": {
+ "util": "^0.12.0",
+ "web3-core-helpers": "1.6.1",
+ "web3-providers-http": "1.6.1",
+ "web3-providers-ipc": "1.6.1",
+ "web3-providers-ws": "1.6.1"
+ }
+ },
+ "web3-core-subscriptions": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.6.1.tgz",
+ "integrity": "sha512-WZwxsYttIojyGQ5RqxuQcKg0IJdDCFpUe4EncS3QKZwxPqWzGmgyLwE0rm7tP+Ux1waJn5CUaaoSCBxWGSun1g==",
+ "requires": {
+ "eventemitter3": "4.0.4",
+ "web3-core-helpers": "1.6.1"
+ }
+ },
+ "web3-eth": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.6.1.tgz",
+ "integrity": "sha512-kOV1ZgCKypSo5BQyltRArS7ZC3bRpIKAxSgzl7pUFinUb/MxfbM9KGeNxUXoCfTSErcCQJaDjcS6bSre5EMKuQ==",
+ "requires": {
+ "web3-core": "1.6.1",
+ "web3-core-helpers": "1.6.1",
+ "web3-core-method": "1.6.1",
+ "web3-core-subscriptions": "1.6.1",
+ "web3-eth-abi": "1.6.1",
+ "web3-eth-accounts": "1.6.1",
+ "web3-eth-contract": "1.6.1",
+ "web3-eth-ens": "1.6.1",
+ "web3-eth-iban": "1.6.1",
+ "web3-eth-personal": "1.6.1",
+ "web3-net": "1.6.1",
+ "web3-utils": "1.6.1"
+ }
+ },
+ "web3-eth-abi": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.6.1.tgz",
+ "integrity": "sha512-svhYrAlXP9XQtV7poWKydwDJq2CaNLMtmKydNXoOBLcQec6yGMP+v20pgrxF2H6wyTK+Qy0E3/5ciPOqC/VuoQ==",
+ "requires": {
+ "@ethersproject/abi": "5.0.7",
+ "web3-utils": "1.6.1"
+ },
+ "dependencies": {
+ "@ethersproject/abi": {
+ "version": "5.0.7",
+ "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz",
+ "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==",
+ "requires": {
+ "@ethersproject/address": "^5.0.4",
+ "@ethersproject/bignumber": "^5.0.7",
+ "@ethersproject/bytes": "^5.0.4",
+ "@ethersproject/constants": "^5.0.4",
+ "@ethersproject/hash": "^5.0.4",
+ "@ethersproject/keccak256": "^5.0.3",
+ "@ethersproject/logger": "^5.0.5",
+ "@ethersproject/properties": "^5.0.3",
+ "@ethersproject/strings": "^5.0.4"
+ }
+ }
+ }
+ },
+ "web3-eth-accounts": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.6.1.tgz",
+ "integrity": "sha512-rGn3jwnuOKwaQRu4SiShz0YAQ87aVDBKs4HO43+XTCI1q1Y1jn3NOsG3BW9ZHaOckev4+zEyxze/Bsh2oEk24w==",
+ "requires": {
+ "@ethereumjs/common": "^2.5.0",
+ "@ethereumjs/tx": "^3.3.2",
+ "crypto-browserify": "3.12.0",
+ "eth-lib": "0.2.8",
+ "ethereumjs-util": "^7.0.10",
+ "scrypt-js": "^3.0.1",
+ "uuid": "3.3.2",
+ "web3-core": "1.6.1",
+ "web3-core-helpers": "1.6.1",
+ "web3-core-method": "1.6.1",
+ "web3-utils": "1.6.1"
+ },
+ "dependencies": {
+ "eth-lib": {
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
+ "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
+ "requires": {
+ "bn.js": "^4.11.6",
+ "elliptic": "^6.4.0",
+ "xhr-request-promise": "^0.1.2"
+ }
+ },
+ "uuid": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
+ }
+ }
+ },
+ "web3-eth-contract": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.6.1.tgz",
+ "integrity": "sha512-GXqTe3mF6kpbOAakiNc7wtJ120/gpuKMTZjuGFKeeY8aobRLfbfgKzM9IpyqVZV2v5RLuGXDuurVN2KPgtu3hQ==",
+ "requires": {
+ "@types/bn.js": "^4.11.5",
+ "web3-core": "1.6.1",
+ "web3-core-helpers": "1.6.1",
+ "web3-core-method": "1.6.1",
+ "web3-core-promievent": "1.6.1",
+ "web3-core-subscriptions": "1.6.1",
+ "web3-eth-abi": "1.6.1",
+ "web3-utils": "1.6.1"
+ },
+ "dependencies": {
+ "@types/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+ "requires": {
+ "@types/node": "*"
+ }
+ }
+ }
+ },
+ "web3-eth-ens": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.6.1.tgz",
+ "integrity": "sha512-ngprtbnoRgxg8s1wXt9nXpD3h1P+p7XnKXrp/8GdFI9uDmrbSQPRfzBw86jdZgOmy78hAnWmrHI6pBInmgi2qQ==",
+ "requires": {
+ "content-hash": "^2.5.2",
+ "eth-ens-namehash": "2.0.8",
+ "web3-core": "1.6.1",
+ "web3-core-helpers": "1.6.1",
+ "web3-core-promievent": "1.6.1",
+ "web3-eth-abi": "1.6.1",
+ "web3-eth-contract": "1.6.1",
+ "web3-utils": "1.6.1"
+ }
+ },
+ "web3-eth-iban": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.6.1.tgz",
+ "integrity": "sha512-91H0jXZnWlOoXmc13O9NuQzcjThnWyAHyDn5Yf7u6mmKOhpJSGF/OHlkbpXt1Y4v2eJdEPaVFa+6i8aRyagE7Q==",
+ "requires": {
+ "bn.js": "^4.11.9",
+ "web3-utils": "1.6.1"
+ }
+ },
+ "web3-eth-personal": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.6.1.tgz",
+ "integrity": "sha512-ItsC89Ln02+irzJjK6ALcLrMZfbVUCqVbmb/ieDKJ+eLW3pNkBNwoUzaydh92d5NzxNZgNxuQWVdlFyYX2hkEw==",
+ "requires": {
+ "@types/node": "^12.12.6",
+ "web3-core": "1.6.1",
+ "web3-core-helpers": "1.6.1",
+ "web3-core-method": "1.6.1",
+ "web3-net": "1.6.1",
+ "web3-utils": "1.6.1"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "12.20.41",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz",
+ "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q=="
+ }
+ }
+ },
+ "web3-net": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.6.1.tgz",
+ "integrity": "sha512-gpnqKEIwfUHh5ik7wsQFlCje1DfcmGv+Sk7LCh1hCqn++HEDQxJ/mZCrMo11ZZpZHCH7c87imdxTg96GJnRxDw==",
+ "requires": {
+ "web3-core": "1.6.1",
+ "web3-core-method": "1.6.1",
+ "web3-utils": "1.6.1"
+ }
+ },
+ "web3-providers-http": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.6.1.tgz",
+ "integrity": "sha512-xBoKOJxu10+kO3ikamXmBfrWZ/xpQOGy0ocdp7Y81B17En5TXELwlmMXt1UlIgWiyYDhjq4OwlH/VODYqHXy3A==",
+ "requires": {
+ "web3-core-helpers": "1.6.1",
+ "xhr2-cookies": "1.1.0"
+ }
+ },
+ "web3-providers-ipc": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.6.1.tgz",
+ "integrity": "sha512-anyoIZlpMzwEQI4lwylTzDrHsVp20v0QUtSTp2B5jInBinmQtyCE7vnbX20jEQ4j5uPwfJabKNtoJsk6a3O4WQ==",
+ "requires": {
+ "oboe": "2.1.5",
+ "web3-core-helpers": "1.6.1"
+ }
+ },
+ "web3-providers-ws": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.6.1.tgz",
+ "integrity": "sha512-FWMEFYb4rYFYRgSFBf/O1Ex4p/YKSlN+JydCtdlJwRimd89qm95CTfs4xGjCskwvXMjV2sarH+f1NPwJXicYpg==",
+ "requires": {
+ "eventemitter3": "4.0.4",
+ "web3-core-helpers": "1.6.1",
+ "websocket": "^1.0.32"
+ }
+ },
+ "web3-shh": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.6.1.tgz",
+ "integrity": "sha512-oP00HbAtybLCGlLOZUYXOdeB9xq88k2l0TtStvKBtmFqRt+zVk5TxEeuOnVPRxNhcA2Un8RUw6FtvgZlWStu9A==",
+ "requires": {
+ "web3-core": "1.6.1",
+ "web3-core-method": "1.6.1",
+ "web3-core-subscriptions": "1.6.1",
+ "web3-net": "1.6.1"
+ }
+ },
+ "web3-utils": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.1.tgz",
+ "integrity": "sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w==",
+ "requires": {
+ "bn.js": "^4.11.9",
+ "ethereum-bloom-filters": "^1.0.6",
+ "ethereumjs-util": "^7.1.0",
+ "ethjs-unit": "0.1.6",
+ "number-to-bn": "1.7.0",
+ "randombytes": "^2.1.0",
+ "utf8": "3.0.0"
+ }
+ },
+ "webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
+ },
+ "websocket": {
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz",
+ "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==",
+ "requires": {
+ "bufferutil": "^4.0.1",
+ "debug": "^2.2.0",
+ "es5-ext": "^0.10.50",
+ "typedarray-to-buffer": "^3.1.5",
+ "utf-8-validate": "^5.0.2",
+ "yaeti": "^0.0.6"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
+ "requires": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "which-boxed-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+ "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+ "requires": {
+ "is-bigint": "^1.0.1",
+ "is-boolean-object": "^1.1.0",
+ "is-number-object": "^1.0.4",
+ "is-string": "^1.0.5",
+ "is-symbol": "^1.0.3"
+ }
+ },
+ "which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
+ },
+ "which-pm-runs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
+ "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=",
+ "optional": true,
+ "peer": true
+ },
+ "which-typed-array": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz",
+ "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==",
+ "requires": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "es-abstract": "^1.18.5",
+ "foreach": "^2.0.5",
+ "has-tostringtag": "^1.0.0",
+ "is-typed-array": "^1.1.7"
+ }
+ },
+ "wide-align": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+ "requires": {
+ "string-width": "^1.0.2 || 2"
+ },
+ "dependencies": {
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ }
+ }
+ },
+ "window-size": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
+ "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=",
+ "dev": true
+ },
+ "word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
+ },
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
+ },
+ "workerpool": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
+ "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A=="
+ },
+ "wrap-ansi": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+ "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "string-width": "^3.0.0",
+ "strip-ansi": "^5.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "write": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+ "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
+ "requires": {
+ "mkdirp": "^0.5.1"
+ }
+ },
+ "ws": {
+ "version": "7.4.6",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
+ "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A=="
+ },
+ "xhr": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz",
+ "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==",
+ "requires": {
+ "global": "~4.4.0",
+ "is-function": "^1.0.1",
+ "parse-headers": "^2.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "xhr-request": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz",
+ "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==",
+ "requires": {
+ "buffer-to-arraybuffer": "^0.0.5",
+ "object-assign": "^4.1.1",
+ "query-string": "^5.0.1",
+ "simple-get": "^2.7.0",
+ "timed-out": "^4.0.1",
+ "url-set-query": "^1.0.0",
+ "xhr": "^2.0.4"
+ },
+ "dependencies": {
+ "decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="
+ },
+ "simple-get": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
+ "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
+ "requires": {
+ "decompress-response": "^3.3.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ }
+ }
+ },
+ "xhr-request-promise": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz",
+ "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==",
+ "requires": {
+ "xhr-request": "^1.1.0"
+ }
+ },
+ "xhr2-cookies": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz",
+ "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=",
+ "requires": {
+ "cookiejar": "^2.1.1"
+ }
+ },
+ "xmlhttprequest": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
+ "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw="
+ },
+ "xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
+ },
+ "y18n": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
+ },
+ "yaeti": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
+ "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc="
+ },
+ "yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+ },
+ "yargs": {
+ "version": "13.3.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+ "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+ "requires": {
+ "cliui": "^5.0.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^3.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^13.1.2"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+ "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
+ }
+ }
+ },
+ "yargs-unparser": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
+ "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
+ "requires": {
+ "flat": "^4.1.0",
+ "lodash": "^4.17.15",
+ "yargs": "^13.3.0"
+ }
+ },
+ "yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
+ }
+ }
+}
\ No newline at end of file
diff --git a/bridge/package.json b/bridge/package.json
new file mode 100644
index 000000000..838397ddd
--- /dev/null
+++ b/bridge/package.json
@@ -0,0 +1,68 @@
+{
+ "name": "bridge",
+ "private": true,
+ "version": "3.0.0",
+ "description": "Token Bridge Contracts",
+ "scripts": {
+ "preinstall": "npx npm-force-resolutions",
+ "ganache": "npx ganache-cli --quiet -i 5777 --chainId 5777 -k istanbul",
+ "ganache-mirror": "npx ganache-cli --quiet -i 5776 --chainId 5776 -p 8546 -k istanbul",
+ "start": "npm run lint && npm run migrate && npm run test",
+ "lint": "npx solhint \"contracts/**/*.sol\"",
+ "compile": "npx hardhat compile --show-stack-traces",
+ "test": "npx hardhat test --show-stack-traces",
+ "coverage": "npx hardhat coverage",
+ "size": "npx hardhat size-contracts",
+ "flatten": "npx waffle flatten",
+ "deployFromScratchTag": "npx hardhat deploy --tags DeployFromScratch --show-stack-traces --network",
+ "deployUpgradeTag": "npx hardhat deploy --tags Upgrade --show-stack-traces --network",
+ "deployIntegrationTag": "hardhat deploy --tags IntegrationTest --show-stack-traces --network",
+ "deployLocalIntegrationTest": "npm run deployIntegrationTag development && npm run deployIntegrationTag mirrorDevelopment",
+ "reDeployLocalIntegrationTest": "ps aux | grep ganache-cli | awk '{print $2}' | xargs kill -9 & npm run ganache & npm run ganache-mirror & npm run deployLocalIntegrationTest"
+ },
+ "keywords": [
+ "rsk",
+ "erc20",
+ "token",
+ "bridge",
+ "ethereum"
+ ],
+ "author": "IOVLabs",
+ "engines": {
+ "node": "16"
+ },
+ "dependencies": {
+ "@nomiclabs/hardhat-etherscan": "^3.0.1",
+ "@nomiclabs/hardhat-truffle5": "^2.0.0",
+ "@nomiclabs/hardhat-web3": "^2.0.0",
+ "@thinkanddev/deploy-eip-1820-web3-rsk": "^1.0.2",
+ "@thinkanddev/hardhat-erc1820-rsk": "^0.1.2",
+ "@truffle/compile-common": "^0.7.15",
+ "chalk": "^4.1.0",
+ "hardhat-contract-sizer": "^2.3.0",
+ "hardhat-deploy": "^0.9.24",
+ "hardhat-gas-reporter": "^1.0.6",
+ "npm-force-resolutions": "0.0.10",
+ "resolve": "^1.21.0",
+ "solhint": "^3.3.6",
+ "solidity-coverage": "^0.7.20",
+ "truffle-assertions": "^0.9.2"
+ },
+ "devDependencies": {
+ "coveralls": "^3.1.1",
+ "ethereum-waffle": "^3.4.0",
+ "hardhat": "^2.9.3",
+ "hardhat-abi-exporter": "^2.2.1",
+ "prettier": "^2.3.2",
+ "prettier-plugin-solidity": "^1.0.0-beta.17"
+ },
+ "prettier": {
+ "parser": "json5",
+ "printWidth": 120,
+ "tabWidth": 2,
+ "useTabs": false,
+ "singleQuote": true,
+ "bracketSpacing": false,
+ "semi": true
+ }
+}
diff --git a/bridge/sidedeploy.js b/bridge/sidedeploy.js
deleted file mode 100644
index eb2dccf67..000000000
--- a/bridge/sidedeploy.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const fs = require('fs');
-const promisify = require('./test/utils').promisify;
-
-const FederatedManager = artifacts.require('./FederatedManager');
-const SideToken = artifacts.require('./SideToken');
-const Custodian = artifacts.require('./Custodian');
-
-async function run() {
- const accounts = await promisify(cb => web3.eth.getAccounts(cb));
-
- const members = [ accounts[1], accounts[2], accounts[3], accounts[4], accounts[5] ];
-
- const manager = await FederatedManager.new(members);
- console.log('Manager deployed at', manager.address);
-
- const token = await SideToken.new("SIDE", "SIDE", 18, manager.address);
- console.log('SideToken deployed at', token.address);
-
- console.log('SideToken controlled by', await token.manager());
-
- await manager.setTransferable(token.address);
- console.log('SideToken controlled by Manager');
-
- const transferable = await manager.transferable();
- console.log('Manager controls', transferable);
-
- const config = {
- host: web3.currentProvider.host,
- accounts: accounts,
- token: token.address,
- manager: manager.address,
- members: members
- };
-
- fs.writeFileSync('sideconf.json', JSON.stringify(config, null, 4));
-}
-
-module.exports = function (cb) {
- run().then(function () {
- console.log('done');
- cb(null, null);
- });
-}
-
diff --git a/bridge/slither.config.json b/bridge/slither.config.json
new file mode 100644
index 000000000..f29db91cd
--- /dev/null
+++ b/bridge/slither.config.json
@@ -0,0 +1,4 @@
+{
+ "filter_paths": "MultiSigWallet.sol,contracts/test,contracts/zeppelin,contracts/previous",
+ "detectors_to_exclude": "solc-version,pragma,naming-convention,too-many-digits,assembly-usage"
+}
diff --git a/bridge/slither.db.json b/bridge/slither.db.json
new file mode 100644
index 000000000..b3d7948bd
--- /dev/null
+++ b/bridge/slither.db.json
@@ -0,0 +1 @@
+[{"check": "reentrancy-no-eth", "impact": "Medium", "confidence": "Medium", "description": "Reentrancy in Bridge_v0.createSideToken(address,string) (Bridge_v0.sol#185-199):\n\tExternal calls:\n\t- sideToken = sideTokenFactory.createSideToken(newSymbol,newSymbol) (Bridge_v0.sol#193)\n\tState variables written after the call(s):\n\t- mappedTokens (Bridge_v0.sol#194)\n", "elements": [{"type": "function", "name": "createSideToken", "source_mapping": {"start": 8275, "length": 649, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Bridge_v0", "source_mapping": {"start": 706, "length": 11072, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283], "starting_column": 1, "ending_column": 2}}, "signature": "createSideToken(address,string)"}}, {"type": "node", "name": "sideToken = sideTokenFactory.createSideToken(newSymbol,newSymbol)", "source_mapping": {"start": 8616, "length": 66, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [193], "starting_column": 13, "ending_column": 79}, "type_specific_fields": {"parent": {"type": "function", "name": "createSideToken", "source_mapping": {"start": 8275, "length": 649, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Bridge_v0", "source_mapping": {"start": 706, "length": 11072, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283], "starting_column": 1, "ending_column": 2}}, "signature": "createSideToken(address,string)"}}}, "additional_fields": {"underlying_type": "external_calls"}}, {"type": "node", "name": "mappedTokens[token] = sideToken", "source_mapping": {"start": 8696, "length": 31, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [194], "starting_column": 13, "ending_column": 44}, "type_specific_fields": {"parent": {"type": "function", "name": "createSideToken", "source_mapping": {"start": 8275, "length": 649, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Bridge_v0", "source_mapping": {"start": 706, "length": 11072, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283], "starting_column": 1, "ending_column": 2}}, "signature": "createSideToken(address,string)"}}}, "additional_fields": {"underlying_type": "variables_written", "variable_name": "mappedTokens"}}]}, {"check": "reentrancy-benign", "impact": "Low", "confidence": "Medium", "description": "Reentrancy in Bridge_v0.createSideToken(address,string) (Bridge_v0.sol#185-199):\n\tExternal calls:\n\t- sideToken = sideTokenFactory.createSideToken(newSymbol,newSymbol) (Bridge_v0.sol#193)\n\tState variables written after the call(s):\n\t- originalTokens (Bridge_v0.sol#196)\n", "elements": [{"type": "function", "name": "createSideToken", "source_mapping": {"start": 8275, "length": 649, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Bridge_v0", "source_mapping": {"start": 706, "length": 11072, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283], "starting_column": 1, "ending_column": 2}}, "signature": "createSideToken(address,string)"}}, {"type": "node", "name": "sideToken = sideTokenFactory.createSideToken(newSymbol,newSymbol)", "source_mapping": {"start": 8616, "length": 66, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [193], "starting_column": 13, "ending_column": 79}, "type_specific_fields": {"parent": {"type": "function", "name": "createSideToken", "source_mapping": {"start": 8275, "length": 649, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Bridge_v0", "source_mapping": {"start": 706, "length": 11072, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283], "starting_column": 1, "ending_column": 2}}, "signature": "createSideToken(address,string)"}}}, "additional_fields": {"underlying_type": "external_calls"}}, {"type": "node", "name": "originalTokens[sideTokenAddress] = token", "source_mapping": {"start": 8800, "length": 40, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [196], "starting_column": 13, "ending_column": 53}, "type_specific_fields": {"parent": {"type": "function", "name": "createSideToken", "source_mapping": {"start": 8275, "length": 649, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Bridge_v0", "source_mapping": {"start": 706, "length": 11072, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283], "starting_column": 1, "ending_column": 2}}, "signature": "createSideToken(address,string)"}}}, "additional_fields": {"underlying_type": "variables_written", "variable_name": "originalTokens"}}]}, {"check": "reentrancy-benign", "impact": "Low", "confidence": "Medium", "description": "Reentrancy in Bridge_v0.receiveTokens(address,uint256) (Bridge_v0.sol#111-120):\n\tExternal calls:\n\t- ERC20Detailed(tokenToUse).safeTransferFrom(_msgSender(),address(this),amount) (Bridge_v0.sol#117)\n\t- crossTokens(tokenToUse,_msgSender(),amount,) (Bridge_v0.sol#118)\n\tExternal calls sending eth:\n\t- sendIncentiveToEventsCrossers(msg.value) (Bridge_v0.sol#115)\n\tState variables written after the call(s):\n\t- knownTokens (Bridge_v0.sol#118)\n", "elements": [{"type": "function", "name": "receiveTokens", "source_mapping": {"start": 4744, "length": 649, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [111, 112, 113, 114, 115, 116, 117, 118, 119, 120], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Bridge_v0", "source_mapping": {"start": 706, "length": 11072, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283], "starting_column": 1, "ending_column": 2}}, "signature": "receiveTokens(address,uint256)"}}, {"type": "node", "name": "ERC20Detailed(tokenToUse).safeTransferFrom(_msgSender(),address(this),amount)", "source_mapping": {"start": 5227, "length": 79, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [117], "starting_column": 9, "ending_column": 88}, "type_specific_fields": {"parent": {"type": "function", "name": "receiveTokens", "source_mapping": {"start": 4744, "length": 649, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [111, 112, 113, 114, 115, 116, 117, 118, 119, 120], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Bridge_v0", "source_mapping": {"start": 706, "length": 11072, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283], "starting_column": 1, "ending_column": 2}}, "signature": "receiveTokens(address,uint256)"}}}, "additional_fields": {"underlying_type": "external_calls"}}, {"type": "node", "name": "crossTokens(tokenToUse,_msgSender(),amount,)", "source_mapping": {"start": 5316, "length": 49, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [118], "starting_column": 9, "ending_column": 58}, "type_specific_fields": {"parent": {"type": "function", "name": "receiveTokens", "source_mapping": {"start": 4744, "length": 649, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [111, 112, 113, 114, 115, 116, 117, 118, 119, 120], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Bridge_v0", "source_mapping": {"start": 706, "length": 11072, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283], "starting_column": 1, "ending_column": 2}}, "signature": "receiveTokens(address,uint256)"}}}, "additional_fields": {"underlying_type": "external_calls"}}, {"type": "node", "name": "sendIncentiveToEventsCrossers(msg.value)", "source_mapping": {"start": 5069, "length": 40, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [115], "starting_column": 9, "ending_column": 49}, "type_specific_fields": {"parent": {"type": "function", "name": "receiveTokens", "source_mapping": {"start": 4744, "length": 649, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [111, 112, 113, 114, 115, 116, 117, 118, 119, 120], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Bridge_v0", "source_mapping": {"start": 706, "length": 11072, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283], "starting_column": 1, "ending_column": 2}}, "signature": "receiveTokens(address,uint256)"}}}, "additional_fields": {"underlying_type": "external_calls_sending_eth"}}, {"type": "node", "name": "crossTokens(tokenToUse,_msgSender(),amount,)", "source_mapping": {"start": 5316, "length": 49, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [118], "starting_column": 9, "ending_column": 58}, "type_specific_fields": {"parent": {"type": "function", "name": "receiveTokens", "source_mapping": {"start": 4744, "length": 649, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [111, 112, 113, 114, 115, 116, 117, 118, 119, 120], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Bridge_v0", "source_mapping": {"start": 706, "length": 11072, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283], "starting_column": 1, "ending_column": 2}}, "signature": "receiveTokens(address,uint256)"}}}, "additional_fields": {"underlying_type": "variables_written", "variable_name": "knownTokens"}}]}, {"check": "unused-state", "impact": "Informational", "confidence": "High", "description": "Initializable.______gap (zeppelin/upgradable/Initializable.sol#60) is never used in Bridge_v0\n", "elements": [{"type": "variable", "name": "______gap", "source_mapping": {"start": 1951, "length": 29, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/zeppelin/upgradable/Initializable.sol", "filename_relative": "contracts/zeppelin/upgradable/Initializable.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/zeppelin/upgradable/Initializable.sol", "filename_short": "zeppelin/upgradable/Initializable.sol", "is_dependency": false, "lines": [60], "starting_column": 3, "ending_column": 32}, "type_specific_fields": {"parent": {"type": "contract", "name": "Initializable", "source_mapping": {"start": 657, "length": 1326, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/zeppelin/upgradable/Initializable.sol", "filename_relative": "contracts/zeppelin/upgradable/Initializable.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/zeppelin/upgradable/Initializable.sol", "filename_short": "zeppelin/upgradable/Initializable.sol", "is_dependency": false, "lines": [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61], "starting_column": 1, "ending_column": null}}}}, {"type": "contract", "name": "Bridge_v0", "source_mapping": {"start": 706, "length": 11072, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283], "starting_column": 1, "ending_column": 2}}]}, {"check": "external-function", "impact": "Optimization", "confidence": "High", "description": "initialize(address,address,address,address,string) should be declared external:\n\t- Bridge_v0.initialize(address,address,address,address,string) (Bridge_v0.sol#45-62)\n", "elements": [{"type": "function", "name": "initialize", "source_mapping": {"start": 1764, "length": 1088, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Bridge_v0", "source_mapping": {"start": 706, "length": 11072, "filename_used": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_relative": "contracts/Bridge_v0.sol", "filename_absolute": "/Users/pedro/git/public/tokenbridge/bridge/contracts/Bridge_v0.sol", "filename_short": "Bridge_v0.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283], "starting_column": 1, "ending_column": 2}}, "signature": "initialize(address,address,address,address,string)"}}]}]
\ No newline at end of file
diff --git a/bridge/t.cmd b/bridge/t.cmd
deleted file mode 100644
index ead410e55..000000000
--- a/bridge/t.cmd
+++ /dev/null
@@ -1 +0,0 @@
-truffle test --network test
diff --git a/bridge/test/AllowTokens_test.js b/bridge/test/AllowTokens_test.js
new file mode 100644
index 000000000..b9326ff93
--- /dev/null
+++ b/bridge/test/AllowTokens_test.js
@@ -0,0 +1,745 @@
+
+const MainToken = artifacts.require('./MainToken');
+const AllowTokens = artifacts.require('./AllowTokens');
+const MultiSigWallet = artifacts.require('./MultiSigWallet');
+
+const utils = require('./utils');
+const truffleAssertions = require('truffle-assertions');
+const BN = web3.utils.BN;
+const toWei = web3.utils.toWei;
+
+contract('AllowTokens', async function (accounts) {
+ const tokenDeployer= accounts[0];
+ const manager = accounts[1];
+ const anotherAccount = accounts[2];
+ const anotherOwner = accounts[3];
+ const unauthorizedAccount = accounts[6];
+
+ before(async function () {
+ await utils.saveState();
+ });
+
+ after(async function () {
+ await utils.revertState();
+ });
+
+ describe('AllowTokens creation', async () => {
+ it('should initialize correctly', async () => {
+ const smallConfirmations = '100';
+ const mediumConfirmations = '200';
+ const largeConfirmations = '300';
+ const typesInfo = [
+ { description: 'BTC', limits: {
+ min:toWei('0.001'),
+ max:toWei('25'),
+ daily:toWei('100'),
+ mediumAmount:toWei('0.1'),
+ largeAmount:toWei('1') }
+ },
+ { description: 'ETH', limits: {
+ min:toWei('0.01'),
+ max:toWei('750'),
+ daily:toWei('3000'),
+ mediumAmount:toWei('3'),
+ largeAmount:toWei('30') }
+ }
+ ];
+ const allowTokens = await AllowTokens.new();
+ await allowTokens.methods['initialize(address,address,uint256,uint256,uint256,(string,(uint256,uint256,uint256,uint256,uint256))[])'](
+ manager,
+ anotherOwner,
+ smallConfirmations,
+ mediumConfirmations,
+ largeConfirmations,
+ typesInfo
+ );
+ assert.equal(manager, await allowTokens.owner());
+ assert.equal(anotherOwner, await allowTokens.primary());
+ assert.equal(smallConfirmations, await allowTokens.smallAmountConfirmations());
+ assert.equal(mediumConfirmations, await allowTokens.mediumAmountConfirmations());
+ assert.equal(largeConfirmations, await allowTokens.largeAmountConfirmations());
+ const confirmations = await allowTokens.getConfirmations();
+ assert.equal(smallConfirmations, confirmations.smallAmount.toString());
+ assert.equal(mediumConfirmations, confirmations.mediumAmount.toString());
+ assert.equal(largeConfirmations, confirmations.largeAmount.toString());
+ const typeDescriptionLength = await allowTokens.getTypeDescriptionsLength();
+ assert.equal(typesInfo.length.toString(), typeDescriptionLength.toString());
+ const typeDescriptions = await allowTokens.getTypeDescriptions();
+ assert.equal(typeDescriptions.length, typesInfo.length);
+ for(let i = 0; i < typeDescriptions.length; i++) {
+ assert.equal(typeDescriptions[i], typesInfo[i].description);
+ }
+ const typesLimits = await allowTokens.getTypesLimits();
+ assert.equal(typesLimits.length, typesInfo.length);
+ for(let i = 0; i < typesLimits.length; i++) {
+ let limits = await allowTokens.typeLimits(i.toString());
+ assert.equal(typesLimits[i].min, limits.min.toString());
+ assert.equal(typesLimits[i].max, limits.max.toString());
+ assert.equal(typesLimits[i].mediumAmount, limits.mediumAmount.toString());
+ assert.equal(typesLimits[i].largeAmount, limits.largeAmount.toString());
+ }
+ });
+ });
+
+ describe('After AllowTokens initialization', () => {
+ beforeEach(async function () {
+ this.token = await MainToken.new("MAIN", "MAIN", 18, 10000, { from: tokenDeployer });
+ this.allowTokens = await AllowTokens.new();
+ await this.allowTokens.methods['initialize(address,address,uint256,uint256,uint256,(string,(uint256,uint256,uint256,uint256,uint256))[])'](
+ manager,
+ tokenDeployer,
+ '10',
+ '20',
+ '30',
+ []
+ );
+ this.typeId = 0;
+ });
+
+ describe('Set Token', async function () {
+ it('should fail calling from unauthorized sender', async function () {
+ await truffleAssertions.fails(
+ this.allowTokens.setToken(this.token.address, 0, { from: unauthorizedAccount }),
+ truffleAssertions.ErrorType.REVERT,
+ 'AllowTokens: unauthorized sender'
+ );
+ });
+
+ it('should fail calling with type id bigger than type descriptions', async function () {
+ const currentTypeDescriptionLength = await this.allowTokens.getTypeDescriptionsLength();
+ await truffleAssertions.fails(
+ this.allowTokens.setToken(this.token.address, currentTypeDescriptionLength + 1, { from: manager }),
+ truffleAssertions.ErrorType.REVERT,
+ 'AllowTokens: typeId does not exist'
+ );
+ });
+ });
+
+ describe('Tokens whitelist', async function () {
+ it('should have correct version', async function () {
+ const version = await this.allowTokens.version();
+ assert.equal(version, 'v1');
+ });
+
+ it('fails isTokenAllowed if null address provided', async function() {
+ await truffleAssertions.fails(this.allowTokens.isTokenAllowed(utils.NULL_ADDRESS),
+ truffleAssertions.ErrorType.REVERT);
+ })
+
+ it('add token type', async function() {
+ assert.equal('0', (await this.allowTokens.getTypeDescriptionsLength()).toString());
+ await this.allowTokens.addTokenType('RIF', { max:toWei('10000'), min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3') }, { from: manager });
+ assert.equal('1', (await this.allowTokens.getTypeDescriptionsLength()).toString());
+ assert.equal('RIF', (await this.allowTokens.typeDescriptions('0')));
+ });
+
+ it('fail if add token type is empty', async function() {
+ assert.equal('0', (await this.allowTokens.getTypeDescriptionsLength()).toString());
+ await truffleAssertions.fails(
+ this.allowTokens.addTokenType('', { max:toWei('10000'), min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3') }, { from: manager }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ assert.equal('0', (await this.allowTokens.getTypeDescriptionsLength()).toString());
+ });
+
+ it('fail if over 250 token type', async function() {
+ for(var i = 0; i < 250; i++) {
+ await this.allowTokens.addTokenType('RIF', { max:toWei('10000'), min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3') }, { from: manager });
+ }
+ assert.equal('250', (await this.allowTokens.getTypeDescriptionsLength()).toString());
+ await truffleAssertions.fails(
+ this.allowTokens.addTokenType('250TH', { max:toWei('10000'), min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3') }, { from: manager }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('validates whitelisted token', async function() {
+ await this.allowTokens.addTokenType('RIF', { max:toWei('10000'), min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3') }, { from: manager });
+ const typeId = 0;
+ //Use owner to set the token
+ await this.allowTokens.setToken(this.token.address, typeId, { from: manager });
+ let isAllowed = await this.allowTokens.isTokenAllowed(this.token.address);
+ assert.equal(isAllowed, true);
+ const otherToken = await MainToken.new("OTHER", "OTHER", 18, 10000, { from: tokenDeployer });
+ //use primary to set token
+ await this.allowTokens.setToken(otherToken.address, typeId, { from: tokenDeployer });
+ isAllowed = await this.allowTokens.isTokenAllowed(otherToken.address);
+ assert.equal(isAllowed, true);
+ });
+
+ it('should add multiple tokens', async function() {
+ await this.allowTokens.addTokenType('RIF', { max:toWei('10000'), min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3') }, { from: manager });
+ const typeId = 0;
+ const otherToken = await MainToken.new("OTHER", "OTHER", 18, 10000, { from: tokenDeployer });
+ await this.allowTokens.setMultipleTokens( [
+ { token:this.token.address, typeId: typeId },
+ { token: otherToken.address, typeId: typeId }
+ ], { from: manager });
+ let isAllowed = await this.allowTokens.isTokenAllowed(this.token.address);
+ assert.equal(isAllowed, true);
+ isAllowed = await this.allowTokens.isTokenAllowed(otherToken.address);
+ assert.equal(isAllowed, true);
+ });
+
+ it('fail if setToken caller is not the owner', async function() {
+ const previousIsTokenAllowed = await this.allowTokens.isTokenAllowed(this.token.address);
+ await this.allowTokens.addTokenType('RIF', { max:toWei('10000'), min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3') }, { from: manager });
+ const typeId = 0;
+ await truffleAssertions.fails(this.allowTokens.setToken(this.token.address, typeId, { from: anotherOwner }), truffleAssertions.ErrorType.REVERT);
+
+ const isTokenAllowed = await this.allowTokens.isTokenAllowed(this.token.address);
+ assert.equal(isTokenAllowed, previousIsTokenAllowed);
+ });
+
+ it('fail if setToken address is empty', async function() {
+ await this.allowTokens.addTokenType('RIF', { max:toWei('10000'), min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3') }, { from: manager });
+ const typeId = 0;
+ await truffleAssertions.fails(this.allowTokens.setToken(utils.NULL_ADDRESS, typeId, { from: manager }), truffleAssertions.ErrorType.REVERT);
+ });
+
+ it('fail if setToken typeid does not exist', async function() {
+ await this.allowTokens.addTokenType('RIF', { max:toWei('10000'), min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3') }, { from: manager });
+ const typeId = '2';
+ await truffleAssertions.fails(this.allowTokens.setToken(this.token.address, typeId, { from: manager }));
+ });
+
+ it('setToken type even if address was already added', async function() {
+ let result = await this.allowTokens.getInfoAndLimits(this.token.address);
+ assert.equal(result.info.typeId.toString(), '0');
+ assert.equal(result.info.allowed, false);
+
+ await this.allowTokens.addTokenType('RIF', { max:toWei('10000'), min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3') }, { from: manager });
+ let typeId = 0;
+ await this.allowTokens.setToken(this.token.address, typeId, { from: manager });
+ result = await this.allowTokens.getInfoAndLimits(this.token.address);
+ assert.equal(result.info.typeId.toString(), typeId.toString());
+ assert.equal(result.info.allowed, true);
+
+ await this.allowTokens.addTokenType('DOC', { max:toWei('20000'), min:toWei('2'), daily:toWei('200000'), mediumAmount:toWei('3'), largeAmount:toWei('10')}, { from: manager });
+ typeId = 1;
+ await this.allowTokens.setToken(this.token.address, typeId, { from: manager });
+ result = await this.allowTokens.getInfoAndLimits(this.token.address);
+ assert.equal(result.info.typeId.toString(), typeId.toString());
+ assert.equal(result.info.allowed, true);
+ });
+
+ it('removes allowed token', async function() {
+ await this.allowTokens.addTokenType('RIF', { max:toWei('10000'), min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3') }, { from: manager });
+ let typeId = 0;
+ await this.allowTokens.setToken(this.token.address, typeId, { from: manager });
+ let isAllowed = await this.allowTokens.isTokenAllowed(this.token.address);
+ assert.equal(isAllowed, true);
+
+ await this.allowTokens.removeAllowedToken(this.token.address, { from: manager });
+ isAllowed = await this.allowTokens.isTokenAllowed(this.token.address);
+ assert.equal(isAllowed, false);
+ });
+
+ it('fail if removeAllowedToken caller is not the owner', async function() {
+ await this.allowTokens.addTokenType('RIF', { max:toWei('10000'), min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3') }, { from: manager });
+ const typeId = 0;
+ await this.allowTokens.setToken(this.token.address, typeId, { from: manager });
+ const previousIsTokenAllowed = await this.allowTokens.isTokenAllowed(this.token.address);
+ await truffleAssertions.fails(this.allowTokens.removeAllowedToken(this.token.address, { from: tokenDeployer }), truffleAssertions.ErrorType.REVERT);
+
+ const isTokenAllowed = await this.allowTokens.isTokenAllowed(this.token.address);
+ assert.equal(isTokenAllowed, previousIsTokenAllowed);
+ });
+
+ it('fail if removeAllowedToken address is not in the whitelist', async function() {
+ await truffleAssertions.fails(this.allowTokens.removeAllowedToken(this.token.address, { from: manager }), truffleAssertions.ErrorType.REVERT);
+ });
+
+
+ });
+
+ describe('Limits of tokens allowed', async function() {
+ beforeEach(async function () {
+ await this.allowTokens.addTokenType('RIF', { max:toWei('10000'), min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3') }, { from: manager });
+ });
+
+ it('should set initial values', async function() {
+ const limits = await this.allowTokens.typeLimits(this.typeId);
+ assert.equal(limits.max.toString(), web3.utils.toWei('10000'));
+ assert.equal(limits.min.toString(), web3.utils.toWei('1'));
+ assert.equal(limits.daily.toString(), web3.utils.toWei('100000'));
+ });
+
+ it ('sets new limits for tokens', async function() {
+ const newMaxTokens = web3.utils.toWei('50000');
+ const newMinTokens = web3.utils.toWei('10');
+ const newDailyLimit = web3.utils.toWei('50000');
+
+ await this.allowTokens.setTypeLimits(this.typeId, {max: newMaxTokens, min:newMinTokens, daily:newDailyLimit, mediumAmount:toWei('100'), largeAmount:toWei('1000')}, { from: manager });
+ const limits = await this.allowTokens.typeLimits(this.typeId);
+
+ assert.equal(limits.max.toString(), newMaxTokens.toString());
+ assert.equal(limits.min.toString(), newMinTokens.toString());
+ assert.equal(limits.daily.toString(), newDailyLimit.toString());
+ });
+
+ it('fail if not the owner', async function() {
+ const newMaxTokens = web3.utils.toWei('50000');
+ const newMinTokens = web3.utils.toWei('10');
+ const newDailyLimit = web3.utils.toWei('50000');
+
+ let previousLimits = await this.allowTokens.typeLimits(this.typeId);
+ await truffleAssertions.fails(
+ this.allowTokens.setTypeLimits(
+ this.typeId, {max: newMaxTokens, min:newMinTokens, daily:newDailyLimit, mediumAmount:toWei('100'), largeAmount:toWei('1000')},
+ { from: tokenDeployer }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ const limits = await this.allowTokens.typeLimits(this.typeId);
+ assert.equal(limits.max.toString(), previousLimits.max.toString());
+ assert.equal(limits.min.toString(), previousLimits.min.toString());
+ assert.equal(limits.daily.toString(), previousLimits.daily.toString());
+ });
+
+ it('fail if max is smaller than min', async function() {
+ const newMaxTokens = web3.utils.toWei('9');
+ const newMinTokens = web3.utils.toWei('10');
+ const newDailyLimit = web3.utils.toWei('50000');
+ const mediumAmount = web3.utils.toWei('11');
+ const largeAmount = web3.utils.toWei('12');
+ await truffleAssertions.fails(
+ this.allowTokens.setTypeLimits(
+ this.typeId, {max: newMaxTokens, min:newMinTokens, daily:newDailyLimit, mediumAmount:mediumAmount, largeAmount:largeAmount},
+ { from: manager }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail daily limit smaller than max', async function() {
+ const newMaxTokens = web3.utils.toWei('100');
+ const newMinTokens = web3.utils.toWei('10');
+ const newDailyLimit = web3.utils.toWei('99');
+ const mediumAmount = web3.utils.toWei('11');
+ const largeAmount = web3.utils.toWei('12');
+ await truffleAssertions.fails(
+ this.allowTokens.setTypeLimits(
+ this.typeId, {max: newMaxTokens, min:newMinTokens, daily:newDailyLimit, mediumAmount:mediumAmount, largeAmount:largeAmount},
+ { from: manager }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail if typeId bigger than max', async function() {
+ const typeId = Number(await this.allowTokens.getTypeDescriptionsLength())+1;
+ const newMaxTokens = web3.utils.toWei('50');
+ const newMinTokens = web3.utils.toWei('10');
+ const newDailyLimit = web3.utils.toWei('300');
+ const mediumAmount = web3.utils.toWei('11');
+ const largeAmount = web3.utils.toWei('12');
+ await truffleAssertions.fails(
+ this.allowTokens.setTypeLimits(
+ typeId.toString(), {max: newMaxTokens, min:newMinTokens, daily:newDailyLimit, mediumAmount:mediumAmount, largeAmount:largeAmount},
+ { from: manager }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail medium amount smaller than min limit', async function() {
+ const newMaxTokens = web3.utils.toWei('100');
+ const newMinTokens = web3.utils.toWei('10');
+ const newDailyLimit = web3.utils.toWei('1000');
+ const mediumAmount = web3.utils.toWei('10');
+ const largeAmount = web3.utils.toWei('12');
+ await truffleAssertions.fails(
+ this.allowTokens.setTypeLimits(
+ this.typeId, {max: newMaxTokens, min:newMinTokens, daily:newDailyLimit, mediumAmount:mediumAmount, largeAmount:largeAmount},
+ { from: manager }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail large amount smaller than medium amount', async function() {
+ const newMaxTokens = web3.utils.toWei('100');
+ const newMinTokens = web3.utils.toWei('10');
+ const newDailyLimit = web3.utils.toWei('1000');
+ const mediumAmount = web3.utils.toWei('11');
+ const largeAmount = web3.utils.toWei('11');
+ await truffleAssertions.fails(
+ this.allowTokens.setTypeLimits(
+ this.typeId, {max: newMaxTokens, min:newMinTokens, daily:newDailyLimit, mediumAmount:mediumAmount, largeAmount:largeAmount},
+ { from: manager }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('calcMaxWithdraw', async function() {
+ const newMaxTokens = web3.utils.toWei('10000');
+ const newMinTokens = web3.utils.toWei('1');
+ const newDailyLimit = web3.utils.toWei('12000');
+ const mediumAmount = web3.utils.toWei('2');
+ const largeAmount = web3.utils.toWei('3');
+
+ await this.allowTokens.setTypeLimits(this.typeId, {max: newMaxTokens, min:newMinTokens, daily:newDailyLimit, mediumAmount:mediumAmount, largeAmount:largeAmount}, { from: manager });
+ await this.allowTokens.setToken(this.token.address, this.typeId, { from: manager });
+
+ let maxWithdraw = await this.allowTokens.calcMaxWithdraw(this.token.address);
+ assert.equal(maxWithdraw, newMaxTokens);
+
+ await this.allowTokens.updateTokenTransfer(this.token.address, newMaxTokens);
+ maxWithdraw = await this.allowTokens.calcMaxWithdraw(this.token.address);
+ let expected = web3.utils.toWei('2000');
+ assert.equal(maxWithdraw.toString(), expected);
+
+ await this.allowTokens.updateTokenTransfer(this.token.address, expected);
+ maxWithdraw = await this.allowTokens.calcMaxWithdraw(this.token.address);
+ assert.equal(maxWithdraw.toString(), '0');
+ });
+ });
+
+
+ describe('updateTokenTransfer', async function() {
+
+ it('should check max value', async function() {
+ const maxLimit = toWei('10000');
+ await this.allowTokens.addTokenType('RIF', { max:maxLimit, min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3')}, { from: manager });
+ await this.allowTokens.setToken(this.token.address, this.typeId, { from: manager });
+
+ await this.allowTokens.updateTokenTransfer(this.token.address, maxLimit);
+
+ await truffleAssertions.fails(
+ this.allowTokens.updateTokenTransfer(this.token.address, new BN(maxLimit).add(new BN('1'))),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should check min value', async function() {
+ const minLimit = toWei('1');
+ await this.allowTokens.addTokenType('RIF', {max:toWei('10000'), min:minLimit, daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3')}, { from: manager });
+ await this.allowTokens.setToken(this.token.address, this.typeId, { from: manager });
+
+ await this.allowTokens.updateTokenTransfer(this.token.address, minLimit);
+
+ await truffleAssertions.fails(
+ this.allowTokens.updateTokenTransfer(this.token.address, new BN(minLimit).sub(new BN('1'))),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should check daily limit', async function() {
+ const minLimit = toWei('1');
+ const dailyLimit = toWei('1');
+ await this.allowTokens.addTokenType('RIF', { max:toWei('1'), min:minLimit, daily:dailyLimit, mediumAmount:toWei('2'), largeAmount:toWei('3')}, { from: manager });
+ await this.allowTokens.setToken(this.token.address, this.typeId, { from: manager });
+
+ await this.allowTokens.updateTokenTransfer(this.token.address, minLimit);
+
+ await truffleAssertions.fails(
+ this.allowTokens.updateTokenTransfer(this.token.address, dailyLimit),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should allow side and whitelisted tokens', async function() {
+ let maxLimit = toWei('10000');
+ await this.allowTokens.addTokenType('RIF', {max:maxLimit, min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3')}, { from: manager });
+ await this.allowTokens.setToken(this.token.address, this.typeId, { from: manager });
+
+ await this.allowTokens.updateTokenTransfer(this.token.address, maxLimit);
+ });
+
+ it('should check allowed token if not side or allowed token', async function() {
+ const maxTokensAllowed = toWei('10000');
+ //Token not allowed
+ await truffleAssertions.fails(
+ this.allowTokens.updateTokenTransfer(this.token.address, maxTokensAllowed),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ await this.allowTokens.addTokenType('RIF', {max:maxTokensAllowed, min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3')}, { from: manager });
+ await this.allowTokens.setToken(this.token.address, this.typeId, { from: manager });
+
+ await this.allowTokens.updateTokenTransfer(this.token.address, maxTokensAllowed);
+ });
+
+ });
+
+ describe('Set Confirmations', async function() {
+
+ it('should set confirmations', async function() {
+ let newSmallAmountConfirmations = '15';
+ let newMediumAmountConfirmations = '23';
+ let newLargeAmountConfirmations = '150';
+ await this.allowTokens.setConfirmations(newSmallAmountConfirmations, newMediumAmountConfirmations, newLargeAmountConfirmations, { from: manager });
+ assert.equal(newSmallAmountConfirmations, (await this.allowTokens.smallAmountConfirmations()).toString());
+ assert.equal(newMediumAmountConfirmations, (await this.allowTokens.mediumAmountConfirmations()).toString());
+ assert.equal(newLargeAmountConfirmations, (await this.allowTokens.largeAmountConfirmations()).toString());
+
+ newSmallAmountConfirmations = '0';
+ newMediumAmountConfirmations = '0';
+ newLargeAmountConfirmations = '0';
+ await this.allowTokens.setConfirmations(newSmallAmountConfirmations, newMediumAmountConfirmations, newLargeAmountConfirmations, { from: manager });
+ assert.equal(newSmallAmountConfirmations, (await this.allowTokens.smallAmountConfirmations()).toString());
+ assert.equal(newMediumAmountConfirmations, (await this.allowTokens.mediumAmountConfirmations()).toString());
+ assert.equal(newLargeAmountConfirmations, (await this.allowTokens.largeAmountConfirmations()).toString());
+
+ newSmallAmountConfirmations = '10';
+ newMediumAmountConfirmations = '10';
+ newLargeAmountConfirmations = '100';
+ await this.allowTokens.setConfirmations(newSmallAmountConfirmations, newMediumAmountConfirmations, newLargeAmountConfirmations, { from: manager });
+ assert.equal(newSmallAmountConfirmations, (await this.allowTokens.smallAmountConfirmations()).toString());
+ assert.equal(newMediumAmountConfirmations, (await this.allowTokens.mediumAmountConfirmations()).toString());
+ assert.equal(newLargeAmountConfirmations, (await this.allowTokens.largeAmountConfirmations()).toString());
+
+ newSmallAmountConfirmations = '10';
+ newMediumAmountConfirmations = '100';
+ newLargeAmountConfirmations = '100';
+ await this.allowTokens.setConfirmations(newSmallAmountConfirmations, newMediumAmountConfirmations, newLargeAmountConfirmations, { from: manager });
+ assert.equal(newSmallAmountConfirmations, (await this.allowTokens.smallAmountConfirmations()).toString());
+ assert.equal(newMediumAmountConfirmations, (await this.allowTokens.mediumAmountConfirmations()).toString());
+ assert.equal(newLargeAmountConfirmations, (await this.allowTokens.largeAmountConfirmations()).toString());
+
+ newSmallAmountConfirmations = '100';
+ newMediumAmountConfirmations = '100';
+ newLargeAmountConfirmations = '1000';
+ await this.allowTokens.setConfirmations(newSmallAmountConfirmations, newMediumAmountConfirmations, newLargeAmountConfirmations, { from: manager });
+ assert.equal(newSmallAmountConfirmations, (await this.allowTokens.smallAmountConfirmations()).toString());
+ assert.equal(newMediumAmountConfirmations, (await this.allowTokens.mediumAmountConfirmations()).toString());
+ assert.equal(newLargeAmountConfirmations, (await this.allowTokens.largeAmountConfirmations()).toString());
+ });
+
+ it('should fail to set small amount confirmations bigger than medium', async function() {
+ const newSmallAmountConfirmations = '30';
+ const newMediumAmountConfirmations = '10';
+ const newLargeAmountConfirmations = '50';
+ await truffleAssertions.fails(
+ this.allowTokens.setConfirmations(
+ newSmallAmountConfirmations, newMediumAmountConfirmations, newLargeAmountConfirmations,
+ { from: manager }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should fail to set medium amount confirmations bigger than large', async function() {
+ const newSmallAmountConfirmations = '30';
+ const newMediumAmountConfirmations = '50';
+ const newLargeAmountConfirmations = '40';
+ await truffleAssertions.fails(
+ this.allowTokens.setConfirmations(
+ newSmallAmountConfirmations, newMediumAmountConfirmations, newLargeAmountConfirmations,
+ { from: manager }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ });
+
+ describe('Ownable methods', async function() {
+
+ it('Should renounce ownership', async function() {
+ await this.allowTokens.renounceOwnership({ from: manager });
+ const owner = await this.allowTokens.owner();
+ assert.equal(BigInt(owner), 0);
+ });
+
+ it('Should not renounce ownership when not called by the owner', async function() {
+ const owner = await this.allowTokens.owner();
+ await truffleAssertions.fails(this.allowTokens.renounceOwnership(), truffleAssertions.ErrorType.REVERT);
+ const ownerAfter = await this.allowTokens.owner();
+
+ assert.equal(owner, ownerAfter);
+ });
+
+ it('Should transfer ownership', async function() {
+ await this.allowTokens.transferOwnership(anotherOwner, { from: manager });
+ const owner = await this.allowTokens.owner();
+ assert.equal(owner, anotherOwner);
+ });
+
+ it('Should not transfer ownership when not called by the owner', async function() {
+ const owner = await this.allowTokens.owner();
+ await truffleAssertions.fails(this.allowTokens.transferOwnership(anotherOwner), truffleAssertions.ErrorType.REVERT);
+ const ownerAfter = await this.allowTokens.owner();
+
+ assert.equal(owner, ownerAfter);
+ });
+ })
+
+ describe('Secondary methods', async function() {
+
+ it('Should not allowed when not called by primary', async function() {
+ const maxTokensAllowed = toWei('10000');
+ await truffleAssertions.fails(
+ this.allowTokens.updateTokenTransfer(this.token.address, maxTokensAllowed, {from: anotherAccount}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('Should not transfer primary when not called by the owner', async function() {
+ const owner = await this.allowTokens.primary();
+ await truffleAssertions.fails(
+ this.allowTokens.transferPrimary(anotherOwner, {from: anotherAccount}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ const ownerAfter = await this.allowTokens.primary();
+
+ assert.equal(owner, ownerAfter);
+ });
+
+ it('Should transfer primary', async function() {
+ await this.allowTokens.transferPrimary(anotherOwner);
+ const primary = await this.allowTokens.primary();
+ assert.equal(primary, anotherOwner);
+ const owner = await this.allowTokens.owner();
+ assert.notEqual(owner, primary);
+ });
+ })
+
+ describe('Calls from MultiSig', async function() {
+ const multiSigOnwerA = accounts[2];
+ const multiSigOnwerB = accounts[3];
+
+ beforeEach(async function () {
+ this.multiSig = await MultiSigWallet.new([multiSigOnwerA, multiSigOnwerB], 2);
+ this.allowTokens = await AllowTokens.new();
+ await this.allowTokens.methods['initialize(address,address,uint256,uint256,uint256,(string,(uint256,uint256,uint256,uint256,uint256))[])'](
+ this.multiSig.address,
+ tokenDeployer,
+ '0',
+ '0' ,
+ '0',
+ []
+ );
+ let data = this.allowTokens.contract.methods.addTokenType('RIF', {max:toWei('10000'), min:toWei('1'), daily:toWei('100000'), mediumAmount:toWei('2'), largeAmount:toWei('3')}).encodeABI();
+ await this.multiSig.submitTransaction(this.allowTokens.address, 0, data, { from: multiSigOnwerA });
+ this.txIndex = 0
+ await this.multiSig.confirmTransaction(this.txIndex, { from: multiSigOnwerB });
+ });
+
+ it('should fail to add a new allowed token due to missing signatures', async function() {
+ const data = this.allowTokens.contract.methods.setToken(this.token.address, this.typeId).encodeABI();
+ await this.multiSig.submitTransaction(this.allowTokens.address, 0, data, { from: multiSigOnwerA });
+ this.txIndex++;
+ let tx = await this.multiSig.transactions(this.txIndex);
+ assert.equal(tx.executed, false);
+
+ const isAllowed = await this.allowTokens.isTokenAllowed(this.token.address);
+ assert.equal(isAllowed, false);
+ });
+
+ it('should add a new allowed token', async function() {
+ const data = this.allowTokens.contract.methods.setToken(this.token.address, this.typeId).encodeABI();
+
+ await this.multiSig.submitTransaction(this.allowTokens.address, 0, data, { from: multiSigOnwerA });
+ this.txIndex++;
+ await this.multiSig.confirmTransaction(this.txIndex, { from: multiSigOnwerB });
+
+ const isAllowed = await this.allowTokens.isTokenAllowed(this.token.address);
+ assert.equal(isAllowed, true);
+ });
+
+ it('should fail to remove an allowed token due to missing signatures', async function() {
+ let data = this.allowTokens.contract.methods.setToken(this.token.address, this.typeId).encodeABI();
+ await this.multiSig.submitTransaction(this.allowTokens.address, 0, data, { from: multiSigOnwerA });
+ this.txIndex++;
+ await this.multiSig.confirmTransaction(this.txIndex, { from: multiSigOnwerB });
+ let tx = await this.multiSig.transactions(this.txIndex);
+ assert.equal(tx.executed, true);
+
+ data = this.allowTokens.contract.methods.removeAllowedToken(this.token.address).encodeABI();
+ await this.multiSig.submitTransaction(this.allowTokens.address, 0, data, { from: multiSigOnwerA });
+ this.txIndex++;
+ tx = await this.multiSig.transactions(this.txIndex);
+ assert.equal(tx.executed, false);
+
+ const isAllowed = await this.allowTokens.isTokenAllowed(this.token.address);
+ assert.equal(isAllowed, true);
+ });
+
+ it('should remove an allowed token', async function() {
+ let data = this.allowTokens.contract.methods.setToken(this.token.address, this.typeId).encodeABI();
+ await this.multiSig.submitTransaction(this.allowTokens.address, 0, data, { from: multiSigOnwerA });
+ this.txIndex++;
+ await this.multiSig.confirmTransaction(this.txIndex, { from: multiSigOnwerB });
+
+ data = this.allowTokens.contract.methods.removeAllowedToken(this.token.address).encodeABI();
+ await this.multiSig.submitTransaction(this.allowTokens.address, 0, data, { from: multiSigOnwerA });
+ this.txIndex++;
+ await this.multiSig.confirmTransaction(this.txIndex, { from: multiSigOnwerB });
+
+ let tx = await this.multiSig.transactions(this.txIndex);
+ assert.equal(tx.executed, true);
+
+ const isAllowed = await this.allowTokens.isTokenAllowed(this.token.address);
+ assert.equal(isAllowed, false);
+ });
+
+ it('should fail to set max tokens due to missing signatures', async function() {
+ let result = await this.allowTokens.getInfoAndLimits(this.token.address);
+ let limit = result.limit;
+ let maxTokens = limit.max.toString();
+ let newMax = web3.utils.toWei('1000');
+
+ let data = this.allowTokens.contract.methods.setTypeLimits(result.info.typeId.toString(), {max:newMax, min:limit.min.toString(), daily:limit.daily.toString(), mediumAmount:toWei('2'), largeAmount:toWei('3')}).encodeABI();
+ await this.multiSig.submitTransaction(this.allowTokens.address, 0, data, { from: multiSigOnwerA });
+ this.txIndex++;
+
+ let tx = await this.multiSig.transactions(this.txIndex);
+ assert.equal(tx.executed, false);
+
+ result = await this.allowTokens.getInfoAndLimits(this.token.address);
+ let maxTokensAfter = result.limit.max;
+ assert.equal(maxTokensAfter.toString(), maxTokens);
+ });
+
+ it('should set max tokens', async function() {
+ let newMax = web3.utils.toWei('1000');
+ let result = await this.allowTokens.getInfoAndLimits(this.token.address);
+ let limit = result.limit;
+ let data = this.allowTokens.contract.methods.setTypeLimits(result.info.typeId.toString(), {max:newMax, min:limit.min.toString(), daily:limit.daily.toString(), mediumAmount:toWei('2'), largeAmount:toWei('3')}).encodeABI();
+ await this.multiSig.submitTransaction(this.allowTokens.address, 0, data, { from: multiSigOnwerA });
+ this.txIndex++;
+ await this.multiSig.confirmTransaction(this.txIndex, { from: multiSigOnwerB });
+
+ let tx = await this.multiSig.transactions(this.txIndex);
+ assert.equal(tx.executed, true);
+
+ result = await this.allowTokens.getInfoAndLimits(this.token.address);
+ assert.equal(result.limit.max.toString(), newMax);
+ });
+
+ it('should set min tokens', async function() {
+ let limit = await this.allowTokens.typeLimits(this.typeId);
+ let newMin = web3.utils.toWei('10');
+ let data = this.allowTokens.contract.methods.setTypeLimits(this.typeId, {max:limit.max.toString(), min:newMin.toString(), daily:limit.daily.toString(), mediumAmount:toWei('100'), largeAmount:toWei('1000')}).encodeABI();
+ await this.multiSig.submitTransaction(this.allowTokens.address, 0, data, { from: multiSigOnwerA });
+ this.txIndex++;
+ await this.multiSig.confirmTransaction(this.txIndex, { from: multiSigOnwerB });
+
+ let tx = await this.multiSig.transactions(this.txIndex);
+ assert.equal(tx.executed, true);
+
+ limit = await this.allowTokens.typeLimits(this.typeId);
+ assert.equal(limit.min.toString(), newMin.toString());
+ });
+
+ it('should change daily limit', async function() {
+ let limit = await this.allowTokens.typeLimits(this.typeId);
+ let newDailyLimit = web3.utils.toWei('50000');
+ let data = this.allowTokens.contract.methods.setTypeLimits(this.typeId, {max:limit.max.toString(), min:limit.min.toString(), daily:newDailyLimit, mediumAmount:toWei('2'), largeAmount:toWei('3')}).encodeABI();
+ await this.multiSig.submitTransaction(this.allowTokens.address, 0, data, { from: multiSigOnwerA });
+ this.txIndex++;
+ await this.multiSig.confirmTransaction(this.txIndex, { from: multiSigOnwerB });
+
+ let tx = await this.multiSig.transactions(this.txIndex);
+ assert.equal(tx.executed, true);
+
+ limit = await this.allowTokens.typeLimits(this.typeId);
+ assert.equal(limit.daily.toString(), newDailyLimit);
+ });
+ });
+ });
+});
diff --git a/bridge/test/BridgeV3_to_bridgeV4_test.js b/bridge/test/BridgeV3_to_bridgeV4_test.js
new file mode 100644
index 000000000..b1ffacb34
--- /dev/null
+++ b/bridge/test/BridgeV3_to_bridgeV4_test.js
@@ -0,0 +1,175 @@
+const ERC777 = artifacts.require('ERC777');
+const BridgeV4 = artifacts.require('Bridge');
+const BridgeV3 = artifacts.require('BridgeV3');
+const ProxyAdmin = artifacts.require('ProxyAdmin');
+const SideTokenFactory = artifacts.require('SideTokenFactory');
+const FederationV3 = artifacts.require('Federation');
+const FederationV2 = artifacts.require('FederationV2');
+const BridgeProxy = artifacts.require('BridgeProxy');
+const FederationProxy = artifacts.require('FederationProxy');
+const AllowTokens = artifacts.require('AllowTokens');
+const utils = require("./utils");
+const chains = require('../hardhat/helper/chains');
+const MainToken = artifacts.require('./MainToken');
+const toWei = web3.utils.toWei;
+
+contract('Bridge Multichain Deploy Check', async function (accounts) {
+ const bridgeManager = accounts[1];
+ const federatorOwner = accounts[2];
+ const federatorMember1 = accounts[3];
+ const federatorMember2 = accounts[4];
+ const allowTokensManager = accounts[5];
+ const allowTokensPrimary = accounts[6];
+ const tokenOwner = accounts[7];
+ const symbolPrefix = 'bd';
+ const tokenName = 'MAIN';
+ const tokenSymbol = 'MAIN';
+
+ beforeEach(async function() {
+ this.bridgeV3 = await BridgeV3.new();
+ this.bridgeV4 = await BridgeV4.new();
+ this.allowTokens = await AllowTokens.new();
+
+ this.federationV2 = await FederationV2.new();
+ this.federationV3 = await FederationV3.new();
+ this.proxyAdmin = await ProxyAdmin.new();
+ this.sideTokenFactory = await SideTokenFactory.new();
+
+ await this.allowTokens.initialize(allowTokensManager, allowTokensPrimary, 1, 1, 1, [
+ { description: 'BTC', limits: {
+ min:toWei('0.0000001'),
+ max:toWei('2500'),
+ daily:toWei('100000'),
+ mediumAmount:toWei('100'),
+ largeAmount:toWei('10000') }
+ },
+ { description: 'ETH', limits: {
+ min:toWei('0.01'),
+ max:toWei('750'),
+ daily:toWei('3000'),
+ mediumAmount:toWei('3'),
+ largeAmount:toWei('30') }
+ }
+ ]);
+
+ this.token = await MainToken.new(tokenName, tokenSymbol, 18, toWei('1000000000'), { from: tokenOwner });
+ await this.allowTokens.setToken(this.token.address, 0, { from: allowTokensManager });
+ });
+
+ describe('Upgrate from BridgeV3 to BridgeV4', async function () {
+ it('should update the contract version from v3 to v4', async function () {
+ const initializeDataBridgeV3 = await this.bridgeV3.contract.methods.initialize(
+ bridgeManager,
+ this.federationV2.address,
+ this.allowTokens.address,
+ this.sideTokenFactory.address,
+ symbolPrefix
+ ).encodeABI();
+ const bridgeProxy = await BridgeProxy.new(this.bridgeV3.address, this.proxyAdmin.address, initializeDataBridgeV3);
+ const bridgeV3Implementation = new web3.eth.Contract(this.bridgeV3.abi, bridgeProxy.address);
+
+ let result = await bridgeV3Implementation.methods.version().call();
+ assert.equal(result, 'v3');
+
+ await this.proxyAdmin.upgrade(bridgeProxy.address, this.bridgeV4.address);
+ const bridgeV4Implementation = new web3.eth.Contract(this.bridgeV4.abi, bridgeProxy.address);
+
+ result = await bridgeV4Implementation.methods.version().call();
+ assert.equal(result, 'v4');
+ });
+
+ it('should ReceiveTokensTo start in v3 finish in v4', async function () {
+ const initialBalance = await this.token.contract.methods.balanceOf(tokenOwner).call();
+ const initializeDataBridgeV3 = await this.bridgeV3.contract.methods.initialize(
+ bridgeManager,
+ this.federationV2.address,
+ this.allowTokens.address,
+ this.sideTokenFactory.address,
+ symbolPrefix
+ ).encodeABI();
+ console.log('initialize bridge v3')
+
+ const initializeDataFederatorV2 = await this.federationV2.contract.methods.initialize(
+ [federatorMember1, federatorMember2],
+ 2,
+ this.bridgeV4.address,
+ federatorOwner
+ ).encodeABI();
+ console.log('initialize federator v2')
+
+ const bridgeProxy = await BridgeProxy.new(this.bridgeV3.address, this.proxyAdmin.address, initializeDataBridgeV3);
+ const federationProxy = await FederationProxy.new(this.federationV2.address, this.proxyAdmin.address, initializeDataFederatorV2);
+
+ const bridgeV3Implementation = new web3.eth.Contract(this.bridgeV3.abi, bridgeProxy.address);
+ const federationV2Implementation = new web3.eth.Contract(this.federationV2.abi, federationProxy.address);
+ console.log('set bridge v3')
+
+ await bridgeV3Implementation.methods.changeFederation(federationProxy.address).send({from: bridgeManager});
+ await federationV2Implementation.methods.setBridge(bridgeProxy.address).send({from: federatorOwner});
+ await this.allowTokens.transferPrimary(bridgeProxy.address, {from: allowTokensPrimary});
+
+ const amount = toWei('1000');
+ console.log('is tokenAllowed v2')
+
+ const tokenAllowed = await this.allowTokens.isTokenAllowed(this.token.address);
+ assert.equal(tokenAllowed, true);
+
+ let receipt = await this.token.approve(bridgeProxy.address, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+ receipt = await bridgeV3Implementation.methods.receiveTokensTo(
+ this.token.address,
+ tokenOwner,
+ amount
+ ).send({from: tokenOwner});
+ const crossEvent = receipt.events.Cross;
+
+ const balanceAfterReceiveTokens = await this.token.contract.methods.balanceOf(tokenOwner).call();
+ assert.equal(new web3.utils.BN(balanceAfterReceiveTokens).add(new web3.utils.BN(amount)).toString(), initialBalance);
+
+ await federationV2Implementation.methods.voteTransaction(
+ this.token.address,
+ tokenOwner,
+ tokenOwner,
+ amount,
+ crossEvent.blockHash,
+ crossEvent.transactionHash,
+ crossEvent.logIndex,
+ ).send({from: federatorMember1});
+
+ await this.proxyAdmin.upgrade(bridgeProxy.address, this.bridgeV4.address);
+ await this.proxyAdmin.upgrade(federationProxy.address, this.federationV3.address);
+
+ const bridgeV4Implementation = new web3.eth.Contract(this.bridgeV4.abi, bridgeProxy.address);
+ const federationV3Implementation = new web3.eth.Contract(this.federationV3.abi, federationProxy.address);
+
+ await federationV3Implementation.methods.voteTransaction(
+ this.token.address,
+ tokenOwner,
+ tokenOwner,
+ amount,
+ crossEvent.blockHash,
+ crossEvent.transactionHash,
+ crossEvent.logIndex,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ ).send({from: federatorMember2});
+
+ await bridgeV4Implementation.methods.claim(
+ {
+ to: tokenOwner,
+ amount: amount,
+ blockHash: crossEvent.blockHash,
+ transactionHash: crossEvent.transactionHash,
+ logIndex: crossEvent.logIndex,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ },
+ ).send({from: tokenOwner});
+
+ const originalTokenAddress = await bridgeV4Implementation.methods.originalTokenAddresses(crossEvent.transactionHash).call();
+ const originalTokenContract = new web3.eth.Contract(ERC777.abi, originalTokenAddress );
+
+ const balance = await originalTokenContract.methods.balanceOf(tokenOwner).call();
+ assert.equal(initialBalance, balance);
+ });
+ });
+});
diff --git a/bridge/test/Bridge_test.js b/bridge/test/Bridge_test.js
index 98d7b3ef3..9a2a1926c 100644
--- a/bridge/test/Bridge_test.js
+++ b/bridge/test/Bridge_test.js
@@ -1,135 +1,2952 @@
-const MainToken = artifacts.require('./MainToken');
-const Bridge = artifacts.require('./Bridge');
-
-const expectThrow = require('./utils').expectThrow;
-
-contract('Bridge', function (accounts) {
- const bridgeOwner = accounts[0];
- const tokenOwner = accounts[1];
- const bridgeManager = accounts[2];
- const anAccount = accounts[3];
- const newBridgeManager = accounts[4];
- const tokenAddress = accounts[5];
- const anotherAccount = accounts[6];
-
- describe('bridge with token contract', function () {
- beforeEach(async function () {
- this.token = await MainToken.new("MAIN", "MAIN", 18, 10000, { from: tokenOwner });
- this.bridge = await Bridge.new(bridgeManager, this.token.address, { from: bridgeOwner });
- });
-
- it('check manager', async function () {
- const manager = await this.bridge.manager();
-
- assert.equal(manager, bridgeManager);
- });
-
- it('check token', async function () {
- const token = await this.bridge.token();
-
- assert.equal(token, this.token.address);
- });
-
- it('change manager', async function () {
- await this.bridge.changeManager(newBridgeManager, { from: bridgeManager });
-
- const manager = await this.bridge.manager();
-
- assert.equal(manager, newBridgeManager);
- });
-
- it('only manager can change manager', async function () {
- expectThrow(this.bridge.changeManager(newBridgeManager));
-
- const manager = await this.bridge.manager();
-
- assert.equal(manager, bridgeManager);
- });
-
- it('accept transfer', async function () {
- await this.token.transfer(this.bridge.address, 1000, { from: tokenOwner });
-
- const tokenBalance = await this.token.balanceOf(tokenOwner);
- assert.equal(tokenBalance, 9000);
-
- const bridgeBalance = await this.token.balanceOf(this.bridge.address);
- assert.equal(bridgeBalance, 1000);
-
- await this.bridge.acceptTransfer(anAccount, 500, { from: bridgeManager });
-
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 500);
-
- const newBridgeBalance = await this.token.balanceOf(this.bridge.address);
- assert.equal(newBridgeBalance, 500);
- });
-
- it('accept transfer only manager', async function () {
- await this.token.transfer(this.bridge.address, 1000, { from: tokenOwner });
-
- const tokenBalance = await this.token.balanceOf(tokenOwner);
- assert.equal(tokenBalance, 9000);
-
- const bridgeBalance = await this.token.balanceOf(this.bridge.address);
- assert.equal(bridgeBalance, 1000);
-
- expectThrow(this.bridge.acceptTransfer(anAccount, 500, { from: bridgeOwner }));
- expectThrow(this.bridge.acceptTransfer(anAccount, 500, { from: anAccount }));
-
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 0);
-
- const newBridgeBalance = await this.token.balanceOf(this.bridge.address);
- assert.equal(newBridgeBalance, 1000);
- });
- });
-
- describe('bridge with token address', function () {
- beforeEach(async function () {
- this.bridge = await Bridge.new(bridgeManager, tokenAddress, { from: bridgeOwner });
- });
-
- it('calling token fallback', async function () {
- const result = await this.bridge.tokenFallback(anAccount, 100, "0x010203", { from: tokenAddress });
-
- assert.ok(result);
- });
-
- it('only token can call token fallback', async function () {
- expectThrow(this.bridge.tokenFallback(anAccount, 100, "0x010203", { from: anAccount }));
- });
- });
-
- describe('bridge maps addresses', function () {
- beforeEach(async function () {
- this.bridge = await Bridge.new(bridgeManager, tokenAddress, { from: bridgeOwner });
- });
-
- it('not mapped address', async function () {
- const result = await this.bridge.getMappedAddress(anAccount);
-
- assert.ok(result);
- assert.equal(result, anAccount);
-
- const result2 = await this.bridge.getMappedInverseAddress(anAccount);
-
- assert.ok(result2);
- assert.equal(result2, anAccount);
- });
-
- it('map address', async function () {
- await this.bridge.mapAddress(anotherAccount, { from: anAccount });
-
- const result = await this.bridge.getMappedAddress(anAccount);
-
- assert.ok(result);
- assert.equal(result, anotherAccount);
-
- const result2 = await this.bridge.getMappedInverseAddress(anotherAccount);
-
- assert.ok(result2);
- assert.equal(result2, anAccount);
- });
- });
-});
-
+const MainToken = artifacts.require('./MainToken');
+const AlternativeERC20Detailed = artifacts.require('./AlternativeERC20Detailed');
+const SideToken = artifacts.require('./SideToken');
+const Bridge = artifacts.require('./Bridge');
+const AllowTokens = artifacts.require('./AllowTokens');
+const SideTokenFactory = artifacts.require('./SideTokenFactory');
+const mockReceiveTokensCall = artifacts.require('./mockReceiveTokensCall');
+const WRBTC = artifacts.require('./WRBTC');
+
+const utils = require('./utils');
+const chains = require('../hardhat/helper/chains');
+const truffleAssertions = require('truffle-assertions');
+const ethUtil = require('ethereumjs-util');
+
+const BN = web3.utils.BN;
+const ONE_DAY = 24*3600;
+const toWei = web3.utils.toWei;
+
+const keccak256 = web3.utils.keccak256;
+const mainTokenName = 'MAIN on Ethereum';
+
+async function getClaimDigest(
+ bridge,
+ claim, //{address _to,uint256 _amount,bytes32 _transactionHash,uint256 originChainId,address _relayer,uint256 _fee},
+ nonce,
+ deadline
+) {
+ const CLAIM_TYPEHASH = await bridge.CLAIM_TYPEHASH();
+ const DOMAIN_SEPARATOR = await bridge.domainSeparator();
+
+ return web3.utils.soliditySha3(
+ {t:'bytes1', v:'0x19'},
+ {t:'bytes1', v:'0x01'},
+ {t:'bytes32', v:DOMAIN_SEPARATOR},
+ {t:'bytes32', v:keccak256(
+ web3.eth.abi.encodeParameters(
+ ['bytes32', 'address', 'uint256', 'bytes32', 'uint256', 'address', 'uint256', 'uint256', 'uint256'],
+ [CLAIM_TYPEHASH, claim.to, claim.amount, claim.transactionHash, claim.originChainId, claim.relayer, claim.fee, nonce, deadline]
+ )
+ )
+ }
+ )
+}
+
+contract('Bridge', async function (accounts) {
+ const bridgeOwner = accounts[0];
+ const tokenOwner = accounts[1];
+ const bridgeManager = accounts[2];
+ const anAccount = accounts[3];
+ const newBridgeManager = accounts[4];
+ const federation = accounts[5];
+ const tokenName = 'MAIN';
+ const tokenSymbol = 'MAIN';
+ const eventSignature = web3.eth.abi.encodeEventSignature('Cross(address,address,uint256,address,uint256,uint256,bytes)');
+ // Bug ganache treast chainid opcode as 1 https://github.com/trufflesuite/ganache-core/issues/451
+ const chainId = await web3.eth.getChainId();
+
+ before(async function () {
+ await utils.saveState();
+ });
+
+ after(async function () {
+ await utils.revertState();
+ });
+
+ beforeEach(async function () {
+ this.token = await MainToken.new(tokenName, tokenSymbol, 18, web3.utils.toWei('1000000000'), { from: tokenOwner });
+ this.allowTokens = await AllowTokens.new();
+ await this.allowTokens.methods['initialize(address,address,uint256,uint256,uint256,(string,(uint256,uint256,uint256,uint256,uint256))[])'](
+ bridgeManager,
+ bridgeOwner,
+ '0',
+ '0',
+ '0',
+ [{
+ description:'MAIN',
+ limits: {
+ max:toWei('10000'),
+ min:toWei('1'),
+ daily:toWei('100000'),
+ mediumAmount:toWei('2'),
+ largeAmount:toWei('3')
+ }
+ }]
+ );
+ this.typeId = 0;
+ await this.allowTokens.setToken(this.token.address, this.typeId, { from: bridgeManager });
+ this.sideTokenFactory = await SideTokenFactory.new();
+ this.bridge = await Bridge.new();
+ await this.bridge.methods['initialize(address,address,address,address)'](bridgeManager,
+ federation, this.allowTokens.address, this.sideTokenFactory.address);
+ await this.sideTokenFactory.transferPrimary(this.bridge.address);
+ await this.allowTokens.transferPrimary(this.bridge.address, { from: bridgeOwner });
+ });
+
+ describe('Main network', async function () {
+
+ it('should retrieve the version', async function () {
+ const result = await this.bridge.version();
+ assert.equal(result, "v4");
+ });
+
+ describe('owner', async function () {
+ it('check manager', async function () {
+ const manager = await this.bridge.owner();
+ assert.equal(manager, bridgeManager);
+ });
+
+ it('change manager', async function () {
+ const receipt = await this.bridge.transferOwnership(newBridgeManager, { from: bridgeManager });
+ utils.checkRcpt(receipt);
+ const manager = await this.bridge.owner();
+ assert.equal(manager, newBridgeManager);
+ });
+
+ it('only manager can change manager', async function () {
+ await truffleAssertions.fails(this.bridge.transferOwnership(newBridgeManager), truffleAssertions.ErrorType.REVERT);
+ const manager = await this.bridge.owner();
+ assert.equal(manager, bridgeManager);
+ });
+
+ it('change allowTokens', async function () {
+ let allowTokens = await this.bridge.allowTokens();
+ assert.equal(allowTokens, this.allowTokens.address);
+ const receipt = await this.bridge.changeAllowTokens(anAccount, { from: bridgeManager });
+ utils.checkRcpt(receipt);
+ allowTokens = await this.bridge.allowTokens();
+ assert.equal(allowTokens, anAccount);
+ });
+
+ it('only manager can change allowTokens', async function () {
+ let allowTokens = await this.bridge.allowTokens();
+ assert.equal(allowTokens, this.allowTokens.address);
+ await truffleAssertions.fails(
+ this.bridge.changeAllowTokens(anAccount, { from: tokenOwner }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ allowTokens = await this.bridge.allowTokens();
+ assert.equal(allowTokens, this.allowTokens.address);
+ });
+
+ it('change allowTokens fail if zero address', async function () {
+ let allowTokens = await this.bridge.allowTokens();
+ assert.equal(allowTokens, this.allowTokens.address);
+ await truffleAssertions.fails(
+ this.bridge.changeAllowTokens(utils.NULL_ADDRESS, { from: bridgeManager }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ allowTokens = await this.bridge.allowTokens();
+ assert.equal(allowTokens, this.allowTokens.address);
+ });
+
+ it('setFeePercentage successful', async function () {
+ const payment = 999; //9.99%
+ const feePercentageDivider = (await this.bridge.feePercentageDivider()).toNumber();
+ await this.bridge.setFeePercentage(payment, { from: bridgeManager});
+ const result = await this.bridge.getFeePercentage();
+ assert.equal(result, payment);
+ assert.equal((9.99/100).toFixed(4), payment/feePercentageDivider);
+ });
+
+ it('setFeePercentage should fail if not the owner', async function () {
+ const payment = 1000;
+ await truffleAssertions.fails(
+ this.bridge.setFeePercentage(payment, { from: tokenOwner}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ const result = await this.bridge.getFeePercentage();
+ assert.equal(result, 0);
+ });
+
+ it('setFeePercentage should fail if 10% or more', async function () {
+ const payment = await this.bridge.feePercentageDivider()/10;
+ await truffleAssertions.fails(
+ this.bridge.setFeePercentage(payment, { from: bridgeManager}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+
+ it('check federation', async function () {
+ const federationAddress = await this.bridge.getFederation();
+ assert.equal(federationAddress, federation);
+ });
+
+ it('change federation', async function () {
+ const receipt = await this.bridge.changeFederation(newBridgeManager, { from: bridgeManager });
+ utils.checkRcpt(receipt);
+ const federationAddress = await this.bridge.getFederation();
+ assert.equal(federationAddress, newBridgeManager);
+ });
+
+ it('only manager can change the federation', async function () {
+ await truffleAssertions.fails(this.bridge.changeFederation(newBridgeManager), truffleAssertions.ErrorType.REVERT);
+ const federationAddress = await this.bridge.getFederation();
+ assert.equal(federationAddress, federation);
+ });
+
+ it('change federation new fed cant be null', async function () {
+ await truffleAssertions.fails(
+ this.bridge.changeFederation(utils.NULL_ADDRESS, { from: bridgeManager }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ const federationAddress = await this.bridge.getFederation();
+ assert.equal(federationAddress, federation);
+ });
+ });
+
+ describe('createSiteTokens', async function() {
+ it('should create side token', async function () {
+ await this.bridge.createSideToken(
+ 0,
+ this.token.address,
+ 6,
+ 'eMAIN',
+ mainTokenName,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: bridgeManager }
+ );
+ const sideTokenAddress = await this.bridge.sideTokenByOriginalToken(chains.HARDHAT_TEST_NET_CHAIN_ID, this.token.address);
+ const sideToken = await SideToken.at(sideTokenAddress);
+ const sideTokenSymbol = await sideToken.symbol();
+ assert.equal(sideTokenSymbol, 'eMAIN');
+
+ const sideTokenDecimals = await sideToken.decimals();
+ assert.equal(sideTokenDecimals.toString(), '18');
+
+ const sideTokenGranularity = await sideToken.granularity();
+ assert.equal(sideTokenGranularity.toString(), '1000000000000');
+
+ const originalToken = await this.bridge.getOriginalTokenBySideToken(sideTokenAddress);
+ assert.equal(originalToken.tokenAddress, this.token.address);
+
+ const result = await this.allowTokens.getInfoAndLimits(sideTokenAddress);
+ assert.equal(result.info.typeId.toString(), '0');
+ assert.equal(result.info.allowed, true);
+
+ });
+
+ it('fail create side token if decimals bigger than 18', async function () {
+ await truffleAssertions.fails(
+ this.bridge.createSideToken(
+ 0,
+ this.token.address,
+ 19,
+ 'MAIN',
+ 'MAIN',
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: bridgeManager }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail create side token if inexistent chainId', async function () {
+ await truffleAssertions.fails(
+ this.bridge.createSideToken(
+ 0,
+ this.token.address,
+ 18,
+ 'MAIN',
+ 'MAIN',
+ 0,
+ { from: bridgeManager }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail create side token if inexistent typeId', async function () {
+ await truffleAssertions.fails(
+ this.bridge.createSideToken(
+ 1,
+ this.token.address,
+ 18,
+ 'MAIN',
+ 'MAIN',
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: bridgeManager }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail create side token if not the owner', async function () {
+ await truffleAssertions.fails(
+ this.bridge.createSideToken(
+ 0,
+ this.token.address,
+ 18,
+ 'MAIN',
+ 'MAIN',
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: federation }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail create side token if no token address', async function () {
+ await truffleAssertions.fails(
+ this.bridge.createSideToken(
+ 0,
+ utils.NULL_ADDRESS,
+ 18,
+ 'MAIN',
+ 'MAIN',
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: bridgeManager }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+ it('fail create side token if already created', async function () {
+ await this.bridge.createSideToken(
+ 0,
+ this.token.address,
+ 18,
+ 'MAIN',
+ 'MAIN',
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: bridgeManager }
+ );
+ await truffleAssertions.fails(
+ this.bridge.createSideToken(
+ 0,
+ this.token.address,
+ 18,
+ 'MAIN',
+ 'MAIN',
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: bridgeManager }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should create multiple side token', async function () {
+ const otherTokenAddr = utils.getRandomAddress();
+ await this.bridge.createMultipleSideTokens(
+ [{
+ _typeId: 0,
+ _originalTokenAddress: this.token.address,
+ _originalTokenDecimals: 6,
+ _originalTokenSymbol: 'eMAIN',
+ _originalTokenName: mainTokenName,
+ _originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID
+ },
+ {
+ _typeId: 0,
+ _originalTokenAddress: otherTokenAddr,
+ _originalTokenDecimals: 18,
+ _originalTokenSymbol: 'eOTHER',
+ _originalTokenName: 'Other token on Ethereum',
+ _originChainId: chains.BSC_TEST_NET_CHAIN_ID
+ }],
+ { from: bridgeManager }
+ );
+ const sideTokenAddress = await this.bridge.sideTokenByOriginalToken(chains.HARDHAT_TEST_NET_CHAIN_ID, this.token.address);
+ const sideToken = await SideToken.at(sideTokenAddress);
+ const sideTokenSymbol = await sideToken.symbol();
+ assert.equal(sideTokenSymbol, 'eMAIN');
+
+ const sideTokenDecimals = await sideToken.decimals();
+ assert.equal(sideTokenDecimals.toString(), '18');
+
+ const sideTokenGranularity = await sideToken.granularity();
+ assert.equal(sideTokenGranularity.toString(), '1000000000000');
+
+ const originalToken = await this.bridge.getOriginalTokenBySideToken(sideTokenAddress);
+ assert.equal(originalToken.tokenAddress, this.token.address);
+
+ const otherResult = await this.allowTokens.getInfoAndLimits(sideTokenAddress);
+ assert.equal(otherResult.info.typeId.toString(), '0');
+ assert.equal(otherResult.info.allowed, true);
+
+ const otherSideTokenAddress = await this.bridge.sideTokenByOriginalToken(chains.BSC_TEST_NET_CHAIN_ID, otherTokenAddr);
+ const otherSideToken = await SideToken.at(otherSideTokenAddress);
+ const otherSideTokenSymbol = await otherSideToken.symbol();
+ assert.equal(otherSideTokenSymbol, 'eOTHER');
+
+ const otherSideTokenDecimals = await otherSideToken.decimals();
+ assert.equal(otherSideTokenDecimals.toString(), '18');
+
+ const otherSideTokenGranularity = await otherSideToken.granularity();
+ assert.equal(otherSideTokenGranularity.toString(), '1');
+
+ const otherOriginalToken = await this.bridge.getOriginalTokenBySideToken(otherSideTokenAddress);
+ assert.equal(otherOriginalToken.tokenAddress.toLowerCase(), otherTokenAddr);
+
+ const result = await this.allowTokens.getInfoAndLimits(otherSideTokenAddress);
+ assert.equal(result.info.typeId.toString(), '0');
+ assert.equal(result.info.allowed, true);
+
+ });
+ });
+
+ describe('receiveTokens', async function () {
+ it('receiveTokens approve and transferFrom for ERC20', async function () {
+ const amount = web3.utils.toWei('1000');
+ const originalTokenBalance = await this.token.balanceOf(tokenOwner);
+ let receipt = await this.token.approve(this.bridge.address, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+ receipt = await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address, anAccount, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+ truffleAssertions.eventEmitted(receipt, 'Cross', (ev) => {
+ return ev._tokenAddress === this.token.address
+ && ev._from === tokenOwner
+ && ev._to === anAccount
+ && ev._amount.toString() === amount
+ && ev._userData === null;
+ });
+
+ const tokenBalance = await this.token.balanceOf(tokenOwner);
+ assert.equal(tokenBalance.toString(), new BN(originalTokenBalance).sub(new BN(amount)).toString());
+ const bridgeBalance = await this.token.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance.toString(), amount.toString());
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address);
+ assert.equal(isKnownToken, true);
+ });
+
+ it('receiveTokens approve and transferFrom for ERC20 Max allowed tokens 18 decimals', async function () {
+ let limit = await this.allowTokens.typeLimits(this.typeId);
+ const amount = limit.max;
+ const originalTokenBalance = await this.token.balanceOf(tokenOwner);
+ let receipt = await this.token.approve(this.bridge.address, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+ receipt = await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address, tokenOwner, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+
+ const tokenBalance = await this.token.balanceOf(tokenOwner);
+ assert.equal(tokenBalance.toString(), new BN(originalTokenBalance).sub(new BN(amount)).toString());
+ const bridgeBalance = await this.token.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance.toString(), amount.toString());
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address);
+ assert.equal(isKnownToken, true);
+ });
+
+ it('receiveTokens approve and transferFrom for ERC20 Min allowed tokens 18 decimals', async function () {
+ let limit = await this.allowTokens.typeLimits(this.typeId);
+ const amount = await limit.min;
+ const originalTokenBalance = await this.token.balanceOf(tokenOwner);
+ let receipt = await this.token.approve(this.bridge.address, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+ receipt = await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address, tokenOwner, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+
+ const tokenBalance = await this.token.balanceOf(tokenOwner);
+ assert.equal(tokenBalance.toString(), new BN(originalTokenBalance).sub(new BN(amount)).toString());
+ const bridgeBalance = await this.token.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance.toString(), amount.toString());
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address);
+ assert.equal(isKnownToken, true);
+ });
+
+ it('receiveTokens approve and transferFrom for ERC20 Max allowed tokens 8 decimals', async function () {
+ let limit = await this.allowTokens.typeLimits(this.typeId);
+ const maxTokens = limit.max;
+ const amount = new BN(maxTokens).div(new BN((10**10).toString()));
+ let token = await AlternativeERC20Detailed.new("AlternativeERC20Detailed", utils.ascii_to_hexa('x'), '8', amount, { from: tokenOwner });
+
+ await this.allowTokens.setToken(token.address, this.typeId, { from: bridgeManager });
+ const originalTokenBalance = await token.balanceOf(tokenOwner);
+ let receipt = await token.approve(this.bridge.address, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+ receipt = await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, token.address, tokenOwner, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+
+ const tokenBalance = await token.balanceOf(tokenOwner);
+ assert.equal(tokenBalance.toString(), new BN(originalTokenBalance).sub(new BN(amount)).toString());
+ const bridgeBalance = await token.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance.toString(), amount.toString());
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, token.address);
+ assert.equal(isKnownToken, true);
+ });
+
+
+ it('receiveTokens approve and transferFrom for ERC20 Min allowed tokens 8 decimals', async function () {
+ let limit = await this.allowTokens.typeLimits(this.typeId);
+ const minTokens = limit.min;
+ const amount = new BN(minTokens).div(new BN((10**10).toString()));
+ let token = await AlternativeERC20Detailed.new("AlternativeERC20Detailed", utils.ascii_to_hexa('x'), '8', amount, { from: tokenOwner });
+
+ await this.allowTokens.setToken(token.address, this.typeId, { from: bridgeManager });
+ const originalTokenBalance = await token.balanceOf(tokenOwner);
+ let receipt = await token.approve(this.bridge.address, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+ receipt = await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, token.address, tokenOwner, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+
+ const tokenBalance = await token.balanceOf(tokenOwner);
+ assert.equal(tokenBalance.toString(), new BN(originalTokenBalance).sub(new BN(amount)).toString());
+ const bridgeBalance = await token.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance.toString(), amount.toString());
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, token.address);
+ assert.equal(isKnownToken, true);
+ });
+
+ it('receiveTokens approve and transferFrom Alternative ERC20 Detailed', async function () {
+ const amount = web3.utils.toWei('1000', 'gwei'); // In GWei cause it gas 10 decimals
+ const decimals = '10';
+ const symbol = "ERC20";
+ let erc20Alternative = await AlternativeERC20Detailed.new("AlternativeERC20Detailed", utils.ascii_to_hexa(symbol), decimals, amount, { from: tokenOwner });
+
+ await this.allowTokens.setToken(erc20Alternative.address, this.typeId, { from: bridgeManager });
+ const originalTokenBalance = await erc20Alternative.balanceOf(tokenOwner);
+ let receipt = await erc20Alternative.approve(this.bridge.address, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+ receipt = await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, erc20Alternative.address, anAccount, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+
+ truffleAssertions.eventEmitted(receipt, 'Cross', (ev) => {
+ return ev._tokenAddress === erc20Alternative.address
+ && ev._from === tokenOwner
+ && ev._to === anAccount
+ && ev._amount.toString() === amount
+ && ev._userData === null;
+ });
+
+ const tokenBalance = await erc20Alternative.balanceOf(tokenOwner);
+ assert.equal(tokenBalance.toString(), new BN(originalTokenBalance).sub(new BN(amount)).toString());
+ const bridgeBalance = await erc20Alternative.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance, amount);
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, erc20Alternative.address);
+ assert.equal(isKnownToken, true);
+ });
+
+ it('depositTo using network currency', async function () {
+ const amount = web3.utils.toWei('1');
+ const wrbtc = await WRBTC.new({ from: tokenOwner });
+
+ await this.bridge.setWrappedCurrency(wrbtc.address, { from: bridgeManager });
+ await this.allowTokens.setToken(wrbtc.address, this.typeId, { from: bridgeManager });
+
+ const receipt = await this.bridge.depositTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, anAccount, { from: tokenOwner, value: amount });
+ utils.checkRcpt(receipt);
+
+ truffleAssertions.eventEmitted(receipt, 'Cross', (ev) => {
+ return ev._tokenAddress === wrbtc.address
+ && ev._from === tokenOwner
+ && ev._to === anAccount
+ && ev._amount.toString() === amount
+ && ev._userData === null;
+ });
+
+ const bridgeBalance = await wrbtc.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance, amount);
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, wrbtc.address);
+ assert.equal(isKnownToken, true);
+ });
+
+ it('fail depositTo invalid chainId', async function () {
+ const amount = web3.utils.toWei('1');
+ const wrbtc = await WRBTC.new({ from: tokenOwner });
+
+ await this.bridge.setWrappedCurrency(wrbtc.address, { from: bridgeManager });
+ await this.allowTokens.setToken(wrbtc.address, this.typeId, { from: bridgeManager });
+ await truffleAssertions.fails(
+ this.bridge.depositTo(0, anAccount, { from: tokenOwner, value: amount }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail depositTo no wrapped currency set', async function () {
+ const amount = web3.utils.toWei('1');
+ const wrbtc = await WRBTC.new({ from: tokenOwner });
+
+ await this.allowTokens.setToken(wrbtc.address, this.typeId, { from: bridgeManager });
+ await truffleAssertions.fails(
+ this.bridge.depositTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, anAccount, { from: tokenOwner, value: amount }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('call depositTo from a contract', async function () {
+ const amount = web3.utils.toWei('1');
+ const wrbtc = await WRBTC.new({ from: tokenOwner });
+ const mockContract = await mockReceiveTokensCall.new(this.bridge.address)
+ await this.bridge.setWrappedCurrency(wrbtc.address, { from: bridgeManager });
+ await this.allowTokens.setToken(wrbtc.address, this.typeId, { from: bridgeManager });
+ const receipt = await mockContract.callDepositTo(anAccount, chains.ETHEREUM_MAIN_NET_CHAIN_ID, { from: tokenOwner, value: amount });
+ utils.checkRcpt(receipt);
+
+ const bridgeBalance = await wrbtc.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance, amount);
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, wrbtc.address);
+ assert.equal(isKnownToken, true);
+ });
+
+ it('receiveTokens approve and transferFrom for ERC777', async function () {
+ const amount = web3.utils.toWei('1000');
+ const granularity = '1000';
+ let erc777 = await SideToken.new("ERC777", "777", tokenOwner, granularity, { from: tokenOwner });
+
+ await this.allowTokens.setToken(erc777.address, this.typeId, { from: bridgeManager });
+ await erc777.mint(tokenOwner, amount, "0x", "0x", {from: tokenOwner });
+
+ const originalTokenBalance = await erc777.balanceOf(tokenOwner);
+ let receipt = await erc777.approve(this.bridge.address, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+ receipt = await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, erc777.address, tokenOwner, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+
+ truffleAssertions.eventEmitted(receipt, 'Cross', (ev) => {
+ return ev._tokenAddress === erc777.address
+ && ev._from === tokenOwner
+ && ev._to === tokenOwner
+ && ev._amount.toString() === amount
+ && ev._userData === null;
+ });
+
+ const tokenBalance = await erc777.balanceOf(tokenOwner);
+ assert.equal(tokenBalance.toString(), new BN(originalTokenBalance).sub(new BN(amount)).toString());
+ const bridgeBalance = await erc777.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance, amount);
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, erc777.address);
+ assert.equal(isKnownToken, true);
+ });
+
+ it('tokensReceived for ERC777', async function () {
+ const amount = web3.utils.toWei('1000');
+ const granularity = '100';
+ let erc777 = await SideToken.new("ERC777", "777", tokenOwner, granularity, { from: tokenOwner });
+ await this.allowTokens.setToken(erc777.address, this.typeId.toString(), { from: bridgeManager });
+ await erc777.mint(tokenOwner, amount, "0x", "0x", {from: tokenOwner });
+ const originalTokenBalance = await erc777.balanceOf(tokenOwner);
+ const userData = web3.eth.abi.encodeParameters(
+ ["address", "uint256"],
+ [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]
+ );
+ const result = await erc777.send(this.bridge.address, amount, userData, { from: tokenOwner });
+ utils.checkRcpt(result);
+
+ assert.equal(result.receipt.rawLogs[3].topics[0], eventSignature);
+ let decodedLog = web3.eth.abi.decodeLog([
+ {
+ "indexed": true,
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "_destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "_userData",
+ "type": "bytes"
+ }
+ ], result.receipt.rawLogs[3].data, result.receipt.rawLogs[3].topics.slice(1));
+
+ assert.equal(decodedLog._tokenAddress, erc777.address);
+ assert.equal(decodedLog._from, tokenOwner);
+ assert.equal(decodedLog._to, anAccount);
+ assert.equal(decodedLog._amount, amount);
+ assert.equal(decodedLog._userData, userData);
+ assert.equal(decodedLog._originChainId, chainId);
+ assert.equal(decodedLog._destinationChainId, chains.ETHEREUM_MAIN_NET_CHAIN_ID);
+
+ const tokenBalance = await erc777.balanceOf(tokenOwner);
+ assert.equal(tokenBalance.toString(), new BN(originalTokenBalance).sub(new BN(amount)).toString());
+ const bridgeBalance = await erc777.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance, amount);
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, erc777.address);
+ assert.equal(isKnownToken, true);
+ });
+
+ it('tokensReceived for ERC777 called with contract', async function () {
+ const amount = web3.utils.toWei('1000');
+ const granularity = '100';
+ const erc777 = await SideToken.new("ERC777", "777", tokenOwner, granularity, { from: tokenOwner });
+ await this.allowTokens.setToken(erc777.address, this.typeId.toString(), { from: bridgeManager });
+ const mockContract = await mockReceiveTokensCall.new(this.bridge.address);
+ await erc777.mint(mockContract.address, amount, "0x", "0x", {from: tokenOwner });
+ const originalTokenBalance = await erc777.balanceOf(mockContract.address);
+
+ const userData = web3.eth.abi.encodeParameters(
+ ["address", "uint256"],
+ [anAccount.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]
+ );
+
+ const result = await mockContract.callTokensReceived(erc777.address, amount, userData, { from: tokenOwner });
+ utils.checkRcpt(result);
+
+ assert.equal(result.receipt.rawLogs[3].topics[0], eventSignature);
+ let decodedLog = web3.eth.abi.decodeLog([
+ {
+ "indexed": true,
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "_destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "_userData",
+ "type": "bytes"
+ }
+ ], result.receipt.rawLogs[3].data, result.receipt.rawLogs[3].topics.slice(1));
+
+ assert.equal(decodedLog._tokenAddress, erc777.address);
+ assert.equal(decodedLog._from, mockContract.address);
+ assert.equal(decodedLog._to, anAccount);
+ assert.equal(decodedLog._amount, amount);
+ assert.equal(decodedLog._userData, userData);
+ assert.equal(decodedLog._originChainId, chainId);
+ assert.equal(decodedLog._destinationChainId, chains.ETHEREUM_MAIN_NET_CHAIN_ID);
+
+ const tokenBalance = await erc777.balanceOf(mockContract.address);
+ assert.equal(tokenBalance.toString(), new BN(originalTokenBalance).sub(new BN(amount)).toString());
+ const bridgeBalance = await erc777.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance, amount);
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, erc777.address);
+ assert.equal(isKnownToken, true);
+ });
+
+ it('tokensReceived for ERC777 user without address in data', async function () {
+ const amount = web3.utils.toWei('1000');
+ const granularity = '100';
+ let erc777 = await SideToken.new("ERC777", "777", tokenOwner, granularity, { from: tokenOwner });
+
+ await this.allowTokens.setToken(erc777.address, this.typeId, { from: bridgeManager });
+ await erc777.mint(tokenOwner, amount, "0x", "0x", { from: tokenOwner });
+ const originalTokenBalance = await erc777.balanceOf(tokenOwner);
+ const userData = web3.eth.abi.encodeParameters(
+ ["uint256"],
+ [chains.ETHEREUM_MAIN_NET_CHAIN_ID]
+ );
+ let result = await erc777.send(this.bridge.address, amount, userData, { from: tokenOwner });
+ utils.checkRcpt(result);
+
+ assert.equal(result.receipt.rawLogs[3].topics[0], eventSignature);
+ let decodedLog = web3.eth.abi.decodeLog([
+ {
+ "indexed": true,
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "_destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "_userData",
+ "type": "bytes"
+ }
+ ], result.receipt.rawLogs[3].data, result.receipt.rawLogs[3].topics.slice(1));
+
+ assert.equal(decodedLog._tokenAddress, erc777.address);
+ assert.equal(decodedLog._from, tokenOwner);
+ assert.equal(decodedLog._to, tokenOwner);
+ assert.equal(decodedLog._amount, amount);
+ assert.equal(decodedLog._userData, userData);
+ assert.equal(decodedLog._originChainId, chainId);
+ assert.equal(decodedLog._destinationChainId, chains.ETHEREUM_MAIN_NET_CHAIN_ID);
+
+ const tokenBalance = await erc777.balanceOf(tokenOwner);
+ assert.equal(tokenBalance.toString(), new BN(originalTokenBalance).sub(new BN(amount)).toString());
+ const bridgeBalance = await erc777.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance, amount);
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, erc777.address);
+ assert.equal(isKnownToken, true);
+ });
+
+ it('tokensReceived for ERC777 with payment', async function () {
+ const amount = new BN(web3.utils.toWei('1000'));
+ const payment = new BN('185'); //1.85%
+ await this.bridge.setFeePercentage(payment, { from: bridgeManager});
+ const feePercentageDivider = await this.bridge.feePercentageDivider();
+ const fees = amount.mul(payment).div(feePercentageDivider);
+ const granularity = '100';
+ let erc777 = await SideToken.new("ERC777", "777", tokenOwner, granularity, { from: tokenOwner });
+
+ await this.allowTokens.setToken(erc777.address, this.typeId, { from: bridgeManager });
+ await erc777.mint(tokenOwner, amount, "0x", "0x", {from: tokenOwner });
+ const originalTokenBalance = await erc777.balanceOf(tokenOwner);
+ const userData = web3.eth.abi.encodeParameters(
+ ["address", "uint256"],
+ [tokenOwner.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]
+ );
+ let result = await erc777.send(this.bridge.address, amount, userData, { from: tokenOwner });
+ utils.checkRcpt(result);
+
+ assert.equal(result.receipt.rawLogs[3].topics[0], eventSignature);
+ let decodedLog = web3.eth.abi.decodeLog([
+ {
+ "indexed": true,
+ "name": "_tokenAddress",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "_destinationChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "_originChainId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "_userData",
+ "type": "bytes"
+ }
+ ], result.receipt.rawLogs[3].data, result.receipt.rawLogs[3].topics.slice(1));
+
+ assert.equal(decodedLog._tokenAddress, erc777.address);
+ assert.equal(decodedLog._from, tokenOwner);
+ assert.equal(decodedLog._to, tokenOwner);
+ assert.equal(decodedLog._amount, amount.sub(fees).toString());
+ assert.equal(decodedLog._userData, userData);
+ assert.equal(decodedLog._originChainId, chainId);
+ assert.equal(decodedLog._destinationChainId, chains.ETHEREUM_MAIN_NET_CHAIN_ID);
+
+ const tokenBalance = await erc777.balanceOf(tokenOwner);
+ assert.equal(tokenBalance.toString(), originalTokenBalance.sub(amount).toString());
+ const bridgeBalance = await erc777.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance.toString(), amount.sub(fees).toString());
+ const ownerBalance = await erc777.balanceOf(bridgeManager);
+ assert.equal(ownerBalance.toString(), fees.toString());
+ assert.equal(fees.toString(), (amount*1.85/100).toString());
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, erc777.address);
+ assert.equal(isKnownToken, true);
+ });
+
+ it('tokensReceived should fail if not a token contract', async function () {
+ const amount = web3.utils.toWei('1000');
+ const granularity = '100';
+ const erc777 = await SideToken.new("ERC777", "777", tokenOwner, granularity, { from: tokenOwner });
+
+ await this.allowTokens.setToken(erc777.address, this.typeId, { from: bridgeManager });
+ await erc777.mint(tokenOwner, amount, "0x", "0x", {from: tokenOwner });
+ const userData = tokenOwner;
+ await truffleAssertions.fails(
+ this.bridge.tokensReceived(tokenOwner,tokenOwner, this.bridge.address, amount, userData, '0x', { from: tokenOwner }),
+ truffleAssertions.ErrorType.REVERT);
+ });
+
+ it('tokensReceived should fail if not directed to bridge', async function () {
+ const amount = web3.utils.toWei('1000');
+ const granularity = '100';
+ const erc777 = await SideToken.new("ERC777", "777", tokenOwner, granularity, { from: tokenOwner });
+
+ await this.allowTokens.setToken(erc777.address, this.typeId, { from: bridgeManager });
+ await erc777.mint(tokenOwner, amount, "0x", "0x", {from: tokenOwner });
+ const userData = tokenOwner;
+ await truffleAssertions.fails(
+ this.bridge.tokensReceived(erc777.address, erc777.address, tokenOwner, amount, userData, '0x', { from: tokenOwner }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('tokensReceived should fail if calling from contract not whitelisted', async function () {
+ const amount = web3.utils.toWei('1000');
+ const granularity = '100';
+ const erc777 = await SideToken.new("ERC777", "777", tokenOwner, granularity, { from: tokenOwner });
+
+ await this.allowTokens.setToken(erc777.address, this.typeId, { from: bridgeManager });
+ await erc777.mint(tokenOwner, amount, "0x", "0x", {from: tokenOwner });
+ const userData = tokenOwner;
+ await truffleAssertions.fails(
+ this.bridge.tokensReceived(erc777.address, this.allowTokens.address, this.bridge.address, amount, userData, '0x', { from: tokenOwner }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('tokensReceived should fail if calling from contract with no data', async function () {
+ const amount = web3.utils.toWei('1000');
+ const granularity = '100';
+ const erc777 = await SideToken.new("ERC777", "777", tokenOwner, granularity, { from: tokenOwner });
+
+ await this.allowTokens.setToken(erc777.address, this.typeId, { from: bridgeManager });
+ await erc777.mint(tokenOwner, amount, "0x", "0x", {from: tokenOwner });
+ const userData = "0x";
+ await truffleAssertions.fails(
+ this.bridge.tokensReceived(erc777.address, erc777.address, this.bridge.address, amount, userData, '0x', { from: tokenOwner }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+
+ it('send money to contract should fail', async function () {
+ const payment = new BN('1000');
+ await truffleAssertions.fails(
+ web3.eth.sendTransaction({ from:tokenOwner, to: this.bridge.address, value: payment }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('receiveTokens with payment successful', async function () {
+ const payment = new BN('33');
+ const amount = new BN(web3.utils.toWei('1000'));
+ const feePercentageDivider = await this.bridge.feePercentageDivider();
+ const fees = amount.mul(payment).div(feePercentageDivider);
+ const originalTokenBalance = await this.token.balanceOf(tokenOwner);
+ await this.bridge.setFeePercentage(payment, { from: bridgeManager});
+ await this.token.approve(this.bridge.address, amount, { from: tokenOwner });
+
+ const receipt = await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address, tokenOwner, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+
+ const ownerBalance = await this.token.balanceOf(bridgeManager);
+ assert.equal(ownerBalance.toString(), fees.toString());
+ assert.equal(fees.toString(), (amount*0.33/100).toString());
+ const tokenBalance = await this.token.balanceOf(tokenOwner);
+ assert.equal(tokenBalance.toString(), originalTokenBalance.sub(amount));
+ const bridgeBalance = await this.token.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance.toString(), amount.sub(fees).toString());
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address);
+ assert.equal(isKnownToken, true);
+ });
+
+ it('receiveTokens with payment and granularity successful', async function () {
+ const payment = new BN('33');
+ const amount = new BN(web3.utils.toWei('1000'));
+ const granularity = '100';
+ let erc777 = await SideToken.new("ERC777", "777", tokenOwner, granularity, { from: tokenOwner });
+
+ await this.allowTokens.setToken(erc777.address, this.typeId, { from: bridgeManager });
+ await erc777.mint(tokenOwner, amount, "0x", "0x", {from: tokenOwner });
+ const feePercentageDivider = await this.bridge.feePercentageDivider();
+ const fees = amount.mul(payment).div(feePercentageDivider);
+ const originalTokenBalance = await erc777.balanceOf(tokenOwner);
+ await this.bridge.setFeePercentage(payment, { from: bridgeManager});
+ await erc777.approve(this.bridge.address, amount, { from: tokenOwner });
+
+ const receipt = await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, erc777.address, tokenOwner, amount, { from: tokenOwner });
+ utils.checkRcpt(receipt);
+
+ const ownerBalance = await erc777.balanceOf(bridgeManager);
+ assert.equal(ownerBalance.toString(), fees.toString());
+ assert.equal(fees.toString(), (amount*0.33/100).toString());
+ const tokenBalance = await erc777.balanceOf(tokenOwner);
+ assert.equal(tokenBalance.toString(), originalTokenBalance.sub(amount));
+ const bridgeBalance = await erc777.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance.toString(), amount.sub(fees).toString());
+ const isKnownToken = await this.bridge.knownToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, erc777.address);
+ assert.equal(isKnownToken, true);
+ });
+
+ it('receiveTokens should reject token not allowed', async function () {
+ const newToken = await MainToken.new("MAIN", "MAIN", 18, web3.utils.toWei('1000000000'), { from: tokenOwner });
+ const amount = web3.utils.toWei('1000');
+ await newToken.approve(this.bridge.address, amount, { from: tokenOwner });
+ await truffleAssertions.fails(
+ this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, newToken.address, tokenOwner, amount, { from: tokenOwner }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('receiveTokens should work calling from a contract', async function () {
+ const otherContract = await mockReceiveTokensCall.new(this.bridge.address);
+ const amount = web3.utils.toWei('1000');
+ await this.token.transfer(otherContract.address, amount, { from: tokenOwner });
+ await otherContract.callReceiveTokens(this.token.address, tokenOwner, amount, chains.ETHEREUM_MAIN_NET_CHAIN_ID);
+ });
+
+ it('rejects to receive tokens greater than max tokens allowed 18 decimals', async function() {
+ const limit = await this.allowTokens.typeLimits(this.typeId);
+ const maxTokensAllowed = limit.max;
+ const amount = maxTokensAllowed.add(new BN('1'));
+ await this.token.approve(this.bridge.address, amount.toString(), { from: tokenOwner });
+
+ await truffleAssertions.fails(
+ this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address, tokenOwner, amount.toString(), { from: tokenOwner}),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ const isKnownToken = await this.bridge.knownToken(chains.HARDHAT_TEST_NET_CHAIN_ID, this.token.address);
+ assert.equal(isKnownToken, false);
+ const bridgeBalance = await this.token.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance, 0);
+ });
+
+ it('rejects to receive tokens greater than max tokens allowed 8 decimals', async function() {
+ const newToken = await MainToken.new("MAIN", "MAIN", 8, web3.utils.toWei('1000000000'), { from: tokenOwner });
+ const limit = await this.allowTokens.typeLimits(this.typeId);
+ const maxTokensAllowed = limit.max;
+ const amount = maxTokensAllowed.div(new BN((10**10).toString()).add(new BN('1')));
+ await newToken.approve(this.bridge.address, amount.toString(), { from: tokenOwner });
+
+ await truffleAssertions.fails(
+ this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, newToken.address, tokenOwner, amount.toString(), { from: tokenOwner}),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ const isKnownToken = await this.bridge.knownToken(chains.HARDHAT_TEST_NET_CHAIN_ID, newToken.address);
+ assert.equal(isKnownToken, false);
+ const bridgeBalance = await newToken.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance, 0);
+ });
+
+ it('rejects to receive tokens lesser than min tokens allowed 18 decimals', async function() {
+ const limit = await this.allowTokens.typeLimits(this.typeId);
+ const minTokensAllowed = limit.min;
+ const amount = minTokensAllowed.sub(new BN('1'));
+ await this.token.approve(this.bridge.address, amount.toString(), { from: tokenOwner });
+
+ await truffleAssertions.fails(
+ this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address, tokenOwner, amount.toString(), { from: tokenOwner}),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ const isKnownToken = await this.bridge.knownToken(chains.HARDHAT_TEST_NET_CHAIN_ID, this.token.address);
+ assert.equal(isKnownToken, false);
+ const bridgeBalance = await this.token.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance, 0);
+ });
+
+ it('rejects to receive tokens greater than min tokens allowed 8 decimals', async function() {
+ const newToken = await MainToken.new("MAIN", "MAIN", 8, web3.utils.toWei('1000000000'), { from: tokenOwner });
+ const limit = await this.allowTokens.typeLimits(this.typeId);
+ const maxTokensAllowed = limit.max;
+ const amount = maxTokensAllowed.div(new BN((10**10).toString()).sub(new BN('1')));
+ await newToken.approve(this.bridge.address, amount.toString(), { from: tokenOwner });
+
+ await truffleAssertions.fails(
+ this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, newToken.address, tokenOwner, amount.toString(), { from: tokenOwner}),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ const isKnownToken = await this.bridge.knownToken(chains.HARDHAT_TEST_NET_CHAIN_ID, newToken.address);
+ assert.equal(isKnownToken, false);
+ const bridgeBalance = await newToken.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance, 0);
+ });
+
+ it('rejects to receive tokens over the daily limit 18 decimals', async function() {
+ const limit = await this.allowTokens.typeLimits(this.typeId);
+ const maxTokensAllowed = limit.max;
+ const dailyLimit = limit.daily;
+
+ for(var tokensSent = 0; tokensSent < dailyLimit; tokensSent = BigInt(maxTokensAllowed) + BigInt(tokensSent)) {
+ await this.token.approve(this.bridge.address, maxTokensAllowed, { from: tokenOwner });
+ await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address, tokenOwner, maxTokensAllowed, { from: tokenOwner })
+ }
+ await truffleAssertions.fails(
+ this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address, tokenOwner, maxTokensAllowed, { from: tokenOwner}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('rejects to receive tokens over the daily limit 8 decimals', async function() {
+ const newToken = await MainToken.new("MAIN", "MAIN", 8, web3.utils.toWei('1000000000'), { from: tokenOwner });
+ await this.allowTokens.setToken(newToken.address, this.typeId, { from: bridgeManager });
+ const limit = await this.allowTokens.typeLimits(this.typeId);
+ const maxTokensAllowed = limit.max;
+ const amount = BigInt(maxTokensAllowed) / BigInt(10**10);
+ const dailyLimit = limit.daily;
+
+ for(var tokensSent = 0; tokensSent < dailyLimit; tokensSent = BigInt(maxTokensAllowed) + BigInt(tokensSent)) {
+ await newToken.approve(this.bridge.address, amount.toString(), { from: tokenOwner });
+ await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, newToken.address, tokenOwner, amount.toString(), { from: tokenOwner })
+ }
+ await truffleAssertions.fails(
+ this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, newToken.address, tokenOwner, amount.toString(), { from: tokenOwner}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('clear spent today after 24 hours', async function() {
+ let limit = await this.allowTokens.typeLimits(this.typeId);
+ let maxTokensAllowed = limit.max;
+ let dailyLimit = limit.daily;
+ let maxWidthdraw = await this.allowTokens.calcMaxWithdraw(this.token.address);
+ assert.equal(maxWidthdraw.toString(), maxTokensAllowed.toString());
+
+ for(var tokensSent = 0; tokensSent < dailyLimit; tokensSent = BigInt(maxTokensAllowed) + BigInt(tokensSent)) {
+ await this.token.approve(this.bridge.address, maxTokensAllowed, { from: tokenOwner });
+ await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address, tokenOwner, maxTokensAllowed, { from: tokenOwner })
+ }
+ maxWidthdraw = await this.allowTokens.calcMaxWithdraw(this.token.address);
+ assert.equal(maxWidthdraw.toString(), '0');
+ await utils.increaseTimestamp(web3, ONE_DAY+1);
+ maxWidthdraw = await this.allowTokens.calcMaxWithdraw(this.token.address);
+ assert.equal(maxWidthdraw.toString(), maxTokensAllowed.toString());
+ });
+
+ it('clear spent today and successfully receives tokens', async function() {
+ const amount = web3.utils.toWei('1000');
+ let limit = await this.allowTokens.typeLimits(this.typeId);
+ let maxTokensAllowed = limit.max;
+ let dailyLimit = limit.daily;
+
+ for(let tokensSent = 0; tokensSent < dailyLimit; tokensSent = BigInt(maxTokensAllowed) + BigInt(tokensSent)) {
+ await this.token.approve(this.bridge.address, maxTokensAllowed, { from: tokenOwner });
+ await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address, tokenOwner, maxTokensAllowed, { from: tokenOwner })
+ }
+ await utils.increaseTimestamp(web3, ONE_DAY + 1);
+
+ await this.token.approve(this.bridge.address, amount, { from: tokenOwner });
+ const receipt = await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address, tokenOwner, amount, { from: tokenOwner});
+ utils.checkRcpt(receipt);
+ });
+
+ });
+
+ });
+
+ describe('Mirror Side', async function () {
+ beforeEach(async function () {
+ // Set wrapped currency for main bridge
+ this.wrbtc = await WRBTC.new({ from: tokenOwner });
+ await this.bridge.setWrappedCurrency(this.wrbtc.address, { from: bridgeManager });
+ await this.allowTokens.setToken(this.wrbtc.address, this.typeId, { from: bridgeManager });
+ // Deploy Mirror Bridge and necesary contracts
+ this.mirrorAllowTokens = await AllowTokens.new();
+ await this.mirrorAllowTokens.methods['initialize(address,address,uint256,uint256,uint256,(string,(uint256,uint256,uint256,uint256,uint256))[])'](
+ bridgeManager,
+ bridgeOwner,
+ '0',
+ '0',
+ '0',
+ [{
+ description: 'eMAIN',
+ limits:{
+ max:toWei('10000'),
+ min:toWei('1'),
+ daily:toWei('100000'),
+ mediumAmount:toWei('2'),
+ largeAmount:toWei('3')
+ }
+ }]
+ );
+ this.mirrorSideTokenFactory = await SideTokenFactory.new();
+ this.mirrorBridge = await Bridge.new();
+ await this.mirrorBridge.methods['initialize(address,address,address,address)'](bridgeManager,
+ federation, this.mirrorAllowTokens.address, this.mirrorSideTokenFactory.address, { from: bridgeOwner });
+ await this.mirrorSideTokenFactory.transferPrimary(this.mirrorBridge.address);
+ await this.mirrorAllowTokens.transferPrimary(this.mirrorBridge.address);
+ // Set mirror wrapped currency
+ this.mirrorWrbtc = await WRBTC.new({ from: tokenOwner });
+ await this.mirrorBridge.setWrappedCurrency(this.mirrorWrbtc.address, { from: bridgeManager });
+ await this.mirrorAllowTokens.setToken(this.mirrorWrbtc.address, this.typeId, { from: bridgeManager });
+ //Cross a token
+ this.amount = web3.utils.toWei('1000');
+ this.decimals = (await this.token.decimals()).toString();
+ this.granularity = 1;
+ await this.token.approve(this.bridge.address, this.amount, { from: tokenOwner });
+ this.txReceipt = await this.bridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address, tokenOwner, this.amount, { from: tokenOwner });
+
+ await this.mirrorBridge.createSideToken(
+ 0,
+ this.token.address,
+ 18,
+ tokenSymbol,
+ tokenName,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ { from: bridgeManager }
+ );
+
+ await this.mirrorBridge.createSideToken(
+ 0,
+ this.wrbtc.address,
+ 18,
+ 'WRBTC',
+ 'Wrapped RBTC',
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ { from: bridgeManager }
+ );
+
+ //Cross wrapped token to test unwrap when crossing back
+ this.wrbtcAmount = web3.utils.toWei('2');
+ this.txReceiptWrbtc = await this.bridge.depositTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, tokenOwner, { from: tokenOwner, value: this.wrbtcAmount });
+ });
+
+ describe('Cross the tokens', async function() {
+ describe('acceptTransfer', async function() {
+ it('accept transfer first time for the token', async function () {
+ const transactionDataHash = await this.mirrorBridge.getTransactionDataHash(
+ anAccount,
+ this.amount,
+ this.txReceipt.receipt.blockHash,
+ this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ )
+ const receipt = await this.mirrorBridge.acceptTransfer(
+ this.token.address,
+ tokenOwner,
+ anAccount,
+ this.amount,
+ this.txReceipt.receipt.blockHash,
+ this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: federation }
+ );
+ utils.checkRcpt(receipt);
+
+ const obtainedTransactionDataHash = await this.mirrorBridge.transactionsDataHashes(this.txReceipt.tx);
+ assert.equal(obtainedTransactionDataHash, transactionDataHash);
+
+ const originalTokenAddresses = await this.mirrorBridge.originalTokenAddresses(this.txReceipt.tx);
+ assert.equal(originalTokenAddresses, this.token.address);
+
+ const senderAddresses = await this.mirrorBridge.senderAddresses(this.txReceipt.tx);
+ assert.equal(senderAddresses, tokenOwner);
+
+ });
+
+ it('fail accept transfer with wrong destination chainId', async function () {
+ await truffleAssertions.fails(
+ this.mirrorBridge.acceptTransfer(
+ this.token.address,
+ tokenOwner,
+ anAccount,
+ this.amount,
+ this.txReceipt.receipt.blockHash,
+ this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ { from: federation }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail accept transfer with receiver empty address', async function () {
+ const decimals = 18;
+ const tokenWithDecimals = await MainToken.new("MAIN", "MAIN", decimals, web3.utils.toWei('1000000000'), { from: tokenOwner });
+ await this.mirrorBridge.createSideToken(
+ this.typeId,
+ tokenWithDecimals.address,
+ decimals,
+ "MAIN",
+ "MAIN",
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: bridgeManager }
+ );
+
+ await truffleAssertions.fails(this.mirrorBridge.acceptTransfer(tokenWithDecimals.address, anAccount, utils.NULL_ADDRESS, this.amount,
+ this.txReceipt.receipt.blockHash, this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex, chains.ETHEREUM_MAIN_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail accept transfer with originChainId 0', async function () {
+ const decimals = 18;
+ const tokenWithDecimals = await MainToken.new("MAIN", "MAIN", decimals, web3.utils.toWei('1000000000'), { from: tokenOwner });
+ await this.mirrorBridge.createSideToken(
+ this.typeId,
+ tokenWithDecimals.address,
+ decimals,
+ "MAIN",
+ "MAIN",
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: bridgeManager }
+ );
+
+ await truffleAssertions.fails(this.mirrorBridge.acceptTransfer(tokenWithDecimals.address, anAccount, anAccount, this.amount,
+ this.txReceipt.receipt.blockHash, this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex, 0, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail accept transfer with destinationChainId 0', async function () {
+ const decimals = 18;
+ const tokenWithDecimals = await MainToken.new("MAIN", "MAIN", decimals, web3.utils.toWei('1000000000'), { from: tokenOwner });
+ await this.mirrorBridge.createSideToken(
+ this.typeId,
+ tokenWithDecimals.address,
+ decimals,
+ "MAIN",
+ "MAIN",
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: bridgeManager }
+ );
+
+ await truffleAssertions.fails(this.mirrorBridge.acceptTransfer(tokenWithDecimals.address, anAccount, anAccount, this.amount,
+ this.txReceipt.receipt.blockHash, this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex, chains.ETHEREUM_MAIN_NET_CHAIN_ID, 0, { from: federation }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+
+ it('accept transfer only federation', async function () {
+ await truffleAssertions.fails(this.bridge.acceptTransfer(this.token.address, anAccount, anAccount, this.amount,
+ this.txReceipt.receipt.blockHash, this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex, chains.ETHEREUM_MAIN_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: bridgeOwner }),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ await truffleAssertions.fails(this.bridge.acceptTransfer(this.token.address, anAccount, anAccount, this.amount,
+ this.txReceipt.receipt.blockHash, this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex, chains.ETHEREUM_MAIN_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: bridgeManager }),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ const anAccountBalance = await this.token.balanceOf(anAccount);
+ assert.equal(anAccountBalance, 0);
+
+ const newBridgeBalance = await this.token.balanceOf(this.bridge.address);
+ assert.equal(newBridgeBalance, this.amount);
+ });
+
+ it('should fail accept transfer the same transaction', async function () {
+ await this.mirrorBridge.acceptTransfer(this.token.address, anAccount, anAccount, this.amount,
+ this.txReceipt.receipt.blockHash, this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex, chains.ETHEREUM_MAIN_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation });
+
+ const hasCrossed = await this.mirrorBridge.hasCrossed(this.txReceipt.tx);
+ assert.equal(hasCrossed, true);
+
+ await truffleAssertions.fails(this.mirrorBridge.acceptTransfer(this.token.address, anAccount, anAccount, this.amount,
+ this.txReceipt.receipt.blockHash, this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex, chains.ETHEREUM_MAIN_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation }),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ });
+
+ it('should fail accept transfer null token address', async function () {
+ await truffleAssertions.fails(this.mirrorBridge.acceptTransfer(utils.NULL_ADDRESS, anAccount, anAccount, this.amount,
+ this.txReceipt.receipt.blockHash, this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex, chains.HARDHAT_TEST_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation }),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ });
+
+ it('should fail null receiver address', async function () {
+ await truffleAssertions.fails(this.mirrorBridge.acceptTransfer(this.token.address, anAccount, utils.NULL_ADDRESS, this.amount,
+ this.txReceipt.receipt.blockHash, this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex, chains.HARDHAT_TEST_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation }),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ });
+
+ it('should fail zero amount', async function () {
+ await truffleAssertions.fails(this.mirrorBridge.acceptTransfer(this.token.address, anAccount, anAccount, 0,
+ this.txReceipt.receipt.blockHash, this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex, chains.HARDHAT_TEST_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation }),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ });
+
+ it('should fail null blockhash', async function () {
+ await truffleAssertions.fails(this.mirrorBridge.acceptTransfer(this.token.address, anAccount, anAccount, this.amount,
+ utils.NULL_HASH, this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex, chains.HARDHAT_TEST_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should fail null transaction hash', async function () {
+ await truffleAssertions.fails(this.mirrorBridge.acceptTransfer(this.token.address, anAccount, anAccount, this.amount,
+ this.txReceipt.receipt.blockHash, utils.NULL_HASH,
+ this.txReceipt.receipt.logs[0].logIndex, chains.HARDHAT_TEST_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+ });
+
+ describe('claim', async function() {
+ beforeEach(async function() {
+ await this.mirrorBridge.acceptTransfer(
+ this.token.address,
+ tokenOwner,
+ anAccount,
+ this.amount,
+ this.txReceipt.receipt.blockHash,
+ this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: federation }
+ );
+ });
+
+ it('should claim token transfer', async function() {
+ let hasBeenClaimed = await this.mirrorBridge.hasBeenClaimed(this.txReceipt.tx);
+ assert.equal(hasBeenClaimed, false);
+
+ const transactionDataHash = await this.mirrorBridge.getTransactionDataHash(
+ anAccount,
+ this.amount,
+ this.txReceipt.receipt.blockHash,
+ this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+
+ const obtainedTransactionDataHash = await this.mirrorBridge.transactionsDataHashes(this.txReceipt.tx);
+ assert.equal(obtainedTransactionDataHash, transactionDataHash);
+
+ const receipt = await this.mirrorBridge.claim(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: this.txReceipt.receipt.blockHash,
+ transactionHash: this.txReceipt.tx,
+ logIndex: this.txReceipt.receipt.logs[0].logIndex,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ },
+ { from: federation }
+ );
+ utils.checkRcpt(receipt);
+
+ hasBeenClaimed = await this.mirrorBridge.hasBeenClaimed(this.txReceipt.tx);
+ assert.equal(hasBeenClaimed, true);
+
+ const sideTokenAddress = await this.mirrorBridge.sideTokenByOriginalToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address);
+ const sideToken = await SideToken.at(sideTokenAddress);
+
+ const mirrorBridgeBalance = await sideToken.balanceOf(this.mirrorBridge.address);
+ assert.equal(mirrorBridgeBalance, 0);
+ const mirrorAnAccountBalance = await sideToken.balanceOf(anAccount);
+ assert.equal(mirrorAnAccountBalance, this.amount);
+ });
+
+ it('should claim fallback', async function() {
+ let hasBeenClaimed = await this.mirrorBridge.hasBeenClaimed(this.txReceipt.tx);
+ assert.equal(hasBeenClaimed, false);
+
+ const transactionDataHash = await this.mirrorBridge.getTransactionDataHash(
+ anAccount,
+ this.amount,
+ this.txReceipt.receipt.blockHash,
+ this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID
+ );
+
+ const obtainedTransactionDataHash = await this.mirrorBridge.transactionsDataHashes(this.txReceipt.tx);
+ assert.equal(obtainedTransactionDataHash, transactionDataHash);
+
+ const receipt = await this.mirrorBridge.claimFallback(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: this.txReceipt.receipt.blockHash,
+ transactionHash: this.txReceipt.tx,
+ logIndex: this.txReceipt.receipt.logs[0].logIndex,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ },
+ { from: tokenOwner }
+ );
+ utils.checkRcpt(receipt);
+
+ hasBeenClaimed = await this.mirrorBridge.hasBeenClaimed(this.txReceipt.tx);
+ assert.equal(hasBeenClaimed, true);
+
+ const sideTokenAddress = await this.mirrorBridge.sideTokenByOriginalToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address);
+ const sideToken = await SideToken.at(sideTokenAddress);
+
+ const mirrorBridgeBalance = await sideToken.balanceOf(this.mirrorBridge.address);
+ assert.equal(mirrorBridgeBalance, 0);
+ const mirrorToBalance = await sideToken.balanceOf(anAccount);
+ assert.equal(mirrorToBalance, 0);
+ const mirrorSenderBalance = await sideToken.balanceOf(tokenOwner);
+ assert.equal(mirrorSenderBalance, this.amount);
+ });
+
+ it('fail if claimFallback with incorrect chainId', async function() {
+ await truffleAssertions.fails(
+ this.mirrorBridge.claimFallback(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: this.txReceipt.receipt.blockHash,
+ transactionHash: this.txReceipt.tx,
+ logIndex: this.txReceipt.receipt.logs[0].logIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ { from: bridgeManager }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail if claimFallback with chainId 0', async function() {
+ await truffleAssertions.fails(
+ this.mirrorBridge.claimFallback(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: this.txReceipt.receipt.blockHash,
+ transactionHash: this.txReceipt.tx,
+ logIndex: this.txReceipt.receipt.logs[0].logIndex,
+ originChainId: 0,
+ },
+ { from: bridgeManager }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+
+ it('fail if claim with incorrect account', async function() {
+ await truffleAssertions.fails(
+ this.mirrorBridge.claim(
+ {
+ to: bridgeOwner,
+ amount: this.amount,
+ blockHash: this.txReceipt.receipt.blockHash,
+ transactionHash: this.txReceipt.tx,
+ logIndex: this.txReceipt.receipt.logs[0].logIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ { from: federation }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail if claim with incorrect amount', async function() {
+ await truffleAssertions.fails(
+ this.mirrorBridge.claim(
+ {
+ to: anAccount,
+ amount: '1',
+ blockHash: this.txReceipt.receipt.blockHash,
+ transactionHash: this.txReceipt.tx,
+ logIndex: this.txReceipt.receipt.logs[0].logIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ { from: federation }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail if claim with incorrect blockhash', async function() {
+ await truffleAssertions.fails(
+ this.mirrorBridge.claim(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: utils.getRandomHash(),
+ transactionHash: this.txReceipt.tx,
+ logIndex: this.txReceipt.receipt.logs[0].logIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ { from: federation }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail if claim with incorrect transactionHash', async function() {
+ await truffleAssertions.fails(
+ this.mirrorBridge.claim(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: this.txReceipt.receipt.blockHash,
+ transactionHash: utils.getRandomHash(),
+ logIndex: this.txReceipt.receipt.logs[0].logIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ { from: federation }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail if claim with incorrect logIndex', async function() {
+ await truffleAssertions.fails(
+ this.mirrorBridge.claim(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: this.txReceipt.receipt.blockHash,
+ transactionHash: this.txReceipt.tx,
+ logIndex: '11',
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ { from: federation }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail if claim same transaction twice', async function () {
+ let hasBeenClaimed = await this.mirrorBridge.hasBeenClaimed(this.txReceipt.tx);
+ assert.equal(hasBeenClaimed, false);
+
+ const transactionDataHash = await this.mirrorBridge.getTransactionDataHash(
+ anAccount,
+ this.amount,
+ this.txReceipt.receipt.blockHash,
+ this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+
+ const obtainedTransactionDataHash = await this.mirrorBridge.transactionsDataHashes(this.txReceipt.tx);
+ assert.equal(obtainedTransactionDataHash, transactionDataHash);
+
+ const receipt = await this.mirrorBridge.claim(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: this.txReceipt.receipt.blockHash,
+ transactionHash: this.txReceipt.tx,
+ logIndex: this.txReceipt.receipt.logs[0].logIndex,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ },
+ { from: anAccount }
+ );
+ utils.checkRcpt(receipt);
+
+ hasBeenClaimed = await this.mirrorBridge.hasBeenClaimed(this.txReceipt.tx);
+ assert.equal(hasBeenClaimed, true);
+
+ const sideTokenAddress = await this.mirrorBridge.sideTokenByOriginalToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address);
+ const sideToken = await SideToken.at(sideTokenAddress);
+
+ const mirrorBridgeBalance = await sideToken.balanceOf(this.mirrorBridge.address);
+ assert.equal(mirrorBridgeBalance, 0);
+ const mirrorAnAccountBalance = await sideToken.balanceOf(anAccount);
+ assert.equal(mirrorAnAccountBalance, this.amount);
+
+ await truffleAssertions.fails(
+ this.mirrorBridge.claim(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: this.txReceipt.receipt.blockHash,
+ transactionHash: this.txReceipt.tx,
+ logIndex: this.txReceipt.receipt.logs[0].logIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ { from: anAccount }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should claim with decimals other than 18', async function () {
+ const decimals = 6;
+ const tokenWithDecimals = await MainToken.new("MAIN", "MAIN", decimals, web3.utils.toWei('1000000000'), { from: tokenOwner });
+ const txReceipt = await this.mirrorBridge.createSideToken(
+ this.typeId,
+ tokenWithDecimals.address,
+ decimals,
+ "rMAIN",
+ "MAIN on RSK",
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: bridgeManager }
+ );
+
+ let receipt = await this.mirrorBridge.acceptTransfer(tokenWithDecimals.address, anAccount, anAccount, this.amount,
+ txReceipt.receipt.blockHash, txReceipt.tx,
+ txReceipt.receipt.logs[0].logIndex, chains.HARDHAT_TEST_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation });
+ utils.checkRcpt(receipt);
+
+ receipt = await this.mirrorBridge.claim(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: txReceipt.receipt.blockHash,
+ transactionHash: txReceipt.tx,
+ logIndex: txReceipt.receipt.logs[0].logIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ { from: anAccount }
+ );
+ utils.checkRcpt(receipt);
+
+ const sideTokenAddress = await this.mirrorBridge.sideTokenByOriginalToken(chains.HARDHAT_TEST_NET_CHAIN_ID, tokenWithDecimals.address);
+ let sideToken = await SideToken.at(sideTokenAddress);
+ const sideTokenSymbol = await sideToken.symbol();
+ assert.equal(sideTokenSymbol, "rMAIN");
+
+ const originalToken = await this.mirrorBridge.getOriginalTokenBySideToken(sideTokenAddress);
+ assert.equal(originalToken.tokenAddress, tokenWithDecimals.address);
+
+ const mirrorBridgeBalance = await sideToken.balanceOf(this.mirrorBridge.address);
+ assert.equal(mirrorBridgeBalance, 0);
+ const mirrorAnAccountBalance = await sideToken.balanceOf(anAccount);
+ let expectedAmount = new BN(this.amount.toString());
+ expectedAmount = expectedAmount.mul(new BN(10).pow(new BN(18-decimals)));
+ assert.equal(mirrorAnAccountBalance.toString(), expectedAmount.toString());
+ });
+
+ it('should claim first time from ERC777 with granularity', async function () {
+ const granularity = '100';
+ const tokenWithGranularity = await SideToken.new("MAIN", "MAIN", tokenOwner, granularity, { from: tokenOwner });
+ tokenWithGranularity.mint(tokenOwner, this.amount, '0x', '0x', { from: tokenOwner });
+ const txReceipt = await this.mirrorBridge.createSideToken(
+ this.typeId,
+ tokenWithGranularity.address,
+ 18,
+ "rMAIN",
+ "MAIN on RSK",
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: bridgeManager }
+ );
+
+ let receipt = await this.mirrorBridge.acceptTransfer(tokenWithGranularity.address, anAccount, anAccount, this.amount,
+ txReceipt.receipt.blockHash, txReceipt.tx,
+ txReceipt.receipt.logs[0].logIndex, chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation });
+ utils.checkRcpt(receipt);
+
+ receipt = await this.mirrorBridge.claim(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: txReceipt.receipt.blockHash,
+ transactionHash: txReceipt.tx,
+ logIndex: txReceipt.receipt.logs[0].logIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ { from: anAccount }
+ );
+ utils.checkRcpt(receipt);
+
+ const sideTokenAddress = await this.mirrorBridge.sideTokenByOriginalToken(chains.HARDHAT_TEST_NET_CHAIN_ID, tokenWithGranularity.address);
+ let sideToken = await SideToken.at(sideTokenAddress);
+ const sideTokenSymbol = await sideToken.symbol();
+ assert.equal(sideTokenSymbol, "rMAIN");
+
+ const originalToken = await this.mirrorBridge.getOriginalTokenBySideToken(sideTokenAddress);
+ assert.equal(originalToken.tokenAddress, tokenWithGranularity.address);
+
+ const mirrorBridgeBalance = await sideToken.balanceOf(this.mirrorBridge.address);
+ assert.equal(mirrorBridgeBalance, 0);
+ const mirrorAnAccountBalance = await sideToken.balanceOf(anAccount);
+ assert.equal(mirrorAnAccountBalance.toString(), this.amount.toString());
+ });
+
+ });
+
+ describe('claim gasless', async function() {
+ beforeEach(async function() {
+ this.accountWallet = await web3.eth.accounts.privateKeyToAccount(utils.getRandomHash());
+ this.gaslessAmount = '1001';
+ this.gaslessBlockHash = utils.getRandomHash();
+ this.gaslessTxHash = utils.getRandomHash();
+ this.gaslessLogIndex = '0';
+
+ await this.mirrorBridge.acceptTransfer(
+ this.token.address,
+ tokenOwner,
+ this.accountWallet.address,
+ this.gaslessAmount,
+ this.gaslessBlockHash,
+ this.gaslessTxHash,
+ this.gaslessLogIndex,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: federation }
+ );
+ });
+
+ it('should have CLAIM_TYPEHASH', async function() {
+ const expectedTypeHash =
+ keccak256('Claim(address to,uint256 amount,bytes32 transactionHash,uint256 originChainId,address relayer,uint256 fee,uint256 nonce,uint256 deadline)');
+ const CLAIM_TYPEHASH = await this.mirrorBridge.CLAIM_TYPEHASH();
+ assert.equal(CLAIM_TYPEHASH, expectedTypeHash);
+ });
+
+ it('should have domainSeparator', async function() {
+ const expectedTypeHash = keccak256(
+ web3.eth.abi.encodeParameters(
+ ['bytes32', 'bytes32', 'bytes32', 'uint256', 'address'],
+ [
+ keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
+ keccak256('RSK Token Bridge'),
+ keccak256('1'),
+ chainId,
+ this.mirrorBridge.address
+ ]
+ )
+ )
+ const DOMAIN_SEPARATOR = await this.mirrorBridge.domainSeparator();
+ assert.equal(DOMAIN_SEPARATOR, expectedTypeHash);
+ });
+
+ it('should claim gasless', async function() {
+ let hasBeenClaimed = await this.mirrorBridge.hasBeenClaimed(this.gaslessTxHash);
+ assert.equal(hasBeenClaimed, false);
+
+ const transactionDataHash = await this.mirrorBridge.getTransactionDataHash(
+ this.accountWallet.address,
+ this.gaslessAmount,
+ this.gaslessBlockHash,
+ this.gaslessTxHash,
+ this.gaslessLogIndex,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+
+ const obtainedTransactionDataHash = await this.mirrorBridge.transactionsDataHashes(this.gaslessTxHash);
+ assert.equal(obtainedTransactionDataHash, transactionDataHash);
+
+ const relayer = federation;
+ const fee = '11';
+ const nonce = (await this.mirrorBridge.nonces(this.accountWallet.address)).toString();
+ const deadline = Number.MAX_SAFE_INTEGER.toString();
+
+ const digest = await getClaimDigest(
+ this.mirrorBridge,
+ {
+ to: this.accountWallet.address,
+ amount: this.gaslessAmount,
+ transactionHash: this.gaslessTxHash,
+ relayer: relayer,
+ fee: fee,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID
+ },
+ nonce,
+ deadline
+ );
+
+ const { v, r, s } = ethUtil.ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(this.accountWallet.privateKey.slice(2), 'hex'));
+
+ const receipt = await this.mirrorBridge.claimGasless(
+ {
+ to: this.accountWallet.address,
+ amount: this.gaslessAmount,
+ blockHash: this.gaslessBlockHash,
+ transactionHash: this.gaslessTxHash,
+ logIndex: this.gaslessLogIndex,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID
+ },
+ relayer,
+ fee,
+ deadline,
+ v,
+ r,
+ s,
+ { from: tokenOwner }
+ );
+ utils.checkRcpt(receipt);
+
+ hasBeenClaimed = await this.mirrorBridge.hasBeenClaimed(this.gaslessTxHash);
+ assert.equal(hasBeenClaimed, true);
+
+ const sideTokenAddress = await this.mirrorBridge.sideTokenByOriginalToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address);
+ const sideToken = await SideToken.at(sideTokenAddress);
+
+ const mirrorBridgeBalance = await sideToken.balanceOf(this.mirrorBridge.address);
+ assert.equal(mirrorBridgeBalance.toString(), '0');
+ const mirrorToBalance = await sideToken.balanceOf(this.accountWallet.address);
+ assert.equal(mirrorToBalance.toString(), this.gaslessAmount - fee);
+ const mirrorRelayerBalance = await sideToken.balanceOf(relayer);
+ assert.equal(mirrorRelayerBalance.toString(), fee);
+ expect((await this.mirrorBridge.nonces(this.accountWallet.address)).toString()).to.eq('1');
+ });
+
+ it('fail claim gasless invalid signature', async function() {
+ const relayer = federation;
+ const fee = '11';
+ const nonce = (await this.mirrorBridge.nonces(this.accountWallet.address)).toString();
+ const deadline = Number.MAX_SAFE_INTEGER.toString();
+
+ const digest = await getClaimDigest(
+ this.mirrorBridge,
+ {
+ to: this.accountWallet.address,
+ amount: this.gaslessAmount,
+ transactionHash: this.gaslessTxHash,
+ relayer: federation,
+ fee: fee,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID
+ },
+ nonce,
+ deadline
+ );
+
+ const { v, r, s } = ethUtil.ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(this.accountWallet.privateKey.slice(2), 'hex'));
+
+ await truffleAssertions.fails(
+ this.mirrorBridge.claimGasless(
+ {
+ to: this.accountWallet.address,
+ amount: this.gaslessAmount,
+ blockHash: this.gaslessBlockHash,
+ transactionHash: this.gaslessTxHash,
+ logIndex: this.gaslessLogIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ relayer,
+ fee,
+ deadline,
+ v,
+ s,
+ r,
+ { from: tokenOwner }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail claim gasless incorrect to', async function() {
+ const relayer = federation;
+ const fee = '11';
+ const nonce = (await this.mirrorBridge.nonces(this.accountWallet.address)).toString();
+ const deadline = Number.MAX_SAFE_INTEGER.toString();
+
+ const digest = await getClaimDigest(
+ this.mirrorBridge,
+ {
+ to: this.accountWallet.address,
+ amount: this.gaslessAmount,
+ transactionHash: this.gaslessTxHash,
+ relayer: federation,
+ fee: fee,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID
+ },
+ nonce,
+ deadline
+ );
+
+ const { v, r, s } = ethUtil.ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(this.accountWallet.privateKey.slice(2), 'hex'));
+
+ await truffleAssertions.fails(
+ this.mirrorBridge.claimGasless(
+ {
+ to: anAccount,
+ amount: this.gaslessAmount,
+ blockHash: this.gaslessBlockHash,
+ transactionHash: this.gaslessTxHash,
+ logIndex: this.gaslessLogIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ relayer,
+ fee,
+ deadline,
+ v,
+ r,
+ s,
+ { from: tokenOwner }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail claim gasless incorrect amount', async function() {
+ const relayer = federation;
+ const fee = '11';
+ const nonce = (await this.mirrorBridge.nonces(this.accountWallet.address)).toString();
+ const deadline = Number.MAX_SAFE_INTEGER.toString();
+
+ const digest = await getClaimDigest(
+ this.mirrorBridge,
+ {
+ to: this.accountWallet.address,
+ amount: this.gaslessAmount,
+ transactionHash: this.gaslessTxHash,
+ relayer: federation,
+ fee: fee,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID
+ },
+ nonce,
+ deadline
+ );
+
+ const { v, r, s } = ethUtil.ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(this.accountWallet.privateKey.slice(2), 'hex'));
+
+ await truffleAssertions.fails(
+ this.mirrorBridge.claimGasless(
+ {
+ to: this.accountWallet.address,
+ amount: this.amount,
+ blockHash: this.gaslessBlockHash,
+ transactionHash: this.gaslessTxHash,
+ logIndex: this.gaslessLogIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ relayer,
+ fee,
+ deadline,
+ v,
+ r,
+ s,
+ { from: tokenOwner }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail claim gasless incorrect fee', async function() {
+ const relayer = federation;
+ const fee = '11';
+ const nonce = (await this.mirrorBridge.nonces(this.accountWallet.address)).toString();
+ const deadline = Number.MAX_SAFE_INTEGER.toString();
+
+ const digest = await getClaimDigest(
+ this.mirrorBridge,
+ {
+ to: this.accountWallet.address,
+ amount: this.gaslessAmount,
+ transactionHash: this.gaslessTxHash,
+ relayer: federation,
+ fee: fee,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID
+ },
+ nonce,
+ deadline
+ );
+
+ const { v, r, s } = ethUtil.ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(this.accountWallet.privateKey.slice(2), 'hex'));
+
+ await truffleAssertions.fails(
+ this.mirrorBridge.claimGasless(
+ {
+ to: this.accountWallet.address,
+ amount: this.gaslessAmount,
+ blockHash: this.gaslessBlockHash,
+ transactionHash: this.gaslessTxHash,
+ logIndex: this.gaslessLogIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ relayer,
+ '100',
+ deadline,
+ v,
+ r,
+ s,
+ { from: tokenOwner }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail claim gasless incorrect relayer', async function() {
+ const relayer = federation;
+ const fee = '11';
+ const nonce = (await this.mirrorBridge.nonces(this.accountWallet.address)).toString();
+ const deadline = Number.MAX_SAFE_INTEGER.toString();
+
+ const digest = await getClaimDigest(
+ this.mirrorBridge,
+ {
+ to: this.accountWallet.address,
+ amount: this.gaslessAmount,
+ transactionHash: this.gaslessTxHash,
+ relayer: federation,
+ fee: fee,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID
+ },
+ nonce,
+ deadline
+ );
+
+ const { v, r, s } = ethUtil.ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(this.accountWallet.privateKey.slice(2), 'hex'));
+
+ await truffleAssertions.fails(
+ this.mirrorBridge.claimGasless(
+ {
+ to: this.accountWallet.address,
+ amount: this.gaslessAmount,
+ blockHash: this.gaslessBlockHash,
+ transactionHash: this.gaslessTxHash,
+ logIndex: this.gaslessLogIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ anAccount,
+ fee,
+ deadline,
+ v,
+ r,
+ s,
+ { from: tokenOwner }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail claim gasless expired deadline', async function() {
+ const relayer = federation;
+ const fee = '11';
+ const nonce = (await this.mirrorBridge.nonces(this.accountWallet.address)).toString();
+ const deadline = '1';
+
+ const digest = await getClaimDigest(
+ this.mirrorBridge,
+ {
+ to: this.accountWallet.address,
+ amount: this.gaslessAmount,
+ transactionHash: this.gaslessTxHash,
+ relayer: federation,
+ fee: fee,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID
+ },
+ nonce,
+ deadline
+ );
+
+ const { v, r, s } = ethUtil.ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(this.accountWallet.privateKey.slice(2), 'hex'));
+
+ await truffleAssertions.fails(
+ this.mirrorBridge.claimGasless(
+ {
+ to: this.accountWallet.address,
+ amount: this.gaslessAmount,
+ blockHash: this.gaslessBlockHash,
+ transactionHash: this.gaslessTxHash,
+ logIndex: this.gaslessLogIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ relayer,
+ fee,
+ deadline,
+ v,
+ r,
+ s,
+ { from: tokenOwner }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('fail claim gasless fee bigger than amount', async function() {
+ const relayer = federation;
+ const fee = this.gaslessAmount + 1;
+ const nonce = (await this.mirrorBridge.nonces(this.accountWallet.address)).toString();
+ const deadline = Number.MAX_SAFE_INTEGER.toString();
+
+ const digest = await getClaimDigest(
+ this.mirrorBridge,
+ {
+ to: this.accountWallet.address,
+ amount: this.gaslessAmount,
+ transactionHash: this.gaslessTxHash,
+ relayer: federation,
+ fee: fee,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID
+ },
+ nonce,
+ deadline
+ );
+
+ const { v, r, s } = ethUtil.ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(this.accountWallet.privateKey.slice(2), 'hex'));
+
+ await truffleAssertions.fails(
+ this.mirrorBridge.claimGasless(
+ {
+ to: this.accountWallet.address,
+ amount: this.gaslessAmount,
+ blockHash: this.gaslessBlockHash,
+ transactionHash: this.gaslessTxHash,
+ logIndex: this.gaslessLogIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID,
+ },
+ relayer,
+ fee,
+ deadline,
+ v,
+ r,
+ s,
+ { from: tokenOwner }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ }); // end claim gasless
+
+ it('crossback with amount lower than granularity', async function () {
+ const granularity = '10000000000000000';
+ const decimals = '2';
+ const blockHash = utils.getRandomHash();
+ const txHash = utils.getRandomHash();
+ const logIndex = 1;
+
+ const aToken = await MainToken.new(tokenName, tokenSymbol, decimals, web3.utils.toWei('1000000000'), { from: tokenOwner });
+
+ await this.mirrorBridge.createSideToken(
+ this.typeId,
+ aToken.address,
+ decimals,
+ tokenSymbol,
+ tokenName,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ { from: bridgeManager }
+ );
+
+ const acceptTxReceipt = await this.mirrorBridge.acceptTransfer(aToken.address, anAccount, anAccount, this.amount,
+ blockHash, txHash, logIndex, chains.ETHEREUM_MAIN_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation });
+ utils.checkRcpt(acceptTxReceipt);
+
+ await this.mirrorBridge.claim(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: blockHash,
+ transactionHash: txHash,
+ logIndex: logIndex,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ },
+ { from: anAccount }
+ );
+
+ const amountToCrossBack = new BN(web3.utils.toWei('1'));
+ const payment = new BN('33');
+
+ const sideTokenAddress = await this.mirrorBridge.sideTokenByOriginalToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, aToken.address);
+ const sideToken = await SideToken.at(sideTokenAddress);
+ const feePercentageDivider = await this.mirrorBridge.feePercentageDivider();
+ const fees = amountToCrossBack.mul(payment).div(feePercentageDivider);
+ const modulo = amountToCrossBack.sub(fees).mod(new BN(granularity));
+
+ const originalTokenBalance = await sideToken.balanceOf(anAccount);
+ await this.mirrorBridge.setFeePercentage(payment, { from: bridgeManager});
+ await sideToken.approve(this.mirrorBridge.address, amountToCrossBack, { from: anAccount });
+
+ const receipt = await this.mirrorBridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, sideToken.address, anAccount, amountToCrossBack, { from: anAccount });
+ utils.checkRcpt(receipt);
+
+ const ownerBalance = await sideToken.balanceOf(bridgeManager);
+ assert.equal(ownerBalance.toString(), fees.add(modulo).toString());
+ assert.equal(fees.toString(), (amountToCrossBack*0.33/100).toString());
+ const tokenBalance = await sideToken.balanceOf(anAccount);
+ assert.equal(tokenBalance.toString(), originalTokenBalance.sub(amountToCrossBack));
+ const bridgeBalance = await sideToken.balanceOf(this.mirrorBridge.address);
+ assert.equal(bridgeBalance.toString(), '0');
+ });
+
+ it('crossback with amount lower than granularity and no fees', async function () {
+ const granularity = '10000000000000000';
+ const decimals = '2';
+ const blockHash = utils.getRandomHash();
+ const txHash = utils.getRandomHash();
+ const logIndex = 1;
+
+ const aToken = await MainToken.new(tokenName, tokenSymbol, decimals, web3.utils.toWei('1000000000'), { from: tokenOwner });
+
+ await this.mirrorBridge.createSideToken(
+ this.typeId,
+ aToken.address,
+ decimals,
+ "MAIN", "MAIN",
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: bridgeManager }
+ );
+
+ await this.mirrorBridge.acceptTransfer(aToken.address, anAccount, anAccount, this.amount,
+ blockHash, txHash, logIndex, chains.HARDHAT_TEST_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation });
+
+ await this.mirrorBridge.claim(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: blockHash,
+ transactionHash: txHash,
+ logIndex: logIndex,
+ originChainId: chains.HARDHAT_TEST_NET_CHAIN_ID
+ },
+ { from: anAccount }
+ );
+
+ const amountToCrossBack = new BN(web3.utils.toWei('1'));
+ const payment = new BN(0);
+
+ const sideTokenAddress = await this.mirrorBridge.sideTokenByOriginalToken(chains.HARDHAT_TEST_NET_CHAIN_ID, aToken.address);
+ const sideToken = await SideToken.at(sideTokenAddress);
+ const feePercentageDivider = await this.mirrorBridge.feePercentageDivider();
+ const fees = amountToCrossBack.mul(payment).div(feePercentageDivider);
+ const modulo = amountToCrossBack.sub(fees).mod(new BN(granularity));
+ const originalTokenBalance = await sideToken.balanceOf(anAccount);
+
+ await this.mirrorBridge.setFeePercentage(payment, { from: bridgeManager});
+ await sideToken.approve(this.mirrorBridge.address, amountToCrossBack, { from: anAccount });
+
+ const receipt = await this.mirrorBridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, sideToken.address, anAccount, amountToCrossBack, { from: anAccount });
+ utils.checkRcpt(receipt);
+
+ const ownerBalance = await sideToken.balanceOf(bridgeManager);
+ assert.equal(ownerBalance.toString(), fees.add(modulo).toString());
+ const tokenBalance = await sideToken.balanceOf(anAccount);
+ assert.equal(tokenBalance.toString(), originalTokenBalance.sub(amountToCrossBack));
+ const bridgeBalance = await sideToken.balanceOf(this.mirrorBridge.address);
+ assert.equal(bridgeBalance.toString(), '0');
+ });
+
+ it('crossback wrapped network currency', async function () {
+ const granularity = '1';
+ const blockHash = utils.getRandomHash();
+ const txHash = utils.getRandomHash();
+ const logIndex = 1;
+
+ await this.mirrorBridge.acceptTransfer(this.wrbtc.address, anAccount, anAccount, this.amount,
+ blockHash, txHash, logIndex, chains.ETHEREUM_MAIN_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation });
+
+ await this.mirrorBridge.claim(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: blockHash,
+ transactionHash: txHash,
+ logIndex: logIndex,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID
+ },
+ { from: anAccount }
+ );
+
+ const amountToCrossBack = new BN(web3.utils.toWei('1'));
+ const payment = new BN(0);
+
+ const sideTokenAddress = await this.mirrorBridge.sideTokenByOriginalToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.wrbtc.address);
+ const sideToken = await SideToken.at(sideTokenAddress);
+ const feePercentageDivider = await this.mirrorBridge.feePercentageDivider();
+ const fees = amountToCrossBack.mul(payment).div(feePercentageDivider);
+ const modulo = amountToCrossBack.sub(fees).mod(new BN(granularity));
+ const originalTokenBalance = await sideToken.balanceOf(anAccount);
+
+ await this.mirrorBridge.setFeePercentage(payment, { from: bridgeManager});
+ await sideToken.approve(this.mirrorBridge.address, amountToCrossBack, { from: anAccount });
+
+ const receipt = await this.mirrorBridge.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID, sideToken.address, anAccount, amountToCrossBack, { from: anAccount });
+ utils.checkRcpt(receipt);
+
+ const ownerBalance = await sideToken.balanceOf(bridgeManager);
+ assert.equal(ownerBalance.toString(), fees.add(modulo).toString());
+ const tokenBalance = await sideToken.balanceOf(anAccount);
+ assert.equal(tokenBalance.toString(), originalTokenBalance.sub(amountToCrossBack));
+ const bridgeBalance = await sideToken.balanceOf(this.mirrorBridge.address);
+ assert.equal(bridgeBalance.toString(), '0');
+ });
+
+ });
+
+ describe('Cross back the tokens', async function () {
+ beforeEach(async function () {
+ // Transfer to Side Token
+ await this.mirrorBridge.acceptTransfer(this.token.address, tokenOwner, anAccount, this.amount,
+ this.txReceipt.receipt.blockHash, this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex, chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation });
+ this.amountToCrossBack = web3.utils.toWei('100');
+ this.decimals = (await this.token.decimals()).toString();
+ this.granularity = 1;
+ this.sideTokenAddress = await this.mirrorBridge.sideTokenByOriginalToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.token.address);
+
+ await this.mirrorBridge.claim(
+ {
+ to: anAccount,
+ amount: this.amount,
+ blockHash: this.txReceipt.receipt.blockHash,
+ transactionHash: this.txReceipt.tx,
+ logIndex: this.txReceipt.receipt.logs[0].logIndex,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID
+ },
+ { from: anAccount }
+ );
+
+ //Transfer Side WRBTC
+ await this.mirrorBridge.acceptTransfer(this.wrbtc.address, tokenOwner, anAccount, this.wrbtcAmount,
+ this.txReceiptWrbtc.receipt.blockHash, this.txReceiptWrbtc.tx,
+ this.txReceiptWrbtc.receipt.logs[0].logIndex, chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation });
+
+ await this.mirrorBridge.claim(
+ {
+ to: anAccount,
+ amount: this.wrbtcAmount,
+ blockHash: this.txReceiptWrbtc.receipt.blockHash,
+ transactionHash: this.txReceiptWrbtc.tx,
+ logIndex: this.txReceiptWrbtc.receipt.logs[0].logIndex,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ },
+ { from: anAccount }
+ );
+
+ this.wrbtcAmountToCrossBack = web3.utils.toWei('1');
+ this.sideWrbtcAddress = await this.mirrorBridge.sideTokenByOriginalToken(chains.ETHEREUM_MAIN_NET_CHAIN_ID, this.wrbtc.address);
+ });
+
+ describe('Should burn the side tokens when transfered to the bridge', function () {
+ it('using IERC20 approve and transferFrom', async function () {
+ let sideToken = await SideToken.at(this.sideTokenAddress);
+ let mirrorAnAccountBalance = await sideToken.balanceOf(anAccount);
+ assert.equal(mirrorAnAccountBalance.toString(), this.amount.toString());
+
+ //Transfer the Side tokens to the bridge, the bridge burns them and creates an event
+ let receipt = await sideToken.approve(this.mirrorBridge.address, this.amountToCrossBack, { from: anAccount });
+ utils.checkRcpt(receipt);
+ receipt = await this.mirrorBridge.receiveTokensTo(
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ this.sideTokenAddress,
+ tokenOwner,
+ this.amountToCrossBack,
+ { from: anAccount }
+ );
+ utils.checkRcpt(receipt);
+
+ mirrorAnAccountBalance = await sideToken.balanceOf(anAccount);
+ assert.equal(mirrorAnAccountBalance.toString(), new BN(this.amount).sub( new BN(this.amountToCrossBack)).toString());
+
+ let mirrorBridgeBalance = await sideToken.balanceOf(this.mirrorBridge.address);
+ assert.equal(mirrorBridgeBalance.toString(), '0');
+ });
+
+ it('using ERC777 tokensReceived', async function () {
+ let sideToken = await SideToken.at(this.sideTokenAddress);
+ let mirrorAnAccountBalance = await sideToken.balanceOf(anAccount);
+ assert.equal(mirrorAnAccountBalance.toString(), this.amount.toString());
+
+ const userData = web3.eth.abi.encodeParameters(
+ ["address", "uint256"],
+ [tokenOwner.toLowerCase(), chains.ETHEREUM_MAIN_NET_CHAIN_ID]
+ );
+ //Transfer the Side tokens to the bridge, the bridge burns them and creates an event
+ const receipt = await sideToken.send(this.mirrorBridge.address, this.amountToCrossBack, userData, { from: anAccount });
+ utils.checkRcpt(receipt);
+
+ mirrorAnAccountBalance = await sideToken.balanceOf(anAccount);
+ assert.equal(mirrorAnAccountBalance.toString(), new BN(this.amount).sub(new BN(this.amountToCrossBack)).toString());
+
+ let mirrorBridgeBalance = await sideToken.balanceOf(this.mirrorBridge.address);
+ assert.equal(mirrorBridgeBalance.toString(), '0');
+ });
+
+ });
+
+ describe('After the mirror Bridge burned the tokens', function () {
+ beforeEach(async function () {
+ this.accountWallet = await web3.eth.accounts.privateKeyToAccount(utils.getRandomHash());
+ //Transfer the Side tokens to the bridge, the bridge burns them and creates an event
+ this.sideToken = await SideToken.at(this.sideTokenAddress);
+ await this.sideToken.approve(this.mirrorBridge.address, this.amountToCrossBack, { from: anAccount });
+ await this.mirrorBridge.receiveTokensTo(
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ this.sideTokenAddress,
+ this.accountWallet.address,
+ this.amountToCrossBack,
+ { from: anAccount }
+ );
+
+ //Transfer the Side tokens to the bridge, the bridge burns them and creates an event
+ this.sideWrbtc = await SideToken.at(this.sideWrbtcAddress);
+ await this.sideWrbtc.approve(this.mirrorBridge.address, this.wrbtcAmountToCrossBack, { from: anAccount });
+ await this.mirrorBridge.receiveTokensTo(
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ this.sideWrbtc.address,
+ this.accountWallet.address,
+ this.wrbtcAmountToCrossBack,
+ { from: anAccount }
+ );
+ });
+
+ it('main Bridge should release the tokens', async function () {
+ let tx = await this.bridge.acceptTransfer(this.token.address, anAccount, this.accountWallet.address, this.amountToCrossBack,
+ this.txReceipt.receipt.blockHash, this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex, chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation });
+ utils.checkRcpt(tx);
+
+ await this.bridge.claim(
+ {
+ to: this.accountWallet.address,
+ amount: this.amountToCrossBack,
+ blockHash: this.txReceipt.receipt.blockHash,
+ transactionHash: this.txReceipt.tx,
+ logIndex: this.txReceipt.receipt.logs[0].logIndex,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID
+ },
+ { from: anAccount }
+ );
+
+ let bridgeBalance = await this.token.balanceOf(this.bridge.address);
+ assert.equal(bridgeBalance, this.amount - this.amountToCrossBack);
+
+ let anAccountBalance = await this.token.balanceOf(this.accountWallet.address);
+ assert.equal(anAccountBalance, this.amountToCrossBack);
+ });
+ it('main Bridge should release the network currency', async function () {
+ let tx = await this.bridge.acceptTransfer(this.wrbtc.address, anAccount, this.accountWallet.address, this.wrbtcAmountToCrossBack,
+ this.txReceiptWrbtc.receipt.blockHash, this.txReceiptWrbtc.tx,
+ this.txReceiptWrbtc.receipt.logs[0].logIndex, chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation });
+ utils.checkRcpt(tx);
+
+ await this.bridge.claim(
+ {
+ to: this.accountWallet.address,
+ amount: this.wrbtcAmountToCrossBack,
+ blockHash: this.txReceiptWrbtc.receipt.blockHash,
+ transactionHash: this.txReceiptWrbtc.tx,
+ logIndex: this.txReceiptWrbtc.receipt.logs[0].logIndex,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID
+ },
+ { from: anAccount }
+ );
+
+ const bridgeBalance = await this.wrbtc.balanceOf(this.bridge.address);
+ assert.equal(Number(bridgeBalance), Number(this.wrbtcAmount) - Number(this.wrbtcAmountToCrossBack));
+
+ const anAccountBalance = await web3.eth.getBalance(this.accountWallet.address);
+ assert.equal(anAccountBalance.toString(), this.wrbtcAmountToCrossBack);
+ });
+
+ it('should claim gasless crossing back', async function() {
+ const relayer = federation;
+ const fee = '11';
+ const nonce = (await this.bridge.nonces(this.accountWallet.address)).toString();
+ const deadline = Number.MAX_SAFE_INTEGER.toString();
+
+ await this.bridge.acceptTransfer(this.token.address, anAccount, this.accountWallet.address, this.amountToCrossBack,
+ this.txReceipt.receipt.blockHash, this.txReceipt.tx,
+ this.txReceipt.receipt.logs[0].logIndex, chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation });
+
+ const digest = await getClaimDigest(
+ this.bridge,
+ {
+ to: this.accountWallet.address,
+ amount: this.amountToCrossBack,
+ transactionHash: this.txReceipt.tx,
+ relayer: federation,
+ fee: fee,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ },
+ nonce,
+ deadline
+ );
+
+ const { v, r, s } = ethUtil.ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(this.accountWallet.privateKey.slice(2), 'hex'));
+
+ const receipt = await this.bridge.claimGasless(
+ {
+ to: this.accountWallet.address,
+ amount: this.amountToCrossBack,
+ blockHash: this.txReceipt.receipt.blockHash,
+ transactionHash: this.txReceipt.tx,
+ logIndex: this.txReceipt.receipt.logs[0].logIndex,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ },
+ relayer,
+ fee,
+ deadline,
+ v,
+ r,
+ s,
+ { from: anAccount }
+ );
+ utils.checkRcpt(receipt);
+
+ const hasBeenClaimed = await this.bridge.hasBeenClaimed(this.txReceipt.tx);
+ assert.equal(hasBeenClaimed, true);
+
+ const toBalance = await this.token.balanceOf(this.accountWallet.address);
+ assert.equal(toBalance.toString(), this.amountToCrossBack - fee);
+ const relayerBalance = await this.token.balanceOf(relayer);
+ assert.equal(relayerBalance.toString(), fee);
+ expect((await this.bridge.nonces(this.accountWallet.address)).toString()).to.eq('1');
+ });
+ it('should claim gasless network currency crossing back', async function() {
+ const relayer = federation;
+ const fee = '11';
+ const nonce = (await this.bridge.nonces(this.accountWallet.address)).toString();
+ const deadline = Number.MAX_SAFE_INTEGER.toString();
+
+ await this.bridge.acceptTransfer(this.wrbtc.address, anAccount, this.accountWallet.address, this.wrbtcAmountToCrossBack,
+ this.txReceiptWrbtc.receipt.blockHash, this.txReceiptWrbtc.tx,
+ this.txReceiptWrbtc.receipt.logs[0].logIndex, chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation });
+
+ const digest = await getClaimDigest(
+ this.bridge,
+ {
+ to: this.accountWallet.address,
+ amount: this.wrbtcAmountToCrossBack,
+ transactionHash: this.txReceiptWrbtc.tx,
+ relayer: federation,
+ fee: fee,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ },
+ nonce,
+ deadline
+ );
+
+ const { v, r, s } = ethUtil.ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(this.accountWallet.privateKey.slice(2), 'hex'));
+
+ const originalToBalance = await web3.eth.getBalance(this.accountWallet.address);
+ const originalRelayerBalance = await web3.eth.getBalance(relayer);
+
+ const receipt = await this.bridge.claimGasless(
+ {
+ to: this.accountWallet.address,
+ amount: this.wrbtcAmountToCrossBack,
+ blockHash: this.txReceiptWrbtc.receipt.blockHash,
+ transactionHash: this.txReceiptWrbtc.tx,
+ logIndex: this.txReceiptWrbtc.receipt.logs[0].logIndex,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ },
+ relayer,
+ fee,
+ deadline,
+ v,
+ r,
+ s,
+ { from: anAccount }
+ );
+ utils.checkRcpt(receipt);
+
+ const hasBeenClaimed = await this.bridge.hasBeenClaimed(this.txReceiptWrbtc.tx);
+ assert.equal(hasBeenClaimed, true);
+
+ const toBalance = await web3.eth.getBalance(this.accountWallet.address);
+ assert.equal(new BN(originalToBalance).add(new BN(toBalance)).toString(), this.wrbtcAmountToCrossBack - fee);
+ const relayerBalance = await web3.eth.getBalance(relayer);
+ assert.equal(new BN(relayerBalance).sub(new BN(originalRelayerBalance)).toString(), fee);
+ expect((await this.bridge.nonces(this.accountWallet.address)).toString()).to.eq('1');
+ });
+ }); // After the mirror Bridge burned the tokens
+
+ });
+
+ });
+
+ describe('Pausable methods', async function() {
+ it('Should pause the bridge contract', async function() {
+ let isPaused = await this.bridge.paused();
+ assert.equal(isPaused, false);
+
+ await this.bridge.pause({ from: bridgeManager });
+ isPaused = await this.bridge.paused();
+ assert.equal(isPaused, true);
+ });
+
+ it('Should not pause the bridge contract without pauser role', async function() {
+ let isPaused = await this.bridge.paused();
+ assert.equal(isPaused, false);
+
+ await truffleAssertions.fails(this.bridge.pause(), truffleAssertions.ErrorType.REVERT);
+ isPaused = await this.bridge.paused();
+ assert.equal(isPaused, false);
+ });
+
+ it('Should unpause the bridge contract', async function() {
+ await this.bridge.pause({ from: bridgeManager });
+ let isPaused = await this.bridge.paused();
+ assert.equal(isPaused, true);
+
+ await this.bridge.unpause({ from: bridgeManager });
+ isPaused = await this.bridge.paused();
+ assert.equal(isPaused, false);
+ });
+
+ it('Should not unpause the bridge contract without pauser role', async function() {
+ await this.bridge.pause({ from: bridgeManager });
+ let isPaused = await this.bridge.paused();
+ assert.equal(isPaused, true);
+
+ await truffleAssertions.fails(this.bridge.unpause(), truffleAssertions.ErrorType.REVERT);
+ isPaused = await this.bridge.paused();
+ assert.equal(isPaused, true);
+ });
+ })
+
+ describe('Ownable methods', async function() {
+ const anotherOwner = accounts[7];
+
+ it('Should renounce ownership', async function() {
+ await this.bridge.renounceOwnership({ from: bridgeManager });
+ const owner = await this.bridge.owner();
+ assert.equal(BigInt(owner), 0);
+ });
+
+ it('Should not renounce ownership when not called by the owner', async function() {
+ const owner = await this.bridge.owner();
+ await truffleAssertions.fails(this.bridge.renounceOwnership(), truffleAssertions.ErrorType.REVERT);
+ const ownerAfter = await this.bridge.owner();
+
+ assert.equal(owner, ownerAfter);
+ });
+
+ it('Should transfer ownership', async function() {
+ await this.bridge.transferOwnership(anotherOwner, { from: bridgeManager });
+ const owner = await this.bridge.owner();
+ assert.equal(owner, anotherOwner);
+ });
+
+ it('Should not transfer ownership when not called by the owner', async function() {
+ const owner = await this.bridge.owner();
+ await truffleAssertions.fails(this.bridge.transferOwnership(anotherOwner), truffleAssertions.ErrorType.REVERT);
+ const ownerAfter = await this.bridge.owner();
+
+ assert.equal(owner, ownerAfter);
+ });
+ });
+
+ describe('Upgrading methods', async function() {
+ it('Should start upgrade the bridge contract', async function() {
+ let isUpgrading = await this.bridge.isUpgrading();
+ assert.equal(isUpgrading, false);
+
+ await this.bridge.setUpgrading(true, { from: bridgeManager });
+ isUpgrading = await this.bridge.isUpgrading();
+ assert.equal(isUpgrading, true);
+ });
+
+ it('Should not set upgrading of the bridge contract if not the owner', async function() {
+ let isUpgrading = await this.bridge.isUpgrading();
+ assert.equal(isUpgrading, false);
+
+ await truffleAssertions.fails(this.bridge.setUpgrading(true), truffleAssertions.ErrorType.REVERT);
+ isUpgrading = await this.bridge.isUpgrading();
+ assert.equal(isUpgrading, false);
+ });
+
+ it('Should end upgrade of the bridge contract', async function() {
+ await this.bridge.setUpgrading(true, { from: bridgeManager });
+ let isUpgrading = await this.bridge.isUpgrading();
+ assert.equal(isUpgrading, true);
+
+ await this.bridge.setUpgrading(false, { from: bridgeManager });
+ isUpgrading = await this.bridge.isUpgrading();
+ assert.equal(isUpgrading, false);
+ });
+
+ it('Should not end upgrade of the bridge contract if not the owner', async function() {
+ await this.bridge.setUpgrading(true, { from: bridgeManager });
+ let isUpgrading = await this.bridge.isUpgrading();
+ assert.equal(isUpgrading, true);
+
+ await truffleAssertions.fails(this.bridge.setUpgrading(false), truffleAssertions.ErrorType.REVERT);
+ isUpgrading = await this.bridge.isUpgrading();
+ assert.equal(isUpgrading, true);
+ });
+
+ describe('when Upgrading', async function() {
+ beforeEach(async function() {
+ await this.bridge.setUpgrading(true, { from: bridgeManager });
+ });
+
+ it('should create side token', async function () {
+ await this.bridge.createSideToken(
+ 0,
+ this.token.address,
+ 6,
+ 'eMAIN',
+ mainTokenName,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: bridgeManager }
+ );
+ const sideTokenAddress = await this.bridge.sideTokenByOriginalToken(chains.HARDHAT_TEST_NET_CHAIN_ID, this.token.address);
+ const sideToken = await SideToken.at(sideTokenAddress);
+ const sideTokenSymbol = await sideToken.symbol();
+ assert.equal(sideTokenSymbol, 'eMAIN');
+
+ const sideTokenDecimals = await sideToken.decimals();
+ assert.equal(sideTokenDecimals.toString(), '18');
+
+ const sideTokenGranularity = await sideToken.granularity();
+ assert.equal(sideTokenGranularity.toString(), '1000000000000');
+
+ const originalToken = await this.bridge.getOriginalTokenBySideToken(sideTokenAddress);
+ assert.equal(originalToken.tokenAddress, this.token.address);
+
+ const result = await this.allowTokens.getInfoAndLimits(sideTokenAddress);
+ assert.equal(result.info.typeId.toString(), '0');
+ assert.equal(result.info.allowed, true);
+
+ });
+
+ it('should reject receiveTokens ERC20', async function () {
+ const amount = web3.utils.toWei('1000');
+ await this.token.approve(this.bridge.address, amount, { from: tokenOwner });
+ await truffleAssertions.fails(
+ this.bridge.receiveTokensTo(
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ this.token.address,
+ tokenOwner,
+ amount,
+ { from: tokenOwner }
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should reject tokensReceived for ERC777', async function () {
+ const amount = web3.utils.toWei('1000');
+ const granularity = '100';
+ let erc777 = await SideToken.new("ERC777", "777", tokenOwner, granularity, { from: tokenOwner });
+
+ await this.allowTokens.setToken(erc777.address, this.typeId, { from: bridgeManager });
+ await erc777.mint(tokenOwner, amount, "0x", "0x", {from: tokenOwner });
+ await truffleAssertions.fails(
+ erc777.send(this.bridge.address, amount, tokenOwner, { from: tokenOwner }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should accept transfer for the token', async function () {
+ await this.bridge.createSideToken(
+ 0,
+ this.token.address,
+ 18,
+ 'MAIN',
+ 'MAIN',
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ { from: bridgeManager }
+ );
+
+ const sideTokenAddress = await this.bridge.sideTokenByOriginalToken(chains.HARDHAT_TEST_NET_CHAIN_ID, this.token.address);
+ const sideToken = await SideToken.at(sideTokenAddress);
+
+ const originalToken = await this.bridge.getOriginalTokenBySideToken(sideTokenAddress);
+ assert.equal(originalToken.tokenAddress, this.token.address);
+
+ const balanceBeforeTransfer = await sideToken.balanceOf(anAccount);
+ const bridgeBalanceBeforeTransfer = await sideToken.balanceOf(this.bridge.address);
+
+ const amount = web3.utils.toWei('1000');
+ const blockHash = utils.getRandomHash();
+ const txHash = utils.getRandomHash();
+ const logIndex = 1;
+
+ const transactionDataHash = await this.bridge.getTransactionDataHash(
+ anAccount,
+ amount,
+ blockHash,
+ txHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ )
+
+ const receipt = await this.bridge.acceptTransfer(
+ this.token.address, anAccount, anAccount, amount,
+ blockHash, txHash, logIndex, chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID, { from: federation });
+ utils.checkRcpt(receipt);
+
+
+ const mirrorBridgeBalance = await sideToken.balanceOf(this.bridge.address);
+ assert.equal(mirrorBridgeBalance.toString(), bridgeBalanceBeforeTransfer.toString());
+ const mirrorAnAccountBalance = await sideToken.balanceOf(anAccount);
+ assert.equal(mirrorAnAccountBalance.toString(), balanceBeforeTransfer.toString());
+
+ const obtainedTransactionDataHash = await this.bridge.transactionsDataHashes(txHash);
+ assert.equal(obtainedTransactionDataHash, transactionDataHash);
+
+ const originalTokenAddresses = await this.bridge.originalTokenAddresses(txHash);
+ assert.equal(originalTokenAddresses, this.token.address);
+
+ const senderAddresses = await this.bridge.senderAddresses(txHash);
+ assert.equal(senderAddresses, anAccount);
+ });
+ });
+ });
+
+ describe('change SideTokenFactory', async function() {
+
+ it('should reject empty address', async function () {
+ await truffleAssertions.fails(
+ this.bridge.changeSideTokenFactory(utils.NULL_ADDRESS, { from: bridgeManager }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should be successful', async function () {
+ const newAddress = utils.getRandomAddress();
+ await this.bridge.changeSideTokenFactory(newAddress, { from: bridgeManager });
+ const result = await this.bridge.sideTokenFactory();
+ assert.equal(result.toLowerCase(), newAddress.toLowerCase());
+ });
+ });
+
+});
+
diff --git a/bridge/test/Bridge_upgrade_test.js b/bridge/test/Bridge_upgrade_test.js
new file mode 100644
index 000000000..b39b3e9a7
--- /dev/null
+++ b/bridge/test/Bridge_upgrade_test.js
@@ -0,0 +1,334 @@
+//Upgradable Contracts
+const BridgeV3 = artifacts.require('BridgeV3');
+const BridgeV4 = artifacts.require('Bridge');
+const BridgeProxy = artifacts.require('BridgeProxy');
+const ProxyAdmin = artifacts.require('ProxyAdmin');
+
+//Normal Contracts
+const SideTokenFactoryV1 = artifacts.require('./SideTokenFactoryV1');
+const SideTokenFactory = artifacts.require('./SideTokenFactory');
+const SideToken = artifacts.require('./SideToken');
+const AllowTokensV1 = artifacts.require('./AllowTokens');
+const MainToken = artifacts.require('./MainToken');
+
+const truffleAssertions = require('truffle-assertions');
+const chains = require('../hardhat/helper/chains');
+const utils = require('./utils');
+const toWei = web3.utils.toWei;
+
+contract('Bridge upgrade test', async (accounts) => {
+ const deployerAddress = accounts[0];
+ const managerAddress = accounts[1];
+ const anAccount = accounts[2];
+ const otherAccount = accounts[3];
+ const federationAddress = accounts[5];
+
+ before(async function () {
+ await utils.saveState();
+ });
+
+ after(async function () {
+ await utils.revertState();
+ });
+
+ beforeEach(async () => {
+ this.typeId = 0;
+ this.proxyAdmin = await ProxyAdmin.new();
+ this.allowTokensV1 = await AllowTokensV1.new();
+ await this.allowTokensV1.methods['initialize(address,address,uint256,uint256,uint256,(string,(uint256,uint256,uint256,uint256,uint256))[])'](
+ managerAddress,
+ deployerAddress,
+ '0',
+ '0',
+ '0',
+ [{
+ description:'MAIN',
+ limits: {
+ max:toWei('10000'),
+ min:toWei('1'),
+ daily:toWei('100000'),
+ mediumAmount:toWei('2'),
+ largeAmount:toWei('3')
+ }
+ }]
+ );
+ this.sideTokenFactoryV1 = await SideTokenFactoryV1.new();
+ this.token = await MainToken.new("MAIN", "MAIN", 18, web3.utils.toWei('1000000'), { from: deployerAddress });
+ this.amount = web3.utils.toWei('1000');
+ await this.allowTokensV1.setToken(this.token.address, this.typeId, { from: managerAddress });
+ });
+
+ describe('freshly created', async () => {
+ it('should create a proxy', async () => {
+ const bridgeLogic = await BridgeV3.new()
+ const bridgeProxy = await BridgeProxy.new(bridgeLogic.address, this.proxyAdmin.address, '0x');
+ const proxy = new web3.eth.Contract(BridgeV3.abi, bridgeProxy.address);
+ let result = await proxy.methods.version().call();
+ assert.equal(result, 'v3');
+
+ result = await proxy.methods.owner().call();
+ assert.equal(result, "0x0000000000000000000000000000000000000000");
+ result = await proxy.methods.allowTokens().call();
+ assert.equal(result, "0x0000000000000000000000000000000000000000");
+ result = await proxy.methods.sideTokenFactory().call();
+ assert.equal(result, "0x0000000000000000000000000000000000000000");
+ result = await proxy.methods.symbolPrefix().call();
+ assert.equal(result, 0);
+ });
+
+ it('should initialize it', async () => {
+ const bridgeLogic = await BridgeV3.new()
+ const initData = bridgeLogic.contract.methods.initialize(managerAddress, federationAddress, this.allowTokensV1.address, this.sideTokenFactoryV1.address, 'r').encodeABI();
+ const bridgeProxy = await BridgeProxy.new(bridgeLogic.address, this.proxyAdmin.address, initData);
+ const proxy = new web3.eth.Contract(BridgeV3.abi, bridgeProxy.address);
+
+ result = await proxy.methods.owner().call();
+ assert.equal(result, managerAddress);
+ result = await proxy.methods.allowTokens().call();
+ assert.equal(result, this.allowTokensV1.address);
+ result = await proxy.methods.sideTokenFactory().call();
+ assert.equal(result, this.sideTokenFactoryV1.address);
+ result = await proxy.methods.symbolPrefix().call();
+ assert.equal(result, 'r');
+ result = await proxy.methods.getFederation().call();
+ assert.equal(result, federationAddress);
+ });
+
+ describe('initialized', async () => {
+ beforeEach(async() => {
+ const bridgeLogic = await BridgeV3.new()
+ const initData = bridgeLogic.contract.methods.initialize(managerAddress, federationAddress, this.allowTokensV1.address, this.sideTokenFactoryV1.address, 'r').encodeABI();
+ this.bridgeProxy = await BridgeProxy.new(bridgeLogic.address, this.proxyAdmin.address, initData);
+ this.proxyBridge = new web3.eth.Contract(BridgeV3.abi, this.bridgeProxy.address);
+ const result = await this.proxyBridge.methods.symbolPrefix().call();
+ assert.equal(result, 'r');
+ await this.allowTokensV1.transferPrimary(this.proxyBridge.options.address);
+ });
+
+ it('should set fees pecentage', async () => {
+ let feePercentage = '20'; //0.2%
+ const tx = await this.proxyBridge.methods.setFeePercentage(feePercentage).send({from: managerAddress});
+ assert.equal(tx.status, true);
+ utils.checkGas(tx.cumulativeGasUsed);
+ const result = await this.proxyBridge.methods.getFeePercentage().call();
+ assert.equal(result.toString(), feePercentage);
+ });
+
+ it('should receive tokens', async () => {
+ const amount = web3.utils.toWei('1');
+ await this.token.transfer(anAccount, amount, { from: deployerAddress });
+ await this.token.approve(this.proxyBridge.options.address, amount, { from: anAccount });
+
+ const tx = await this.proxyBridge.methods.receiveTokensTo(this.token.address, anAccount, amount).send({ from: anAccount, gas: 200_000});
+ assert.equal(tx.status, true);
+ utils.checkGas(tx.cumulativeGasUsed);
+
+ assert.equal(tx.events.Cross.event, 'Cross');
+ const balance = await this.token.balanceOf(this.proxyBridge.options.address);
+ assert.equal(balance, amount);
+ const isKnownToken = await this.proxyBridge.methods.knownTokens(this.token.address).call();
+ assert.equal(isKnownToken, true);
+ });
+
+ it('should update it', async () => {
+ let result = await this.proxyBridge.methods.version().call();
+ assert.equal(result, 'v3');
+
+ /* Upgrade the contract at the address of our instance to the new logic */
+ const bridgeLogic = await BridgeV4.new()
+ await this.proxyAdmin.upgrade(this.proxyBridge.options.address, bridgeLogic.address)
+ const newProxy = new web3.eth.Contract(BridgeV4.abi, this.proxyBridge.options.address);
+
+ result = await newProxy.methods.version().call();
+ assert.equal(result, 'v4');
+
+ result = await newProxy.methods.owner().call();
+ assert.equal(result, managerAddress);
+ result = await newProxy.methods.allowTokens().call();
+ assert.equal(result, this.allowTokensV1.address);
+ result = await newProxy.methods.sideTokenFactory().call();
+ assert.equal(result, this.sideTokenFactoryV1.address);
+ result = await newProxy.methods.getFederation().call();
+ assert.equal(result, federationAddress);
+ });
+
+ it('should have new method setFeePercentage after update', async () => {
+ let feePercentage = '20'; //0.2%
+ await this.proxyBridge.methods.setFeePercentage(feePercentage).send({from: managerAddress});
+ result = await this.proxyBridge.methods.getFeePercentage().call();
+ assert.equal(result.toString(), feePercentage);
+
+ const bridgeLogic = await BridgeV4.new();
+ await this.proxyAdmin.upgrade(this.proxyBridge.options.address, bridgeLogic.address);
+ const newProxy = new web3.eth.Contract(BridgeV4.abi, this.proxyBridge.options.address);
+
+ result = await newProxy.methods.getFeePercentage().call();
+ // This is the previous value from getCRossingPayment
+ assert.equal(result.toString(), feePercentage);
+
+ feePercentage = '300'; //3%
+ await newProxy.methods.setFeePercentage(feePercentage).send({from: managerAddress});
+ result = await newProxy.methods.getFeePercentage().call();
+ assert.equal(result.toString(), feePercentage);
+ });
+
+ describe('upgrade governance', () => {
+ it('proxy owner', async () => {
+ let owner = await this.proxyAdmin.owner();
+ assert.equal(owner, deployerAddress);
+ });
+
+ it('proxy admin', async () => {
+ const admin = await this.proxyAdmin.getProxyAdmin(this.proxyBridge.options.address);
+ assert.equal(admin, this.proxyAdmin.address);
+ });
+
+ it('should renounce ownership', async () => {
+ let owner = await this.proxyAdmin.owner();
+ assert.equal(owner, deployerAddress);
+
+ await this.proxyAdmin.renounceOwnership();
+
+ owner = await this.proxyAdmin.owner();
+ assert.equal(owner, 0);
+
+ const bridgeLogic = await BridgeV4.new();
+ await truffleAssertions.fails(
+ this.proxyAdmin.upgrade(this.proxyBridge.options.address, bridgeLogic.address),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should transfer ownership', async () => {
+ let owner = await this.proxyAdmin.owner();
+ assert.equal(owner, deployerAddress);
+
+ await this.proxyAdmin.transferOwnership(anAccount);
+
+ owner = await this.proxyAdmin.owner();
+ assert.equal(owner, anAccount);
+
+ const bridgeLogic = await BridgeV4.new();
+ await truffleAssertions.fails(
+ this.proxyAdmin.upgrade(this.proxyBridge.options.address, bridgeLogic.address),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ });// end upgrade governance
+
+ describe('after upgrade', async () => {
+ beforeEach(async () => {
+ this.typeId = 0;
+ const bridgeLogic = await BridgeV4.new();
+ await this.proxyAdmin.upgrade(this.proxyBridge.options.address, bridgeLogic.address);
+ this.proxyBridge = new web3.eth.Contract(BridgeV4.abi, this.proxyBridge.options.address);
+ this.sideTokenFactory = await SideTokenFactory.new();
+ await this.sideTokenFactory.transferPrimary(this.proxyBridge.options.address);
+ const result = await this.proxyBridge.methods.version().call();
+ assert.equal(result, 'v4');
+ });
+
+ it('should have new method changeSideTokenFactory', async () => {
+ await this.proxyBridge.methods.changeSideTokenFactory(this.sideTokenFactory.address).call({from: managerAddress});
+ });
+
+ it('should have new method changeAllowTokens', async () => {
+ await this.proxyBridge.methods.changeAllowTokens(this.allowTokensV1.address).call({from: managerAddress});
+ });
+
+ describe('after changeSideTokenFactory and changeAllowTokens', async () => {
+ beforeEach(async () => {
+ await this.proxyBridge.methods.changeSideTokenFactory(this.sideTokenFactory.address).send({from: managerAddress});
+ await this.proxyBridge.methods.changeAllowTokens(this.allowTokensV1.address).send({from: managerAddress});
+ });
+
+ it('should have removed the method tokenFallback', async () => {
+ await truffleAssertions.fails(
+ this.token.transferAndCall(this.proxyBridge.options.address, web3.utils.toWei('1000'), '0x',
+ { from: deployerAddress }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should receive tokens', async () => {
+ const amount = web3.utils.toWei('1000');
+ await this.token.transfer(anAccount, amount, { from: deployerAddress });
+ await this.token.approve(this.proxyBridge.options.address, amount, { from: anAccount });
+
+ const tx = await this.proxyBridge.methods.receiveTokensTo(chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ this.token.address, anAccount, amount).send({ from: anAccount, gas: 200_000});
+ assert.equal(Number(tx.status), 1, "Should be a succesful Tx");
+
+ assert.equal(tx.events.Cross.event, 'Cross');
+ const balance = await this.token.balanceOf(this.proxyBridge.options.address);
+ assert.equal(balance, amount);
+ const isKnownToken = await this.proxyBridge.methods.knownToken(
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ this.token.address
+ ).call();
+ assert.equal(isKnownToken, true);
+ });
+
+ it('should accept Transfer', async () => {
+ await this.proxyBridge.methods.createSideToken(
+ this.typeId,
+ this.token.address,
+ 18,
+ 'rMAIN',
+ 'MAIN on RSK',
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ ).send({from: managerAddress, gas: 4_000_000});
+
+ const sideTokenAddress = await this.proxyBridge.methods.sideTokenByOriginalToken(
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ this.token.address
+ ).call();
+ let sideToken = await SideToken.at(sideTokenAddress);
+ const sideTokenSymbol = await sideToken.symbol();
+ assert.equal(sideTokenSymbol, "rMAIN");
+
+ const originalToken = await this.proxyBridge.methods.getOriginalTokenBySideToken(sideTokenAddress).call();
+ assert.equal(originalToken.tokenAddress, this.token.address);
+
+ const blockHash = utils.getRandomHash();
+ const txHash = utils.getRandomHash();
+ const logIndex = 0;
+ const tx = await this.proxyBridge.methods.acceptTransfer(
+ this.token.address,
+ anAccount,
+ otherAccount,
+ this.amount,
+ blockHash,
+ txHash,
+ logIndex,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID
+ ).send({ from: federationAddress, gas: 200_000});
+ assert.equal(Number(tx.status), 1, "Should be a succesful Tx");
+
+ await this.proxyBridge.methods.claim(
+ {
+ to: otherAccount,
+ amount: this.amount,
+ blockHash: blockHash,
+ transactionHash: txHash,
+ logIndex: logIndex,
+ originChainId: chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ }
+ ).send({ from: federationAddress, gas: 200_000 });
+
+ const hasBeenClaimed = await this.proxyBridge.methods.hasBeenClaimed(txHash).call();
+ assert.equal(hasBeenClaimed, true);
+
+ const mirrorBridgeBalance = await sideToken.balanceOf(this.proxyBridge.options.address);
+ assert.equal(mirrorBridgeBalance, 0);
+ const mirrorAnAccountBalance = await sideToken.balanceOf(otherAccount);
+ assert.equal(mirrorAnAccountBalance, this.amount);
+ });
+ }); // end after changeSideTokenFactory
+ }); //end after upgrade
+
+ }); // end initialized
+ }); // end freshly created
+});
\ No newline at end of file
diff --git a/bridge/test/FederatedManagerBridge_test.js b/bridge/test/FederatedManagerBridge_test.js
deleted file mode 100644
index 22701d5f6..000000000
--- a/bridge/test/FederatedManagerBridge_test.js
+++ /dev/null
@@ -1,158 +0,0 @@
-const FederatedManager = artifacts.require('./FederatedManager');
-const MainToken = artifacts.require('./MainToken');
-const SideToken = artifacts.require('./SideToken');
-const Bridge = artifacts.require('./Bridge');
-
-const expectThrow = require('./utils').expectThrow;
-
-contract('FederatedManager', function (accounts) {
- const members = [ accounts[1], accounts[2], accounts[3], accounts[4], accounts[5] ];
- const notmember = accounts[0];
- const newmanager = accounts[8];
- const newmanager2 = accounts[9];
-
- describe('change bridge manager', function () {
- const managerOwner = accounts[0];
- const tokenOwner = accounts[6];
-
- beforeEach(async function () {
- this.manager = await FederatedManager.new(members, { from: managerOwner });
- this.token = await SideToken.new("MAIN", "MAIN", 18, this.manager.address, { from: tokenOwner });
-
- await this.manager.setTransferable(this.token.address);
- });
-
- it('vote new manager', async function() {
- await this.manager.voteNewManager(newmanager, { from: members[0] });
-
- const tokenManager = await this.token.manager();
- assert.equal(tokenManager, this.manager.address);
-
- const votes = await this.manager.newManagerVotes(newmanager);
-
- assert.ok(votes);
- assert.equal(votes.length, 1);
- assert.equal(votes[0], members[0]);
-
- const novotes = await this.manager.newManagerNoVotes(newmanager);
-
- assert.equal(novotes, 1);
- });
-
- it('enought votes to change manager', async function() {
- await this.manager.voteNewManager(newmanager, { from: members[0] });
- await this.manager.voteNewManager(newmanager, { from: members[1] });
- await this.manager.voteNewManager(newmanager, { from: members[2] });
-
- const tokenManager = await this.token.manager();
- assert.equal(tokenManager, newmanager);
-
- const votes = await this.manager.newManagerVotes(newmanager);
-
- assert.ok(votes);
- assert.equal(votes.length, 0);
-
- const novotes = await this.manager.newManagerNoVotes(newmanager);
-
- assert.equal(novotes, 0);
- });
-
- it('vote new manager only by a member', async function() {
- expectThrow(this.manager.voteNewManager(newmanager, { from: notmember }));
-
- const tokenManager = await this.token.manager();
- assert.equal(tokenManager, this.manager.address);
-
- const votes = await this.manager.newManagerVotes(newmanager);
-
- assert.ok(votes);
- assert.equal(votes.length, 0);
-
- const novotes = await this.manager.newManagerNoVotes(newmanager);
-
- assert.equal(novotes, 0);
- });
-
- it('vote new manager who is the manager', async function() {
- await this.manager.voteNewManager(this.manager.address, { from: members[0] });
-
- const tokenManager = await this.token.manager();
- assert.equal(tokenManager, this.manager.address);
-
- const votes = await this.manager.newManagerVotes(this.manager.address);
-
- assert.ok(votes);
- assert.equal(votes.length, 0);
-
- const novotes = await this.manager.newManagerNoVotes(this.manager.address);
-
- assert.equal(novotes, 0);
- });
-
- it('two votes new manager', async function() {
- await this.manager.voteNewManager(newmanager, { from: members[0] });
- await this.manager.voteNewManager(newmanager, { from: members[1] });
-
- const tokenManager = await this.token.manager();
- assert.equal(tokenManager, this.manager.address);
-
- const votes = await this.manager.newManagerVotes(newmanager);
-
- assert.ok(votes);
- assert.equal(votes.length, 2);
- assert.equal(votes[0], members[0]);
- assert.equal(votes[1], members[1]);
-
- const novotes = await this.manager.newManagerNoVotes(newmanager);
-
- assert.equal(novotes, 2);
- });
-
- it('two repeated votes new manager', async function() {
- await this.manager.voteNewManager(newmanager, { from: members[0] });
- await this.manager.voteNewManager(newmanager, { from: members[0] });
-
- const tokenManager = await this.token.manager();
- assert.equal(tokenManager, this.manager.address);
-
- const votes = await this.manager.newManagerVotes(newmanager);
-
- assert.ok(votes);
- assert.equal(votes.length, 1);
- assert.equal(votes[0], members[0]);
-
- const novotes = await this.manager.newManagerNoVotes(newmanager);
-
- assert.equal(novotes, 1);
- });
-
- it('two votes to two new different managers', async function() {
- await this.manager.voteNewManager(newmanager, { from: members[0] });
- await this.manager.voteNewManager(newmanager2, { from: members[1] });
-
- const tokenManager = await this.token.manager();
- assert.equal(tokenManager, this.manager.address);
-
- const votes1 = await this.manager.newManagerVotes(newmanager);
-
- assert.ok(votes1);
- assert.equal(votes1.length, 1);
- assert.equal(votes1[0], members[0]);
-
- const votes2 = await this.manager.newManagerVotes(newmanager2);
-
- assert.ok(votes2);
- assert.equal(votes2.length, 1);
- assert.equal(votes2[0], members[1]);
-
- const novotes1 = await this.manager.newManagerNoVotes(newmanager);
-
- assert.equal(novotes1, 1);
-
- const novotes2 = await this.manager.newManagerNoVotes(newmanager2);
-
- assert.equal(novotes2, 1);
- });
- });
-});
-
diff --git a/bridge/test/FederatedManagerMembers_test.js b/bridge/test/FederatedManagerMembers_test.js
deleted file mode 100644
index f287c54cf..000000000
--- a/bridge/test/FederatedManagerMembers_test.js
+++ /dev/null
@@ -1,295 +0,0 @@
-const FederatedManager = artifacts.require('./FederatedManager');
-
-const expectThrow = require('./utils').expectThrow;
-
-contract('FederatedManager', function (accounts) {
- const members = [ accounts[1], accounts[2], accounts[3], accounts[4], accounts[5] ];
- const newmember = accounts[6];
- const newmember2 = accounts[7];
- const notmember = accounts[0];
- const oldmember = members[members.length - 1];
- const oldmember2 = members[members.length - 2];
-
- describe('add member', function () {
- beforeEach(async function () {
- this.manager = await FederatedManager.new(members);
- });
-
- it('vote add member', async function() {
- await this.manager.voteAddMember(newmember, { from: members[0] });
-
- const ismember = await this.manager.isMember(newmember);
- assert.equal(ismember, false);
-
- const votes = await this.manager.addMemberVotes(newmember);
-
- assert.ok(votes);
- assert.equal(votes.length, 1);
- assert.equal(votes[0], members[0]);
-
- const novotes = await this.manager.addMemberNoVotes(newmember);
-
- assert.equal(novotes, 1);
- });
-
- it('enought votes to add member', async function() {
- await this.manager.voteAddMember(newmember, { from: members[0] });
- await this.manager.voteAddMember(newmember, { from: members[1] });
- await this.manager.voteAddMember(newmember, { from: members[2] });
-
- const ismember = await this.manager.isMember(newmember);
- assert.equal(ismember, true);
-
- const votes = await this.manager.addMemberVotes(newmember);
-
- assert.ok(votes);
- assert.equal(votes.length, 0);
-
- const novotes = await this.manager.addMemberNoVotes(newmember);
-
- assert.equal(novotes, 0);
- });
-
- it('vote add member only by a member', async function() {
- expectThrow(this.manager.voteAddMember(newmember, { from: accounts[0] }));
-
- const ismember = await this.manager.isMember(newmember);
- assert.equal(ismember, false);
-
- const votes = await this.manager.addMemberVotes(newmember);
-
- assert.ok(votes);
- assert.equal(votes.length, 0);
-
- const novotes = await this.manager.addMemberNoVotes(newmember);
-
- assert.equal(novotes, 0);
- });
-
- it('vote add member who is a member', async function() {
- await this.manager.voteAddMember(members[1], { from: members[0] });
-
- const ismember = await this.manager.isMember(members[1]);
- assert.equal(ismember, true);
-
- const votes = await this.manager.addMemberVotes(members[1]);
-
- assert.ok(votes);
- assert.equal(votes.length, 0);
-
- const novotes = await this.manager.addMemberNoVotes(members[1]);
-
- assert.equal(novotes, 0);
- });
-
- it('two votes add member', async function() {
- await this.manager.voteAddMember(newmember, { from: members[0] });
- await this.manager.voteAddMember(newmember, { from: members[1] });
-
- const ismember = await this.manager.isMember(newmember);
- assert.equal(ismember, false);
-
- const votes = await this.manager.addMemberVotes(newmember);
-
- assert.ok(votes);
- assert.equal(votes.length, 2);
- assert.equal(votes[0], members[0]);
- assert.equal(votes[1], members[1]);
-
- const novotes = await this.manager.addMemberNoVotes(newmember);
-
- assert.equal(novotes, 2);
- });
-
- it('two repeated votes add member', async function() {
- await this.manager.voteAddMember(newmember, { from: members[0] });
- await this.manager.voteAddMember(newmember, { from: members[0] });
-
- const ismember = await this.manager.isMember(newmember);
- assert.equal(ismember, false);
-
- const votes = await this.manager.addMemberVotes(newmember);
-
- assert.ok(votes);
- assert.equal(votes.length, 1);
- assert.equal(votes[0], members[0]);
-
- const novotes = await this.manager.addMemberNoVotes(newmember);
-
- assert.equal(novotes, 1);
- });
-
- it('two votes to add two different members', async function() {
- await this.manager.voteAddMember(newmember, { from: members[0] });
- await this.manager.voteAddMember(newmember2, { from: members[1] });
-
- const ismember = await this.manager.isMember(newmember);
- assert.equal(ismember, false);
-
- const ismember2 = await this.manager.isMember(newmember2);
- assert.equal(ismember2, false);
-
- const votes1 = await this.manager.addMemberVotes(newmember);
-
- assert.ok(votes1);
- assert.equal(votes1.length, 1);
- assert.equal(votes1[0], members[0]);
-
- const votes2 = await this.manager.addMemberVotes(newmember2);
-
- assert.ok(votes2);
- assert.equal(votes2.length, 1);
- assert.equal(votes2[0], members[1]);
-
- const novotes1 = await this.manager.addMemberNoVotes(newmember);
-
- assert.equal(novotes1, 1);
-
- const novotes2 = await this.manager.addMemberNoVotes(newmember2);
-
- assert.equal(novotes2, 1);
- });
- });
-
- describe('remove member', function () {
- beforeEach(async function () {
- this.manager = await FederatedManager.new(members);
- });
-
- it('vote remove member', async function() {
- await this.manager.voteRemoveMember(oldmember, { from: members[0] });
-
- const ismember = await this.manager.isMember(oldmember);
- assert.equal(ismember, true);
-
- const votes = await this.manager.removeMemberVotes(oldmember);
-
- assert.ok(votes);
- assert.equal(votes.length, 1);
- assert.equal(votes[0], members[0]);
-
- const novotes = await this.manager.removeMemberNoVotes(oldmember);
-
- assert.equal(novotes, 1);
- });
-
- it('enought votes to remove member', async function() {
- await this.manager.voteRemoveMember(oldmember, { from: members[0] });
- await this.manager.voteRemoveMember(oldmember, { from: members[1] });
- await this.manager.voteRemoveMember(oldmember, { from: members[2] });
-
- const ismember = await this.manager.isMember(oldmember);
- assert.equal(ismember, false);
-
- const votes = await this.manager.removeMemberVotes(oldmember);
-
- assert.ok(votes);
- assert.equal(votes.length, 0);
-
- const novotes = await this.manager.removeMemberNoVotes(oldmember);
-
- assert.equal(novotes, 0);
- });
-
- it('vote remove member only by a member', async function() {
- expectThrow(this.manager.voteRemoveMember(oldmember, { from: accounts[0] }));
-
- const ismember = await this.manager.isMember(oldmember);
- assert.equal(ismember, true);
-
- const votes = await this.manager.removeMemberVotes(oldmember);
-
- assert.ok(votes);
- assert.equal(votes.length, 0);
-
- const novotes = await this.manager.removeMemberNoVotes(oldmember);
-
- assert.equal(novotes, 0);
- });
-
- it('vote remove member who is not a member', async function() {
- await this.manager.voteRemoveMember(notmember, { from: members[0] });
-
- const ismember = await this.manager.isMember(notmember);
- assert.equal(ismember, false);
-
- const votes = await this.manager.removeMemberVotes(notmember);
-
- assert.ok(votes);
- assert.equal(votes.length, 0);
-
- const novotes = await this.manager.removeMemberNoVotes(notmember);
-
- assert.equal(novotes, 0);
- });
-
- it('two votes remove member', async function() {
- await this.manager.voteRemoveMember(oldmember, { from: members[0] });
- await this.manager.voteRemoveMember(oldmember, { from: members[1] });
-
- const ismember = await this.manager.isMember(oldmember);
- assert.equal(ismember, true);
-
- const votes = await this.manager.removeMemberVotes(oldmember);
-
- assert.ok(votes);
- assert.equal(votes.length, 2);
- assert.equal(votes[0], members[0]);
- assert.equal(votes[1], members[1]);
-
- const novotes = await this.manager.removeMemberNoVotes(oldmember);
-
- assert.equal(novotes, 2);
- });
-
- it('two repeated votes remove member', async function() {
- await this.manager.voteRemoveMember(oldmember, { from: members[0] });
- await this.manager.voteRemoveMember(oldmember, { from: members[0] });
-
- const ismember = await this.manager.isMember(oldmember);
- assert.equal(ismember, true);
-
- const votes = await this.manager.removeMemberVotes(oldmember);
-
- assert.ok(votes);
- assert.equal(votes.length, 1);
- assert.equal(votes[0], members[0]);
-
- const novotes = await this.manager.removeMemberNoVotes(oldmember);
-
- assert.equal(novotes, 1);
- });
-
- it('two votes to add two different members', async function() {
- await this.manager.voteRemoveMember(oldmember, { from: members[0] });
- await this.manager.voteRemoveMember(oldmember2, { from: members[1] });
-
- const ismember = await this.manager.isMember(oldmember);
- assert.equal(ismember, true);
-
- const ismember2 = await this.manager.isMember(oldmember2);
- assert.equal(ismember2, true);
-
- const votes1 = await this.manager.removeMemberVotes(oldmember);
-
- assert.ok(votes1);
- assert.equal(votes1.length, 1);
- assert.equal(votes1[0], members[0]);
-
- const votes2 = await this.manager.removeMemberVotes(oldmember2);
-
- assert.ok(votes2);
- assert.equal(votes2.length, 1);
- assert.equal(votes2[0], members[1]);
-
- const novotes1 = await this.manager.removeMemberNoVotes(oldmember);
-
- assert.equal(novotes1, 1);
-
- const novotes2 = await this.manager.removeMemberNoVotes(oldmember2);
-
- assert.equal(novotes2, 1);
- });
- });
-});
-
diff --git a/bridge/test/FederatedManagerTransfers_test.js b/bridge/test/FederatedManagerTransfers_test.js
deleted file mode 100644
index 6de520c6e..000000000
--- a/bridge/test/FederatedManagerTransfers_test.js
+++ /dev/null
@@ -1,363 +0,0 @@
-const FederatedManager = artifacts.require('./FederatedManager');
-const MainToken = artifacts.require('./MainToken');
-const SideToken = artifacts.require('./SideToken');
-const Bridge = artifacts.require('./Bridge');
-
-const expectThrow = require('./utils').expectThrow;
-
-contract('FederatedManager', function (accounts) {
- const members = [ accounts[1], accounts[2], accounts[3], accounts[4], accounts[5] ];
- const notmember = accounts[0];
-
- describe('members and votes', function () {
- beforeEach(async function () {
- this.manager = await FederatedManager.new(members);
- });
-
- it('is member', async function() {
- const notmember = await this.manager.isMember(accounts[0]);
-
- assert.equal(notmember, false);
-
- for (var k = 0; k < members.length; k++) {
- const ismember = await this.manager.isMember(members[k]);
-
- assert.ok(ismember);
- }
- });
-
- it('no votes for unknown transaction', async function() {
- const votes = await this.manager.transactionVotes(1, 2, 3, 4, 5);
-
- assert.ok(votes);
- assert.ok(Array.isArray(votes));
- assert.equal(votes.length, 0);
-
- const novotes = await this.manager.transactionNoVotes(1, 2, 3, 4, 5);
-
- assert.equal(novotes, 0);
- });
-
- it('one vote for transaction', async function() {
- await this.manager.voteTransaction(1, 2, 3, 4, 5, { from: members[0] });
-
- const votes = await this.manager.transactionVotes(1, 2, 3, 4, 5);
-
- assert.ok(votes);
- assert.ok(Array.isArray(votes));
- assert.equal(votes.length, 1);
- assert.equal(votes[0], members[0]);
-
- const novotes = await this.manager.transactionNoVotes(1, 2, 3, 4, 5);
-
- assert.equal(novotes, 1);
- });
-
- it('vote only member', async function() {
- expectThrow(this.manager.voteTransaction(1, 2, 3, 4, 5));
-
- const votes = await this.manager.transactionVotes(1, 2, 3, 4, 5);
-
- assert.ok(votes);
- assert.ok(Array.isArray(votes));
- assert.equal(votes.length, 0);
- });
-
- it('two votes for transaction', async function() {
- await this.manager.voteTransaction(1, 2, 3, 4, 5, { from: members[0] });
- await this.manager.voteTransaction(1, 2, 3, 4, 5, { from: members[1] });
-
- const votes = await this.manager.transactionVotes(1, 2, 3, 4, 5);
-
- assert.ok(votes);
- assert.ok(Array.isArray(votes));
- assert.equal(votes.length, 2);
- assert.equal(votes[0], members[0]);
- assert.equal(votes[1], members[1]);
-
- const novotes = await this.manager.transactionNoVotes(1, 2, 3, 4, 5);
-
- assert.equal(novotes, 2);
- });
-
- it('two repeated votes for transaction', async function() {
- await this.manager.voteTransaction(1, 2, 3, 4, 5, { from: members[0] });
- await this.manager.voteTransaction(1, 2, 3, 4, 5, { from: members[0] });
-
- const votes = await this.manager.transactionVotes(1, 2, 3, 4, 5);
-
- assert.ok(votes);
- assert.ok(Array.isArray(votes));
- assert.equal(votes.length, 1);
- assert.equal(votes[0], members[0]);
- });
- });
-
- describe('transferable', function () {
- beforeEach(async function () {
- this.manager = await FederatedManager.new(members);
- });
-
- it('set transferable', async function () {
- await this.manager.setTransferable(accounts[6]);
-
- const transferable = await this.manager.transferable();
-
- assert.equal(transferable, accounts[6]);
- });
-
- it('set transferable only owner', async function () {
- expectThrow(this.manager.setTransferable(accounts[6], { from: accounts[1] }));
-
- const transferable = await this.manager.transferable();
-
- assert.equal(transferable, 0);
- });
-
- it('set transferable only once', async function () {
- await this.manager.setTransferable(accounts[6]);
- expectThrow(this.manager.setTransferable(accounts[7]));
-
- const transferable = await this.manager.transferable();
-
- assert.equal(transferable, accounts[6]);
- });
- });
-
- describe('accept transfer using bridge', function () {
- const managerOwner = accounts[0];
- const tokenOwner = accounts[6];
- const bridgeOwner = accounts[7];
- const anAccount = accounts[8];
-
- beforeEach(async function () {
- this.manager = await FederatedManager.new(members, { from: managerOwner });
- this.token = await MainToken.new("MAIN", "MAIN", 18, 10000, { from: tokenOwner });
- this.bridge = await Bridge.new(this.manager.address, this.token.address, { from: bridgeOwner });
-
- await this.token.transfer(this.bridge.address, 1000, { from: tokenOwner });
- await this.manager.setTransferable(this.bridge.address);
- });
-
- it('initial state', async function () {
- const tokenOwnerBalance = await this.token.balanceOf(tokenOwner);
- assert.equal(tokenOwnerBalance, 9000);
-
- const bridgeBalance = await this.token.balanceOf(this.bridge.address);
- assert.equal(bridgeBalance, 1000);
-
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 0);
- });
-
- if('no block voted yet', async function () {
- const lastBlockNumber = await this.manager.lastBlockNumber(members[0]);
-
- assert.equal(lastBlockNumber, 0);
-
- const lastBlockHash = await this.manager.lastBlockHash(members[0]);
-
- assert.equals(lastBlockHash, 0);
- });
-
- it('two votes of five no accept transfer', async function () {
- await this.manager.voteTransaction(1, '0x02', 3, anAccount, 100, { from: members[0] });
- await this.manager.voteTransaction(1, '0x02', 3, anAccount, 100, { from: members[1] });
-
- const tokenOwnerBalance = await this.token.balanceOf(tokenOwner);
- assert.equal(tokenOwnerBalance, 9000);
-
- const bridgeBalance = await this.token.balanceOf(this.bridge.address);
- assert.equal(bridgeBalance, 1000);
-
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 0);
-
- const lastBlockNumber1 = await this.manager.lastBlockNumber(members[0]);
- const lastBlockHash1 = await this.manager.lastBlockHash(members[0]);
-
- assert.equal(lastBlockNumber1, 1);
- assert.equal(lastBlockHash1, '0x0200000000000000000000000000000000000000000000000000000000000000');
-
- const lastBlockNumber2 = await this.manager.lastBlockNumber(members[1]);
- const lastBlockHash2 = await this.manager.lastBlockHash(members[1]);
-
- assert.equal(lastBlockNumber2, 1);
- assert.equal(lastBlockHash2 , '0x0200000000000000000000000000000000000000000000000000000000000000');
- });
-
- it('votes two transactions', async function () {
- await this.manager.voteTransaction(1, '0x03', 3, anAccount, 100, { from: members[0] });
- await this.manager.voteTransaction(2, '0x02', 3, anAccount, 100, { from: members[0] });
-
- const tokenOwnerBalance = await this.token.balanceOf(tokenOwner);
- assert.equal(tokenOwnerBalance, 9000);
-
- const bridgeBalance = await this.token.balanceOf(this.bridge.address);
- assert.equal(bridgeBalance, 1000);
-
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 0);
-
- const lastBlockNumber = await this.manager.lastBlockNumber(members[0]);
- const lastBlockHash = await this.manager.lastBlockHash(members[0]);
-
- assert.equal(lastBlockNumber, 2);
- assert.equal(lastBlockHash, '0x0200000000000000000000000000000000000000000000000000000000000000');
- });
-
- it('votes two transactions in inverser block order', async function () {
- await this.manager.voteTransaction(2, '0x03', 3, anAccount, 100, { from: members[0] });
- await this.manager.voteTransaction(1, '0x02', 3, anAccount, 100, { from: members[0] });
-
- const tokenOwnerBalance = await this.token.balanceOf(tokenOwner);
- assert.equal(tokenOwnerBalance, 9000);
-
- const bridgeBalance = await this.token.balanceOf(this.bridge.address);
- assert.equal(bridgeBalance, 1000);
-
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 0);
-
- const lastBlockNumber = await this.manager.lastBlockNumber(members[0]);
- const lastBlockHash = await this.manager.lastBlockHash(members[0]);
-
- assert.equal(lastBlockNumber, 2);
- assert.equal(lastBlockHash, '0x0300000000000000000000000000000000000000000000000000000000000000');
- });
-
- it('three votes of five then accept transfer', async function () {
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[0] });
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[1] });
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[2] });
-
- const tokenOwnerBalance = await this.token.balanceOf(tokenOwner);
- assert.equal(tokenOwnerBalance, 9000);
-
- const bridgeBalance = await this.token.balanceOf(this.bridge.address);
- assert.equal(bridgeBalance, 900);
-
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 100);
-
- const votes = await this.manager.transactionVotes(1, 2, 3, anAccount, 100);
-
- assert.ok(votes);
- assert.ok(Array.isArray(votes));
- assert.equal(votes.length, 0);
- });
-
- it('four votes of five only one accept transfer', async function () {
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[0] });
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[1] });
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[2] });
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[3] });
-
- const tokenOwnerBalance = await this.token.balanceOf(tokenOwner);
- assert.equal(tokenOwnerBalance, 9000);
-
- const bridgeBalance = await this.token.balanceOf(this.bridge.address);
- assert.equal(bridgeBalance, 900);
-
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 100);
-
- const votes = await this.manager.transactionVotes(1, 2, 3, anAccount, 100);
-
- assert.ok(votes);
- assert.ok(Array.isArray(votes));
- assert.equal(votes.length, 0);
- });
- });
-
- describe('accept transfer using side token', function () {
- const managerOwner = accounts[0];
- const tokenOwner = accounts[6];
- const anAccount = accounts[7];
-
- beforeEach(async function () {
- this.manager = await FederatedManager.new(members, { from: managerOwner });
- this.token = await SideToken.new("MAIN", "MAIN", 18, this.manager.address, { from: tokenOwner });
-
- await this.manager.setTransferable(this.token.address);
- });
-
- it('initial state', async function () {
- const tokenOwnerBalance = await this.token.balanceOf(tokenOwner);
- assert.equal(tokenOwnerBalance, 0);
-
- const managerBalance = await this.token.balanceOf(this.manager.address);
- assert.equal(managerBalance, 0);
-
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 0);
- });
-
- it('two votes of five no accept transfer', async function () {
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[0] });
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[1] });
-
- const processed = await this.manager.transactionWasProcessed(1, 2, 3, anAccount, 100);
- assert.equal(processed, false);
-
- const tokenOwnerBalance = await this.token.balanceOf(tokenOwner);
- assert.equal(tokenOwnerBalance, 0);
-
- const managerBalance = await this.token.balanceOf(this.manager.address);
- assert.equal(managerBalance, 0);
-
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 0);
- });
-
- it('three votes of five then accept transfer', async function () {
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[0] });
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[1] });
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[2] });
-
- const processed = await this.manager.transactionWasProcessed(1, 2, 3, anAccount, 100);
- assert.equal(processed, true);
-
- const tokenOwnerBalance = await this.token.balanceOf(tokenOwner);
- assert.equal(tokenOwnerBalance, 0);
-
- const managerBalance = await this.token.balanceOf(this.manager.address);
- assert.equal(managerBalance, 0);
-
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 100);
-
- const votes = await this.manager.transactionVotes(1, 2, 3, anAccount, 100);
-
- assert.ok(votes);
- assert.ok(Array.isArray(votes));
- assert.equal(votes.length, 0);
- });
-
- it('four votes of five only one accept transfer', async function () {
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[0] });
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[1] });
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[2] });
- await this.manager.voteTransaction(1, 2, 3, anAccount, 100, { from: members[3] });
-
- const processed = await this.manager.transactionWasProcessed(1, 2, 3, anAccount, 100);
- assert.equal(processed, true);
-
- const tokenOwnerBalance = await this.token.balanceOf(tokenOwner);
- assert.equal(tokenOwnerBalance, 0);
-
- const managerBalance = await this.token.balanceOf(this.manager.address);
- assert.equal(managerBalance, 0);
-
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 100);
-
- const votes = await this.manager.transactionVotes(1, 2, 3, anAccount, 100);
-
- assert.ok(votes);
- assert.ok(Array.isArray(votes));
- assert.equal(votes.length, 0);
- });
- });
-});
-
diff --git a/bridge/test/Federation_test.js b/bridge/test/Federation_test.js
new file mode 100644
index 000000000..54e929906
--- /dev/null
+++ b/bridge/test/Federation_test.js
@@ -0,0 +1,1401 @@
+const Federation = artifacts.require('Federation');
+const AllowTokens = artifacts.require('./AllowTokens');
+const Bridge = artifacts.require('./Bridge');
+const SideTokenFactory = artifacts.require('./SideTokenFactory');
+
+const truffleAssertions = require('truffle-assertions');
+const utils = require('./utils');
+const chains = require('../hardhat/helper/chains');
+const BN = web3.utils.BN;
+const toWei = web3.utils.toWei;
+
+contract('Federation', async function (accounts) {
+ const deployer = accounts[0];
+ const anAccount = accounts[1];
+ const federator1 = accounts[2];
+ const federator2 = accounts[3];
+ const federator3 = accounts[4];
+ const bridge = utils.getRandomAddress();
+
+ before(async function () {
+ await utils.saveState();
+ });
+
+ after(async function () {
+ await utils.revertState();
+ });
+
+ beforeEach(async function () {
+ this.federators = await Federation.new();
+ });
+
+ describe('Initialization', async function() {
+ it('should use initialize', async function () {
+ await this.federators.initialize([federator1, federator2], 1, bridge, deployer);
+ });
+
+ it('should fail if required is not the same as memebers length', async function () {
+ await truffleAssertions.fails(
+ this.federators.initialize([federator1, federator2], 3, bridge, deployer),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should fail if repeated memebers', async function () {
+ await truffleAssertions.fails(
+ this.federators.initialize([federator1, federator1], 2, bridge, deployer),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should fail if null memeber', async function () {
+ await truffleAssertions.fails(
+ this.federators.initialize([federator1, utils.NULL_ADDRESS], 2, bridge, deployer),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should fail if null bridge', async function () {
+ await truffleAssertions.fails(
+ this.federators.initialize([federator1], 1, utils.NULL_ADDRESS, deployer),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should fail if bigger max memeber length', async function () {
+ const members = [];
+ for(let i = 0; i <= 50; i++) {
+ members[i]=utils.getRandomAddress();
+ }
+ await truffleAssertions.fails(
+ this.federators.initialize(members, 2, bridge, deployer),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should be successful with max memeber length', async function () {
+ const members = [];
+ for(let i = 0; i < 50; i++) {
+ members[i]=utils.getRandomAddress();
+ }
+ await this.federators.initialize(members, 2, bridge, deployer);
+ const resultMembers = await this.federators.getMembers();
+ assert.equal(resultMembers.length, 50);
+ });
+ });
+
+ describe('After initialization', async function() {
+
+ beforeEach(async function () {
+ this.members = [federator1, federator2];
+ await this.federators.initialize(this.members, 1, bridge, deployer);
+ });
+
+ describe('Members', async function () {
+ it('should have initial values from constructor', async function () {
+ const members = await this.federators.getMembers();
+ assert.equal(members.length, this.members.length);
+ assert.equal(members[0], this.members[0]);
+ assert.equal(members[1], this.members[1]);
+
+ const owner = await this.federators.owner();
+ assert.equal(owner, deployer);
+ });
+
+ it('should have correct version', async function () {
+ const version = await this.federators.version();
+ assert.equal(version, 'v3');
+ });
+
+ it('isMember should work correctly', async function() {
+ let isMember = await this.federators.isMember(federator1);
+ assert.equal(isMember, true);
+
+ isMember = await this.federators.isMember(federator2);
+ assert.equal(isMember, true);
+
+ isMember = await this.federators.isMember(federator3);
+ assert.equal(isMember, false);
+ });
+
+ it('setBridge should work correctly', async function() {
+ const result = await this.federators.setBridge(anAccount);
+
+ const bridge = await this.federators.bridge();
+ assert.equal(bridge, anAccount);
+
+ truffleAssertions.eventEmitted(result, 'BridgeChanged', (ev) => {
+ return ev.bridge === bridge;
+ });
+ });
+
+
+ it('setBridge should fail if empty', async function() {
+ await truffleAssertions.fails(
+ this.federators.setBridge(utils.NULL_ADDRESS),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ describe('addMember', async function() {
+ it('should be succesful', async function() {
+ const receipt = await this.federators.addMember(federator3);
+ utils.checkRcpt(receipt);
+
+ const isMember = await this.federators.isMember(federator3);
+ assert.equal(isMember, true);
+
+ const members = await this.federators.getMembers();
+ assert.equal(members.length, this.members.length + 1);
+ assert.equal(members[2], federator3);
+ truffleAssertions.eventEmitted(receipt, 'MemberAddition', (ev) => {
+ return ev.member === federator3;
+ });
+ });
+
+ it('should fail if not the owner', async function() {
+ await truffleAssertions.fails(
+ this.federators.addMember(federator3, { from: federator1 }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ await truffleAssertions.fails(
+ this.federators.addMember(federator3, { from: anAccount }),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ const isMember = await this.federators.isMember(federator3);
+ assert.equal(isMember, false);
+ const members = await this.federators.getMembers();
+ assert.equal(members.length, this.members.length);
+ });
+
+ it('should fail if empty', async function() {
+ await truffleAssertions.fails(this.federators.addMember(utils.NULL_ADDRESS), truffleAssertions.ErrorType.REVERT);
+ });
+
+ it('should fail if already exists', async function() {
+ await truffleAssertions.fails(this.federators.addMember(federator2), truffleAssertions.ErrorType.REVERT);
+
+ const isMember = await this.federators.isMember(federator2);
+ assert.equal(isMember, true);
+ const members = await this.federators.getMembers();
+ assert.equal(members.length, this.members.length);
+ });
+
+ it('should fail if max members', async function() {
+ for(i=2; i < 50; i++) {
+ await this.federators.addMember(utils.getRandomAddress());
+ }
+
+ await truffleAssertions.fails(this.federators.addMember(anAccount), truffleAssertions.ErrorType.REVERT);
+
+ const isMember = await this.federators.isMember(anAccount);
+ assert.equal(isMember, false);
+ const members = await this.federators.getMembers();
+ assert.equal(members.length, 50);
+ });
+ });
+
+ describe('removeMember', async function() {
+ it('should be succesful with 1 required and 2 members', async function() {
+ const receipt = await this.federators.removeMember(federator1);
+ utils.checkRcpt(receipt);
+
+ const isMember = await this.federators.isMember(federator1);
+ assert.equal(isMember, false);
+ const members = await this.federators.getMembers();
+ assert.equal(members.length, 1);
+ assert.equal(members[0], federator2);
+
+ truffleAssertions.eventEmitted(receipt, 'MemberRemoval', (ev) => {
+ return ev.member === federator1;
+ });
+ });
+
+ it('should be succesful with 2 required and 3 memebers', async function() {
+ await this.federators.changeRequirement(2);
+
+ await this.federators.addMember(federator3);
+ let members = await this.federators.getMembers();
+ assert.equal(members.length, 3);
+
+ const receipt = await this.federators.removeMember(federator1);
+ utils.checkRcpt(receipt);
+
+ const isMember = await this.federators.isMember(federator1);
+ assert.equal(isMember, false);
+ members = await this.federators.getMembers();
+ assert.equal(members.length, 2);
+ assert.equal(members[0], federator3);
+
+ truffleAssertions.eventEmitted(receipt, 'MemberRemoval', (ev) => {
+ return ev.member === federator1;
+ });
+ });
+
+ it('should fail if lower than required', async function() {
+ await this.federators.changeRequirement(2);
+ let members = await this.federators.getMembers();
+ assert.equal(members.length, 2);
+
+ await truffleAssertions.fails(this.federators.removeMember(federator1), truffleAssertions.ErrorType.REVERT);
+
+ members = await this.federators.getMembers();
+ assert.equal(members.length, 2);
+ });
+
+ it('should fail if not the owner', async function() {
+ await truffleAssertions.fails(
+ this.federators.removeMember(federator1, { from: federator2 }),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ const isMember = await this.federators.isMember(federator1);
+ assert.equal(isMember, true);
+ const members = await this.federators.getMembers();
+ assert.equal(members.length, this.members.length);
+ });
+
+ it('should fail if nulll address', async function() {
+ await truffleAssertions.fails(this.federators.removeMember(utils.NULL_ADDRESS), truffleAssertions.ErrorType.REVERT);
+ });
+
+ it('should fail if doesnt exists', async function() {
+ await truffleAssertions.fails(this.federators.removeMember(anAccount), truffleAssertions.ErrorType.REVERT);
+
+ const isMember = await this.federators.isMember(anAccount);
+ assert.equal(isMember, false);
+ const members = await this.federators.getMembers();
+ assert.equal(members.length, this.members.length);
+ });
+
+ it('should fail when removing all members', async function() {
+ await this.federators.removeMember(federator2);
+ await truffleAssertions.fails(this.federators.removeMember(federator1), truffleAssertions.ErrorType.REVERT);
+
+ const isMember = await this.federators.isMember(federator1);
+ assert.equal(isMember, true);
+ const members = await this.federators.getMembers();
+ assert.equal(members.length, 1);
+ assert.equal(members[0], federator1);
+ });
+ });
+
+ describe('changeRequirement', async function() {
+ it('should be succesful', async function() {
+ const receipt = await this.federators.changeRequirement(2);
+ utils.checkRcpt(receipt);
+
+ const required = await this.federators.required();
+ assert.equal(required, 2);
+
+ truffleAssertions.eventEmitted(receipt, 'RequirementChange', (ev) => {
+ return parseInt(ev.required) === 2;
+ });
+ });
+
+ it('should fail if not the owner', async function() {
+ await truffleAssertions.fails(
+ this.federators.changeRequirement(2, { from: anAccount }),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ const required = await this.federators.required();
+ assert.equal(required, 1);
+ });
+
+ it('should fail if less than 2', async function() {
+ await this.federators.changeRequirement(2);
+ await truffleAssertions.fails(this.federators.changeRequirement(1), truffleAssertions.ErrorType.REVERT);
+
+ const required = await this.federators.required();
+ assert.equal(required, 2);
+ });
+
+ it('should fail if required bigger than memebers', async function() {
+ await truffleAssertions.fails(this.federators.changeRequirement(3), truffleAssertions.ErrorType.REVERT);
+
+ let required = await this.federators.required();
+ assert.equal(required, 1);
+ });
+ });
+
+ const arrayMembersToString = (array) => {
+ const result = []
+ for (const element of array) {
+ result.push(element.toString());
+ }
+ return result;
+ }
+
+ describe('emitHeartbeat', async function() {
+ const fedRskChainId = '30';
+ const fedEthChainId = '1';
+ const fedBscChainId = '56';
+ const federatorVersion = '3.0.0';
+ const nodeRskInfo = 'rskjar/2.2.0';
+ const nodeEthInfo = 'geth/1.13.15';
+ const nodeBscInfo = 'geth/1.1.5';
+ const fedRskBlock = '123456';
+ const fedEthBlock = '999000000';
+ const fedBscBlock = '999000000';
+
+ it('should be succesful', async function() {
+ const receipt = await this.federators.emitHeartbeat(
+ federatorVersion,
+ [ fedRskChainId, fedEthChainId, fedBscChainId ],
+ [ fedRskBlock, fedEthBlock, fedBscBlock ],
+ [ nodeRskInfo, nodeEthInfo, nodeBscInfo ],
+ {from: federator1}
+ );
+ utils.checkRcpt(receipt);
+
+ assert.equal(receipt.logs[0].event, 'HeartBeat');
+ assert.equal(receipt.logs[0].args[0], federator1);
+ assert.equal(receipt.logs[0].args[1], await web3.eth.net.getId() );
+ assert.equal(receipt.logs[0].args[2], await web3.eth.getBlockNumber());
+ assert.equal(receipt.logs[0].args[3], federatorVersion);
+ assert.deepEqual(arrayMembersToString(receipt.logs[0].args[4]),
+ [ fedRskChainId, fedEthChainId, fedBscChainId ]
+ );
+ assert.deepEqual(arrayMembersToString(receipt.logs[0].args[5]), [ fedRskBlock, fedEthBlock, fedBscBlock ]);
+ assert.deepEqual(arrayMembersToString(receipt.logs[0].args[6]), [ nodeRskInfo, nodeEthInfo, nodeBscInfo ]);
+ });
+
+ it('should fail if not a memeber', async function() {
+ await truffleAssertions.fails(
+ this.federators.emitHeartbeat(
+ federatorVersion,
+ [ fedRskChainId, fedEthChainId, fedBscChainId ],
+ [ fedRskBlock, fedEthBlock, fedBscBlock ],
+ [ nodeRskInfo, nodeEthInfo, nodeBscInfo ],
+ {from: anAccount}
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should fail if different array size', async function() {
+ await truffleAssertions.fails(
+ this.federators.emitHeartbeat(
+ federatorVersion,
+ [ fedRskChainId, fedEthChainId, fedBscChainId ],
+ [ fedRskBlock, fedEthBlock, fedBscBlock ],
+ [ nodeRskInfo, nodeEthInfo ],
+ {from: anAccount}
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ await truffleAssertions.fails(
+ this.federators.emitHeartbeat(
+ federatorVersion,
+ [ fedRskChainId, fedEthChainId ],
+ [ fedRskBlock, fedEthBlock, fedBscBlock ],
+ [ nodeRskInfo, nodeEthInfo, nodeBscInfo ],
+ {from: anAccount}
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ await truffleAssertions.fails(
+ this.federators.emitHeartbeat(
+ federatorVersion,
+ [ fedRskChainId, fedEthChainId, fedBscChainId ],
+ [ fedRskBlock, fedEthBlock ],
+ [ nodeRskInfo, nodeEthInfo, nodeBscInfo ],
+ {from: anAccount}
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ });
+
+ });
+
+ describe('Transactions', async function() {
+ const originalTokenAddress = utils.getRandomAddress();
+ const amount = web3.utils.toWei('10');
+ const blockHash = utils.getRandomHash();
+ const transactionHash = utils.getRandomHash();
+ const logIndex = new BN(1);
+ const decimals = 18;
+ const typeId = 0;
+
+ beforeEach(async function () {
+ this.allowTokens = await AllowTokens.new();
+ await this.allowTokens.methods['initialize(address,address,uint256,uint256,uint256,(string,(uint256,uint256,uint256,uint256,uint256))[])'](
+ deployer,
+ deployer,
+ '0',
+ '0',
+ '0',
+ [{
+ description:'RIF',
+ limits:{
+ max:toWei('10000'),
+ min:toWei('1'),
+ daily:toWei('100000'),
+ mediumAmount:toWei('2'),
+ largeAmount:toWei('3')
+ }
+ }]
+ );
+
+ await this.allowTokens.setToken(originalTokenAddress, typeId);
+ this.sideTokenFactory = await SideTokenFactory.new();
+ this.bridge = await Bridge.new();
+ await this.bridge.methods['initialize(address,address,address,address)'](deployer, this.federators.address,
+ this.allowTokens.address, this.sideTokenFactory.address);
+ await this.sideTokenFactory.transferPrimary(this.bridge.address);
+ await this.allowTokens.transferPrimary(this.bridge.address);
+ await this.federators.setBridge(this.bridge.address);
+
+ await this.bridge.createSideToken(
+ typeId,
+ originalTokenAddress,
+ decimals,
+ 'MAIN',
+ 'MAIN',
+ chains.HARDHAT_TEST_NET_CHAIN_ID
+ );
+ });
+
+ it('voteTransaction should be successful with 1/1 federators require 1', async function() {
+ this.federators.removeMember(federator2)
+ let transactionId = await this.federators.getTransactionId(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+ let transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 0);
+
+ let hasVoted = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVoted, false);
+
+ const receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator1}
+ );
+ utils.checkRcpt(receipt);
+
+ hasVoted = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVoted, true);
+
+ transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 1);
+
+ let transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator1});
+ assert.equal(transactionWasProcessed, true);
+
+ transactionWasProcessed = await this.bridge.hasCrossed(transactionHash);
+ assert.equal(transactionWasProcessed, true);
+
+ let transactionDataHash = await this.bridge.getTransactionDataHash(
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+ let bridgeTransactionDataWasProcessed = await this.bridge.transactionsDataHashes(transactionHash);
+ assert.equal(transactionDataHash, bridgeTransactionDataWasProcessed);
+
+ truffleAssertions.eventEmitted(receipt, 'Voted', (ev) => {
+ return ev.federator === federator1 && ev.transactionId === transactionId;
+ });
+
+ truffleAssertions.eventEmitted(receipt, 'Executed', (ev) => {
+ return ev.federator === federator1 && ev.transactionId === transactionId;
+ });
+ });
+
+ it('voteTransaction should fail with wrong acceptTransfer arguments', async function() {
+ this.federators.removeMember(federator2);
+ const wrongTokenAddress = "0x0000000000000000000000000000000000000000";
+ const transactionId = await this.federators.getTransactionId(
+ wrongTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID
+ );
+ let transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 0);
+
+ let hasVoted = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVoted, false);
+
+ await truffleAssertions.fails(
+ this.federators.voteTransaction(
+ wrongTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator1}
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ hasVoted = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVoted, false);
+
+ transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 0);
+
+ let transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator1});
+ assert.equal(transactionWasProcessed, false);
+
+ const bridgeTransactionId = await this.bridge.getTransactionDataHash(
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID
+ );
+ transactionWasProcessed = await this.bridge.hasCrossed(bridgeTransactionId);
+ assert.equal(transactionWasProcessed, false);
+ });
+
+ it('voteTransaction should be pending with 1/2 feds require 2', async function() {
+ await this.federators.changeRequirement(2);
+ const transactionId = await this.federators.getTransactionId(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+ let transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 0);
+
+ let hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, false);
+ let hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+
+ const receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator1}
+ );
+ utils.checkRcpt(receipt);
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+
+ transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 1);
+
+ let transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator1});
+ assert.equal(transactionWasProcessed, false);
+
+ transactionWasProcessed = await this.bridge.hasCrossed(transactionHash);
+ assert.equal(transactionWasProcessed, false);
+
+ truffleAssertions.eventEmitted(receipt, 'Voted', (ev) => {
+ return ev.federator === federator1 && ev.transactionId === transactionId;
+ });
+
+ truffleAssertions.eventNotEmitted(receipt, 'Executed');
+ });
+
+ it('voteTransaction should be pending with 1/2 feds require 2 and voted twice', async function() {
+ await this.federators.changeRequirement(2);
+ const transactionId = await this.federators.getTransactionId(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+ let transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 0);
+
+ let hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, false);
+ let hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+
+ const receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator1}
+ );
+ utils.checkRcpt(receipt);
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+
+ const secondReceipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator1}
+ );
+ utils.checkRcpt(secondReceipt);
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+
+ transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 1);
+
+ let transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator1});
+ assert.equal(transactionWasProcessed, false);
+
+ transactionWasProcessed = await this.bridge.hasCrossed(transactionHash);
+ assert.equal(transactionWasProcessed, false);
+
+ truffleAssertions.eventEmitted(receipt, 'Voted', (ev) => {
+ return ev.federator === federator1 && ev.transactionId === transactionId;
+ });
+
+ truffleAssertions.eventNotEmitted(receipt, 'Executed');
+ });
+
+ it('voteTransaction should be successful with 2/2 feds require 1', async function() {
+ const transactionId = await this.federators.getTransactionId(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID
+ );
+ let transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 0);
+
+ let hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, false);
+ let hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+
+ let receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator1}
+ );
+ utils.checkRcpt(receipt);
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+
+ transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 1);
+
+ let transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator1});
+ assert.equal(transactionWasProcessed, false);
+
+ receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator2}
+ );
+ utils.checkRcpt(receipt);
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, true);
+
+ transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 2);
+
+ transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator2});
+ assert.equal(transactionWasProcessed, true);
+
+ const expectedHash = await this.bridge.getTransactionDataHash(
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID
+ );
+ const bridgeTransactionHash = await this.bridge.transactionsDataHashes(transactionHash);
+ assert.equal(bridgeTransactionHash, expectedHash);
+
+ transactionWasProcessed = await this.bridge.hasCrossed(transactionHash);
+ assert.equal(transactionWasProcessed, true);
+ });
+
+ it('voteTransaction should be successful with 2/2 feds require 2', async function() {
+ await this.federators.changeRequirement(2);
+ const transactionId = await this.federators.getTransactionId(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID
+ );
+ let transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 0);
+
+ let hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, false);
+ let hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+
+ let receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator1}
+ );
+ utils.checkRcpt(receipt);
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+
+ transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 1);
+
+ let transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator1});
+ assert.equal(transactionWasProcessed, false);
+
+ receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator2}
+ );
+ utils.checkRcpt(receipt);
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, true);
+
+ transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 2);
+
+ transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator2});
+ assert.equal(transactionWasProcessed, true);
+
+ const expectedHash = await this.bridge.getTransactionDataHash(
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+ const bridgeTransactionHash = await this.bridge.transactionsDataHashes(transactionHash);
+ assert.equal(bridgeTransactionHash, expectedHash);
+
+ transactionWasProcessed = await this.bridge.hasCrossed(transactionHash);
+ assert.equal(transactionWasProcessed, true);
+ });
+
+ it('voteTransaction should be successful with 2/3 feds', async function() {
+ this.federators.addMember(federator3);
+
+ let transactionId = await this.federators.getTransactionId(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+
+ let hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, false);
+ let hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+ let hasVotedFederator3 = await this.federators.hasVoted(transactionId, {from: federator3});
+ assert.equal(hasVotedFederator3, false);
+
+ await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator1}
+ );
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+ hasVotedFederator3 = await this.federators.hasVoted(transactionId, {from: federator3});
+ assert.equal(hasVotedFederator3, false);
+
+ let transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator1});
+ assert.equal(transactionWasProcessed, false);
+
+ const receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator2}
+ );
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, true);
+ hasVotedFederator3 = await this.federators.hasVoted(transactionId, {from: federator3});
+ assert.equal(hasVotedFederator3, false);
+
+ const hasVoted = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVoted, true);
+
+ let count = await this.federators.getTransactionCount(transactionId, {from: federator2});
+ assert.equal(count, 2);
+
+ transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator2});
+ assert.equal(transactionWasProcessed, true);
+
+ const expectedHash = await this.bridge.getTransactionDataHash(
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+ const bridgeTransactionHash = await this.bridge.transactionsDataHashes(transactionHash);
+ assert.equal(bridgeTransactionHash, expectedHash);
+
+ transactionWasProcessed = await this.bridge.hasCrossed(transactionHash);
+ assert.equal(transactionWasProcessed, true);
+ });
+
+ it('voteTransaction should be successful with 2/3 feds require 2', async function() {
+ await this.federators.changeRequirement(2);
+ this.federators.addMember(federator3);
+
+ let transactionId = await this.federators.getTransactionId(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+
+ let hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, false);
+ let hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+ let hasVotedFederator3 = await this.federators.hasVoted(transactionId, {from: federator3});
+ assert.equal(hasVotedFederator3, false);
+
+ let receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator1}
+ );
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+ hasVotedFederator3 = await this.federators.hasVoted(transactionId, {from: federator3});
+ assert.equal(hasVotedFederator3, false);
+
+ let transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator1});
+ assert.equal(transactionWasProcessed, false);
+
+ receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator2}
+ );
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, true);
+ hasVotedFederator3 = await this.federators.hasVoted(transactionId, {from: federator3});
+ assert.equal(hasVotedFederator3, false);
+
+ let count = await this.federators.getTransactionCount(transactionId, {from: federator2});
+ assert.equal(count, 2);
+
+ transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator2});
+ assert.equal(transactionWasProcessed, true);
+
+ const expectedHash = await this.bridge.getTransactionDataHash(
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+ const bridgeTransactionHash = await this.bridge.transactionsDataHashes(transactionHash);
+ assert.equal(bridgeTransactionHash, expectedHash);
+
+ transactionWasProcessed = await this.bridge.hasCrossed(transactionHash);
+ assert.equal(transactionWasProcessed, true);
+ });
+
+ it('voteTransaction should handle correctly already processed transaction', async function() {
+ this.federators.addMember(federator3);
+
+ let transactionId = await this.federators.getTransactionId(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+
+ let hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, false);
+ let hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+ let hasVotedFederator3 = await this.federators.hasVoted(transactionId, {from: federator3});
+ assert.equal(hasVotedFederator3, false);
+
+ let receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator1}
+ );
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+ hasVotedFederator3 = await this.federators.hasVoted(transactionId, {from: federator3});
+ assert.equal(hasVotedFederator3, false);
+
+ let transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator1});
+ assert.equal(transactionWasProcessed, false);
+
+ receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator2}
+ );
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, true);
+ hasVotedFederator3 = await this.federators.hasVoted(transactionId, {from: federator3});
+ assert.equal(hasVotedFederator3, false);
+
+ let count = await this.federators.getTransactionCount(transactionId, {from: federator2});
+ assert.equal(count, 2);
+
+ transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator2});
+ assert.equal(transactionWasProcessed, true);
+
+ const expectedHash = await this.bridge.getTransactionDataHash(
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+ const bridgeTransactionHash = await this.bridge.transactionsDataHashes(transactionHash);
+ assert.equal(bridgeTransactionHash, expectedHash);
+
+ transactionWasProcessed = await this.bridge.hasCrossed(transactionHash);
+ assert.equal(transactionWasProcessed, true);
+
+ receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator3}
+ );
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, true);
+ hasVotedFederator3 = await this.federators.hasVoted(transactionId, {from: federator3});
+ assert.equal(hasVotedFederator3, false);
+
+ transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator2});
+ assert.equal(transactionWasProcessed, true);
+ });
+
+ it('voteTransaction should be successful with 3/3 feds require 3', async function() {
+ await this.federators.addMember(federator3);
+ await this.federators.changeRequirement(3);
+
+ let transactionId = await this.federators.getTransactionId(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+
+ let hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, false);
+ let hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+ let hasVotedFederator3 = await this.federators.hasVoted(transactionId, {from: federator3});
+ assert.equal(hasVotedFederator3, false);
+
+ let receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator1}
+ );
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, false);
+ hasVotedFederator3 = await this.federators.hasVoted(transactionId, {from: federator3});
+ assert.equal(hasVotedFederator3, false);
+
+ let transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator1});
+ assert.equal(transactionWasProcessed, false);
+
+ receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator2}
+ );
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, true);
+ hasVotedFederator3 = await this.federators.hasVoted(transactionId, {from: federator3});
+ assert.equal(hasVotedFederator3, false);
+
+ let count = await this.federators.getTransactionCount(transactionId, {from: federator2});
+ assert.equal(count, 2);
+
+ transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator2});
+ assert.equal(transactionWasProcessed, false);
+
+ let bridgeTransactionHash = await this.bridge.transactionsDataHashes(transactionHash);
+ assert.equal(bridgeTransactionHash, utils.NULL_HASH);
+
+ transactionWasProcessed = await this.bridge.hasCrossed(transactionHash);
+ assert.equal(transactionWasProcessed, false);
+
+ receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator3}
+ );
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ hasVotedFederator2 = await this.federators.hasVoted(transactionId, {from: federator2});
+ assert.equal(hasVotedFederator2, true);
+ hasVotedFederator3 = await this.federators.hasVoted(transactionId, {from: federator3});
+ assert.equal(hasVotedFederator3, true);
+
+ count = await this.federators.getTransactionCount(transactionId, {from: federator2});
+ assert.equal(count, 3);
+
+ transactionWasProcessed = await this.federators.transactionWasProcessed(transactionId, {from: federator2});
+ assert.equal(transactionWasProcessed, true);
+
+ const expectedHash = await this.bridge.getTransactionDataHash(
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+ bridgeTransactionHash = await this.bridge.transactionsDataHashes(transactionHash);
+ assert.equal(bridgeTransactionHash, expectedHash);
+
+ transactionWasProcessed = await this.bridge.hasCrossed(transactionHash);
+ assert.equal(transactionWasProcessed, true);
+ });
+
+ it('should fail if not federators member', async function() {
+ await truffleAssertions.fails(
+ this.federators.voteTransaction(originalTokenAddress,
+ anAccount, anAccount, amount, blockHash, transactionHash, logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID, chains.HARDHAT_TEST_NET_CHAIN_ID
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('voteTransaction should be successfull if already voted', async function() {
+ const transactionId = await this.federators.getTransactionId(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ );
+ const transactionCount = await this.federators.getTransactionCount(transactionId);
+ assert.equal(transactionCount, 0);
+
+ let hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, false);
+
+ let receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.ETHEREUM_MAIN_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator1}
+ );
+ utils.checkRcpt(receipt);
+
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+
+ receipt = await this.federators.voteTransaction(
+ originalTokenAddress,
+ anAccount,
+ anAccount,
+ amount,
+ blockHash,
+ transactionHash,
+ logIndex,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ chains.HARDHAT_TEST_NET_CHAIN_ID,
+ {from: federator1}
+ );
+ utils.checkRcpt(receipt);
+ hasVotedFederator1 = await this.federators.hasVoted(transactionId, {from: federator1});
+ assert.equal(hasVotedFederator1, true);
+ });
+ });
+
+ describe('Ownable methods', async function() {
+
+ it('Should renounce ownership', async function() {
+ await this.federators.renounceOwnership();
+ const owner = await this.federators.owner();
+ assert.equal(parseInt(owner), 0);
+ });
+
+ it('Should not renounce ownership when not called by the owner', async function() {
+ const owner = await this.federators.owner();
+ await truffleAssertions.fails(
+ this.federators.renounceOwnership({from: anAccount}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ const ownerAfter = await this.federators.owner();
+ assert.equal(owner, ownerAfter);
+ });
+
+ it('Should transfer ownership', async function() {
+ await this.federators.transferOwnership(anAccount);
+ const owner = await this.federators.owner();
+ assert.equal(owner, anAccount);
+ });
+
+ it('Should not transfer ownership when not called by the owner', async function() {
+ const owner = await this.federators.owner();
+ await truffleAssertions.fails(
+ this.federators.transferOwnership(anAccount, {from:federator1}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ const ownerAfter = await this.federators.owner();
+ assert.equal(owner, ownerAfter);
+ });
+
+ });
+
+ });
+});
diff --git a/bridge/test/LibUtils_test.js b/bridge/test/LibUtils_test.js
new file mode 100644
index 000000000..7182b7cf9
--- /dev/null
+++ b/bridge/test/LibUtils_test.js
@@ -0,0 +1,125 @@
+const LibUtilsHarness = artifacts.require('./LibUtilsHarness');
+const MainToken = artifacts.require('./MainToken');
+const AlternativeERC20Detailed = artifacts.require('./AlternativeERC20Detailed');
+const SideToken = artifacts.require('./SideToken');
+
+const BN = web3.utils.BN;
+const truffleAssertions = require('truffle-assertions');
+const utils = require('./utils');
+
+contract('LibUtils', async function (accounts) {
+ const owner = accounts[0];
+
+ before(async function () {
+ await utils.saveState();
+ });
+
+ after(async function () {
+ await utils.revertState();
+ });
+
+ beforeEach(async function () {
+ this.utilsLib = await LibUtilsHarness.new();
+ });
+
+ describe('decimals conversion', async function () {
+ it('decimals to granularity', async function () {
+ let resultGranularity = await this.utilsLib.decimalsToGranularity(18);
+ assert.equal(resultGranularity.toString(), '1');
+ resultGranularity = await this.utilsLib.decimalsToGranularity(9);
+ assert.equal(resultGranularity.toString(), '1000000000');
+ resultGranularity = await this.utilsLib.decimalsToGranularity(6);
+ assert.equal(resultGranularity.toString(), '1000000000000');
+ resultGranularity = await this.utilsLib.decimalsToGranularity(0);
+ assert.equal(resultGranularity.toString(), new BN('1000000000000000000').toString());
+ });
+
+ it('decimals to granularity should fail over 18 decimals', async function () {
+ await truffleAssertions.fails(this.utilsLib.decimalsToGranularity(19), truffleAssertions.ErrorType.REVERT);
+ });
+
+ });
+ describe('getDecimals', async function () {
+ it('from uint8', async function () {
+ let token = await MainToken.new("MAIN", "MAIN", 18, web3.utils.toWei('10000'), { from: owner });
+ let resultDecimals = await this.utilsLib.getDecimals(token.address);
+ assert.equal(resultDecimals, 18);
+ token = await MainToken.new("MAIN", "MAIN", 0, web3.utils.toWei('10000'), { from: owner });
+ resultDecimals = await this.utilsLib.getDecimals(token.address);
+ assert.equal(resultDecimals, 0);
+ });
+
+ it('Throw if is not a contract', async function () {
+ await truffleAssertions.fails(this.utilsLib.getDecimals(owner), truffleAssertions.ErrorType.REVERT);
+ });
+
+ it('Throw if does not have decimals()', async function () {
+ await truffleAssertions.fails(this.utilsLib.getDecimals(this.utilsLib.address), truffleAssertions.ErrorType.REVERT);
+ });
+
+ it('from uint256', async function () {
+ let token = await AlternativeERC20Detailed.new("ALT", utils.ascii_to_hexa("ALT"), 18, web3.utils.toWei('10000'), { from: owner });
+ let resultGranularity = await this.utilsLib.getDecimals(token.address);
+ assert.equal(resultGranularity, 18);
+ token = await AlternativeERC20Detailed.new("ALT", utils.ascii_to_hexa("ALT"), 0, web3.utils.toWei('10000'), { from: owner });
+ resultGranularity = await this.utilsLib.getDecimals(token.address);
+ assert.equal(resultGranularity, 0);
+ });
+ });
+
+
+ describe('getGranularity', async function () {
+ it('from ERC777', async function () {
+ let granularity = '1';
+ let token = await SideToken.new("SIDE", "SIDE", owner, granularity);
+ let resultGranularity = await this.utilsLib.getGranularity(token.address);
+ assert.equal(resultGranularity.toString(), granularity);
+
+ granularity = '1000000000000000000';
+ token = await SideToken.new("SIDE", "SIDE", owner, granularity);
+ resultGranularity = await this.utilsLib.getGranularity(token.address);
+ assert.equal(resultGranularity.toString(), granularity);
+ });
+ });
+
+ describe('bytesToAddress', async function () {
+ it('should convert bytes to address', async function () {
+ const bytes = accounts[1];
+ let result = await this.utilsLib.bytesToAddress(bytes);
+
+ assert.equal(result, accounts[1]);
+ });
+ it('should convert only firs 20 bytes to address', async function () {
+ const bytes = accounts[1] + owner.substring(2);
+ let result = await this.utilsLib.bytesToAddress(bytes);
+
+ assert.equal(result, accounts[1]);
+ });
+ });
+
+ describe('toUint128', async function() {
+ it('Should convert bytes to uint128', async function() {
+ const number = 13499;
+ const hex = number.toString(16);
+ const hex32BytesString = '0x' + hex.padStart(32, '0');
+
+ const returnValue32 = await this.utilsLib.toUint128(hex32BytesString, 0);
+ assert.equal(returnValue32, number);
+
+ const hex34BytesString = '0x' + hex.padStart(34, '0');
+ const sub32Char = hex34BytesString.split('0x')[1].substring(0,32);
+ const convertedResult = parseInt(sub32Char, 16);
+
+ const returnValue34 = await this.utilsLib.toUint128(hex34BytesString, 0);
+
+ assert.equal(returnValue34, convertedResult);
+ });
+
+ it('Should validate if the byte size is not out of bounds', async function() {
+ const invalidBytesSize = '0x1ABC7154748D1CE5144';
+
+ await truffleAssertions.fails(this.utilsLib.toUint128(invalidBytesSize, 0), "LibUtils: toUint128_outOfBounds");
+ });
+ });
+
+});
diff --git a/bridge/test/MainToken_test.js b/bridge/test/MainToken_test.js
deleted file mode 100644
index 6413bea4f..000000000
--- a/bridge/test/MainToken_test.js
+++ /dev/null
@@ -1,18 +0,0 @@
-const MainToken = artifacts.require('./MainToken');
-
-contract('MainToken', function (accounts) {
- beforeEach(async function () {
- this.token = await MainToken.new("MAIN", "MAIN", 18, 10000);
- });
-
- it('initial balances', async function () {
- const balance = await this.token.balanceOf(accounts[0]);
-
- assert.equal(balance, 10000);
-
- const totalSupply = await this.token.totalSupply();
-
- assert.equal(totalSupply, 10000);
- });
-});
-
diff --git a/bridge/test/MultiSig_test.js b/bridge/test/MultiSig_test.js
new file mode 100644
index 000000000..25dad0f69
--- /dev/null
+++ b/bridge/test/MultiSig_test.js
@@ -0,0 +1,368 @@
+const MultiSigWallet = artifacts.require('./MultiSigWallet');
+
+const truffleAssertions = require('truffle-assertions');
+const utils = require('./utils');
+const NULL_ADDRESS = utils.NULL_ADDRESS;
+
+contract('MultiSigWallet', async (accounts) => {
+ const multiSigOwner = accounts[0];
+ const additionalOwner = accounts[1];
+ const anotherAccount = accounts[2];
+ const sampleTx = {
+ destination: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
+ value: 0,
+ data: '0x29ee8e450000000000000000000000007ba156fe5471185cb3eec2de9c058412c452bb4c000000000000000000000000cd2a3d9f938e13cd947ec05abc7fe734df8dd8260000000000000000000000000000000000000000000000000000002e90edd00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000005654d41494e000000000000000000000000000000000000000000000000000000'
+ };
+
+ before(async function () {
+ await utils.saveState();
+ });
+
+ after(async function () {
+ await utils.revertState();
+ });
+
+ beforeEach(async () => {
+ this.multiSig = await MultiSigWallet.new([multiSigOwner], 1);
+ assert.ok(this.multiSig);
+ });
+
+ describe('initial state', async () => {
+ it('set the correct values', async () => {
+ const owners = await this.multiSig.getOwners();
+ assert.equal(owners.length, 1);
+ assert.equal(owners[0], multiSigOwner);
+
+ const required = await this.multiSig.required();
+ assert.equal(required, 1);
+ });
+
+ it('throws error with invalid parameters', async () => {
+ await truffleAssertions.fails(
+ MultiSigWallet.new([NULL_ADDRESS], 1),
+ truffleAssertions.ErrorType.REVERT
+ );
+ await truffleAssertions.fails(
+ MultiSigWallet.new([multiSigOwner], 3),
+ truffleAssertions.ErrorType.REVERT
+ );
+ await truffleAssertions.fails(
+ MultiSigWallet.new([multiSigOwner, multiSigOwner], 0),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+ })
+
+ describe('add owner', async () => {
+ it('adds a new owner successfully', async () => {
+ let txData = this.multiSig.contract.methods.addOwner(additionalOwner).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ let isOwner = await this.multiSig.isOwner(additionalOwner)
+ assert.equal(isOwner, true);
+
+ const owners = await this.multiSig.getOwners();
+ assert.equal(owners.length, 2);
+ });
+
+ it('throws error with invalid parameters', async () => {
+ await truffleAssertions.fails(
+ this.multiSig.contract.methods.addOwner(multiSigOwner).call({from: multiSigOwner}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ let txData = this.multiSig.contract.methods.addOwner(NULL_ADDRESS).encodeABI();
+ let txId = 0;
+ await this.multiSig.submitTransaction(this.multiSig.address, txId, txData);
+ let executionResult = await this.multiSig.transactions(txId);
+ assert.equal(executionResult.executed, false);
+ txData = this.multiSig.contract.methods.addOwner(multiSigOwner).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, txId, txData);
+ executionResult = await this.multiSig.transactions(txId);
+ assert.equal(executionResult.executed, false);
+ });
+ })
+
+ describe('remove owner', async () => {
+ it('removes an owner successfully', async () => {
+ let txData = this.multiSig.contract.methods.addOwner(additionalOwner).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ let isOwner = await this.multiSig.isOwner(additionalOwner)
+ assert.equal(isOwner, true);
+
+ txData = this.multiSig.contract.methods.removeOwner(additionalOwner).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ isOwner = await this.multiSig.isOwner(additionalOwner)
+ assert.equal(isOwner, false);
+
+ const owners = await this.multiSig.getOwners();
+ assert.equal(owners.length, 1);
+ });
+
+ it('removes current owner successfully', async () => {
+ let txData = this.multiSig.contract.methods.addOwner(additionalOwner).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ let isOwner = await this.multiSig.isOwner(additionalOwner)
+ assert.equal(isOwner, true);
+
+ txData = this.multiSig.contract.methods.removeOwner(multiSigOwner).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ isOwner = await this.multiSig.isOwner(multiSigOwner)
+ assert.equal(isOwner, false);
+
+ const owners = await this.multiSig.getOwners();
+ assert.equal(owners.length, 1);
+ });
+
+ it('removes the owner and updates requirements', async () => {
+ let txData = this.multiSig.contract.methods.addOwner(additionalOwner).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ let isOwner = await this.multiSig.isOwner(additionalOwner)
+ assert.equal(isOwner, true);
+
+ txData = this.multiSig.contract.methods.changeRequirement(2).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ let required = await this.multiSig.required();
+ assert.equal(required, 2);
+
+ txData = this.multiSig.contract.methods.removeOwner(additionalOwner).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+ await this.multiSig.confirmTransaction(2, { from: additionalOwner });
+
+ isOwner = await this.multiSig.isOwner(additionalOwner)
+ assert.equal(isOwner, false);
+
+ required = await this.multiSig.required();
+ assert.equal(required, 1);
+ });
+
+ it('throws error with invalid parameters', async () => {
+ await truffleAssertions.fails
+ (this.multiSig.contract.methods.removeOwner(multiSigOwner).call({from: multiSigOwner}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ await truffleAssertions.fails(
+ this.multiSig.contract.methods.removeOwner(multiSigOwner).call({from: this.multiSig.address}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ await truffleAssertions.fails(
+ this.multiSig.contract.methods.removeOwner(NULL_ADDRESS).call({from: this.multiSig.address}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ await truffleAssertions.fails(
+ this.multiSig.contract.methods.removeOwner(anotherAccount).call({from: this.multiSig.address}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+ })
+
+ describe('replace owner', async () => {
+ it('replaces an owner successfully', async () => {
+ let txData = this.multiSig.contract.methods.addOwner(additionalOwner).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ txData = this.multiSig.contract.methods.replaceOwner(additionalOwner, anotherAccount).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ let isOwner = await this.multiSig.isOwner(additionalOwner)
+ assert.equal(isOwner, false);
+
+ isOwner = await this.multiSig.isOwner(anotherAccount)
+ assert.equal(isOwner, true);
+
+ const owners = await this.multiSig.getOwners();
+ assert.equal(owners.length, 2);
+ });
+
+ it('throws error with invalid parameters', async () => {
+ await truffleAssertions.fails(
+ this.multiSig.contract.methods.replaceOwner(NULL_ADDRESS, multiSigOwner).call({from: this.multiSig.address}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ await truffleAssertions.fails(
+ this.multiSig.contract.methods.replaceOwner(multiSigOwner, multiSigOwner).call({from: this.multiSig.address}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ await truffleAssertions.fails(
+ this.multiSig.contract.methods.replaceOwner(additionalOwner, anotherAccount).call({from: this.multiSig.address}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+ })
+
+ describe('change requirement', async () => {
+ it('changes the required signers successfully', async () => {
+ let txData = this.multiSig.contract.methods.addOwner(additionalOwner).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ txData = this.multiSig.contract.methods.changeRequirement(2).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ const required = await this.multiSig.required();
+ assert.equal(required, 2);
+ });
+
+ it('throws error with invalid parameters', async () => {
+ await truffleAssertions.fails(
+ this.multiSig.contract.methods.changeRequirement(0).call({from: this.multiSig.address}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ await truffleAssertions.fails(
+ this.multiSig.contract.methods.changeRequirement(3).call({from: this.multiSig.address}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+ })
+
+ describe('submit transaction', async () => {
+ it('submits a new transaction successfully', async () => {
+ await this.multiSig.submitTransaction(sampleTx.destination, sampleTx.value, sampleTx.data);
+
+ const transactionCount = await this.multiSig.transactionCount.call();
+ assert.equal(transactionCount, BigInt(1));
+
+ const tx = await this.multiSig.transactions(0);
+ assert.equal(tx.destination, sampleTx.destination);
+ assert.equal(tx.value, sampleTx.value);
+ assert.equal(tx.data, sampleTx.data);
+ assert.equal(tx.executed, true);
+ });
+
+ it('throws error with invalid parameters', async () => {
+ await truffleAssertions.fails(
+ this.multiSig.submitTransaction(NULL_ADDRESS, sampleTx.value, sampleTx.data, {from: multiSigOwner}),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+ })
+
+ describe('confirm transaction', async () => {
+ it('confirms a transaction successfully', async () => {
+ let txData = this.multiSig.contract.methods.addOwner(additionalOwner).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ txData = this.multiSig.contract.methods.changeRequirement(2).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ await this.multiSig.submitTransaction(sampleTx.destination, sampleTx.value, sampleTx.data);
+ let isConfirmed = await this.multiSig.confirmations(0, additionalOwner);
+ assert.equal(isConfirmed, false);
+
+ await this.multiSig.confirmTransaction(2, { from: additionalOwner });
+
+ isConfirmed = await this.multiSig.confirmations(2, additionalOwner);
+ assert.equal(isConfirmed, true);
+ });
+
+ it('throws error with invalid parameters', async () => {
+ await truffleAssertions.fails(this.multiSig.confirmTransaction(0, {from: multiSigOwner}), truffleAssertions.ErrorType.REVERT);
+ let txData = this.multiSig.contract.methods.addOwner(additionalOwner).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+ await truffleAssertions.fails(this.multiSig.confirmTransaction(0, {from: multiSigOwner}), truffleAssertions.ErrorType.REVERT);
+
+ });
+ })
+
+ describe('revoke confirmation', async () => {
+ it('revokes a confirmation successfully', async () => {
+ let txData = this.multiSig.contract.methods.addOwner(additionalOwner).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ txData = this.multiSig.contract.methods.addOwner(anotherAccount).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ txData = this.multiSig.contract.methods.changeRequirement(3).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ await this.multiSig.submitTransaction(sampleTx.destination, sampleTx.value, sampleTx.data);
+ await this.multiSig.confirmTransaction(3, { from: additionalOwner });
+
+ let isConfirmed = await this.multiSig.confirmations(3, additionalOwner);
+ assert.equal(isConfirmed, true);
+
+ await this.multiSig.revokeConfirmation(3, { from: additionalOwner });
+ isConfirmed = await this.multiSig.confirmations(3, additionalOwner);
+ assert.equal(isConfirmed, false);
+ });
+
+ it('throws error with invalid parameters', async () => {
+ await truffleAssertions.fails(this.multiSig.revokeConfirmation(0, {from: multiSigOwner}), truffleAssertions.ErrorType.REVERT);
+ await truffleAssertions.fails(this.multiSig.revokeConfirmation(1, {from: multiSigOwner}), truffleAssertions.ErrorType.REVERT);
+ });
+ })
+
+ describe('is confirmed', async () => {
+ it('checks if transaction is confirmed successfully', async () => {
+ let txData = this.multiSig.contract.methods.addOwner(additionalOwner).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ txData = this.multiSig.contract.methods.changeRequirement(2).encodeABI();
+ await this.multiSig.submitTransaction(this.multiSig.address, 0, txData);
+
+ await this.multiSig.submitTransaction(sampleTx.destination, sampleTx.value, sampleTx.data);
+ let isConfirmed = await this.multiSig.isConfirmed(2);
+ assert.equal(isConfirmed, false);
+
+ await this.multiSig.confirmTransaction(2, { from: additionalOwner });
+
+ isConfirmed = await this.multiSig.isConfirmed(2);
+ assert.equal(isConfirmed, true);
+ });
+ })
+
+ describe('get confirmation count', async () => {
+ it('checks confirmation count successfully', async () => {
+ await this.multiSig.submitTransaction(sampleTx.destination, sampleTx.value, sampleTx.data);
+ let count = await this.multiSig.getConfirmationCount(0);
+ assert.equal(count, 1);
+ });
+ })
+
+ describe('get transaction count', async () => {
+ it('checks transaction count successfully', async () => {
+ await this.multiSig.submitTransaction(sampleTx.destination, sampleTx.value, sampleTx.data);
+ let count = await this.multiSig.getTransactionCount(false, true);
+ assert.equal(count, 1);
+
+ count = await this.multiSig.getTransactionCount(true, false);
+ assert.equal(count, 0);
+ });
+ })
+
+ describe('get confirmations', async () => {
+ it('get transaction confirmations successfully', async () => {
+ await this.multiSig.submitTransaction(sampleTx.destination, sampleTx.value, sampleTx.data);
+ let confirmations = await this.multiSig.getConfirmations(0);
+ assert.equal(confirmations.length, 1);
+ assert.equal(confirmations[0], multiSigOwner);
+ });
+ })
+
+ describe('get transaction ids', async () => {
+ it('get transaction ids successfully', async () => {
+ await this.multiSig.submitTransaction(sampleTx.destination, sampleTx.value, sampleTx.data);
+ let ids = await this.multiSig.getTransactionIds(0, 1, false, true);
+ assert.equal(ids.length, 1);
+ });
+ })
+
+ describe('send value to multisig', async () => {
+ it('transfer a payment to the multisig address', async () => {
+ const payment = 1000;
+ await web3.eth.sendTransaction( { from: multiSigOwner, to: this.multiSig.address, value: payment } )
+ let multiSigBalance = await web3.eth.getBalance(this.multiSig.address);
+ assert.equal(payment, BigInt(multiSigBalance));
+ })
+
+ it('send 0 ether to default method', async () => {
+ await web3.eth.sendTransaction( { from: multiSigOwner, to: this.multiSig.address, value: 0 } )
+ })
+ })
+
+});
+
diff --git a/bridge/test/SideTokenFactory_test.js b/bridge/test/SideTokenFactory_test.js
new file mode 100644
index 000000000..ec4487791
--- /dev/null
+++ b/bridge/test/SideTokenFactory_test.js
@@ -0,0 +1,85 @@
+const SideToken = artifacts.require('./SideToken');
+const SideTokenFactory = artifacts.require('./SideTokenFactory');
+
+const truffleAssertions = require('truffle-assertions');
+const utils = require('./utils');
+
+contract('SideTokenFactory', async function (accounts) {
+ const tokenCreator = accounts[0];
+ const anAccount = accounts[1];
+
+ before(async function () {
+ await utils.saveState();
+ });
+
+ after(async function () {
+ await utils.revertState();
+ });
+
+ beforeEach(async function () {
+ this.sideTokenFactory = await SideTokenFactory.new();
+ });
+
+ it('creates a new side token with correct parameters', async function () {
+ let receipt = await this.sideTokenFactory.createSideToken("SIDE", "SIDE", 1);
+ utils.checkRcpt(receipt);
+
+ receipt = await this.sideTokenFactory.createSideToken("OTHERSYMBOL", "OTHERSYMBOL", 1);
+ utils.checkRcpt(receipt);
+ });
+
+ it('fails to create a new side token due to wrong caller', async function() {
+ assert.equal(await this.sideTokenFactory.primary(), tokenCreator);
+ await truffleAssertions.fails(
+ this.sideTokenFactory.createSideToken("SIDE", "SIDE", 1, { from: anAccount }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should create side token', async function () {
+ let receipt = await this.sideTokenFactory.createSideToken("SIDE", "SID", 1);
+ utils.checkRcpt(receipt);
+ assert.equal(receipt.logs[0].event, 'SideTokenCreated');
+ let sideTokenAddress = receipt.logs[0].args[0];
+ assert.isTrue(sideTokenAddress != 0);
+ assert.equal(receipt.logs[0].args[1], "SID");
+
+ let sideToken = await SideToken.at(sideTokenAddress);
+
+ const tokenBalance = await sideToken.balanceOf(tokenCreator);
+ assert.equal(tokenBalance, 0);
+
+ const totalSupply = await sideToken.totalSupply();
+ assert.equal(totalSupply, 0);
+
+ const symbol = await sideToken.symbol();
+ assert.equal(symbol, "SID");
+
+ const name = await sideToken.name();
+ assert.equal(name, "SIDE");
+
+ let minter = await sideToken.minter();
+ assert.equal(minter, tokenCreator);
+
+ receipt = await this.sideTokenFactory.createSideToken("OTHERSYMBOL", "OTHERSYMBOL", 1, { from: tokenCreator});
+ utils.checkRcpt(receipt);
+ assert.equal(receipt.logs[0].event, 'SideTokenCreated');
+ let newSideTokenAddress = receipt.logs[0].args[0];
+ assert.isTrue(newSideTokenAddress != 0);
+ assert.isTrue(newSideTokenAddress != sideTokenAddress);
+ assert.equal(receipt.logs[0].args[1], "OTHERSYMBOL");
+ });
+
+ it('should create mintable tokens with caller', async function () {
+ await this.sideTokenFactory.transferPrimary(anAccount);
+ assert.equal(await this.sideTokenFactory.primary(), anAccount);
+
+ const receipt = await this.sideTokenFactory.createSideToken("SIDE", "SID", 1, { from: anAccount });
+ const sideTokenAddress = receipt.logs[0].args[0];
+ const sideToken = await SideToken.at(sideTokenAddress);
+
+ const minter = await sideToken.minter();
+ assert.equal(minter, anAccount);
+ });
+
+});
diff --git a/bridge/test/SideToken_test.js b/bridge/test/SideToken_test.js
index aaf0270c1..a5aea5114 100644
--- a/bridge/test/SideToken_test.js
+++ b/bridge/test/SideToken_test.js
@@ -1,111 +1,524 @@
const SideToken = artifacts.require('./SideToken');
+const mockERC677Receiver = artifacts.require('./mockERC677Receiver');
+const mockERC777Recipient = artifacts.require('./mockERC777Recipient');
-const expectThrow = require('./utils').expectThrow;
+const truffleAssertions = require('truffle-assertions');
+const ethUtil = require('ethereumjs-util');
-contract('SideToken', function (accounts) {
+const utils = require('./utils');
+const keccak256 = web3.utils.keccak256;
+
+contract('SideToken', async function (accounts) {
const tokenCreator = accounts[0];
- const tokenManager = accounts[1];
- const anAccount = accounts[2];
- const anotherAccount = accounts[3];
-
- beforeEach(async function () {
- this.token = await SideToken.new("MAIN", "MAIN", 18, tokenManager);
+ const anAccount = accounts[1];
+ const anotherAccount = accounts[2];
+
+ before(async function () {
+ await utils.saveState();
});
- it('initial state', async function () {
- const creatorBalance = await this.token.balanceOf(tokenCreator);
- assert.equal(creatorBalance, 0);
+ after(async function () {
+ await utils.revertState();
+ });
- const tokenBalance = await this.token.balanceOf(this.token.address);
- assert.equal(tokenBalance, 0);
+ describe('constructor', async function () {
- const managerBalance = await this.token.balanceOf(tokenManager);
- assert.equal(managerBalance, 0);
-
- const totalSupply = await this.token.totalSupply();
- assert.equal(totalSupply, 0);
+ it('should create side token', async function () {
+ const token = await SideToken.new("SIDE", "SIDE", tokenCreator, 1);
+ assert.isNotEmpty(token.address)
+ });
+ it('should fail empty minter address', async function () {
+ await truffleAssertions.fails(SideToken.new("SIDE", "SIDE", utils.NULL_ADDRESS, 1), truffleAssertions.ErrorType.REVERT);
+ });
+
+ it('should fail empty granularity', async function () {
+ await truffleAssertions.fails(SideToken.new("SIDE", "SIDE", tokenCreator, 0), truffleAssertions.ErrorType.REVERT);
+ });
});
- it('accept transfer', async function () {
- await this.token.acceptTransfer(anAccount, 1000, { from: tokenManager });
-
- const creatorBalance = await this.token.balanceOf(tokenCreator);
- assert.equal(creatorBalance, 0);
+ describe('granularity 1', async function () {
+ beforeEach(async function () {
+ this.token = await SideToken.new("SIDE", "SIDE", tokenCreator, 1);
+ });
- const tokenBalance = await this.token.balanceOf(this.token.address);
- assert.equal(tokenBalance, 0);
+ it('initial state', async function () {
+ const creatorBalance = await this.token.balanceOf(tokenCreator);
+ assert.equal(creatorBalance, 0);
- const managerBalance = await this.token.balanceOf(tokenManager);
- assert.equal(managerBalance, 0);
+ const tokenBalance = await this.token.balanceOf(this.token.address);
+ assert.equal(tokenBalance, 0);
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 1000);
-
- const totalSupply = await this.token.totalSupply();
- assert.equal(totalSupply, 1000);
- });
+ const anAccountBalance = await this.token.balanceOf(anAccount);
+ assert.equal(anAccountBalance, 0);
+
+ const totalSupply = await this.token.totalSupply();
+ assert.equal(totalSupply, 0);
+
+ const granularity = await this.token.granularity();
+ assert.equal(granularity, 1);
+ });
+
+ it('mint', async function () {
+ let receipt = await this.token.mint(anAccount, 1000, '0x', '0x', { from: tokenCreator });
+ utils.checkRcpt(receipt);
+
+ const creatorBalance = await this.token.balanceOf(tokenCreator);
+ assert.equal(creatorBalance, 0);
+
+ const tokenBalance = await this.token.balanceOf(this.token.address);
+ assert.equal(tokenBalance, 0);
+
+ const anAccountBalance = await this.token.balanceOf(anAccount);
+ assert.equal(anAccountBalance, 1000);
+
+ const totalSupply = await this.token.totalSupply();
+ assert.equal(totalSupply, 1000);
+ });
+
+ it('mint only default operators', async function () {
+ await truffleAssertions.fails(
+ this.token.mint(anAccount, 1000, '0x', '0x', { from: anAccount }),
+ truffleAssertions.ErrorType.REVERT
+ );
+
+ const creatorBalance = await this.token.balanceOf(tokenCreator);
+ assert.equal(creatorBalance, 0);
+
+ const tokenBalance = await this.token.balanceOf(this.token.address);
+ assert.equal(tokenBalance, 0);
+
+ const anAccountBalance = await this.token.balanceOf(anAccount);
+ assert.equal(anAccountBalance, 0);
+
+ const totalSupply = await this.token.totalSupply();
+ assert.equal(totalSupply, 0);
+ });
+
+ it('transfer account to account', async function () {
+ await this.token.mint(anAccount, 1000, '0x', '0x', { from: tokenCreator });
+ let receipt = await this.token.transfer(anotherAccount, 400, { from: anAccount });
+ utils.checkRcpt(receipt);
+
+ const creatorBalance = await this.token.balanceOf(tokenCreator);
+ assert.equal(creatorBalance, 0);
+
+ const tokenBalance = await this.token.balanceOf(this.token.address);
+ assert.equal(tokenBalance, 0);
+
+ const anAccountBalance = await this.token.balanceOf(anAccount);
+ assert.equal(anAccountBalance, 600);
+
+ const anotherAccountBalance = await this.token.balanceOf(anotherAccount);
+ assert.equal(anotherAccountBalance, 400);
+
+ const totalSupply = await this.token.totalSupply();
+ assert.equal(totalSupply, 1000);
+ });
+
+ it('send to ERC777 contract', async function () {
+ await this.token.mint(anAccount, 1000, '0x', '0x', { from: tokenCreator });
+
+ let receiver = await mockERC777Recipient.new();
+ let result = await this.token.send(receiver.address, 400, '0x000001',{ from: anAccount });
+ utils.checkRcpt(result);
+
+ let eventSignature = web3.eth.abi.encodeEventSignature('Success(address,address,address,uint256,bytes,bytes)');
+
+ let decodedLog = web3.eth.abi.decodeLog([
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "userData",
+ "type": "bytes"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "operatorData",
+ "type": "bytes"
+ }
+ ], result.receipt.rawLogs[2].data, result.receipt.rawLogs[2].topics.slice(1));
+
+ assert.equal(result.receipt.rawLogs[2].topics[0], eventSignature);
+ assert.equal(decodedLog.operator, anAccount);
+ assert.equal(decodedLog.from, anAccount);
+ assert.equal(decodedLog.to, receiver.address);
+ assert.equal(decodedLog.amount, 400);
+ assert.equal(decodedLog.userData, '0x000001');
+
+ const anAccountBalance = await this.token.balanceOf(anAccount);
+ assert.equal(anAccountBalance, 600);
+
+ const anotherAccountBalance = await this.token.balanceOf(receiver.address);
+ assert.equal(anotherAccountBalance, 400);
+
+ const totalSupply = await this.token.totalSupply();
+ assert.equal(totalSupply, 1000);
+ });
+
+ it('transferAndCall to account', async function () {
+ await this.token.mint(anAccount, 1000, '0x', '0x', { from: tokenCreator });
+ await truffleAssertions.fails(
+ this.token.transferAndCall(anotherAccount, 400, '0x', { from: anAccount }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('transferAndCalls to empty account', async function () {
+ await this.token.mint(anAccount, 1000, '0x', '0x', { from: tokenCreator });
+ await truffleAssertions.fails(
+ this.token.transferAndCall(utils.NULL_ADDRESS, 400, '0x', { from: anAccount }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('transferAndCalls to contract', async function () {
+ await this.token.mint(anAccount, 1000, '0x', '0x', { from: tokenCreator });
- it('accept transfer only manager', async function () {
- expectThrow(this.token.acceptTransfer(anAccount, 1000));
- expectThrow(this.token.acceptTransfer(anAccount, 1000, { from: tokenCreator }));
-
- const creatorBalance = await this.token.balanceOf(tokenCreator);
- assert.equal(creatorBalance, 0);
+ let receiver = await mockERC677Receiver.new();
+ const data = '0x000001';
+ let result = await this.token.transferAndCall(receiver.address, 400, data,{ from: anAccount });
+ utils.checkRcpt(result);
- const tokenBalance = await this.token.balanceOf(this.token.address);
- assert.equal(tokenBalance, 0);
+ let eventSignature = web3.eth.abi.encodeEventSignature('Success(address,uint256,bytes)');
+ let decodedLog = web3.eth.abi.decodeLog([
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "_sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "_value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "_data",
+ "type": "bytes"
+ }
+ ], result.receipt.rawLogs[3].data, result.receipt.rawLogs[2].topics.slice(1));
+ assert.equal(result.receipt.rawLogs[3].topics[0], eventSignature);
+ assert.equal(decodedLog._sender, anAccount);
+ assert.equal(decodedLog._value, 400);
+ assert.equal(decodedLog._data, data);
- const managerBalance = await this.token.balanceOf(tokenManager);
- assert.equal(managerBalance, 0);
+ const anAccountBalance = await this.token.balanceOf(anAccount);
+ assert.equal(anAccountBalance, 600);
+
+ const anotherAccountBalance = await this.token.balanceOf(receiver.address);
+ assert.equal(anotherAccountBalance, 400);
+
+ const totalSupply = await this.token.totalSupply();
+ assert.equal(totalSupply, 1000);
+ });
+
+ it('transferAndCalls throws if receiver does not implement IERC677Receiver', async function () {
+ await this.token.mint(anAccount, 1000, '0x', '0x', { from: tokenCreator });
+
+ let receiver = await SideToken.new("SIDE", "SIDE", tokenCreator, '1');
+ await truffleAssertions.fails(
+ this.token.transferAndCall(receiver.address, 400, '0x000001',{ from: anAccount }),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 0);
-
- const totalSupply = await this.token.totalSupply();
- assert.equal(totalSupply, 0);
});
- it('transfer account to account', async function () {
- await this.token.acceptTransfer(anAccount, 1000, { from: tokenManager });
- await this.token.transfer(anotherAccount, 400, { from: anAccount });
-
- const creatorBalance = await this.token.balanceOf(tokenCreator);
- assert.equal(creatorBalance, 0);
+ describe('granularity 1000', async function () {
+ beforeEach(async function () {
+ this.granularity = '1000';
+ this.token = await SideToken.new("SIDE", "SIDE", tokenCreator, this.granularity);
+ });
+
+ it('initial state', async function () {
+ const granularity = await this.token.granularity();
+ assert.equal(granularity.toString(), this.granularity);
+ });
+
+ it('mint', async function () {
+ await this.token.mint(anAccount, this.granularity, '0x', '0x', { from: tokenCreator });
+
+ const anAccountBalance = await this.token.balanceOf(anAccount);
+ assert.equal(anAccountBalance.toString(), this.granularity);
+
+ const totalSupply = await this.token.totalSupply();
+ assert.equal(totalSupply, this.granularity);
+ });
+
+ it('mint works if less than granularity', async function () {
+ const anAccountBalance = await this.token.balanceOf(anAccount);
+ const amount = 100;
+ await this.token.mint(anAccount, amount, '0x', '0x', { from: tokenCreator });
+ const anAccountNewBalance = await this.token.balanceOf(anAccount);
+ assert.equal(Number(anAccountBalance) + amount, Number(anAccountNewBalance));
+ });
- const tokenBalance = await this.token.balanceOf(this.token.address);
- assert.equal(tokenBalance, 0);
+ it('mint throws if not multiple of granularity', async function () {
+ const anAccountBalance = await this.token.balanceOf(anAccount);
+ const amount = 1001;
+ await this.token.mint(anAccount, 1001, '0x', '0x', { from: tokenCreator });
+ const anAccountNewBalance = await this.token.balanceOf(anAccount);
+ assert.equal(Number(anAccountBalance) + amount, Number(anAccountNewBalance));
+ });
- const managerBalance = await this.token.balanceOf(tokenManager);
- assert.equal(managerBalance, 0);
+ it('transfer account to account', async function () {
+ await this.token.mint(anAccount, 10000, '0x', '0x', { from: tokenCreator });
+ await this.token.transfer(anotherAccount, 1000, { from: anAccount });
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 600);
-
- const anotherAccountBalance = await this.token.balanceOf(anotherAccount);
- assert.equal(anotherAccountBalance, 400);
+ const anAccountBalance = await this.token.balanceOf(anAccount);
+ assert.equal(anAccountBalance.toString(), '9000');
- const totalSupply = await this.token.totalSupply();
- assert.equal(totalSupply, 1000);
+ const anotherAccountBalance = await this.token.balanceOf(anotherAccount);
+ assert.equal(anotherAccountBalance.toString(), '1000');
+
+ const totalSupply = await this.token.totalSupply();
+ assert.equal(totalSupply.toString(), '10000');
+ });
+
+ it('transfer works if less than granularity', async function () {
+ const amount = 100;
+ await this.token.mint(anAccount, 10000, '0x', '0x', { from: tokenCreator });
+ balance = await this.token.balanceOf(anotherAccount);
+ await this.token.transfer(anotherAccount, amount, { from: anAccount });
+ newBalance = await this.token.balanceOf(anotherAccount);
+ assert.equal(Number(newBalance), Number(balance) + amount);
+ });
+
+ it('transfer works if not multiple of granularity', async function () {
+ const amount = 1100;
+ await this.token.mint(anAccount, 10000, '0x', '0x', { from: tokenCreator });
+ balance = await this.token.balanceOf(anotherAccount);
+ await this.token.transfer(anotherAccount, amount, { from: anAccount });
+ newBalance = await this.token.balanceOf(anotherAccount);
+ assert.equal(Number(newBalance), Number(balance) + amount);
+ });
+
+ it('burn works if not multiple of granularity', async function () {
+ const amount = 1;
+ await this.token.mint(anAccount, 1000000, '0x', '0x', { from: tokenCreator });
+ balance = await this.token.balanceOf(anAccount);
+ await this.token.burn(amount, '0x', { from: anAccount });
+ newBalance = await this.token.balanceOf(anAccount);
+ assert.equal(Number(balance) - amount, Number(newBalance));
+ });
});
- it('transfer account to manager', async function () {
- await this.token.acceptTransfer(anAccount, 1000, { from: tokenManager });
- await this.token.transfer(tokenManager, 400, { from: anAccount });
-
- const creatorBalance = await this.token.balanceOf(tokenCreator);
- assert.equal(creatorBalance, 0);
+ describe('permit', async function() {
+ beforeEach(async function () {
+ this.token = await SideToken.new("SIDE", "SIDE", tokenCreator, 1);
+ });
+
+ it('should have PERMIT_TYPEHASH', async function() {
+ const expectedTypeHash = keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)');
+ const PERMIT_TYPEHASH = await this.token.PERMIT_TYPEHASH();
+ assert.equal(PERMIT_TYPEHASH, expectedTypeHash);
+ });
+
+ it('should have domainSeparator', async function() {
+ const name = await this.token.name();
+ // Bug ganache treast chainid opcode as 1 https://github.com/trufflesuite/ganache-core/issues/451
+ const chainId = await web3.eth.getChainId();
+
+ const expectedTypeHash = keccak256(
+ web3.eth.abi.encodeParameters(
+ ['bytes32', 'bytes32', 'bytes32', 'uint256', 'address'],
+ [
+ keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
+ keccak256(name),
+ keccak256('1'),
+ chainId,
+ this.token.address
+ ]
+ )
+ )
+ const DOMAIN_SEPARATOR = await this.token.domainSeparator();
+ assert.equal(DOMAIN_SEPARATOR, expectedTypeHash);
+ });
+
+ async function getApprovalDigest(
+ token,
+ approve, //{owner: string, spender: string, value: BigNumber},
+ nonce,
+ deadline
+ ) {
+ const PERMIT_TYPEHASH = await token.PERMIT_TYPEHASH();
+ const DOMAIN_SEPARATOR = await token.domainSeparator();
+ return web3.utils.soliditySha3(
+ {t:'bytes1', v:'0x19'},
+ {t:'bytes1', v:'0x01'},
+ {t:'bytes32', v:DOMAIN_SEPARATOR},
+ {t:'bytes32', v:keccak256(
+ web3.eth.abi.encodeParameters(
+ ['bytes32', 'address', 'address', 'uint256', 'uint256', 'uint256'],
+ [PERMIT_TYPEHASH, approve.owner, approve.spender, approve.value, nonce, deadline]
+ )
+ )
+ }
+ )
+ }
- const tokenBalance = await this.token.balanceOf(this.token.address);
- assert.equal(tokenBalance, 0);
+ it('should accept signed permit', async function () {
+ const amount = '1001';
+ const accountWallet = await web3.eth.accounts.privateKeyToAccount(utils.getRandomHash());
+ await this.token.mint(accountWallet.address, amount, '0x', '0x');
- const managerBalance = await this.token.balanceOf(tokenManager);
- assert.equal(managerBalance, 0);
+ const nonce = (await this.token.nonces(accountWallet.address)).toString();
+ const deadline = Number.MAX_SAFE_INTEGER.toString();
+ const digest = await getApprovalDigest(
+ this.token,
+ { owner: accountWallet.address, spender: anotherAccount, value: amount },
+ nonce,
+ deadline
+ );
- const anAccountBalance = await this.token.balanceOf(anAccount);
- assert.equal(anAccountBalance, 600);
+ const { v, r, s } = ethUtil.ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(accountWallet.privateKey.slice(2), 'hex'));
- const totalSupply = await this.token.totalSupply();
- assert.equal(totalSupply, 600);
+ const receipt = await this.token.permit(
+ accountWallet.address,
+ anotherAccount,
+ amount,
+ deadline,
+ v,
+ r,
+ s
+ );
+
+ truffleAssertions.eventEmitted(receipt, 'Approval', (ev) => {
+ return ev.owner === accountWallet.address
+ && ev.spender === anotherAccount
+ && ev.value.toString() === amount
+ });
+
+ expect((await this.token.allowance(accountWallet.address, anotherAccount)).toString()).to.eq(amount);
+ expect((await this.token.nonces(accountWallet.address)).toString()).to.eq('1');
+ })
+
+ it('should fail invalid signature', async function () {
+ const amount = '1001';
+ const accountWallet = await web3.eth.accounts.privateKeyToAccount(utils.getRandomHash());
+ await this.token.mint(accountWallet.address, amount, '0x', '0x');
+
+ const nonce = (await this.token.nonces(accountWallet.address)).toString();
+ const deadline = Number.MAX_SAFE_INTEGER.toString();
+ const digest = await getApprovalDigest(
+ this.token,
+ { owner: accountWallet.address, spender: anotherAccount, value: amount },
+ nonce,
+ deadline
+ );
+
+ const { v, r, s } = ethUtil.ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(accountWallet.privateKey.slice(2), 'hex'));
+
+ await truffleAssertions.fails(this.token.permit(
+ accountWallet.address,
+ anotherAccount,
+ amount,
+ deadline,
+ v,
+ s,
+ r
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should fail invalid nonce', async function () {
+ const amount = '1001';
+ const accountWallet = await web3.eth.accounts.privateKeyToAccount(utils.getRandomHash());
+ await this.token.mint(accountWallet.address, amount, '0x', '0x');
+
+ const nonce = (await this.token.nonces(accountWallet.address)).toString();
+ const deadline = Number.MAX_SAFE_INTEGER.toString();
+ const digest = await getApprovalDigest(
+ this.token,
+ { owner: accountWallet.address, spender: anotherAccount, value: amount },
+ nonce,
+ deadline
+ );
+
+ const { v, r, s } = ethUtil.ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(accountWallet.privateKey.slice(2), 'hex'));
+
+ await this.token.permit(
+ accountWallet.address,
+ anotherAccount,
+ amount,
+ deadline,
+ v,
+ r,
+ s
+ );
+
+ await truffleAssertions.fails(
+ this.token.permit(
+ accountWallet.address,
+ anotherAccount,
+ amount,
+ deadline,
+ v,
+ r,
+ s
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
+
+ it('should fail expired deadline', async function () {
+ const amount = '1001';
+ const accountWallet = await web3.eth.accounts.privateKeyToAccount(utils.getRandomHash());
+ await this.token.mint(accountWallet.address, amount, '0x', '0x');
+
+ const nonce = (await this.token.nonces(accountWallet.address)).toString();
+ const deadline = '1';
+ const digest = await getApprovalDigest(
+ this.token,
+ { owner: accountWallet.address, spender: anotherAccount, value: amount },
+ nonce,
+ deadline
+ );
+
+ const { v, r, s } = ethUtil.ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(accountWallet.privateKey.slice(2), 'hex'));
+
+ await truffleAssertions.fails(this.token.permit(
+ accountWallet.address,
+ anotherAccount,
+ amount,
+ deadline,
+ v,
+ r,
+ s
+ ),
+ truffleAssertions.ErrorType.REVERT
+ );
+ });
});
+
});
diff --git a/bridge/test/utils.js b/bridge/test/utils.js
index 7d2492638..846d1c346 100644
--- a/bridge/test/utils.js
+++ b/bridge/test/utils.js
@@ -1,27 +1,211 @@
+const BN = web3.utils.BN;
-// from https://ethereum.stackexchange.com/questions/11444/web3-js-with-promisified-api
+const GAS_LIMIT = 6800000;
+const ADDRESS_LENGTH = 20;
+const HASH_LENGTH = 32;
+const randomHex = web3.utils.randomHex;
+
+const saveState = async () =>
+ new Promise((resolve) => {
+ web3.currentProvider.send(
+ {
+ jsonrpc: "2.0",
+ method: "evm_snapshot",
+ id: 0,
+ },
+ (error, res) => {
+ const result = parseInt(res.result, 0);
+ lastSnapshot = result;
+ resolve(result);
+ }
+ );
+ });
+
+const revertState = async () => {
+ await new Promise((resolve) =>
+ web3.currentProvider.send(
+ {
+ jsonrpc: "2.0",
+ method: "evm_revert",
+ params: lastSnapshot,
+ id: 0,
+ },
+ (error, res) => {
+ resolve(res.result);
+ }
+ )
+ );
+ //lastSnapshot = await saveState();
+};
+
+// from https://ethereum.stackexchange.com/questions/11444/web3-js-with-promisified-api
const promisify = (inner) =>
new Promise((resolve, reject) =>
inner((err, res) => {
- if (err) { reject(err) }
+ if (err) {
+ reject(err);
+ }
resolve(res);
})
-);
+ );
+
+function checkGas(gas) {
+ //process.stdout.write(`\x1b[36m[Gas:${gas}]\x1b[0m`);
+ assert(gas < GAS_LIMIT, "Gas used bigger than the maximum in mainnet");
+}
+
+function checkRcpt(tx) {
+ assert.equal(Number(tx.receipt.status), 1, "Should be a succesful Tx");
+ checkGas(tx.receipt.gasUsed);
+}
+
+/**
+ * @type {function}
+ * @param {{
+ * tx: string,
+ * receipt: {
+ * gasUsed: number
+ * }
+ * }} tx - is an object returned from the smartcontract tx
+ * @returns {BN} the gas used multiplied by the gas price
+ */
+const getGasUsedByTx = async (tx) => {
+ const gasUsed = new BN(tx.receipt.gasUsed);
+
+ const txWithPrice = await web3.eth.getTransaction(tx.tx);
+ const gasPrice = new BN(txWithPrice.gasPrice);
+
+ return gasUsed.mul(gasPrice);
+};
+
+/**
+ * @type {function}
+ * @param {string} address - addr to check the amount of ether
+ * @returns {BN} - the ether balance of address
+ */
+const getEtherBalance = async (address) => {
+ return new BN(await web3.eth.getBalance(address));
+};
+
+const asyncMine = async () => {
+ return new Promise((resolve, reject) => {
+ web3.currentProvider.send(
+ {
+ jsonrpc: "2.0",
+ method: "evm_mine",
+ id: new Date().getTime(),
+ },
+ (error, result) => {
+ if (error) {
+ return reject(error);
+ }
+ return resolve(result);
+ }
+ );
+ });
+};
+
+let evm_mine = async (iterations) => {
+ for (var i = 0; i < iterations; i++) {
+ await asyncMine();
+ }
+};
+
+function increaseTimestamp(web3, increase) {
+ return new Promise((resolve, reject) => {
+ web3.currentProvider.send(
+ {
+ method: "evm_increaseTime",
+ params: [increase],
+ jsonrpc: "2.0",
+ id: new Date().getTime(),
+ },
+ (error, result) => {
+ if (error) {
+ return reject(error);
+ }
+ return asyncMine().then(() => resolve(result));
+ }
+ );
+ });
+}
+
+function stripHexPrefix(hexString) {
+ if (hexString.substring(0, 2).toLowerCase() === "0x") {
+ hexString = hexString.substring(2);
+ }
+ return hexString;
+}
+
+function calculatePrefixesSuffixes(nodes) {
+ const prefixes = [];
+ const suffixes = [];
+ const ns = [];
+
+ for (let i = 0; i < nodes.length; i++) {
+ nodes[i] = stripHexPrefix(nodes[i]);
+ }
+
+ for (let k = 0, l = nodes.length; k < l; k++) {
+ if (k + 1 < l && nodes[k + 1].indexOf(nodes[k]) >= 0) {
+ continue;
+ }
+
+ ns.push(nodes[k]);
+ }
+
+ let hash = web3.utils.sha3(Buffer.from(ns[0], "hex"));
+ hash = stripHexPrefix(hash);
-async function expectThrow (promise) {
- try {
- await promise;
- } catch (error) {
- return;
+ prefixes.push("0x");
+ suffixes.push("0x");
+
+ for (let k = 1, l = ns.length; k < l; k++) {
+ const p = ns[k].indexOf(hash);
+
+ prefixes.push("0x" + ns[k].substring(0, p));
+ suffixes.push("0x" + ns[k].substring(p + hash.length));
+
+ hash = web3.utils.sha3(Buffer.from(ns[k], "hex"));
+ hash = stripHexPrefix(hash);
+ }
+ return { prefixes: prefixes, suffixes: suffixes };
+}
+
+function ascii_to_hexa(str) {
+ var arr1 = [];
+ for (var n = 0, l = str.length; n < l; n++) {
+ var hex = Number(str.charCodeAt(n)).toString(16);
+ arr1.push(hex);
}
-
- assert.fail('Expected throw not received');
+ return "0x" + arr1.join("");
+}
+
+function getRandomAddress() {
+ return randomHex(ADDRESS_LENGTH);
+}
+
+function getRandomHash() {
+ return randomHex(HASH_LENGTH);
}
module.exports = {
- promisify: promisify,
- expectThrow: expectThrow
+ getEtherBalance: getEtherBalance,
+ getGasUsedByTx: getGasUsedByTx,
+ checkGas: checkGas,
+ checkRcpt: checkRcpt,
+ evm_mine: evm_mine,
+ promisify: promisify,
+ calculatePrefixesSuffixes: calculatePrefixesSuffixes,
+ increaseTimestamp: increaseTimestamp,
+ ascii_to_hexa: ascii_to_hexa,
+ NULL_ADDRESS: "0x0000000000000000000000000000000000000000",
+ NULL_HASH:
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ saveState: saveState,
+ revertState: revertState,
+ getRandomAddress: getRandomAddress,
+ getRandomHash: getRandomHash,
};
-
diff --git a/bridge/truffle-config.js b/bridge/truffle-config.js
deleted file mode 100644
index fd3134a33..000000000
--- a/bridge/truffle-config.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * NB: since truffle-hdwallet-provider 0.0.5 you must wrap HDWallet providers in a
- * function when declaring them. Failure to do so will cause commands to hang. ex:
- * ```
- * mainnet: {
- * provider: function() {
- * return new HDWalletProvider(mnemonic, 'https://mainnet.infura.io/')
- * },
- * network_id: '1',
- * gas: 4500000,
- * gasPrice: 10000000000,
- * },
- */
-
-module.exports = {
- // See
- // to customize your Truffle configuration!met
- networks: {
- development: {
- host: "127.0.0.1",
- port: 8545,
- network_id: "*" // Match any network id
- },
- regtest: {
- host: "127.0.0.1",
- port: 4444,
- network_id: "*" // Match any network id
- },
- }
-};
\ No newline at end of file
diff --git a/bridge/waffle.json b/bridge/waffle.json
new file mode 100644
index 000000000..1c452509f
--- /dev/null
+++ b/bridge/waffle.json
@@ -0,0 +1,3 @@
+{
+ "flattenOutputDirectory": "./flatten"
+}
\ No newline at end of file
diff --git a/crytic-config.json b/crytic-config.json
new file mode 100644
index 000000000..e20cbb0e9
--- /dev/null
+++ b/crytic-config.json
@@ -0,0 +1,3 @@
+{
+ "cwd": "bridge"
+}
\ No newline at end of file
diff --git a/dapps/demo/.gitignore b/dapps/demo/.gitignore
deleted file mode 100644
index b512c09d4..000000000
--- a/dapps/demo/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-node_modules
\ No newline at end of file
diff --git a/dapps/demo/README.md b/dapps/demo/README.md
deleted file mode 100644
index 21ce0d6d8..000000000
--- a/dapps/demo/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Demo Dapp
-
-TBD
-
-
diff --git a/dapps/demo/bs-config.json b/dapps/demo/bs-config.json
deleted file mode 100644
index 1509c5c2c..000000000
--- a/dapps/demo/bs-config.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "server": {
- "baseDir": ["./src", "../../bridge"]
- }
-}
diff --git a/dapps/demo/package-lock.json b/dapps/demo/package-lock.json
deleted file mode 100644
index d6fd86203..000000000
--- a/dapps/demo/package-lock.json
+++ /dev/null
@@ -1,3193 +0,0 @@
-{
- "name": "demodapp",
- "version": "1.0.0",
- "lockfileVersion": 1,
- "requires": true,
- "dependencies": {
- "accepts": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
- "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
- "requires": {
- "mime-types": "2.1.21",
- "negotiator": "0.6.1"
- }
- },
- "after": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
- "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
- },
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
- },
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
- },
- "anymatch": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
- "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
- "requires": {
- "micromatch": "3.1.10",
- "normalize-path": "2.1.1"
- },
- "dependencies": {
- "micromatch": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
- "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
- "requires": {
- "arr-diff": "4.0.0",
- "array-unique": "0.3.2",
- "braces": "2.3.2",
- "define-property": "2.0.2",
- "extend-shallow": "3.0.2",
- "extglob": "2.0.4",
- "fragment-cache": "0.2.1",
- "kind-of": "6.0.2",
- "nanomatch": "1.2.13",
- "object.pick": "1.3.0",
- "regex-not": "1.0.2",
- "snapdragon": "0.8.2",
- "to-regex": "3.0.2"
- }
- }
- }
- },
- "arr-diff": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
- "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
- },
- "arr-flatten": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
- "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
- },
- "arr-union": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
- "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
- },
- "array-unique": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
- "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
- },
- "arraybuffer.slice": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
- "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog=="
- },
- "assign-symbols": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
- "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
- },
- "async": {
- "version": "1.5.2",
- "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz",
- "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
- },
- "async-each": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
- "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0="
- },
- "async-each-series": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz",
- "integrity": "sha1-dhfBkXQB/Yykooqtzj266Yr+tDI="
- },
- "async-limiter": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
- "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
- },
- "atob": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
- "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
- },
- "axios": {
- "version": "0.17.1",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.17.1.tgz",
- "integrity": "sha1-LY4+XQvb1zJ/kbyBT1xXZg+Bgk0=",
- "requires": {
- "follow-redirects": "1.5.9",
- "is-buffer": "1.1.6"
- }
- },
- "backo2": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
- "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
- },
- "balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
- },
- "base": {
- "version": "0.11.2",
- "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
- "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
- "requires": {
- "cache-base": "1.0.1",
- "class-utils": "0.3.6",
- "component-emitter": "1.2.1",
- "define-property": "1.0.0",
- "isobject": "3.0.1",
- "mixin-deep": "1.3.1",
- "pascalcase": "0.1.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "requires": {
- "is-descriptor": "1.0.2"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "requires": {
- "kind-of": "6.0.2"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "requires": {
- "kind-of": "6.0.2"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "requires": {
- "is-accessor-descriptor": "1.0.0",
- "is-data-descriptor": "1.0.0",
- "kind-of": "6.0.2"
- }
- }
- }
- },
- "base64-arraybuffer": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
- "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg="
- },
- "base64id": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
- "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY="
- },
- "batch": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
- "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY="
- },
- "better-assert": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
- "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
- "requires": {
- "callsite": "1.0.0"
- }
- },
- "binary-extensions": {
- "version": "1.12.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz",
- "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg=="
- },
- "blob": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
- "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig=="
- },
- "brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "requires": {
- "balanced-match": "1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "braces": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
- "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
- "requires": {
- "arr-flatten": "1.1.0",
- "array-unique": "0.3.2",
- "extend-shallow": "2.0.1",
- "fill-range": "4.0.0",
- "isobject": "3.0.1",
- "repeat-element": "1.1.3",
- "snapdragon": "0.8.2",
- "snapdragon-node": "2.1.1",
- "split-string": "3.1.0",
- "to-regex": "3.0.2"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "0.1.1"
- }
- }
- }
- },
- "browser-sync": {
- "version": "2.26.3",
- "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.26.3.tgz",
- "integrity": "sha512-VLzpjCA4uXqfzkwqWtMM6hvPm2PNHp2RcmzBXcbi6C9WpkUhhFb8SVAr4CFrCsFxDg+oY6HalOjn8F+egyvhag==",
- "requires": {
- "browser-sync-client": "2.26.2",
- "browser-sync-ui": "2.26.2",
- "bs-recipes": "1.3.4",
- "bs-snippet-injector": "2.0.1",
- "chokidar": "2.0.4",
- "connect": "3.6.6",
- "connect-history-api-fallback": "1.5.0",
- "dev-ip": "1.0.1",
- "easy-extender": "2.3.4",
- "eazy-logger": "3.0.2",
- "etag": "1.8.1",
- "fresh": "0.5.2",
- "fs-extra": "3.0.1",
- "http-proxy": "1.15.2",
- "immutable": "3.8.2",
- "localtunnel": "1.9.1",
- "micromatch": "2.3.11",
- "opn": "5.3.0",
- "portscanner": "2.1.1",
- "qs": "6.2.3",
- "raw-body": "2.3.3",
- "resp-modifier": "6.0.2",
- "rx": "4.1.0",
- "send": "0.16.2",
- "serve-index": "1.9.1",
- "serve-static": "1.13.2",
- "server-destroy": "1.0.1",
- "socket.io": "2.1.1",
- "ua-parser-js": "0.7.17",
- "yargs": "6.4.0"
- }
- },
- "browser-sync-client": {
- "version": "2.26.2",
- "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.26.2.tgz",
- "integrity": "sha512-FEuVJD41fI24HJ30XOT2RyF5WcnEtdJhhTqeyDlnMk/8Ox9MZw109rvk9pdfRWye4soZLe+xcAo9tHSMxvgAdw==",
- "requires": {
- "etag": "1.8.1",
- "fresh": "0.5.2",
- "mitt": "1.1.3",
- "rxjs": "5.5.12"
- }
- },
- "browser-sync-ui": {
- "version": "2.26.2",
- "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.26.2.tgz",
- "integrity": "sha512-LF7GMWo8ELOE0eAlxuRCfnGQT1ZxKP9flCfGgZdXFc6BwmoqaJHlYe7MmVvykKkXjolRXTz8ztXAKGVqNwJ3EQ==",
- "requires": {
- "async-each-series": "0.1.1",
- "connect-history-api-fallback": "1.5.0",
- "immutable": "3.8.2",
- "server-destroy": "1.0.1",
- "socket.io-client": "2.1.1",
- "stream-throttle": "0.1.3"
- }
- },
- "bs-recipes": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz",
- "integrity": "sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU="
- },
- "bs-snippet-injector": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz",
- "integrity": "sha1-YbU5PxH1JVntEgaTEANDtu2wTdU="
- },
- "builtin-modules": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
- "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8="
- },
- "bytes": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
- "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
- },
- "cache-base": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
- "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
- "requires": {
- "collection-visit": "1.0.0",
- "component-emitter": "1.2.1",
- "get-value": "2.0.6",
- "has-value": "1.0.0",
- "isobject": "3.0.1",
- "set-value": "2.0.0",
- "to-object-path": "0.3.0",
- "union-value": "1.0.0",
- "unset-value": "1.0.0"
- }
- },
- "callsite": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
- "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA="
- },
- "camelcase": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
- "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
- },
- "chalk": {
- "version": "1.1.3",
- "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "requires": {
- "ansi-styles": "2.2.1",
- "escape-string-regexp": "1.0.5",
- "has-ansi": "2.0.0",
- "strip-ansi": "3.0.1",
- "supports-color": "2.0.0"
- }
- },
- "chokidar": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz",
- "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==",
- "requires": {
- "anymatch": "2.0.0",
- "async-each": "1.0.1",
- "braces": "2.3.2",
- "fsevents": "1.2.4",
- "glob-parent": "3.1.0",
- "inherits": "2.0.3",
- "is-binary-path": "1.0.1",
- "is-glob": "4.0.0",
- "lodash.debounce": "4.0.8",
- "normalize-path": "2.1.1",
- "path-is-absolute": "1.0.1",
- "readdirp": "2.2.1",
- "upath": "1.1.0"
- }
- },
- "class-utils": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
- "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
- "requires": {
- "arr-union": "3.1.0",
- "define-property": "0.2.5",
- "isobject": "3.0.1",
- "static-extend": "0.1.2"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "requires": {
- "is-descriptor": "0.1.6"
- }
- }
- }
- },
- "cliui": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
- "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
- "requires": {
- "string-width": "1.0.2",
- "strip-ansi": "3.0.1",
- "wrap-ansi": "2.1.0"
- }
- },
- "code-point-at": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
- "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
- },
- "collection-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
- "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
- "requires": {
- "map-visit": "1.0.0",
- "object-visit": "1.0.1"
- }
- },
- "commander": {
- "version": "2.19.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
- "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg=="
- },
- "component-bind": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
- "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
- },
- "component-emitter": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
- "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
- },
- "component-inherit": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
- "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM="
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
- },
- "connect": {
- "version": "3.6.6",
- "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
- "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=",
- "requires": {
- "debug": "2.6.9",
- "finalhandler": "1.1.0",
- "parseurl": "1.3.2",
- "utils-merge": "1.0.1"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "connect-history-api-fallback": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz",
- "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo="
- },
- "connect-logger": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/connect-logger/-/connect-logger-0.0.1.tgz",
- "integrity": "sha1-TZmZeKHSC7RgjnzUNNdBZSJVF0s=",
- "requires": {
- "moment": "2.22.2"
- }
- },
- "cookie": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
- "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
- },
- "copy-descriptor": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
- "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
- },
- "core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
- },
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
- },
- "decode-uri-component": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
- "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
- },
- "define-property": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
- "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
- "requires": {
- "is-descriptor": "1.0.2",
- "isobject": "3.0.1"
- },
- "dependencies": {
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "requires": {
- "kind-of": "6.0.2"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "requires": {
- "kind-of": "6.0.2"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "requires": {
- "is-accessor-descriptor": "1.0.0",
- "is-data-descriptor": "1.0.0",
- "kind-of": "6.0.2"
- }
- }
- }
- },
- "depd": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
- "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
- },
- "destroy": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
- "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
- },
- "dev-ip": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz",
- "integrity": "sha1-p2o+0YVb56ASu4rBbLgPPADcKPA="
- },
- "easy-extender": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz",
- "integrity": "sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==",
- "requires": {
- "lodash": "4.17.11"
- }
- },
- "eazy-logger": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.0.2.tgz",
- "integrity": "sha1-oyWqXlPROiIliJsqxBE7K5Y29Pw=",
- "requires": {
- "tfunk": "3.1.0"
- }
- },
- "ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
- },
- "encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
- },
- "engine.io": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz",
- "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==",
- "requires": {
- "accepts": "1.3.5",
- "base64id": "1.0.0",
- "cookie": "0.3.1",
- "debug": "3.1.0",
- "engine.io-parser": "2.1.3",
- "ws": "3.3.3"
- }
- },
- "engine.io-client": {
- "version": "3.2.1",
- "resolved": "http://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz",
- "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==",
- "requires": {
- "component-emitter": "1.2.1",
- "component-inherit": "0.0.3",
- "debug": "3.1.0",
- "engine.io-parser": "2.1.3",
- "has-cors": "1.1.0",
- "indexof": "0.0.1",
- "parseqs": "0.0.5",
- "parseuri": "0.0.5",
- "ws": "3.3.3",
- "xmlhttprequest-ssl": "1.5.5",
- "yeast": "0.1.2"
- }
- },
- "engine.io-parser": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz",
- "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==",
- "requires": {
- "after": "0.8.2",
- "arraybuffer.slice": "0.0.7",
- "base64-arraybuffer": "0.1.5",
- "blob": "0.0.5",
- "has-binary2": "1.0.3"
- }
- },
- "error-ex": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "requires": {
- "is-arrayish": "0.2.1"
- }
- },
- "escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
- },
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
- },
- "etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
- },
- "eventemitter3": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz",
- "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg="
- },
- "expand-brackets": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
- "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
- "requires": {
- "debug": "2.6.9",
- "define-property": "0.2.5",
- "extend-shallow": "2.0.1",
- "posix-character-classes": "0.1.1",
- "regex-not": "1.0.2",
- "snapdragon": "0.8.2",
- "to-regex": "3.0.2"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "requires": {
- "is-descriptor": "0.1.6"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "0.1.1"
- }
- }
- }
- },
- "expand-range": {
- "version": "1.8.2",
- "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
- "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
- "requires": {
- "fill-range": "2.2.4"
- },
- "dependencies": {
- "fill-range": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz",
- "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==",
- "requires": {
- "is-number": "2.1.0",
- "isobject": "2.1.0",
- "randomatic": "3.1.1",
- "repeat-element": "1.1.3",
- "repeat-string": "1.6.1"
- }
- },
- "is-number": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
- "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
- "requires": {
- "kind-of": "3.2.2"
- }
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "isobject": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
- "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
- "requires": {
- "isarray": "1.0.0"
- }
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "1.1.6"
- }
- }
- }
- },
- "extend-shallow": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
- "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
- "requires": {
- "assign-symbols": "1.0.0",
- "is-extendable": "1.0.1"
- },
- "dependencies": {
- "is-extendable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
- "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
- "requires": {
- "is-plain-object": "2.0.4"
- }
- }
- }
- },
- "extglob": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
- "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
- "requires": {
- "array-unique": "0.3.2",
- "define-property": "1.0.0",
- "expand-brackets": "2.1.4",
- "extend-shallow": "2.0.1",
- "fragment-cache": "0.2.1",
- "regex-not": "1.0.2",
- "snapdragon": "0.8.2",
- "to-regex": "3.0.2"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "requires": {
- "is-descriptor": "1.0.2"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "0.1.1"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "requires": {
- "kind-of": "6.0.2"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "requires": {
- "kind-of": "6.0.2"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "requires": {
- "is-accessor-descriptor": "1.0.0",
- "is-data-descriptor": "1.0.0",
- "kind-of": "6.0.2"
- }
- }
- }
- },
- "filename-regex": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
- "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY="
- },
- "fill-range": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
- "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
- "requires": {
- "extend-shallow": "2.0.1",
- "is-number": "3.0.0",
- "repeat-string": "1.6.1",
- "to-regex-range": "2.1.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "0.1.1"
- }
- }
- }
- },
- "finalhandler": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
- "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
- "requires": {
- "debug": "2.6.9",
- "encodeurl": "1.0.2",
- "escape-html": "1.0.3",
- "on-finished": "2.3.0",
- "parseurl": "1.3.2",
- "statuses": "1.3.1",
- "unpipe": "1.0.0"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "find-up": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
- "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
- "requires": {
- "path-exists": "2.1.0",
- "pinkie-promise": "2.0.1"
- }
- },
- "follow-redirects": {
- "version": "1.5.9",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.9.tgz",
- "integrity": "sha512-Bh65EZI/RU8nx0wbYF9shkFZlqLP+6WT/5FnA3cE/djNSuKNHJEinGGZgu/cQEkeeb2GdFOgenAmn8qaqYke2w==",
- "requires": {
- "debug": "3.1.0"
- }
- },
- "for-in": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
- "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
- },
- "for-own": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
- "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
- "requires": {
- "for-in": "1.0.2"
- }
- },
- "fragment-cache": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
- "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
- "requires": {
- "map-cache": "0.2.2"
- }
- },
- "fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
- },
- "fs-extra": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz",
- "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=",
- "requires": {
- "graceful-fs": "4.1.15",
- "jsonfile": "3.0.1",
- "universalify": "0.1.2"
- }
- },
- "fsevents": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz",
- "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==",
- "optional": true,
- "requires": {
- "nan": "2.11.1",
- "node-pre-gyp": "0.10.0"
- },
- "dependencies": {
- "abbrev": {
- "version": "1.1.1",
- "bundled": true,
- "optional": true
- },
- "ansi-regex": {
- "version": "2.1.1",
- "bundled": true
- },
- "aproba": {
- "version": "1.2.0",
- "bundled": true,
- "optional": true
- },
- "are-we-there-yet": {
- "version": "1.1.4",
- "bundled": true,
- "optional": true,
- "requires": {
- "delegates": "1.0.0",
- "readable-stream": "2.3.6"
- }
- },
- "balanced-match": {
- "version": "1.0.0",
- "bundled": true
- },
- "brace-expansion": {
- "version": "1.1.11",
- "bundled": true,
- "requires": {
- "balanced-match": "1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "chownr": {
- "version": "1.0.1",
- "bundled": true,
- "optional": true
- },
- "code-point-at": {
- "version": "1.1.0",
- "bundled": true
- },
- "concat-map": {
- "version": "0.0.1",
- "bundled": true
- },
- "console-control-strings": {
- "version": "1.1.0",
- "bundled": true
- },
- "core-util-is": {
- "version": "1.0.2",
- "bundled": true,
- "optional": true
- },
- "debug": {
- "version": "2.6.9",
- "bundled": true,
- "optional": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "deep-extend": {
- "version": "0.5.1",
- "bundled": true,
- "optional": true
- },
- "delegates": {
- "version": "1.0.0",
- "bundled": true,
- "optional": true
- },
- "detect-libc": {
- "version": "1.0.3",
- "bundled": true,
- "optional": true
- },
- "fs-minipass": {
- "version": "1.2.5",
- "bundled": true,
- "optional": true,
- "requires": {
- "minipass": "2.2.4"
- }
- },
- "fs.realpath": {
- "version": "1.0.0",
- "bundled": true,
- "optional": true
- },
- "gauge": {
- "version": "2.7.4",
- "bundled": true,
- "optional": true,
- "requires": {
- "aproba": "1.2.0",
- "console-control-strings": "1.1.0",
- "has-unicode": "2.0.1",
- "object-assign": "4.1.1",
- "signal-exit": "3.0.2",
- "string-width": "1.0.2",
- "strip-ansi": "3.0.1",
- "wide-align": "1.1.2"
- }
- },
- "glob": {
- "version": "7.1.2",
- "bundled": true,
- "optional": true,
- "requires": {
- "fs.realpath": "1.0.0",
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "3.0.4",
- "once": "1.4.0",
- "path-is-absolute": "1.0.1"
- }
- },
- "has-unicode": {
- "version": "2.0.1",
- "bundled": true,
- "optional": true
- },
- "iconv-lite": {
- "version": "0.4.21",
- "bundled": true,
- "optional": true,
- "requires": {
- "safer-buffer": "2.1.2"
- }
- },
- "ignore-walk": {
- "version": "3.0.1",
- "bundled": true,
- "optional": true,
- "requires": {
- "minimatch": "3.0.4"
- }
- },
- "inflight": {
- "version": "1.0.6",
- "bundled": true,
- "optional": true,
- "requires": {
- "once": "1.4.0",
- "wrappy": "1.0.2"
- }
- },
- "inherits": {
- "version": "2.0.3",
- "bundled": true
- },
- "ini": {
- "version": "1.3.5",
- "bundled": true,
- "optional": true
- },
- "is-fullwidth-code-point": {
- "version": "1.0.0",
- "bundled": true,
- "requires": {
- "number-is-nan": "1.0.1"
- }
- },
- "isarray": {
- "version": "1.0.0",
- "bundled": true,
- "optional": true
- },
- "minimatch": {
- "version": "3.0.4",
- "bundled": true,
- "requires": {
- "brace-expansion": "1.1.11"
- }
- },
- "minimist": {
- "version": "0.0.8",
- "bundled": true
- },
- "minipass": {
- "version": "2.2.4",
- "bundled": true,
- "requires": {
- "safe-buffer": "5.1.1",
- "yallist": "3.0.2"
- }
- },
- "minizlib": {
- "version": "1.1.0",
- "bundled": true,
- "optional": true,
- "requires": {
- "minipass": "2.2.4"
- }
- },
- "mkdirp": {
- "version": "0.5.1",
- "bundled": true,
- "requires": {
- "minimist": "0.0.8"
- }
- },
- "ms": {
- "version": "2.0.0",
- "bundled": true,
- "optional": true
- },
- "needle": {
- "version": "2.2.0",
- "bundled": true,
- "optional": true,
- "requires": {
- "debug": "2.6.9",
- "iconv-lite": "0.4.21",
- "sax": "1.2.4"
- }
- },
- "node-pre-gyp": {
- "version": "0.10.0",
- "bundled": true,
- "optional": true,
- "requires": {
- "detect-libc": "1.0.3",
- "mkdirp": "0.5.1",
- "needle": "2.2.0",
- "nopt": "4.0.1",
- "npm-packlist": "1.1.10",
- "npmlog": "4.1.2",
- "rc": "1.2.7",
- "rimraf": "2.6.2",
- "semver": "5.5.0",
- "tar": "4.4.1"
- }
- },
- "nopt": {
- "version": "4.0.1",
- "bundled": true,
- "optional": true,
- "requires": {
- "abbrev": "1.1.1",
- "osenv": "0.1.5"
- }
- },
- "npm-bundled": {
- "version": "1.0.3",
- "bundled": true,
- "optional": true
- },
- "npm-packlist": {
- "version": "1.1.10",
- "bundled": true,
- "optional": true,
- "requires": {
- "ignore-walk": "3.0.1",
- "npm-bundled": "1.0.3"
- }
- },
- "npmlog": {
- "version": "4.1.2",
- "bundled": true,
- "optional": true,
- "requires": {
- "are-we-there-yet": "1.1.4",
- "console-control-strings": "1.1.0",
- "gauge": "2.7.4",
- "set-blocking": "2.0.0"
- }
- },
- "number-is-nan": {
- "version": "1.0.1",
- "bundled": true
- },
- "object-assign": {
- "version": "4.1.1",
- "bundled": true,
- "optional": true
- },
- "once": {
- "version": "1.4.0",
- "bundled": true,
- "requires": {
- "wrappy": "1.0.2"
- }
- },
- "os-homedir": {
- "version": "1.0.2",
- "bundled": true,
- "optional": true
- },
- "os-tmpdir": {
- "version": "1.0.2",
- "bundled": true,
- "optional": true
- },
- "osenv": {
- "version": "0.1.5",
- "bundled": true,
- "optional": true,
- "requires": {
- "os-homedir": "1.0.2",
- "os-tmpdir": "1.0.2"
- }
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "bundled": true,
- "optional": true
- },
- "process-nextick-args": {
- "version": "2.0.0",
- "bundled": true,
- "optional": true
- },
- "rc": {
- "version": "1.2.7",
- "bundled": true,
- "optional": true,
- "requires": {
- "deep-extend": "0.5.1",
- "ini": "1.3.5",
- "minimist": "1.2.0",
- "strip-json-comments": "2.0.1"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "bundled": true,
- "optional": true
- }
- }
- },
- "readable-stream": {
- "version": "2.3.6",
- "bundled": true,
- "optional": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "2.0.0",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.1.1",
- "util-deprecate": "1.0.2"
- }
- },
- "rimraf": {
- "version": "2.6.2",
- "bundled": true,
- "optional": true,
- "requires": {
- "glob": "7.1.2"
- }
- },
- "safe-buffer": {
- "version": "5.1.1",
- "bundled": true
- },
- "safer-buffer": {
- "version": "2.1.2",
- "bundled": true,
- "optional": true
- },
- "sax": {
- "version": "1.2.4",
- "bundled": true,
- "optional": true
- },
- "semver": {
- "version": "5.5.0",
- "bundled": true,
- "optional": true
- },
- "set-blocking": {
- "version": "2.0.0",
- "bundled": true,
- "optional": true
- },
- "signal-exit": {
- "version": "3.0.2",
- "bundled": true,
- "optional": true
- },
- "string-width": {
- "version": "1.0.2",
- "bundled": true,
- "requires": {
- "code-point-at": "1.1.0",
- "is-fullwidth-code-point": "1.0.0",
- "strip-ansi": "3.0.1"
- }
- },
- "string_decoder": {
- "version": "1.1.1",
- "bundled": true,
- "optional": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "bundled": true,
- "requires": {
- "ansi-regex": "2.1.1"
- }
- },
- "strip-json-comments": {
- "version": "2.0.1",
- "bundled": true,
- "optional": true
- },
- "tar": {
- "version": "4.4.1",
- "bundled": true,
- "optional": true,
- "requires": {
- "chownr": "1.0.1",
- "fs-minipass": "1.2.5",
- "minipass": "2.2.4",
- "minizlib": "1.1.0",
- "mkdirp": "0.5.1",
- "safe-buffer": "5.1.1",
- "yallist": "3.0.2"
- }
- },
- "util-deprecate": {
- "version": "1.0.2",
- "bundled": true,
- "optional": true
- },
- "wide-align": {
- "version": "1.1.2",
- "bundled": true,
- "optional": true,
- "requires": {
- "string-width": "1.0.2"
- }
- },
- "wrappy": {
- "version": "1.0.2",
- "bundled": true
- },
- "yallist": {
- "version": "3.0.2",
- "bundled": true
- }
- }
- },
- "get-caller-file": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
- "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w=="
- },
- "get-value": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
- "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
- },
- "glob-base": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
- "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
- "requires": {
- "glob-parent": "2.0.0",
- "is-glob": "2.0.1"
- },
- "dependencies": {
- "glob-parent": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
- "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
- "requires": {
- "is-glob": "2.0.1"
- }
- },
- "is-extglob": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
- "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
- },
- "is-glob": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
- "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
- "requires": {
- "is-extglob": "1.0.0"
- }
- }
- }
- },
- "glob-parent": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
- "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
- "requires": {
- "is-glob": "3.1.0",
- "path-dirname": "1.0.2"
- },
- "dependencies": {
- "is-glob": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
- "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
- "requires": {
- "is-extglob": "2.1.1"
- }
- }
- }
- },
- "graceful-fs": {
- "version": "4.1.15",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
- "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA=="
- },
- "has-ansi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
- "requires": {
- "ansi-regex": "2.1.1"
- }
- },
- "has-binary2": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
- "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
- "requires": {
- "isarray": "2.0.1"
- }
- },
- "has-cors": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
- "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
- },
- "has-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
- "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
- "requires": {
- "get-value": "2.0.6",
- "has-values": "1.0.0",
- "isobject": "3.0.1"
- }
- },
- "has-values": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
- "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
- "requires": {
- "is-number": "3.0.0",
- "kind-of": "4.0.0"
- },
- "dependencies": {
- "kind-of": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
- "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
- "requires": {
- "is-buffer": "1.1.6"
- }
- }
- }
- },
- "hosted-git-info": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
- "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w=="
- },
- "http-errors": {
- "version": "1.6.3",
- "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
- "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
- "requires": {
- "depd": "1.1.2",
- "inherits": "2.0.3",
- "setprototypeof": "1.1.0",
- "statuses": "1.5.0"
- },
- "dependencies": {
- "statuses": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
- "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
- }
- }
- },
- "http-proxy": {
- "version": "1.15.2",
- "resolved": "http://registry.npmjs.org/http-proxy/-/http-proxy-1.15.2.tgz",
- "integrity": "sha1-ZC/cr/5S00SNK9o7AHnpQJBk2jE=",
- "requires": {
- "eventemitter3": "1.2.0",
- "requires-port": "1.0.0"
- }
- },
- "iconv-lite": {
- "version": "0.4.23",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
- "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
- "requires": {
- "safer-buffer": "2.1.2"
- }
- },
- "immutable": {
- "version": "3.8.2",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz",
- "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM="
- },
- "indexof": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
- "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
- },
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
- },
- "invert-kv": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
- "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
- },
- "is-accessor-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
- "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
- "requires": {
- "kind-of": "3.2.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "1.1.6"
- }
- }
- }
- },
- "is-arrayish": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
- },
- "is-binary-path": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
- "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
- "requires": {
- "binary-extensions": "1.12.0"
- }
- },
- "is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
- },
- "is-builtin-module": {
- "version": "1.0.0",
- "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
- "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
- "requires": {
- "builtin-modules": "1.1.1"
- }
- },
- "is-data-descriptor": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
- "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
- "requires": {
- "kind-of": "3.2.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "1.1.6"
- }
- }
- }
- },
- "is-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
- "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
- "requires": {
- "is-accessor-descriptor": "0.1.6",
- "is-data-descriptor": "0.1.4",
- "kind-of": "5.1.0"
- },
- "dependencies": {
- "kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
- }
- }
- },
- "is-dotfile": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
- "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE="
- },
- "is-equal-shallow": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
- "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
- "requires": {
- "is-primitive": "2.0.0"
- }
- },
- "is-extendable": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
- "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
- },
- "is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
- },
- "is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
- "requires": {
- "number-is-nan": "1.0.1"
- }
- },
- "is-glob": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
- "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
- "requires": {
- "is-extglob": "2.1.1"
- }
- },
- "is-number": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
- "requires": {
- "kind-of": "3.2.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "1.1.6"
- }
- }
- }
- },
- "is-number-like": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz",
- "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==",
- "requires": {
- "lodash.isfinite": "3.3.2"
- }
- },
- "is-plain-object": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
- "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
- "requires": {
- "isobject": "3.0.1"
- }
- },
- "is-posix-bracket": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
- "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q="
- },
- "is-primitive": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
- "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU="
- },
- "is-utf8": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
- "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
- },
- "is-windows": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
- "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
- },
- "is-wsl": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
- "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0="
- },
- "isarray": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
- "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
- },
- "isobject": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
- },
- "jsonfile": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz",
- "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=",
- "requires": {
- "graceful-fs": "4.1.15"
- }
- },
- "kind-of": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
- "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
- },
- "lcid": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
- "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
- "requires": {
- "invert-kv": "1.0.0"
- }
- },
- "limiter": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.3.tgz",
- "integrity": "sha512-zrycnIMsLw/3ZxTbW7HCez56rcFGecWTx5OZNplzcXUUmJLmoYArC6qdJzmAN5BWiNXGcpjhF9RQ1HSv5zebEw=="
- },
- "lite-server": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/lite-server/-/lite-server-2.4.0.tgz",
- "integrity": "sha512-Vo06tHpXrqm37i6T7tVdq5PSbrFmvQRw64+dlFXdh1tltv6KCvpE+xzXz2+x6KWJ8ja+GgwSy4P13GUWyhaDHQ==",
- "requires": {
- "browser-sync": "2.26.3",
- "connect-history-api-fallback": "1.5.0",
- "connect-logger": "0.0.1",
- "lodash": "4.17.11",
- "minimist": "1.2.0"
- }
- },
- "load-json-file": {
- "version": "1.1.0",
- "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
- "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
- "requires": {
- "graceful-fs": "4.1.15",
- "parse-json": "2.2.0",
- "pify": "2.3.0",
- "pinkie-promise": "2.0.1",
- "strip-bom": "2.0.0"
- }
- },
- "localtunnel": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.9.1.tgz",
- "integrity": "sha512-HWrhOslklDvxgOGFLxi6fQVnvpl6XdX4sPscfqMZkzi3gtt9V7LKBWYvNUcpHSVvjwCQ6xzXacVvICNbNcyPnQ==",
- "requires": {
- "axios": "0.17.1",
- "debug": "2.6.9",
- "openurl": "1.1.1",
- "yargs": "6.6.0"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "yargs": {
- "version": "6.6.0",
- "resolved": "http://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz",
- "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=",
- "requires": {
- "camelcase": "3.0.0",
- "cliui": "3.2.0",
- "decamelize": "1.2.0",
- "get-caller-file": "1.0.3",
- "os-locale": "1.4.0",
- "read-pkg-up": "1.0.1",
- "require-directory": "2.1.1",
- "require-main-filename": "1.0.1",
- "set-blocking": "2.0.0",
- "string-width": "1.0.2",
- "which-module": "1.0.0",
- "y18n": "3.2.1",
- "yargs-parser": "4.2.1"
- }
- }
- }
- },
- "lodash": {
- "version": "4.17.11",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
- "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
- },
- "lodash.debounce": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
- "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
- },
- "lodash.isfinite": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz",
- "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M="
- },
- "map-cache": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
- "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8="
- },
- "map-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
- "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
- "requires": {
- "object-visit": "1.0.1"
- }
- },
- "math-random": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz",
- "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w="
- },
- "micromatch": {
- "version": "2.3.11",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
- "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
- "requires": {
- "arr-diff": "2.0.0",
- "array-unique": "0.2.1",
- "braces": "1.8.5",
- "expand-brackets": "0.1.5",
- "extglob": "0.3.2",
- "filename-regex": "2.0.1",
- "is-extglob": "1.0.0",
- "is-glob": "2.0.1",
- "kind-of": "3.2.2",
- "normalize-path": "2.1.1",
- "object.omit": "2.0.1",
- "parse-glob": "3.0.4",
- "regex-cache": "0.4.4"
- },
- "dependencies": {
- "arr-diff": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
- "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
- "requires": {
- "arr-flatten": "1.1.0"
- }
- },
- "array-unique": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
- "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM="
- },
- "braces": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
- "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
- "requires": {
- "expand-range": "1.8.2",
- "preserve": "0.2.0",
- "repeat-element": "1.1.3"
- }
- },
- "expand-brackets": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
- "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
- "requires": {
- "is-posix-bracket": "0.1.1"
- }
- },
- "extglob": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
- "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
- "requires": {
- "is-extglob": "1.0.0"
- }
- },
- "is-extglob": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
- "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
- },
- "is-glob": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
- "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
- "requires": {
- "is-extglob": "1.0.0"
- }
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "1.1.6"
- }
- }
- }
- },
- "mime": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
- "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
- },
- "mime-db": {
- "version": "1.37.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
- "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg=="
- },
- "mime-types": {
- "version": "2.1.21",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
- "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
- "requires": {
- "mime-db": "1.37.0"
- }
- },
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "requires": {
- "brace-expansion": "1.1.11"
- }
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
- },
- "mitt": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.1.3.tgz",
- "integrity": "sha512-mUDCnVNsAi+eD6qA0HkRkwYczbLHJ49z17BGe2PYRhZL4wpZUFZGJHU7/5tmvohoma+Hdn0Vh/oJTiPEmgSruA=="
- },
- "mixin-deep": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
- "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
- "requires": {
- "for-in": "1.0.2",
- "is-extendable": "1.0.1"
- },
- "dependencies": {
- "is-extendable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
- "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
- "requires": {
- "is-plain-object": "2.0.4"
- }
- }
- }
- },
- "moment": {
- "version": "2.22.2",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz",
- "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y="
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- },
- "nan": {
- "version": "2.11.1",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz",
- "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==",
- "optional": true
- },
- "nanomatch": {
- "version": "1.2.13",
- "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
- "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
- "requires": {
- "arr-diff": "4.0.0",
- "array-unique": "0.3.2",
- "define-property": "2.0.2",
- "extend-shallow": "3.0.2",
- "fragment-cache": "0.2.1",
- "is-windows": "1.0.2",
- "kind-of": "6.0.2",
- "object.pick": "1.3.0",
- "regex-not": "1.0.2",
- "snapdragon": "0.8.2",
- "to-regex": "3.0.2"
- }
- },
- "negotiator": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
- "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
- },
- "normalize-package-data": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
- "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
- "requires": {
- "hosted-git-info": "2.7.1",
- "is-builtin-module": "1.0.0",
- "semver": "5.6.0",
- "validate-npm-package-license": "3.0.4"
- }
- },
- "normalize-path": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
- "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
- "requires": {
- "remove-trailing-separator": "1.1.0"
- }
- },
- "number-is-nan": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
- "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
- },
- "object-component": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
- "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE="
- },
- "object-copy": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
- "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
- "requires": {
- "copy-descriptor": "0.1.1",
- "define-property": "0.2.5",
- "kind-of": "3.2.2"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "requires": {
- "is-descriptor": "0.1.6"
- }
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "1.1.6"
- }
- }
- }
- },
- "object-path": {
- "version": "0.9.2",
- "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.9.2.tgz",
- "integrity": "sha1-D9mnT8X60a45aLWGvaXGMr1sBaU="
- },
- "object-visit": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
- "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
- "requires": {
- "isobject": "3.0.1"
- }
- },
- "object.omit": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
- "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
- "requires": {
- "for-own": "0.1.5",
- "is-extendable": "0.1.1"
- }
- },
- "object.pick": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
- "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
- "requires": {
- "isobject": "3.0.1"
- }
- },
- "on-finished": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
- "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
- "requires": {
- "ee-first": "1.1.1"
- }
- },
- "openurl": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz",
- "integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c="
- },
- "opn": {
- "version": "5.3.0",
- "resolved": "http://registry.npmjs.org/opn/-/opn-5.3.0.tgz",
- "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==",
- "requires": {
- "is-wsl": "1.1.0"
- }
- },
- "os-locale": {
- "version": "1.4.0",
- "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
- "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
- "requires": {
- "lcid": "1.0.0"
- }
- },
- "parse-glob": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
- "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
- "requires": {
- "glob-base": "0.3.0",
- "is-dotfile": "1.0.3",
- "is-extglob": "1.0.0",
- "is-glob": "2.0.1"
- },
- "dependencies": {
- "is-extglob": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
- "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
- },
- "is-glob": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
- "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
- "requires": {
- "is-extglob": "1.0.0"
- }
- }
- }
- },
- "parse-json": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
- "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
- "requires": {
- "error-ex": "1.3.2"
- }
- },
- "parseqs": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
- "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
- "requires": {
- "better-assert": "1.0.2"
- }
- },
- "parseuri": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
- "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
- "requires": {
- "better-assert": "1.0.2"
- }
- },
- "parseurl": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
- "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
- },
- "pascalcase": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
- "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
- },
- "path-dirname": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
- "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA="
- },
- "path-exists": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
- "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
- "requires": {
- "pinkie-promise": "2.0.1"
- }
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
- },
- "path-type": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
- "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
- "requires": {
- "graceful-fs": "4.1.15",
- "pify": "2.3.0",
- "pinkie-promise": "2.0.1"
- }
- },
- "pify": {
- "version": "2.3.0",
- "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
- },
- "pinkie": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
- "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
- },
- "pinkie-promise": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
- "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
- "requires": {
- "pinkie": "2.0.4"
- }
- },
- "portscanner": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.1.1.tgz",
- "integrity": "sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y=",
- "requires": {
- "async": "1.5.2",
- "is-number-like": "1.0.8"
- }
- },
- "posix-character-classes": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
- "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
- },
- "preserve": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
- "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks="
- },
- "process-nextick-args": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
- "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
- },
- "qs": {
- "version": "6.2.3",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz",
- "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4="
- },
- "randomatic": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz",
- "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==",
- "requires": {
- "is-number": "4.0.0",
- "kind-of": "6.0.2",
- "math-random": "1.0.1"
- },
- "dependencies": {
- "is-number": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
- "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ=="
- }
- }
- },
- "range-parser": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
- "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
- },
- "raw-body": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
- "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
- "requires": {
- "bytes": "3.0.0",
- "http-errors": "1.6.3",
- "iconv-lite": "0.4.23",
- "unpipe": "1.0.0"
- }
- },
- "read-pkg": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
- "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
- "requires": {
- "load-json-file": "1.1.0",
- "normalize-package-data": "2.4.0",
- "path-type": "1.1.0"
- }
- },
- "read-pkg-up": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
- "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
- "requires": {
- "find-up": "1.1.2",
- "read-pkg": "1.1.0"
- }
- },
- "readable-stream": {
- "version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
- "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "2.0.0",
- "safe-buffer": "5.1.2",
- "string_decoder": "1.1.1",
- "util-deprecate": "1.0.2"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- }
- }
- },
- "readdirp": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
- "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
- "requires": {
- "graceful-fs": "4.1.15",
- "micromatch": "3.1.10",
- "readable-stream": "2.3.6"
- },
- "dependencies": {
- "micromatch": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
- "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
- "requires": {
- "arr-diff": "4.0.0",
- "array-unique": "0.3.2",
- "braces": "2.3.2",
- "define-property": "2.0.2",
- "extend-shallow": "3.0.2",
- "extglob": "2.0.4",
- "fragment-cache": "0.2.1",
- "kind-of": "6.0.2",
- "nanomatch": "1.2.13",
- "object.pick": "1.3.0",
- "regex-not": "1.0.2",
- "snapdragon": "0.8.2",
- "to-regex": "3.0.2"
- }
- }
- }
- },
- "regex-cache": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
- "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
- "requires": {
- "is-equal-shallow": "0.1.3"
- }
- },
- "regex-not": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
- "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
- "requires": {
- "extend-shallow": "3.0.2",
- "safe-regex": "1.1.0"
- }
- },
- "remove-trailing-separator": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
- "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
- },
- "repeat-element": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
- "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g=="
- },
- "repeat-string": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
- "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
- },
- "require-directory": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
- },
- "require-main-filename": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
- "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
- },
- "requires-port": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
- },
- "resolve-url": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
- "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
- },
- "resp-modifier": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz",
- "integrity": "sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08=",
- "requires": {
- "debug": "2.6.9",
- "minimatch": "3.0.4"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "ret": {
- "version": "0.1.15",
- "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
- "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
- },
- "rx": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
- "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I="
- },
- "rxjs": {
- "version": "5.5.12",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz",
- "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==",
- "requires": {
- "symbol-observable": "1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
- },
- "safe-regex": {
- "version": "1.1.0",
- "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
- "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
- "requires": {
- "ret": "0.1.15"
- }
- },
- "safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
- },
- "semver": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
- "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="
- },
- "send": {
- "version": "0.16.2",
- "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
- "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
- "requires": {
- "debug": "2.6.9",
- "depd": "1.1.2",
- "destroy": "1.0.4",
- "encodeurl": "1.0.2",
- "escape-html": "1.0.3",
- "etag": "1.8.1",
- "fresh": "0.5.2",
- "http-errors": "1.6.3",
- "mime": "1.4.1",
- "ms": "2.0.0",
- "on-finished": "2.3.0",
- "range-parser": "1.2.0",
- "statuses": "1.4.0"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "statuses": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
- "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
- }
- }
- },
- "serve-index": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
- "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
- "requires": {
- "accepts": "1.3.5",
- "batch": "0.6.1",
- "debug": "2.6.9",
- "escape-html": "1.0.3",
- "http-errors": "1.6.3",
- "mime-types": "2.1.21",
- "parseurl": "1.3.2"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "serve-static": {
- "version": "1.13.2",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
- "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
- "requires": {
- "encodeurl": "1.0.2",
- "escape-html": "1.0.3",
- "parseurl": "1.3.2",
- "send": "0.16.2"
- }
- },
- "server-destroy": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz",
- "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0="
- },
- "set-blocking": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
- "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
- },
- "set-value": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
- "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
- "requires": {
- "extend-shallow": "2.0.1",
- "is-extendable": "0.1.1",
- "is-plain-object": "2.0.4",
- "split-string": "3.1.0"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "0.1.1"
- }
- }
- }
- },
- "setprototypeof": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
- "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
- },
- "snapdragon": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
- "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
- "requires": {
- "base": "0.11.2",
- "debug": "2.6.9",
- "define-property": "0.2.5",
- "extend-shallow": "2.0.1",
- "map-cache": "0.2.2",
- "source-map": "0.5.7",
- "source-map-resolve": "0.5.2",
- "use": "3.1.1"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "requires": {
- "is-descriptor": "0.1.6"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "0.1.1"
- }
- }
- }
- },
- "snapdragon-node": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
- "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
- "requires": {
- "define-property": "1.0.0",
- "isobject": "3.0.1",
- "snapdragon-util": "3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "requires": {
- "is-descriptor": "1.0.2"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "requires": {
- "kind-of": "6.0.2"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "requires": {
- "kind-of": "6.0.2"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "requires": {
- "is-accessor-descriptor": "1.0.0",
- "is-data-descriptor": "1.0.0",
- "kind-of": "6.0.2"
- }
- }
- }
- },
- "snapdragon-util": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
- "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
- "requires": {
- "kind-of": "3.2.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "1.1.6"
- }
- }
- }
- },
- "socket.io": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz",
- "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==",
- "requires": {
- "debug": "3.1.0",
- "engine.io": "3.2.1",
- "has-binary2": "1.0.3",
- "socket.io-adapter": "1.1.1",
- "socket.io-client": "2.1.1",
- "socket.io-parser": "3.2.0"
- }
- },
- "socket.io-adapter": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz",
- "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs="
- },
- "socket.io-client": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz",
- "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==",
- "requires": {
- "backo2": "1.0.2",
- "base64-arraybuffer": "0.1.5",
- "component-bind": "1.0.0",
- "component-emitter": "1.2.1",
- "debug": "3.1.0",
- "engine.io-client": "3.2.1",
- "has-binary2": "1.0.3",
- "has-cors": "1.1.0",
- "indexof": "0.0.1",
- "object-component": "0.0.3",
- "parseqs": "0.0.5",
- "parseuri": "0.0.5",
- "socket.io-parser": "3.2.0",
- "to-array": "0.1.4"
- }
- },
- "socket.io-parser": {
- "version": "3.2.0",
- "resolved": "http://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz",
- "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==",
- "requires": {
- "component-emitter": "1.2.1",
- "debug": "3.1.0",
- "isarray": "2.0.1"
- }
- },
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
- },
- "source-map-resolve": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
- "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
- "requires": {
- "atob": "2.1.2",
- "decode-uri-component": "0.2.0",
- "resolve-url": "0.2.1",
- "source-map-url": "0.4.0",
- "urix": "0.1.0"
- }
- },
- "source-map-url": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
- "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
- },
- "spdx-correct": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz",
- "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==",
- "requires": {
- "spdx-expression-parse": "3.0.0",
- "spdx-license-ids": "3.0.2"
- }
- },
- "spdx-exceptions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
- "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA=="
- },
- "spdx-expression-parse": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
- "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
- "requires": {
- "spdx-exceptions": "2.2.0",
- "spdx-license-ids": "3.0.2"
- }
- },
- "spdx-license-ids": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz",
- "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg=="
- },
- "split-string": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
- "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
- "requires": {
- "extend-shallow": "3.0.2"
- }
- },
- "static-extend": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
- "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
- "requires": {
- "define-property": "0.2.5",
- "object-copy": "0.1.0"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "requires": {
- "is-descriptor": "0.1.6"
- }
- }
- }
- },
- "statuses": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
- "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
- },
- "stream-throttle": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz",
- "integrity": "sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM=",
- "requires": {
- "commander": "2.19.0",
- "limiter": "1.1.3"
- }
- },
- "string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
- "requires": {
- "code-point-at": "1.1.0",
- "is-fullwidth-code-point": "1.0.0",
- "strip-ansi": "3.0.1"
- }
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "requires": {
- "safe-buffer": "5.1.2"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "requires": {
- "ansi-regex": "2.1.1"
- }
- },
- "strip-bom": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
- "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
- "requires": {
- "is-utf8": "0.2.1"
- }
- },
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
- },
- "symbol-observable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz",
- "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ="
- },
- "tfunk": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/tfunk/-/tfunk-3.1.0.tgz",
- "integrity": "sha1-OORBT8ZJd9h6/apy+sttKfgve1s=",
- "requires": {
- "chalk": "1.1.3",
- "object-path": "0.9.2"
- }
- },
- "to-array": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
- "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA="
- },
- "to-object-path": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
- "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
- "requires": {
- "kind-of": "3.2.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "1.1.6"
- }
- }
- }
- },
- "to-regex": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
- "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
- "requires": {
- "define-property": "2.0.2",
- "extend-shallow": "3.0.2",
- "regex-not": "1.0.2",
- "safe-regex": "1.1.0"
- }
- },
- "to-regex-range": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
- "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
- "requires": {
- "is-number": "3.0.0",
- "repeat-string": "1.6.1"
- }
- },
- "ua-parser-js": {
- "version": "0.7.17",
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz",
- "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g=="
- },
- "ultron": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
- "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
- },
- "union-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
- "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
- "requires": {
- "arr-union": "3.1.0",
- "get-value": "2.0.6",
- "is-extendable": "0.1.1",
- "set-value": "0.4.3"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "0.1.1"
- }
- },
- "set-value": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
- "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
- "requires": {
- "extend-shallow": "2.0.1",
- "is-extendable": "0.1.1",
- "is-plain-object": "2.0.4",
- "to-object-path": "0.3.0"
- }
- }
- }
- },
- "universalify": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
- "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
- },
- "unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
- },
- "unset-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
- "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
- "requires": {
- "has-value": "0.3.1",
- "isobject": "3.0.1"
- },
- "dependencies": {
- "has-value": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
- "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
- "requires": {
- "get-value": "2.0.6",
- "has-values": "0.1.4",
- "isobject": "2.1.0"
- },
- "dependencies": {
- "isobject": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
- "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
- "requires": {
- "isarray": "1.0.0"
- }
- }
- }
- },
- "has-values": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
- "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- }
- }
- },
- "upath": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz",
- "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw=="
- },
- "urix": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
- "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI="
- },
- "use": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
- "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
- },
- "util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
- },
- "utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
- },
- "validate-npm-package-license": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
- "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
- "requires": {
- "spdx-correct": "3.0.2",
- "spdx-expression-parse": "3.0.0"
- }
- },
- "which-module": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
- "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8="
- },
- "window-size": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
- "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU="
- },
- "wrap-ansi": {
- "version": "2.1.0",
- "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
- "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
- "requires": {
- "string-width": "1.0.2",
- "strip-ansi": "3.0.1"
- }
- },
- "ws": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
- "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
- "requires": {
- "async-limiter": "1.0.0",
- "safe-buffer": "5.1.2",
- "ultron": "1.1.1"
- }
- },
- "xmlhttprequest-ssl": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
- "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
- },
- "y18n": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
- "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
- },
- "yargs": {
- "version": "6.4.0",
- "resolved": "http://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz",
- "integrity": "sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ=",
- "requires": {
- "camelcase": "3.0.0",
- "cliui": "3.2.0",
- "decamelize": "1.2.0",
- "get-caller-file": "1.0.3",
- "os-locale": "1.4.0",
- "read-pkg-up": "1.0.1",
- "require-directory": "2.1.1",
- "require-main-filename": "1.0.1",
- "set-blocking": "2.0.0",
- "string-width": "1.0.2",
- "which-module": "1.0.0",
- "window-size": "0.2.0",
- "y18n": "3.2.1",
- "yargs-parser": "4.2.1"
- }
- },
- "yargs-parser": {
- "version": "4.2.1",
- "resolved": "http://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz",
- "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=",
- "requires": {
- "camelcase": "3.0.0"
- }
- },
- "yeast": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
- "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
- }
- }
-}
diff --git a/dapps/demo/package.json b/dapps/demo/package.json
deleted file mode 100644
index a88e785e4..000000000
--- a/dapps/demo/package.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "name": "demodapp",
- "private": true,
- "version": "1.0.0",
- "description": "Token Bridge Demo Dapp",
- "author": "",
- "scripts": {
- "dev": "lite-server"
- },
- "dependencies": {
- "lite-server": "^2.4.0"
- }
-}
diff --git a/dapps/demo/src/css/.DS_Store b/dapps/demo/src/css/.DS_Store
deleted file mode 100644
index 3cbbb78ab..000000000
Binary files a/dapps/demo/src/css/.DS_Store and /dev/null differ
diff --git a/dapps/demo/src/css/bootstrap-grid.css b/dapps/demo/src/css/bootstrap-grid.css
deleted file mode 100644
index a36cd328d..000000000
--- a/dapps/demo/src/css/bootstrap-grid.css
+++ /dev/null
@@ -1,1912 +0,0 @@
-/*!
- * Bootstrap Grid v4.1.3 (https://getbootstrap.com/)
- * Copyright 2011-2018 The Bootstrap Authors
- * Copyright 2011-2018 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */
-@-ms-viewport {
- width: device-width;
-}
-
-html {
- box-sizing: border-box;
- -ms-overflow-style: scrollbar;
-}
-
-*,
-*::before,
-*::after {
- box-sizing: inherit;
-}
-
-.container {
- width: 100%;
- padding-right: 15px;
- padding-left: 15px;
- margin-right: auto;
- margin-left: auto;
-}
-
-@media (min-width: 576px) {
- .container {
- max-width: 540px;
- }
-}
-
-@media (min-width: 768px) {
- .container {
- max-width: 720px;
- }
-}
-
-@media (min-width: 992px) {
- .container {
- max-width: 960px;
- }
-}
-
-@media (min-width: 1200px) {
- .container {
- max-width: 1140px;
- }
-}
-
-.container-fluid {
- width: 100%;
- padding-right: 15px;
- padding-left: 15px;
- margin-right: auto;
- margin-left: auto;
-}
-
-.row {
- display: -ms-flexbox;
- display: flex;
- -ms-flex-wrap: wrap;
- flex-wrap: wrap;
- margin-right: -15px;
- margin-left: -15px;
-}
-
-.no-gutters {
- margin-right: 0;
- margin-left: 0;
-}
-
-.no-gutters > .col,
-.no-gutters > [class*="col-"] {
- padding-right: 0;
- padding-left: 0;
-}
-
-.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,
-.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,
-.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,
-.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,
-.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,
-.col-xl-auto {
- position: relative;
- width: 100%;
- min-height: 1px;
- padding-right: 15px;
- padding-left: 15px;
-}
-
-.col {
- -ms-flex-preferred-size: 0;
- flex-basis: 0;
- -ms-flex-positive: 1;
- flex-grow: 1;
- max-width: 100%;
-}
-
-.col-auto {
- -ms-flex: 0 0 auto;
- flex: 0 0 auto;
- width: auto;
- max-width: none;
-}
-
-.col-1 {
- -ms-flex: 0 0 8.333333%;
- flex: 0 0 8.333333%;
- max-width: 8.333333%;
-}
-
-.col-2 {
- -ms-flex: 0 0 16.666667%;
- flex: 0 0 16.666667%;
- max-width: 16.666667%;
-}
-
-.col-3 {
- -ms-flex: 0 0 25%;
- flex: 0 0 25%;
- max-width: 25%;
-}
-
-.col-4 {
- -ms-flex: 0 0 33.333333%;
- flex: 0 0 33.333333%;
- max-width: 33.333333%;
-}
-
-.col-5 {
- -ms-flex: 0 0 41.666667%;
- flex: 0 0 41.666667%;
- max-width: 41.666667%;
-}
-
-.col-6 {
- -ms-flex: 0 0 50%;
- flex: 0 0 50%;
- max-width: 50%;
-}
-
-.col-7 {
- -ms-flex: 0 0 58.333333%;
- flex: 0 0 58.333333%;
- max-width: 58.333333%;
-}
-
-.col-8 {
- -ms-flex: 0 0 66.666667%;
- flex: 0 0 66.666667%;
- max-width: 66.666667%;
-}
-
-.col-9 {
- -ms-flex: 0 0 75%;
- flex: 0 0 75%;
- max-width: 75%;
-}
-
-.col-10 {
- -ms-flex: 0 0 83.333333%;
- flex: 0 0 83.333333%;
- max-width: 83.333333%;
-}
-
-.col-11 {
- -ms-flex: 0 0 91.666667%;
- flex: 0 0 91.666667%;
- max-width: 91.666667%;
-}
-
-.col-12 {
- -ms-flex: 0 0 100%;
- flex: 0 0 100%;
- max-width: 100%;
-}
-
-.order-first {
- -ms-flex-order: -1;
- order: -1;
-}
-
-.order-last {
- -ms-flex-order: 13;
- order: 13;
-}
-
-.order-0 {
- -ms-flex-order: 0;
- order: 0;
-}
-
-.order-1 {
- -ms-flex-order: 1;
- order: 1;
-}
-
-.order-2 {
- -ms-flex-order: 2;
- order: 2;
-}
-
-.order-3 {
- -ms-flex-order: 3;
- order: 3;
-}
-
-.order-4 {
- -ms-flex-order: 4;
- order: 4;
-}
-
-.order-5 {
- -ms-flex-order: 5;
- order: 5;
-}
-
-.order-6 {
- -ms-flex-order: 6;
- order: 6;
-}
-
-.order-7 {
- -ms-flex-order: 7;
- order: 7;
-}
-
-.order-8 {
- -ms-flex-order: 8;
- order: 8;
-}
-
-.order-9 {
- -ms-flex-order: 9;
- order: 9;
-}
-
-.order-10 {
- -ms-flex-order: 10;
- order: 10;
-}
-
-.order-11 {
- -ms-flex-order: 11;
- order: 11;
-}
-
-.order-12 {
- -ms-flex-order: 12;
- order: 12;
-}
-
-.offset-1 {
- margin-left: 8.333333%;
-}
-
-.offset-2 {
- margin-left: 16.666667%;
-}
-
-.offset-3 {
- margin-left: 25%;
-}
-
-.offset-4 {
- margin-left: 33.333333%;
-}
-
-.offset-5 {
- margin-left: 41.666667%;
-}
-
-.offset-6 {
- margin-left: 50%;
-}
-
-.offset-7 {
- margin-left: 58.333333%;
-}
-
-.offset-8 {
- margin-left: 66.666667%;
-}
-
-.offset-9 {
- margin-left: 75%;
-}
-
-.offset-10 {
- margin-left: 83.333333%;
-}
-
-.offset-11 {
- margin-left: 91.666667%;
-}
-
-@media (min-width: 576px) {
- .col-sm {
- -ms-flex-preferred-size: 0;
- flex-basis: 0;
- -ms-flex-positive: 1;
- flex-grow: 1;
- max-width: 100%;
- }
- .col-sm-auto {
- -ms-flex: 0 0 auto;
- flex: 0 0 auto;
- width: auto;
- max-width: none;
- }
- .col-sm-1 {
- -ms-flex: 0 0 8.333333%;
- flex: 0 0 8.333333%;
- max-width: 8.333333%;
- }
- .col-sm-2 {
- -ms-flex: 0 0 16.666667%;
- flex: 0 0 16.666667%;
- max-width: 16.666667%;
- }
- .col-sm-3 {
- -ms-flex: 0 0 25%;
- flex: 0 0 25%;
- max-width: 25%;
- }
- .col-sm-4 {
- -ms-flex: 0 0 33.333333%;
- flex: 0 0 33.333333%;
- max-width: 33.333333%;
- }
- .col-sm-5 {
- -ms-flex: 0 0 41.666667%;
- flex: 0 0 41.666667%;
- max-width: 41.666667%;
- }
- .col-sm-6 {
- -ms-flex: 0 0 50%;
- flex: 0 0 50%;
- max-width: 50%;
- }
- .col-sm-7 {
- -ms-flex: 0 0 58.333333%;
- flex: 0 0 58.333333%;
- max-width: 58.333333%;
- }
- .col-sm-8 {
- -ms-flex: 0 0 66.666667%;
- flex: 0 0 66.666667%;
- max-width: 66.666667%;
- }
- .col-sm-9 {
- -ms-flex: 0 0 75%;
- flex: 0 0 75%;
- max-width: 75%;
- }
- .col-sm-10 {
- -ms-flex: 0 0 83.333333%;
- flex: 0 0 83.333333%;
- max-width: 83.333333%;
- }
- .col-sm-11 {
- -ms-flex: 0 0 91.666667%;
- flex: 0 0 91.666667%;
- max-width: 91.666667%;
- }
- .col-sm-12 {
- -ms-flex: 0 0 100%;
- flex: 0 0 100%;
- max-width: 100%;
- }
- .order-sm-first {
- -ms-flex-order: -1;
- order: -1;
- }
- .order-sm-last {
- -ms-flex-order: 13;
- order: 13;
- }
- .order-sm-0 {
- -ms-flex-order: 0;
- order: 0;
- }
- .order-sm-1 {
- -ms-flex-order: 1;
- order: 1;
- }
- .order-sm-2 {
- -ms-flex-order: 2;
- order: 2;
- }
- .order-sm-3 {
- -ms-flex-order: 3;
- order: 3;
- }
- .order-sm-4 {
- -ms-flex-order: 4;
- order: 4;
- }
- .order-sm-5 {
- -ms-flex-order: 5;
- order: 5;
- }
- .order-sm-6 {
- -ms-flex-order: 6;
- order: 6;
- }
- .order-sm-7 {
- -ms-flex-order: 7;
- order: 7;
- }
- .order-sm-8 {
- -ms-flex-order: 8;
- order: 8;
- }
- .order-sm-9 {
- -ms-flex-order: 9;
- order: 9;
- }
- .order-sm-10 {
- -ms-flex-order: 10;
- order: 10;
- }
- .order-sm-11 {
- -ms-flex-order: 11;
- order: 11;
- }
- .order-sm-12 {
- -ms-flex-order: 12;
- order: 12;
- }
- .offset-sm-0 {
- margin-left: 0;
- }
- .offset-sm-1 {
- margin-left: 8.333333%;
- }
- .offset-sm-2 {
- margin-left: 16.666667%;
- }
- .offset-sm-3 {
- margin-left: 25%;
- }
- .offset-sm-4 {
- margin-left: 33.333333%;
- }
- .offset-sm-5 {
- margin-left: 41.666667%;
- }
- .offset-sm-6 {
- margin-left: 50%;
- }
- .offset-sm-7 {
- margin-left: 58.333333%;
- }
- .offset-sm-8 {
- margin-left: 66.666667%;
- }
- .offset-sm-9 {
- margin-left: 75%;
- }
- .offset-sm-10 {
- margin-left: 83.333333%;
- }
- .offset-sm-11 {
- margin-left: 91.666667%;
- }
-}
-
-@media (min-width: 768px) {
- .col-md {
- -ms-flex-preferred-size: 0;
- flex-basis: 0;
- -ms-flex-positive: 1;
- flex-grow: 1;
- max-width: 100%;
- }
- .col-md-auto {
- -ms-flex: 0 0 auto;
- flex: 0 0 auto;
- width: auto;
- max-width: none;
- }
- .col-md-1 {
- -ms-flex: 0 0 8.333333%;
- flex: 0 0 8.333333%;
- max-width: 8.333333%;
- }
- .col-md-2 {
- -ms-flex: 0 0 16.666667%;
- flex: 0 0 16.666667%;
- max-width: 16.666667%;
- }
- .col-md-3 {
- -ms-flex: 0 0 25%;
- flex: 0 0 25%;
- max-width: 25%;
- }
- .col-md-4 {
- -ms-flex: 0 0 33.333333%;
- flex: 0 0 33.333333%;
- max-width: 33.333333%;
- }
- .col-md-5 {
- -ms-flex: 0 0 41.666667%;
- flex: 0 0 41.666667%;
- max-width: 41.666667%;
- }
- .col-md-6 {
- -ms-flex: 0 0 50%;
- flex: 0 0 50%;
- max-width: 50%;
- }
- .col-md-7 {
- -ms-flex: 0 0 58.333333%;
- flex: 0 0 58.333333%;
- max-width: 58.333333%;
- }
- .col-md-8 {
- -ms-flex: 0 0 66.666667%;
- flex: 0 0 66.666667%;
- max-width: 66.666667%;
- }
- .col-md-9 {
- -ms-flex: 0 0 75%;
- flex: 0 0 75%;
- max-width: 75%;
- }
- .col-md-10 {
- -ms-flex: 0 0 83.333333%;
- flex: 0 0 83.333333%;
- max-width: 83.333333%;
- }
- .col-md-11 {
- -ms-flex: 0 0 91.666667%;
- flex: 0 0 91.666667%;
- max-width: 91.666667%;
- }
- .col-md-12 {
- -ms-flex: 0 0 100%;
- flex: 0 0 100%;
- max-width: 100%;
- }
- .order-md-first {
- -ms-flex-order: -1;
- order: -1;
- }
- .order-md-last {
- -ms-flex-order: 13;
- order: 13;
- }
- .order-md-0 {
- -ms-flex-order: 0;
- order: 0;
- }
- .order-md-1 {
- -ms-flex-order: 1;
- order: 1;
- }
- .order-md-2 {
- -ms-flex-order: 2;
- order: 2;
- }
- .order-md-3 {
- -ms-flex-order: 3;
- order: 3;
- }
- .order-md-4 {
- -ms-flex-order: 4;
- order: 4;
- }
- .order-md-5 {
- -ms-flex-order: 5;
- order: 5;
- }
- .order-md-6 {
- -ms-flex-order: 6;
- order: 6;
- }
- .order-md-7 {
- -ms-flex-order: 7;
- order: 7;
- }
- .order-md-8 {
- -ms-flex-order: 8;
- order: 8;
- }
- .order-md-9 {
- -ms-flex-order: 9;
- order: 9;
- }
- .order-md-10 {
- -ms-flex-order: 10;
- order: 10;
- }
- .order-md-11 {
- -ms-flex-order: 11;
- order: 11;
- }
- .order-md-12 {
- -ms-flex-order: 12;
- order: 12;
- }
- .offset-md-0 {
- margin-left: 0;
- }
- .offset-md-1 {
- margin-left: 8.333333%;
- }
- .offset-md-2 {
- margin-left: 16.666667%;
- }
- .offset-md-3 {
- margin-left: 25%;
- }
- .offset-md-4 {
- margin-left: 33.333333%;
- }
- .offset-md-5 {
- margin-left: 41.666667%;
- }
- .offset-md-6 {
- margin-left: 50%;
- }
- .offset-md-7 {
- margin-left: 58.333333%;
- }
- .offset-md-8 {
- margin-left: 66.666667%;
- }
- .offset-md-9 {
- margin-left: 75%;
- }
- .offset-md-10 {
- margin-left: 83.333333%;
- }
- .offset-md-11 {
- margin-left: 91.666667%;
- }
-}
-
-@media (min-width: 992px) {
- .col-lg {
- -ms-flex-preferred-size: 0;
- flex-basis: 0;
- -ms-flex-positive: 1;
- flex-grow: 1;
- max-width: 100%;
- }
- .col-lg-auto {
- -ms-flex: 0 0 auto;
- flex: 0 0 auto;
- width: auto;
- max-width: none;
- }
- .col-lg-1 {
- -ms-flex: 0 0 8.333333%;
- flex: 0 0 8.333333%;
- max-width: 8.333333%;
- }
- .col-lg-2 {
- -ms-flex: 0 0 16.666667%;
- flex: 0 0 16.666667%;
- max-width: 16.666667%;
- }
- .col-lg-3 {
- -ms-flex: 0 0 25%;
- flex: 0 0 25%;
- max-width: 25%;
- }
- .col-lg-4 {
- -ms-flex: 0 0 33.333333%;
- flex: 0 0 33.333333%;
- max-width: 33.333333%;
- }
- .col-lg-5 {
- -ms-flex: 0 0 41.666667%;
- flex: 0 0 41.666667%;
- max-width: 41.666667%;
- }
- .col-lg-6 {
- -ms-flex: 0 0 50%;
- flex: 0 0 50%;
- max-width: 50%;
- }
- .col-lg-7 {
- -ms-flex: 0 0 58.333333%;
- flex: 0 0 58.333333%;
- max-width: 58.333333%;
- }
- .col-lg-8 {
- -ms-flex: 0 0 66.666667%;
- flex: 0 0 66.666667%;
- max-width: 66.666667%;
- }
- .col-lg-9 {
- -ms-flex: 0 0 75%;
- flex: 0 0 75%;
- max-width: 75%;
- }
- .col-lg-10 {
- -ms-flex: 0 0 83.333333%;
- flex: 0 0 83.333333%;
- max-width: 83.333333%;
- }
- .col-lg-11 {
- -ms-flex: 0 0 91.666667%;
- flex: 0 0 91.666667%;
- max-width: 91.666667%;
- }
- .col-lg-12 {
- -ms-flex: 0 0 100%;
- flex: 0 0 100%;
- max-width: 100%;
- }
- .order-lg-first {
- -ms-flex-order: -1;
- order: -1;
- }
- .order-lg-last {
- -ms-flex-order: 13;
- order: 13;
- }
- .order-lg-0 {
- -ms-flex-order: 0;
- order: 0;
- }
- .order-lg-1 {
- -ms-flex-order: 1;
- order: 1;
- }
- .order-lg-2 {
- -ms-flex-order: 2;
- order: 2;
- }
- .order-lg-3 {
- -ms-flex-order: 3;
- order: 3;
- }
- .order-lg-4 {
- -ms-flex-order: 4;
- order: 4;
- }
- .order-lg-5 {
- -ms-flex-order: 5;
- order: 5;
- }
- .order-lg-6 {
- -ms-flex-order: 6;
- order: 6;
- }
- .order-lg-7 {
- -ms-flex-order: 7;
- order: 7;
- }
- .order-lg-8 {
- -ms-flex-order: 8;
- order: 8;
- }
- .order-lg-9 {
- -ms-flex-order: 9;
- order: 9;
- }
- .order-lg-10 {
- -ms-flex-order: 10;
- order: 10;
- }
- .order-lg-11 {
- -ms-flex-order: 11;
- order: 11;
- }
- .order-lg-12 {
- -ms-flex-order: 12;
- order: 12;
- }
- .offset-lg-0 {
- margin-left: 0;
- }
- .offset-lg-1 {
- margin-left: 8.333333%;
- }
- .offset-lg-2 {
- margin-left: 16.666667%;
- }
- .offset-lg-3 {
- margin-left: 25%;
- }
- .offset-lg-4 {
- margin-left: 33.333333%;
- }
- .offset-lg-5 {
- margin-left: 41.666667%;
- }
- .offset-lg-6 {
- margin-left: 50%;
- }
- .offset-lg-7 {
- margin-left: 58.333333%;
- }
- .offset-lg-8 {
- margin-left: 66.666667%;
- }
- .offset-lg-9 {
- margin-left: 75%;
- }
- .offset-lg-10 {
- margin-left: 83.333333%;
- }
- .offset-lg-11 {
- margin-left: 91.666667%;
- }
-}
-
-@media (min-width: 1200px) {
- .col-xl {
- -ms-flex-preferred-size: 0;
- flex-basis: 0;
- -ms-flex-positive: 1;
- flex-grow: 1;
- max-width: 100%;
- }
- .col-xl-auto {
- -ms-flex: 0 0 auto;
- flex: 0 0 auto;
- width: auto;
- max-width: none;
- }
- .col-xl-1 {
- -ms-flex: 0 0 8.333333%;
- flex: 0 0 8.333333%;
- max-width: 8.333333%;
- }
- .col-xl-2 {
- -ms-flex: 0 0 16.666667%;
- flex: 0 0 16.666667%;
- max-width: 16.666667%;
- }
- .col-xl-3 {
- -ms-flex: 0 0 25%;
- flex: 0 0 25%;
- max-width: 25%;
- }
- .col-xl-4 {
- -ms-flex: 0 0 33.333333%;
- flex: 0 0 33.333333%;
- max-width: 33.333333%;
- }
- .col-xl-5 {
- -ms-flex: 0 0 41.666667%;
- flex: 0 0 41.666667%;
- max-width: 41.666667%;
- }
- .col-xl-6 {
- -ms-flex: 0 0 50%;
- flex: 0 0 50%;
- max-width: 50%;
- }
- .col-xl-7 {
- -ms-flex: 0 0 58.333333%;
- flex: 0 0 58.333333%;
- max-width: 58.333333%;
- }
- .col-xl-8 {
- -ms-flex: 0 0 66.666667%;
- flex: 0 0 66.666667%;
- max-width: 66.666667%;
- }
- .col-xl-9 {
- -ms-flex: 0 0 75%;
- flex: 0 0 75%;
- max-width: 75%;
- }
- .col-xl-10 {
- -ms-flex: 0 0 83.333333%;
- flex: 0 0 83.333333%;
- max-width: 83.333333%;
- }
- .col-xl-11 {
- -ms-flex: 0 0 91.666667%;
- flex: 0 0 91.666667%;
- max-width: 91.666667%;
- }
- .col-xl-12 {
- -ms-flex: 0 0 100%;
- flex: 0 0 100%;
- max-width: 100%;
- }
- .order-xl-first {
- -ms-flex-order: -1;
- order: -1;
- }
- .order-xl-last {
- -ms-flex-order: 13;
- order: 13;
- }
- .order-xl-0 {
- -ms-flex-order: 0;
- order: 0;
- }
- .order-xl-1 {
- -ms-flex-order: 1;
- order: 1;
- }
- .order-xl-2 {
- -ms-flex-order: 2;
- order: 2;
- }
- .order-xl-3 {
- -ms-flex-order: 3;
- order: 3;
- }
- .order-xl-4 {
- -ms-flex-order: 4;
- order: 4;
- }
- .order-xl-5 {
- -ms-flex-order: 5;
- order: 5;
- }
- .order-xl-6 {
- -ms-flex-order: 6;
- order: 6;
- }
- .order-xl-7 {
- -ms-flex-order: 7;
- order: 7;
- }
- .order-xl-8 {
- -ms-flex-order: 8;
- order: 8;
- }
- .order-xl-9 {
- -ms-flex-order: 9;
- order: 9;
- }
- .order-xl-10 {
- -ms-flex-order: 10;
- order: 10;
- }
- .order-xl-11 {
- -ms-flex-order: 11;
- order: 11;
- }
- .order-xl-12 {
- -ms-flex-order: 12;
- order: 12;
- }
- .offset-xl-0 {
- margin-left: 0;
- }
- .offset-xl-1 {
- margin-left: 8.333333%;
- }
- .offset-xl-2 {
- margin-left: 16.666667%;
- }
- .offset-xl-3 {
- margin-left: 25%;
- }
- .offset-xl-4 {
- margin-left: 33.333333%;
- }
- .offset-xl-5 {
- margin-left: 41.666667%;
- }
- .offset-xl-6 {
- margin-left: 50%;
- }
- .offset-xl-7 {
- margin-left: 58.333333%;
- }
- .offset-xl-8 {
- margin-left: 66.666667%;
- }
- .offset-xl-9 {
- margin-left: 75%;
- }
- .offset-xl-10 {
- margin-left: 83.333333%;
- }
- .offset-xl-11 {
- margin-left: 91.666667%;
- }
-}
-
-.d-none {
- display: none !important;
-}
-
-.d-inline {
- display: inline !important;
-}
-
-.d-inline-block {
- display: inline-block !important;
-}
-
-.d-block {
- display: block !important;
-}
-
-.d-table {
- display: table !important;
-}
-
-.d-table-row {
- display: table-row !important;
-}
-
-.d-table-cell {
- display: table-cell !important;
-}
-
-.d-flex {
- display: -ms-flexbox !important;
- display: flex !important;
-}
-
-.d-inline-flex {
- display: -ms-inline-flexbox !important;
- display: inline-flex !important;
-}
-
-@media (min-width: 576px) {
- .d-sm-none {
- display: none !important;
- }
- .d-sm-inline {
- display: inline !important;
- }
- .d-sm-inline-block {
- display: inline-block !important;
- }
- .d-sm-block {
- display: block !important;
- }
- .d-sm-table {
- display: table !important;
- }
- .d-sm-table-row {
- display: table-row !important;
- }
- .d-sm-table-cell {
- display: table-cell !important;
- }
- .d-sm-flex {
- display: -ms-flexbox !important;
- display: flex !important;
- }
- .d-sm-inline-flex {
- display: -ms-inline-flexbox !important;
- display: inline-flex !important;
- }
-}
-
-@media (min-width: 768px) {
- .d-md-none {
- display: none !important;
- }
- .d-md-inline {
- display: inline !important;
- }
- .d-md-inline-block {
- display: inline-block !important;
- }
- .d-md-block {
- display: block !important;
- }
- .d-md-table {
- display: table !important;
- }
- .d-md-table-row {
- display: table-row !important;
- }
- .d-md-table-cell {
- display: table-cell !important;
- }
- .d-md-flex {
- display: -ms-flexbox !important;
- display: flex !important;
- }
- .d-md-inline-flex {
- display: -ms-inline-flexbox !important;
- display: inline-flex !important;
- }
-}
-
-@media (min-width: 992px) {
- .d-lg-none {
- display: none !important;
- }
- .d-lg-inline {
- display: inline !important;
- }
- .d-lg-inline-block {
- display: inline-block !important;
- }
- .d-lg-block {
- display: block !important;
- }
- .d-lg-table {
- display: table !important;
- }
- .d-lg-table-row {
- display: table-row !important;
- }
- .d-lg-table-cell {
- display: table-cell !important;
- }
- .d-lg-flex {
- display: -ms-flexbox !important;
- display: flex !important;
- }
- .d-lg-inline-flex {
- display: -ms-inline-flexbox !important;
- display: inline-flex !important;
- }
-}
-
-@media (min-width: 1200px) {
- .d-xl-none {
- display: none !important;
- }
- .d-xl-inline {
- display: inline !important;
- }
- .d-xl-inline-block {
- display: inline-block !important;
- }
- .d-xl-block {
- display: block !important;
- }
- .d-xl-table {
- display: table !important;
- }
- .d-xl-table-row {
- display: table-row !important;
- }
- .d-xl-table-cell {
- display: table-cell !important;
- }
- .d-xl-flex {
- display: -ms-flexbox !important;
- display: flex !important;
- }
- .d-xl-inline-flex {
- display: -ms-inline-flexbox !important;
- display: inline-flex !important;
- }
-}
-
-@media print {
- .d-print-none {
- display: none !important;
- }
- .d-print-inline {
- display: inline !important;
- }
- .d-print-inline-block {
- display: inline-block !important;
- }
- .d-print-block {
- display: block !important;
- }
- .d-print-table {
- display: table !important;
- }
- .d-print-table-row {
- display: table-row !important;
- }
- .d-print-table-cell {
- display: table-cell !important;
- }
- .d-print-flex {
- display: -ms-flexbox !important;
- display: flex !important;
- }
- .d-print-inline-flex {
- display: -ms-inline-flexbox !important;
- display: inline-flex !important;
- }
-}
-
-.flex-row {
- -ms-flex-direction: row !important;
- flex-direction: row !important;
-}
-
-.flex-column {
- -ms-flex-direction: column !important;
- flex-direction: column !important;
-}
-
-.flex-row-reverse {
- -ms-flex-direction: row-reverse !important;
- flex-direction: row-reverse !important;
-}
-
-.flex-column-reverse {
- -ms-flex-direction: column-reverse !important;
- flex-direction: column-reverse !important;
-}
-
-.flex-wrap {
- -ms-flex-wrap: wrap !important;
- flex-wrap: wrap !important;
-}
-
-.flex-nowrap {
- -ms-flex-wrap: nowrap !important;
- flex-wrap: nowrap !important;
-}
-
-.flex-wrap-reverse {
- -ms-flex-wrap: wrap-reverse !important;
- flex-wrap: wrap-reverse !important;
-}
-
-.flex-fill {
- -ms-flex: 1 1 auto !important;
- flex: 1 1 auto !important;
-}
-
-.flex-grow-0 {
- -ms-flex-positive: 0 !important;
- flex-grow: 0 !important;
-}
-
-.flex-grow-1 {
- -ms-flex-positive: 1 !important;
- flex-grow: 1 !important;
-}
-
-.flex-shrink-0 {
- -ms-flex-negative: 0 !important;
- flex-shrink: 0 !important;
-}
-
-.flex-shrink-1 {
- -ms-flex-negative: 1 !important;
- flex-shrink: 1 !important;
-}
-
-.justify-content-start {
- -ms-flex-pack: start !important;
- justify-content: flex-start !important;
-}
-
-.justify-content-end {
- -ms-flex-pack: end !important;
- justify-content: flex-end !important;
-}
-
-.justify-content-center {
- -ms-flex-pack: center !important;
- justify-content: center !important;
-}
-
-.justify-content-between {
- -ms-flex-pack: justify !important;
- justify-content: space-between !important;
-}
-
-.justify-content-around {
- -ms-flex-pack: distribute !important;
- justify-content: space-around !important;
-}
-
-.align-items-start {
- -ms-flex-align: start !important;
- align-items: flex-start !important;
-}
-
-.align-items-end {
- -ms-flex-align: end !important;
- align-items: flex-end !important;
-}
-
-.align-items-center {
- -ms-flex-align: center !important;
- align-items: center !important;
-}
-
-.align-items-baseline {
- -ms-flex-align: baseline !important;
- align-items: baseline !important;
-}
-
-.align-items-stretch {
- -ms-flex-align: stretch !important;
- align-items: stretch !important;
-}
-
-.align-content-start {
- -ms-flex-line-pack: start !important;
- align-content: flex-start !important;
-}
-
-.align-content-end {
- -ms-flex-line-pack: end !important;
- align-content: flex-end !important;
-}
-
-.align-content-center {
- -ms-flex-line-pack: center !important;
- align-content: center !important;
-}
-
-.align-content-between {
- -ms-flex-line-pack: justify !important;
- align-content: space-between !important;
-}
-
-.align-content-around {
- -ms-flex-line-pack: distribute !important;
- align-content: space-around !important;
-}
-
-.align-content-stretch {
- -ms-flex-line-pack: stretch !important;
- align-content: stretch !important;
-}
-
-.align-self-auto {
- -ms-flex-item-align: auto !important;
- align-self: auto !important;
-}
-
-.align-self-start {
- -ms-flex-item-align: start !important;
- align-self: flex-start !important;
-}
-
-.align-self-end {
- -ms-flex-item-align: end !important;
- align-self: flex-end !important;
-}
-
-.align-self-center {
- -ms-flex-item-align: center !important;
- align-self: center !important;
-}
-
-.align-self-baseline {
- -ms-flex-item-align: baseline !important;
- align-self: baseline !important;
-}
-
-.align-self-stretch {
- -ms-flex-item-align: stretch !important;
- align-self: stretch !important;
-}
-
-@media (min-width: 576px) {
- .flex-sm-row {
- -ms-flex-direction: row !important;
- flex-direction: row !important;
- }
- .flex-sm-column {
- -ms-flex-direction: column !important;
- flex-direction: column !important;
- }
- .flex-sm-row-reverse {
- -ms-flex-direction: row-reverse !important;
- flex-direction: row-reverse !important;
- }
- .flex-sm-column-reverse {
- -ms-flex-direction: column-reverse !important;
- flex-direction: column-reverse !important;
- }
- .flex-sm-wrap {
- -ms-flex-wrap: wrap !important;
- flex-wrap: wrap !important;
- }
- .flex-sm-nowrap {
- -ms-flex-wrap: nowrap !important;
- flex-wrap: nowrap !important;
- }
- .flex-sm-wrap-reverse {
- -ms-flex-wrap: wrap-reverse !important;
- flex-wrap: wrap-reverse !important;
- }
- .flex-sm-fill {
- -ms-flex: 1 1 auto !important;
- flex: 1 1 auto !important;
- }
- .flex-sm-grow-0 {
- -ms-flex-positive: 0 !important;
- flex-grow: 0 !important;
- }
- .flex-sm-grow-1 {
- -ms-flex-positive: 1 !important;
- flex-grow: 1 !important;
- }
- .flex-sm-shrink-0 {
- -ms-flex-negative: 0 !important;
- flex-shrink: 0 !important;
- }
- .flex-sm-shrink-1 {
- -ms-flex-negative: 1 !important;
- flex-shrink: 1 !important;
- }
- .justify-content-sm-start {
- -ms-flex-pack: start !important;
- justify-content: flex-start !important;
- }
- .justify-content-sm-end {
- -ms-flex-pack: end !important;
- justify-content: flex-end !important;
- }
- .justify-content-sm-center {
- -ms-flex-pack: center !important;
- justify-content: center !important;
- }
- .justify-content-sm-between {
- -ms-flex-pack: justify !important;
- justify-content: space-between !important;
- }
- .justify-content-sm-around {
- -ms-flex-pack: distribute !important;
- justify-content: space-around !important;
- }
- .align-items-sm-start {
- -ms-flex-align: start !important;
- align-items: flex-start !important;
- }
- .align-items-sm-end {
- -ms-flex-align: end !important;
- align-items: flex-end !important;
- }
- .align-items-sm-center {
- -ms-flex-align: center !important;
- align-items: center !important;
- }
- .align-items-sm-baseline {
- -ms-flex-align: baseline !important;
- align-items: baseline !important;
- }
- .align-items-sm-stretch {
- -ms-flex-align: stretch !important;
- align-items: stretch !important;
- }
- .align-content-sm-start {
- -ms-flex-line-pack: start !important;
- align-content: flex-start !important;
- }
- .align-content-sm-end {
- -ms-flex-line-pack: end !important;
- align-content: flex-end !important;
- }
- .align-content-sm-center {
- -ms-flex-line-pack: center !important;
- align-content: center !important;
- }
- .align-content-sm-between {
- -ms-flex-line-pack: justify !important;
- align-content: space-between !important;
- }
- .align-content-sm-around {
- -ms-flex-line-pack: distribute !important;
- align-content: space-around !important;
- }
- .align-content-sm-stretch {
- -ms-flex-line-pack: stretch !important;
- align-content: stretch !important;
- }
- .align-self-sm-auto {
- -ms-flex-item-align: auto !important;
- align-self: auto !important;
- }
- .align-self-sm-start {
- -ms-flex-item-align: start !important;
- align-self: flex-start !important;
- }
- .align-self-sm-end {
- -ms-flex-item-align: end !important;
- align-self: flex-end !important;
- }
- .align-self-sm-center {
- -ms-flex-item-align: center !important;
- align-self: center !important;
- }
- .align-self-sm-baseline {
- -ms-flex-item-align: baseline !important;
- align-self: baseline !important;
- }
- .align-self-sm-stretch {
- -ms-flex-item-align: stretch !important;
- align-self: stretch !important;
- }
-}
-
-@media (min-width: 768px) {
- .flex-md-row {
- -ms-flex-direction: row !important;
- flex-direction: row !important;
- }
- .flex-md-column {
- -ms-flex-direction: column !important;
- flex-direction: column !important;
- }
- .flex-md-row-reverse {
- -ms-flex-direction: row-reverse !important;
- flex-direction: row-reverse !important;
- }
- .flex-md-column-reverse {
- -ms-flex-direction: column-reverse !important;
- flex-direction: column-reverse !important;
- }
- .flex-md-wrap {
- -ms-flex-wrap: wrap !important;
- flex-wrap: wrap !important;
- }
- .flex-md-nowrap {
- -ms-flex-wrap: nowrap !important;
- flex-wrap: nowrap !important;
- }
- .flex-md-wrap-reverse {
- -ms-flex-wrap: wrap-reverse !important;
- flex-wrap: wrap-reverse !important;
- }
- .flex-md-fill {
- -ms-flex: 1 1 auto !important;
- flex: 1 1 auto !important;
- }
- .flex-md-grow-0 {
- -ms-flex-positive: 0 !important;
- flex-grow: 0 !important;
- }
- .flex-md-grow-1 {
- -ms-flex-positive: 1 !important;
- flex-grow: 1 !important;
- }
- .flex-md-shrink-0 {
- -ms-flex-negative: 0 !important;
- flex-shrink: 0 !important;
- }
- .flex-md-shrink-1 {
- -ms-flex-negative: 1 !important;
- flex-shrink: 1 !important;
- }
- .justify-content-md-start {
- -ms-flex-pack: start !important;
- justify-content: flex-start !important;
- }
- .justify-content-md-end {
- -ms-flex-pack: end !important;
- justify-content: flex-end !important;
- }
- .justify-content-md-center {
- -ms-flex-pack: center !important;
- justify-content: center !important;
- }
- .justify-content-md-between {
- -ms-flex-pack: justify !important;
- justify-content: space-between !important;
- }
- .justify-content-md-around {
- -ms-flex-pack: distribute !important;
- justify-content: space-around !important;
- }
- .align-items-md-start {
- -ms-flex-align: start !important;
- align-items: flex-start !important;
- }
- .align-items-md-end {
- -ms-flex-align: end !important;
- align-items: flex-end !important;
- }
- .align-items-md-center {
- -ms-flex-align: center !important;
- align-items: center !important;
- }
- .align-items-md-baseline {
- -ms-flex-align: baseline !important;
- align-items: baseline !important;
- }
- .align-items-md-stretch {
- -ms-flex-align: stretch !important;
- align-items: stretch !important;
- }
- .align-content-md-start {
- -ms-flex-line-pack: start !important;
- align-content: flex-start !important;
- }
- .align-content-md-end {
- -ms-flex-line-pack: end !important;
- align-content: flex-end !important;
- }
- .align-content-md-center {
- -ms-flex-line-pack: center !important;
- align-content: center !important;
- }
- .align-content-md-between {
- -ms-flex-line-pack: justify !important;
- align-content: space-between !important;
- }
- .align-content-md-around {
- -ms-flex-line-pack: distribute !important;
- align-content: space-around !important;
- }
- .align-content-md-stretch {
- -ms-flex-line-pack: stretch !important;
- align-content: stretch !important;
- }
- .align-self-md-auto {
- -ms-flex-item-align: auto !important;
- align-self: auto !important;
- }
- .align-self-md-start {
- -ms-flex-item-align: start !important;
- align-self: flex-start !important;
- }
- .align-self-md-end {
- -ms-flex-item-align: end !important;
- align-self: flex-end !important;
- }
- .align-self-md-center {
- -ms-flex-item-align: center !important;
- align-self: center !important;
- }
- .align-self-md-baseline {
- -ms-flex-item-align: baseline !important;
- align-self: baseline !important;
- }
- .align-self-md-stretch {
- -ms-flex-item-align: stretch !important;
- align-self: stretch !important;
- }
-}
-
-@media (min-width: 992px) {
- .flex-lg-row {
- -ms-flex-direction: row !important;
- flex-direction: row !important;
- }
- .flex-lg-column {
- -ms-flex-direction: column !important;
- flex-direction: column !important;
- }
- .flex-lg-row-reverse {
- -ms-flex-direction: row-reverse !important;
- flex-direction: row-reverse !important;
- }
- .flex-lg-column-reverse {
- -ms-flex-direction: column-reverse !important;
- flex-direction: column-reverse !important;
- }
- .flex-lg-wrap {
- -ms-flex-wrap: wrap !important;
- flex-wrap: wrap !important;
- }
- .flex-lg-nowrap {
- -ms-flex-wrap: nowrap !important;
- flex-wrap: nowrap !important;
- }
- .flex-lg-wrap-reverse {
- -ms-flex-wrap: wrap-reverse !important;
- flex-wrap: wrap-reverse !important;
- }
- .flex-lg-fill {
- -ms-flex: 1 1 auto !important;
- flex: 1 1 auto !important;
- }
- .flex-lg-grow-0 {
- -ms-flex-positive: 0 !important;
- flex-grow: 0 !important;
- }
- .flex-lg-grow-1 {
- -ms-flex-positive: 1 !important;
- flex-grow: 1 !important;
- }
- .flex-lg-shrink-0 {
- -ms-flex-negative: 0 !important;
- flex-shrink: 0 !important;
- }
- .flex-lg-shrink-1 {
- -ms-flex-negative: 1 !important;
- flex-shrink: 1 !important;
- }
- .justify-content-lg-start {
- -ms-flex-pack: start !important;
- justify-content: flex-start !important;
- }
- .justify-content-lg-end {
- -ms-flex-pack: end !important;
- justify-content: flex-end !important;
- }
- .justify-content-lg-center {
- -ms-flex-pack: center !important;
- justify-content: center !important;
- }
- .justify-content-lg-between {
- -ms-flex-pack: justify !important;
- justify-content: space-between !important;
- }
- .justify-content-lg-around {
- -ms-flex-pack: distribute !important;
- justify-content: space-around !important;
- }
- .align-items-lg-start {
- -ms-flex-align: start !important;
- align-items: flex-start !important;
- }
- .align-items-lg-end {
- -ms-flex-align: end !important;
- align-items: flex-end !important;
- }
- .align-items-lg-center {
- -ms-flex-align: center !important;
- align-items: center !important;
- }
- .align-items-lg-baseline {
- -ms-flex-align: baseline !important;
- align-items: baseline !important;
- }
- .align-items-lg-stretch {
- -ms-flex-align: stretch !important;
- align-items: stretch !important;
- }
- .align-content-lg-start {
- -ms-flex-line-pack: start !important;
- align-content: flex-start !important;
- }
- .align-content-lg-end {
- -ms-flex-line-pack: end !important;
- align-content: flex-end !important;
- }
- .align-content-lg-center {
- -ms-flex-line-pack: center !important;
- align-content: center !important;
- }
- .align-content-lg-between {
- -ms-flex-line-pack: justify !important;
- align-content: space-between !important;
- }
- .align-content-lg-around {
- -ms-flex-line-pack: distribute !important;
- align-content: space-around !important;
- }
- .align-content-lg-stretch {
- -ms-flex-line-pack: stretch !important;
- align-content: stretch !important;
- }
- .align-self-lg-auto {
- -ms-flex-item-align: auto !important;
- align-self: auto !important;
- }
- .align-self-lg-start {
- -ms-flex-item-align: start !important;
- align-self: flex-start !important;
- }
- .align-self-lg-end {
- -ms-flex-item-align: end !important;
- align-self: flex-end !important;
- }
- .align-self-lg-center {
- -ms-flex-item-align: center !important;
- align-self: center !important;
- }
- .align-self-lg-baseline {
- -ms-flex-item-align: baseline !important;
- align-self: baseline !important;
- }
- .align-self-lg-stretch {
- -ms-flex-item-align: stretch !important;
- align-self: stretch !important;
- }
-}
-
-@media (min-width: 1200px) {
- .flex-xl-row {
- -ms-flex-direction: row !important;
- flex-direction: row !important;
- }
- .flex-xl-column {
- -ms-flex-direction: column !important;
- flex-direction: column !important;
- }
- .flex-xl-row-reverse {
- -ms-flex-direction: row-reverse !important;
- flex-direction: row-reverse !important;
- }
- .flex-xl-column-reverse {
- -ms-flex-direction: column-reverse !important;
- flex-direction: column-reverse !important;
- }
- .flex-xl-wrap {
- -ms-flex-wrap: wrap !important;
- flex-wrap: wrap !important;
- }
- .flex-xl-nowrap {
- -ms-flex-wrap: nowrap !important;
- flex-wrap: nowrap !important;
- }
- .flex-xl-wrap-reverse {
- -ms-flex-wrap: wrap-reverse !important;
- flex-wrap: wrap-reverse !important;
- }
- .flex-xl-fill {
- -ms-flex: 1 1 auto !important;
- flex: 1 1 auto !important;
- }
- .flex-xl-grow-0 {
- -ms-flex-positive: 0 !important;
- flex-grow: 0 !important;
- }
- .flex-xl-grow-1 {
- -ms-flex-positive: 1 !important;
- flex-grow: 1 !important;
- }
- .flex-xl-shrink-0 {
- -ms-flex-negative: 0 !important;
- flex-shrink: 0 !important;
- }
- .flex-xl-shrink-1 {
- -ms-flex-negative: 1 !important;
- flex-shrink: 1 !important;
- }
- .justify-content-xl-start {
- -ms-flex-pack: start !important;
- justify-content: flex-start !important;
- }
- .justify-content-xl-end {
- -ms-flex-pack: end !important;
- justify-content: flex-end !important;
- }
- .justify-content-xl-center {
- -ms-flex-pack: center !important;
- justify-content: center !important;
- }
- .justify-content-xl-between {
- -ms-flex-pack: justify !important;
- justify-content: space-between !important;
- }
- .justify-content-xl-around {
- -ms-flex-pack: distribute !important;
- justify-content: space-around !important;
- }
- .align-items-xl-start {
- -ms-flex-align: start !important;
- align-items: flex-start !important;
- }
- .align-items-xl-end {
- -ms-flex-align: end !important;
- align-items: flex-end !important;
- }
- .align-items-xl-center {
- -ms-flex-align: center !important;
- align-items: center !important;
- }
- .align-items-xl-baseline {
- -ms-flex-align: baseline !important;
- align-items: baseline !important;
- }
- .align-items-xl-stretch {
- -ms-flex-align: stretch !important;
- align-items: stretch !important;
- }
- .align-content-xl-start {
- -ms-flex-line-pack: start !important;
- align-content: flex-start !important;
- }
- .align-content-xl-end {
- -ms-flex-line-pack: end !important;
- align-content: flex-end !important;
- }
- .align-content-xl-center {
- -ms-flex-line-pack: center !important;
- align-content: center !important;
- }
- .align-content-xl-between {
- -ms-flex-line-pack: justify !important;
- align-content: space-between !important;
- }
- .align-content-xl-around {
- -ms-flex-line-pack: distribute !important;
- align-content: space-around !important;
- }
- .align-content-xl-stretch {
- -ms-flex-line-pack: stretch !important;
- align-content: stretch !important;
- }
- .align-self-xl-auto {
- -ms-flex-item-align: auto !important;
- align-self: auto !important;
- }
- .align-self-xl-start {
- -ms-flex-item-align: start !important;
- align-self: flex-start !important;
- }
- .align-self-xl-end {
- -ms-flex-item-align: end !important;
- align-self: flex-end !important;
- }
- .align-self-xl-center {
- -ms-flex-item-align: center !important;
- align-self: center !important;
- }
- .align-self-xl-baseline {
- -ms-flex-item-align: baseline !important;
- align-self: baseline !important;
- }
- .align-self-xl-stretch {
- -ms-flex-item-align: stretch !important;
- align-self: stretch !important;
- }
-}
-/*# sourceMappingURL=bootstrap-grid.css.map */
\ No newline at end of file
diff --git a/dapps/demo/src/css/bootstrap-grid.css.map b/dapps/demo/src/css/bootstrap-grid.css.map
deleted file mode 100644
index a636ccee5..000000000
--- a/dapps/demo/src/css/bootstrap-grid.css.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["../../scss/bootstrap-grid.scss","bootstrap-grid.css","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/_variables.scss","../../scss/mixins/_grid-framework.scss","../../scss/utilities/_display.scss","../../scss/utilities/_flex.scss"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGD;EAAgB,oBAAmB;CCApC;;ADGD;EACE,uBAAsB;EACtB,8BAA6B;CAC9B;;AAED;;;EAGE,oBAAmB;CACpB;;AEfC;ECAA,YAAW;EACX,oBAAuC;EACvC,mBAAsC;EACtC,mBAAkB;EAClB,kBAAiB;CDDhB;;AEoDC;EFvDF;ICYI,iBEwLK;GHjMR;CDyBF;;AG2BG;EFvDF;ICYI,iBEyLK;GHlMR;CD+BF;;AGqBG;EFvDF;ICYI,iBE0LK;GHnMR;CDqCF;;AGeG;EFvDF;ICYI,kBE2LM;GHpMT;CD2CF;;AClCC;ECZA,YAAW;EACX,oBAAuC;EACvC,mBAAsC;EACtC,mBAAkB;EAClB,kBAAiB;CDUhB;;AAQD;ECJA,qBAAa;EAAb,cAAa;EACb,oBAAe;EAAf,gBAAe;EACf,oBAAuC;EACvC,mBAAsC;CDGrC;;AAID;EACE,gBAAe;EACf,eAAc;CAOf;;AATD;;EAMI,iBAAgB;EAChB,gBAAe;CAChB;;AIlCH;;;;;;EACE,mBAAkB;EAClB,YAAW;EACX,gBAAe;EACf,oBAA4B;EAC5B,mBAA2B;CAC5B;;AAkBG;EACE,2BAAa;EAAb,cAAa;EACb,qBAAY;EAAZ,aAAY;EACZ,gBAAe;CAChB;;AACD;EACE,mBAAc;EAAd,eAAc;EACd,YAAW;EACX,gBAAe;CAChB;;AAGC;EHFN,wBAAsC;EAAtC,oBAAsC;EAItC,qBAAuC;CGAhC;;AAFD;EHFN,yBAAsC;EAAtC,qBAAsC;EAItC,sBAAuC;CGAhC;;AAFD;EHFN,kBAAsC;EAAtC,cAAsC;EAItC,eAAuC;CGAhC;;AAFD;EHFN,yBAAsC;EAAtC,qBAAsC;EAItC,sBAAuC;CGAhC;;AAFD;EHFN,yBAAsC;EAAtC,qBAAsC;EAItC,sBAAuC;CGAhC;;AAFD;EHFN,kBAAsC;EAAtC,cAAsC;EAItC,eAAuC;CGAhC;;AAFD;EHFN,yBAAsC;EAAtC,qBAAsC;EAItC,sBAAuC;CGAhC;;AAFD;EHFN,yBAAsC;EAAtC,qBAAsC;EAItC,sBAAuC;CGAhC;;AAFD;EHFN,kBAAsC;EAAtC,cAAsC;EAItC,eAAuC;CGAhC;;AAFD;EHFN,yBAAsC;EAAtC,qBAAsC;EAItC,sBAAuC;CGAhC;;AAFD;EHFN,yBAAsC;EAAtC,qBAAsC;EAItC,sBAAuC;CGAhC;;AAFD;EHFN,mBAAsC;EAAtC,eAAsC;EAItC,gBAAuC;CGAhC;;AAGH;EAAwB,mBAAS;EAAT,UAAS;CAAI;;AAErC;EAAuB,mBDoKG;ECpKH,UDoKG;CCpKoB;;AAG5C;EAAwB,kBADZ;EACY,SADZ;CACyB;;AAArC;EAAwB,kBADZ;EACY,SADZ;CACyB;;AAArC;EAAwB,kBADZ;EACY,SADZ;CACyB;;AAArC;EAAwB,kBADZ;EACY,SADZ;CACyB;;AAArC;EAAwB,kBADZ;EACY,SADZ;CACyB;;AAArC;EAAwB,kBADZ;EACY,SADZ;CACyB;;AAArC;EAAwB,kBADZ;EACY,SADZ;CACyB;;AAArC;EAAwB,kBADZ;EACY,SADZ;CACyB;;AAArC;EAAwB,kBADZ;EACY,SADZ;CACyB;;AAArC;EAAwB,kBADZ;EACY,SADZ;CACyB;;AAArC;EAAwB,mBADZ;EACY,UADZ;CACyB;;AAArC;EAAwB,mBADZ;EACY,UADZ;CACyB;;AAArC;EAAwB,mBADZ;EACY,UADZ;CACyB;;AAMnC;EHTR,uBAA8C;CGWrC;;AAFD;EHTR,wBAA8C;CGWrC;;AAFD;EHTR,iBAA8C;CGWrC;;AAFD;EHTR,wBAA8C;CGWrC;;AAFD;EHTR,wBAA8C;CGWrC;;AAFD;EHTR,iBAA8C;CGWrC;;AAFD;EHTR,wBAA8C;CGWrC;;AAFD;EHTR,wBAA8C;CGWrC;;AAFD;EHTR,iBAA8C;CGWrC;;AAFD;EHTR,wBAA8C;CGWrC;;AAFD;EHTR,wBAA8C;CGWrC;;AFDP;EE7BE;IACE,2BAAa;IAAb,cAAa;IACb,qBAAY;IAAZ,aAAY;IACZ,gBAAe;GAChB;EACD;IACE,mBAAc;IAAd,eAAc;IACd,YAAW;IACX,gBAAe;GAChB;EAGC;IHFN,wBAAsC;IAAtC,oBAAsC;IAItC,qBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,kBAAsC;IAAtC,cAAsC;IAItC,eAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,kBAAsC;IAAtC,cAAsC;IAItC,eAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,kBAAsC;IAAtC,cAAsC;IAItC,eAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,mBAAsC;IAAtC,eAAsC;IAItC,gBAAuC;GGAhC;EAGH;IAAwB,mBAAS;IAAT,UAAS;GAAI;EAErC;IAAuB,mBDoKG;ICpKH,UDoKG;GCpKoB;EAG5C;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,mBADZ;IACY,UADZ;GACyB;EAArC;IAAwB,mBADZ;IACY,UADZ;GACyB;EAArC;IAAwB,mBADZ;IACY,UADZ;GACyB;EAMnC;IHTR,eAA4B;GGWnB;EAFD;IHTR,uBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,iBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,iBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,iBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;CL2VV;;AG5VG;EE7BE;IACE,2BAAa;IAAb,cAAa;IACb,qBAAY;IAAZ,aAAY;IACZ,gBAAe;GAChB;EACD;IACE,mBAAc;IAAd,eAAc;IACd,YAAW;IACX,gBAAe;GAChB;EAGC;IHFN,wBAAsC;IAAtC,oBAAsC;IAItC,qBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,kBAAsC;IAAtC,cAAsC;IAItC,eAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,kBAAsC;IAAtC,cAAsC;IAItC,eAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,kBAAsC;IAAtC,cAAsC;IAItC,eAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,mBAAsC;IAAtC,eAAsC;IAItC,gBAAuC;GGAhC;EAGH;IAAwB,mBAAS;IAAT,UAAS;GAAI;EAErC;IAAuB,mBDoKG;ICpKH,UDoKG;GCpKoB;EAG5C;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,mBADZ;IACY,UADZ;GACyB;EAArC;IAAwB,mBADZ;IACY,UADZ;GACyB;EAArC;IAAwB,mBADZ;IACY,UADZ;GACyB;EAMnC;IHTR,eAA4B;GGWnB;EAFD;IHTR,uBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,iBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,iBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,iBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;CLyeV;;AG1eG;EE7BE;IACE,2BAAa;IAAb,cAAa;IACb,qBAAY;IAAZ,aAAY;IACZ,gBAAe;GAChB;EACD;IACE,mBAAc;IAAd,eAAc;IACd,YAAW;IACX,gBAAe;GAChB;EAGC;IHFN,wBAAsC;IAAtC,oBAAsC;IAItC,qBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,kBAAsC;IAAtC,cAAsC;IAItC,eAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,kBAAsC;IAAtC,cAAsC;IAItC,eAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,kBAAsC;IAAtC,cAAsC;IAItC,eAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,mBAAsC;IAAtC,eAAsC;IAItC,gBAAuC;GGAhC;EAGH;IAAwB,mBAAS;IAAT,UAAS;GAAI;EAErC;IAAuB,mBDoKG;ICpKH,UDoKG;GCpKoB;EAG5C;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,mBADZ;IACY,UADZ;GACyB;EAArC;IAAwB,mBADZ;IACY,UADZ;GACyB;EAArC;IAAwB,mBADZ;IACY,UADZ;GACyB;EAMnC;IHTR,eAA4B;GGWnB;EAFD;IHTR,uBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,iBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,iBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,iBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;CLunBV;;AGxnBG;EE7BE;IACE,2BAAa;IAAb,cAAa;IACb,qBAAY;IAAZ,aAAY;IACZ,gBAAe;GAChB;EACD;IACE,mBAAc;IAAd,eAAc;IACd,YAAW;IACX,gBAAe;GAChB;EAGC;IHFN,wBAAsC;IAAtC,oBAAsC;IAItC,qBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,kBAAsC;IAAtC,cAAsC;IAItC,eAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,kBAAsC;IAAtC,cAAsC;IAItC,eAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,kBAAsC;IAAtC,cAAsC;IAItC,eAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,yBAAsC;IAAtC,qBAAsC;IAItC,sBAAuC;GGAhC;EAFD;IHFN,mBAAsC;IAAtC,eAAsC;IAItC,gBAAuC;GGAhC;EAGH;IAAwB,mBAAS;IAAT,UAAS;GAAI;EAErC;IAAuB,mBDoKG;ICpKH,UDoKG;GCpKoB;EAG5C;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,kBADZ;IACY,SADZ;GACyB;EAArC;IAAwB,mBADZ;IACY,UADZ;GACyB;EAArC;IAAwB,mBADZ;IACY,UADZ;GACyB;EAArC;IAAwB,mBADZ;IACY,UADZ;GACyB;EAMnC;IHTR,eAA4B;GGWnB;EAFD;IHTR,uBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,iBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,iBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,iBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;EAFD;IHTR,wBAA8C;GGWrC;CLqwBV;;AMxzBG;EAA2B,yBAAwB;CAAI;;AACvD;EAA2B,2BAA0B;CAAI;;AACzD;EAA2B,iCAAgC;CAAI;;AAC/D;EAA2B,0BAAyB;CAAI;;AACxD;EAA2B,0BAAyB;CAAI;;AACxD;EAA2B,8BAA6B;CAAI;;AAC5D;EAA2B,+BAA8B;CAAI;;AAC7D;EAA2B,gCAAwB;EAAxB,yBAAwB;CAAI;;AACvD;EAA2B,uCAA+B;EAA/B,gCAA+B;CAAI;;AH0C9D;EGlDA;IAA2B,yBAAwB;GAAI;EACvD;IAA2B,2BAA0B;GAAI;EACzD;IAA2B,iCAAgC;GAAI;EAC/D;IAA2B,0BAAyB;GAAI;EACxD;IAA2B,0BAAyB;GAAI;EACxD;IAA2B,8BAA6B;GAAI;EAC5D;IAA2B,+BAA8B;GAAI;EAC7D;IAA2B,gCAAwB;IAAxB,yBAAwB;GAAI;EACvD;IAA2B,uCAA+B;IAA/B,gCAA+B;GAAI;CNk3BjE;;AGx0BG;EGlDA;IAA2B,yBAAwB;GAAI;EACvD;IAA2B,2BAA0B;GAAI;EACzD;IAA2B,iCAAgC;GAAI;EAC/D;IAA2B,0BAAyB;GAAI;EACxD;IAA2B,0BAAyB;GAAI;EACxD;IAA2B,8BAA6B;GAAI;EAC5D;IAA2B,+BAA8B;GAAI;EAC7D;IAA2B,gCAAwB;IAAxB,yBAAwB;GAAI;EACvD;IAA2B,uCAA+B;IAA/B,gCAA+B;GAAI;CNg5BjE;;AGt2BG;EGlDA;IAA2B,yBAAwB;GAAI;EACvD;IAA2B,2BAA0B;GAAI;EACzD;IAA2B,iCAAgC;GAAI;EAC/D;IAA2B,0BAAyB;GAAI;EACxD;IAA2B,0BAAyB;GAAI;EACxD;IAA2B,8BAA6B;GAAI;EAC5D;IAA2B,+BAA8B;GAAI;EAC7D;IAA2B,gCAAwB;IAAxB,yBAAwB;GAAI;EACvD;IAA2B,uCAA+B;IAA/B,gCAA+B;GAAI;CN86BjE;;AGp4BG;EGlDA;IAA2B,yBAAwB;GAAI;EACvD;IAA2B,2BAA0B;GAAI;EACzD;IAA2B,iCAAgC;GAAI;EAC/D;IAA2B,0BAAyB;GAAI;EACxD;IAA2B,0BAAyB;GAAI;EACxD;IAA2B,8BAA6B;GAAI;EAC5D;IAA2B,+BAA8B;GAAI;EAC7D;IAA2B,gCAAwB;IAAxB,yBAAwB;GAAI;EACvD;IAA2B,uCAA+B;IAA/B,gCAA+B;GAAI;CN48BjE;;AMn8BD;EACE;IAAwB,yBAAwB;GAAI;EACpD;IAAwB,2BAA0B;GAAI;EACtD;IAAwB,iCAAgC;GAAI;EAC5D;IAAwB,0BAAyB;GAAI;EACrD;IAAwB,0BAAyB;GAAI;EACrD;IAAwB,8BAA6B;GAAI;EACzD;IAAwB,+BAA8B;GAAI;EAC1D;IAAwB,gCAAwB;IAAxB,yBAAwB;GAAI;EACpD;IAAwB,uCAA+B;IAA/B,gCAA+B;GAAI;CNw9B5D;;AOl/BG;EAAgC,mCAA8B;EAA9B,+BAA8B;CAAI;;AAClE;EAAgC,sCAAiC;EAAjC,kCAAiC;CAAI;;AACrE;EAAgC,2CAAsC;EAAtC,uCAAsC;CAAI;;AAC1E;EAAgC,8CAAyC;EAAzC,0CAAyC;CAAI;;AAE7E;EAA8B,+BAA0B;EAA1B,2BAA0B;CAAI;;AAC5D;EAA8B,iCAA4B;EAA5B,6BAA4B;CAAI;;AAC9D;EAA8B,uCAAkC;EAAlC,mCAAkC;CAAI;;AACpE;EAA8B,8BAAyB;EAAzB,0BAAyB;CAAI;;AAC3D;EAA8B,gCAAuB;EAAvB,wBAAuB;CAAI;;AACzD;EAA8B,gCAAuB;EAAvB,wBAAuB;CAAI;;AACzD;EAA8B,gCAAyB;EAAzB,0BAAyB;CAAI;;AAC3D;EAA8B,gCAAyB;EAAzB,0BAAyB;CAAI;;AAE3D;EAAoC,gCAAsC;EAAtC,uCAAsC;CAAI;;AAC9E;EAAoC,8BAAoC;EAApC,qCAAoC;CAAI;;AAC5E;EAAoC,iCAAkC;EAAlC,mCAAkC;CAAI;;AAC1E;EAAoC,kCAAyC;EAAzC,0CAAyC;CAAI;;AACjF;EAAoC,qCAAwC;EAAxC,yCAAwC;CAAI;;AAEhF;EAAiC,iCAAkC;EAAlC,mCAAkC;CAAI;;AACvE;EAAiC,+BAAgC;EAAhC,iCAAgC;CAAI;;AACrE;EAAiC,kCAA8B;EAA9B,+BAA8B;CAAI;;AACnE;EAAiC,oCAAgC;EAAhC,iCAAgC;CAAI;;AACrE;EAAiC,mCAA+B;EAA/B,gCAA+B;CAAI;;AAEpE;EAAkC,qCAAoC;EAApC,qCAAoC;CAAI;;AAC1E;EAAkC,mCAAkC;EAAlC,mCAAkC;CAAI;;AACxE;EAAkC,sCAAgC;EAAhC,iCAAgC;CAAI;;AACtE;EAAkC,uCAAuC;EAAvC,wCAAuC;CAAI;;AAC7E;EAAkC,0CAAsC;EAAtC,uCAAsC;CAAI;;AAC5E;EAAkC,uCAAiC;EAAjC,kCAAiC;CAAI;;AAEvE;EAAgC,qCAA2B;EAA3B,4BAA2B;CAAI;;AAC/D;EAAgC,sCAAiC;EAAjC,kCAAiC;CAAI;;AACrE;EAAgC,oCAA+B;EAA/B,gCAA+B;CAAI;;AACnE;EAAgC,uCAA6B;EAA7B,8BAA6B;CAAI;;AACjE;EAAgC,yCAA+B;EAA/B,gCAA+B;CAAI;;AACnE;EAAgC,wCAA8B;EAA9B,+BAA8B;CAAI;;AJYlE;EIlDA;IAAgC,mCAA8B;IAA9B,+BAA8B;GAAI;EAClE;IAAgC,sCAAiC;IAAjC,kCAAiC;GAAI;EACrE;IAAgC,2CAAsC;IAAtC,uCAAsC;GAAI;EAC1E;IAAgC,8CAAyC;IAAzC,0CAAyC;GAAI;EAE7E;IAA8B,+BAA0B;IAA1B,2BAA0B;GAAI;EAC5D;IAA8B,iCAA4B;IAA5B,6BAA4B;GAAI;EAC9D;IAA8B,uCAAkC;IAAlC,mCAAkC;GAAI;EACpE;IAA8B,8BAAyB;IAAzB,0BAAyB;GAAI;EAC3D;IAA8B,gCAAuB;IAAvB,wBAAuB;GAAI;EACzD;IAA8B,gCAAuB;IAAvB,wBAAuB;GAAI;EACzD;IAA8B,gCAAyB;IAAzB,0BAAyB;GAAI;EAC3D;IAA8B,gCAAyB;IAAzB,0BAAyB;GAAI;EAE3D;IAAoC,gCAAsC;IAAtC,uCAAsC;GAAI;EAC9E;IAAoC,8BAAoC;IAApC,qCAAoC;GAAI;EAC5E;IAAoC,iCAAkC;IAAlC,mCAAkC;GAAI;EAC1E;IAAoC,kCAAyC;IAAzC,0CAAyC;GAAI;EACjF;IAAoC,qCAAwC;IAAxC,yCAAwC;GAAI;EAEhF;IAAiC,iCAAkC;IAAlC,mCAAkC;GAAI;EACvE;IAAiC,+BAAgC;IAAhC,iCAAgC;GAAI;EACrE;IAAiC,kCAA8B;IAA9B,+BAA8B;GAAI;EACnE;IAAiC,oCAAgC;IAAhC,iCAAgC;GAAI;EACrE;IAAiC,mCAA+B;IAA/B,gCAA+B;GAAI;EAEpE;IAAkC,qCAAoC;IAApC,qCAAoC;GAAI;EAC1E;IAAkC,mCAAkC;IAAlC,mCAAkC;GAAI;EACxE;IAAkC,sCAAgC;IAAhC,iCAAgC;GAAI;EACtE;IAAkC,uCAAuC;IAAvC,wCAAuC;GAAI;EAC7E;IAAkC,0CAAsC;IAAtC,uCAAsC;GAAI;EAC5E;IAAkC,uCAAiC;IAAjC,kCAAiC;GAAI;EAEvE;IAAgC,qCAA2B;IAA3B,4BAA2B;GAAI;EAC/D;IAAgC,sCAAiC;IAAjC,kCAAiC;GAAI;EACrE;IAAgC,oCAA+B;IAA/B,gCAA+B;GAAI;EACnE;IAAgC,uCAA6B;IAA7B,8BAA6B;GAAI;EACjE;IAAgC,yCAA+B;IAA/B,gCAA+B;GAAI;EACnE;IAAgC,wCAA8B;IAA9B,+BAA8B;GAAI;CP6rCrE;;AGjrCG;EIlDA;IAAgC,mCAA8B;IAA9B,+BAA8B;GAAI;EAClE;IAAgC,sCAAiC;IAAjC,kCAAiC;GAAI;EACrE;IAAgC,2CAAsC;IAAtC,uCAAsC;GAAI;EAC1E;IAAgC,8CAAyC;IAAzC,0CAAyC;GAAI;EAE7E;IAA8B,+BAA0B;IAA1B,2BAA0B;GAAI;EAC5D;IAA8B,iCAA4B;IAA5B,6BAA4B;GAAI;EAC9D;IAA8B,uCAAkC;IAAlC,mCAAkC;GAAI;EACpE;IAA8B,8BAAyB;IAAzB,0BAAyB;GAAI;EAC3D;IAA8B,gCAAuB;IAAvB,wBAAuB;GAAI;EACzD;IAA8B,gCAAuB;IAAvB,wBAAuB;GAAI;EACzD;IAA8B,gCAAyB;IAAzB,0BAAyB;GAAI;EAC3D;IAA8B,gCAAyB;IAAzB,0BAAyB;GAAI;EAE3D;IAAoC,gCAAsC;IAAtC,uCAAsC;GAAI;EAC9E;IAAoC,8BAAoC;IAApC,qCAAoC;GAAI;EAC5E;IAAoC,iCAAkC;IAAlC,mCAAkC;GAAI;EAC1E;IAAoC,kCAAyC;IAAzC,0CAAyC;GAAI;EACjF;IAAoC,qCAAwC;IAAxC,yCAAwC;GAAI;EAEhF;IAAiC,iCAAkC;IAAlC,mCAAkC;GAAI;EACvE;IAAiC,+BAAgC;IAAhC,iCAAgC;GAAI;EACrE;IAAiC,kCAA8B;IAA9B,+BAA8B;GAAI;EACnE;IAAiC,oCAAgC;IAAhC,iCAAgC;GAAI;EACrE;IAAiC,mCAA+B;IAA/B,gCAA+B;GAAI;EAEpE;IAAkC,qCAAoC;IAApC,qCAAoC;GAAI;EAC1E;IAAkC,mCAAkC;IAAlC,mCAAkC;GAAI;EACxE;IAAkC,sCAAgC;IAAhC,iCAAgC;GAAI;EACtE;IAAkC,uCAAuC;IAAvC,wCAAuC;GAAI;EAC7E;IAAkC,0CAAsC;IAAtC,uCAAsC;GAAI;EAC5E;IAAkC,uCAAiC;IAAjC,kCAAiC;GAAI;EAEvE;IAAgC,qCAA2B;IAA3B,4BAA2B;GAAI;EAC/D;IAAgC,sCAAiC;IAAjC,kCAAiC;GAAI;EACrE;IAAgC,oCAA+B;IAA/B,gCAA+B;GAAI;EACnE;IAAgC,uCAA6B;IAA7B,8BAA6B;GAAI;EACjE;IAAgC,yCAA+B;IAA/B,gCAA+B;GAAI;EACnE;IAAgC,wCAA8B;IAA9B,+BAA8B;GAAI;CPsyCrE;;AG1xCG;EIlDA;IAAgC,mCAA8B;IAA9B,+BAA8B;GAAI;EAClE;IAAgC,sCAAiC;IAAjC,kCAAiC;GAAI;EACrE;IAAgC,2CAAsC;IAAtC,uCAAsC;GAAI;EAC1E;IAAgC,8CAAyC;IAAzC,0CAAyC;GAAI;EAE7E;IAA8B,+BAA0B;IAA1B,2BAA0B;GAAI;EAC5D;IAA8B,iCAA4B;IAA5B,6BAA4B;GAAI;EAC9D;IAA8B,uCAAkC;IAAlC,mCAAkC;GAAI;EACpE;IAA8B,8BAAyB;IAAzB,0BAAyB;GAAI;EAC3D;IAA8B,gCAAuB;IAAvB,wBAAuB;GAAI;EACzD;IAA8B,gCAAuB;IAAvB,wBAAuB;GAAI;EACzD;IAA8B,gCAAyB;IAAzB,0BAAyB;GAAI;EAC3D;IAA8B,gCAAyB;IAAzB,0BAAyB;GAAI;EAE3D;IAAoC,gCAAsC;IAAtC,uCAAsC;GAAI;EAC9E;IAAoC,8BAAoC;IAApC,qCAAoC;GAAI;EAC5E;IAAoC,iCAAkC;IAAlC,mCAAkC;GAAI;EAC1E;IAAoC,kCAAyC;IAAzC,0CAAyC;GAAI;EACjF;IAAoC,qCAAwC;IAAxC,yCAAwC;GAAI;EAEhF;IAAiC,iCAAkC;IAAlC,mCAAkC;GAAI;EACvE;IAAiC,+BAAgC;IAAhC,iCAAgC;GAAI;EACrE;IAAiC,kCAA8B;IAA9B,+BAA8B;GAAI;EACnE;IAAiC,oCAAgC;IAAhC,iCAAgC;GAAI;EACrE;IAAiC,mCAA+B;IAA/B,gCAA+B;GAAI;EAEpE;IAAkC,qCAAoC;IAApC,qCAAoC;GAAI;EAC1E;IAAkC,mCAAkC;IAAlC,mCAAkC;GAAI;EACxE;IAAkC,sCAAgC;IAAhC,iCAAgC;GAAI;EACtE;IAAkC,uCAAuC;IAAvC,wCAAuC;GAAI;EAC7E;IAAkC,0CAAsC;IAAtC,uCAAsC;GAAI;EAC5E;IAAkC,uCAAiC;IAAjC,kCAAiC;GAAI;EAEvE;IAAgC,qCAA2B;IAA3B,4BAA2B;GAAI;EAC/D;IAAgC,sCAAiC;IAAjC,kCAAiC;GAAI;EACrE;IAAgC,oCAA+B;IAA/B,gCAA+B;GAAI;EACnE;IAAgC,uCAA6B;IAA7B,8BAA6B;GAAI;EACjE;IAAgC,yCAA+B;IAA/B,gCAA+B;GAAI;EACnE;IAAgC,wCAA8B;IAA9B,+BAA8B;GAAI;CP+4CrE;;AGn4CG;EIlDA;IAAgC,mCAA8B;IAA9B,+BAA8B;GAAI;EAClE;IAAgC,sCAAiC;IAAjC,kCAAiC;GAAI;EACrE;IAAgC,2CAAsC;IAAtC,uCAAsC;GAAI;EAC1E;IAAgC,8CAAyC;IAAzC,0CAAyC;GAAI;EAE7E;IAA8B,+BAA0B;IAA1B,2BAA0B;GAAI;EAC5D;IAA8B,iCAA4B;IAA5B,6BAA4B;GAAI;EAC9D;IAA8B,uCAAkC;IAAlC,mCAAkC;GAAI;EACpE;IAA8B,8BAAyB;IAAzB,0BAAyB;GAAI;EAC3D;IAA8B,gCAAuB;IAAvB,wBAAuB;GAAI;EACzD;IAA8B,gCAAuB;IAAvB,wBAAuB;GAAI;EACzD;IAA8B,gCAAyB;IAAzB,0BAAyB;GAAI;EAC3D;IAA8B,gCAAyB;IAAzB,0BAAyB;GAAI;EAE3D;IAAoC,gCAAsC;IAAtC,uCAAsC;GAAI;EAC9E;IAAoC,8BAAoC;IAApC,qCAAoC;GAAI;EAC5E;IAAoC,iCAAkC;IAAlC,mCAAkC;GAAI;EAC1E;IAAoC,kCAAyC;IAAzC,0CAAyC;GAAI;EACjF;IAAoC,qCAAwC;IAAxC,yCAAwC;GAAI;EAEhF;IAAiC,iCAAkC;IAAlC,mCAAkC;GAAI;EACvE;IAAiC,+BAAgC;IAAhC,iCAAgC;GAAI;EACrE;IAAiC,kCAA8B;IAA9B,+BAA8B;GAAI;EACnE;IAAiC,oCAAgC;IAAhC,iCAAgC;GAAI;EACrE;IAAiC,mCAA+B;IAA/B,gCAA+B;GAAI;EAEpE;IAAkC,qCAAoC;IAApC,qCAAoC;GAAI;EAC1E;IAAkC,mCAAkC;IAAlC,mCAAkC;GAAI;EACxE;IAAkC,sCAAgC;IAAhC,iCAAgC;GAAI;EACtE;IAAkC,uCAAuC;IAAvC,wCAAuC;GAAI;EAC7E;IAAkC,0CAAsC;IAAtC,uCAAsC;GAAI;EAC5E;IAAkC,uCAAiC;IAAjC,kCAAiC;GAAI;EAEvE;IAAgC,qCAA2B;IAA3B,4BAA2B;GAAI;EAC/D;IAAgC,sCAAiC;IAAjC,kCAAiC;GAAI;EACrE;IAAgC,oCAA+B;IAA/B,gCAA+B;GAAI;EACnE;IAAgC,uCAA6B;IAA7B,8BAA6B;GAAI;EACjE;IAAgC,yCAA+B;IAA/B,gCAA+B;GAAI;EACnE;IAAgC,wCAA8B;IAA9B,+BAA8B;GAAI;CPw/CrE","file":"bootstrap-grid.css","sourcesContent":["/*!\n * Bootstrap Grid v4.1.3 (https://getbootstrap.com/)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n@at-root {\n @-ms-viewport { width: device-width; } // stylelint-disable-line at-rule-no-vendor-prefix\n}\n\nhtml {\n box-sizing: border-box;\n -ms-overflow-style: scrollbar;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit;\n}\n\n@import \"functions\";\n@import \"variables\";\n\n@import \"mixins/breakpoints\";\n@import \"mixins/grid-framework\";\n@import \"mixins/grid\";\n\n@import \"grid\";\n@import \"utilities/display\";\n@import \"utilities/flex\";\n","/*!\n * Bootstrap Grid v4.1.3 (https://getbootstrap.com/)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n@-ms-viewport {\n width: device-width;\n}\n\nhtml {\n box-sizing: border-box;\n -ms-overflow-style: scrollbar;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit;\n}\n\n.container {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container {\n max-width: 1140px;\n }\n}\n\n.container-fluid {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n.row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n}\n\n.col-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n order: -1;\n}\n\n.order-last {\n order: 13;\n}\n\n.order-0 {\n order: 0;\n}\n\n.order-1 {\n order: 1;\n}\n\n.order-2 {\n order: 2;\n}\n\n.order-3 {\n order: 3;\n}\n\n.order-4 {\n order: 4;\n}\n\n.order-5 {\n order: 5;\n}\n\n.order-6 {\n order: 6;\n}\n\n.order-7 {\n order: 7;\n}\n\n.order-8 {\n order: 8;\n}\n\n.order-9 {\n order: 9;\n}\n\n.order-10 {\n order: 10;\n}\n\n.order-11 {\n order: 11;\n}\n\n.order-12 {\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-sm-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n order: -1;\n }\n .order-sm-last {\n order: 13;\n }\n .order-sm-0 {\n order: 0;\n }\n .order-sm-1 {\n order: 1;\n }\n .order-sm-2 {\n order: 2;\n }\n .order-sm-3 {\n order: 3;\n }\n .order-sm-4 {\n order: 4;\n }\n .order-sm-5 {\n order: 5;\n }\n .order-sm-6 {\n order: 6;\n }\n .order-sm-7 {\n order: 7;\n }\n .order-sm-8 {\n order: 8;\n }\n .order-sm-9 {\n order: 9;\n }\n .order-sm-10 {\n order: 10;\n }\n .order-sm-11 {\n order: 11;\n }\n .order-sm-12 {\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-md-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n order: -1;\n }\n .order-md-last {\n order: 13;\n }\n .order-md-0 {\n order: 0;\n }\n .order-md-1 {\n order: 1;\n }\n .order-md-2 {\n order: 2;\n }\n .order-md-3 {\n order: 3;\n }\n .order-md-4 {\n order: 4;\n }\n .order-md-5 {\n order: 5;\n }\n .order-md-6 {\n order: 6;\n }\n .order-md-7 {\n order: 7;\n }\n .order-md-8 {\n order: 8;\n }\n .order-md-9 {\n order: 9;\n }\n .order-md-10 {\n order: 10;\n }\n .order-md-11 {\n order: 11;\n }\n .order-md-12 {\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-lg-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n order: -1;\n }\n .order-lg-last {\n order: 13;\n }\n .order-lg-0 {\n order: 0;\n }\n .order-lg-1 {\n order: 1;\n }\n .order-lg-2 {\n order: 2;\n }\n .order-lg-3 {\n order: 3;\n }\n .order-lg-4 {\n order: 4;\n }\n .order-lg-5 {\n order: 5;\n }\n .order-lg-6 {\n order: 6;\n }\n .order-lg-7 {\n order: 7;\n }\n .order-lg-8 {\n order: 8;\n }\n .order-lg-9 {\n order: 9;\n }\n .order-lg-10 {\n order: 10;\n }\n .order-lg-11 {\n order: 11;\n }\n .order-lg-12 {\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-xl-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n order: -1;\n }\n .order-xl-last {\n order: 13;\n }\n .order-xl-0 {\n order: 0;\n }\n .order-xl-1 {\n order: 1;\n }\n .order-xl-2 {\n order: 2;\n }\n .order-xl-3 {\n order: 3;\n }\n .order-xl-4 {\n order: 4;\n }\n .order-xl-5 {\n order: 5;\n }\n .order-xl-6 {\n order: 6;\n }\n .order-xl-7 {\n order: 7;\n }\n .order-xl-8 {\n order: 8;\n }\n .order-xl-9 {\n order: 9;\n }\n .order-xl-10 {\n order: 10;\n }\n .order-xl-11 {\n order: 11;\n }\n .order-xl-12 {\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n}\n\n/*# sourceMappingURL=bootstrap-grid.css.map */","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n .container {\n @include make-container();\n @include make-container-max-widths();\n }\n}\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but with 100% width for\n// fluid, full width layouts.\n\n@if $enable-grid-classes {\n .container-fluid {\n @include make-container();\n }\n}\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n }\n\n // Remove the negative margin from default .row, then the horizontal padding\n // from all immediate children columns (to prevent runaway style inheritance).\n .no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n }\n}\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container() {\n width: 100%;\n padding-right: ($grid-gutter-width / 2);\n padding-left: ($grid-gutter-width / 2);\n margin-right: auto;\n margin-left: auto;\n}\n\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n}\n\n@mixin make-row() {\n display: flex;\n flex-wrap: wrap;\n margin-right: ($grid-gutter-width / -2);\n margin-left: ($grid-gutter-width / -2);\n}\n\n@mixin make-col-ready() {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n min-height: 1px; // Prevent collapsing\n padding-right: ($grid-gutter-width / 2);\n padding-left: ($grid-gutter-width / 2);\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02px, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// Variables\n//\n// Variables should follow the `$component-state-property-size` formula for\n// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.\n\n\n//\n// Color system\n//\n\n$white: #fff !default;\n$gray-100: #f8f9fa !default;\n$gray-200: #e9ecef !default;\n$gray-300: #dee2e6 !default;\n$gray-400: #ced4da !default;\n$gray-500: #adb5bd !default;\n$gray-600: #6c757d !default;\n$gray-700: #495057 !default;\n$gray-800: #343a40 !default;\n$gray-900: #212529 !default;\n$black: #000 !default;\n\n$grays: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$grays: map-merge(\n (\n \"100\": $gray-100,\n \"200\": $gray-200,\n \"300\": $gray-300,\n \"400\": $gray-400,\n \"500\": $gray-500,\n \"600\": $gray-600,\n \"700\": $gray-700,\n \"800\": $gray-800,\n \"900\": $gray-900\n ),\n $grays\n);\n\n\n$blue: #007bff !default;\n$indigo: #6610f2 !default;\n$purple: #6f42c1 !default;\n$pink: #e83e8c !default;\n$red: #dc3545 !default;\n$orange: #fd7e14 !default;\n$yellow: #ffc107 !default;\n$green: #28a745 !default;\n$teal: #20c997 !default;\n$cyan: #17a2b8 !default;\n\n$colors: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$colors: map-merge(\n (\n \"blue\": $blue,\n \"indigo\": $indigo,\n \"purple\": $purple,\n \"pink\": $pink,\n \"red\": $red,\n \"orange\": $orange,\n \"yellow\": $yellow,\n \"green\": $green,\n \"teal\": $teal,\n \"cyan\": $cyan,\n \"white\": $white,\n \"gray\": $gray-600,\n \"gray-dark\": $gray-800\n ),\n $colors\n);\n\n$primary: $blue !default;\n$secondary: $gray-600 !default;\n$success: $green !default;\n$info: $cyan !default;\n$warning: $yellow !default;\n$danger: $red !default;\n$light: $gray-100 !default;\n$dark: $gray-800 !default;\n\n$theme-colors: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$theme-colors: map-merge(\n (\n \"primary\": $primary,\n \"secondary\": $secondary,\n \"success\": $success,\n \"info\": $info,\n \"warning\": $warning,\n \"danger\": $danger,\n \"light\": $light,\n \"dark\": $dark\n ),\n $theme-colors\n);\n\n// Set a specific jump point for requesting color jumps\n$theme-color-interval: 8% !default;\n\n// The yiq lightness value that determines when the lightness of color changes from \"dark\" to \"light\". Acceptable values are between 0 and 255.\n$yiq-contrasted-threshold: 150 !default;\n\n// Customize the light and dark text colors for use in our YIQ color contrast function.\n$yiq-text-dark: $gray-900 !default;\n$yiq-text-light: $white !default;\n\n// Options\n//\n// Quickly modify global styling by enabling or disabling optional features.\n\n$enable-caret: true !default;\n$enable-rounded: true !default;\n$enable-shadows: false !default;\n$enable-gradients: false !default;\n$enable-transitions: true !default;\n$enable-hover-media-query: false !default; // Deprecated, no longer affects any compiled CSS\n$enable-grid-classes: true !default;\n$enable-print-styles: true !default;\n\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n$spacer: 1rem !default;\n$spacers: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$spacers: map-merge(\n (\n 0: 0,\n 1: ($spacer * .25),\n 2: ($spacer * .5),\n 3: $spacer,\n 4: ($spacer * 1.5),\n 5: ($spacer * 3)\n ),\n $spacers\n);\n\n// This variable affects the `.h-*` and `.w-*` classes.\n$sizes: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$sizes: map-merge(\n (\n 25: 25%,\n 50: 50%,\n 75: 75%,\n 100: 100%,\n auto: auto\n ),\n $sizes\n);\n\n// Body\n//\n// Settings for the `` element.\n\n$body-bg: $white !default;\n$body-color: $gray-900 !default;\n\n// Links\n//\n// Style anchor elements.\n\n$link-color: theme-color(\"primary\") !default;\n$link-decoration: none !default;\n$link-hover-color: darken($link-color, 15%) !default;\n$link-hover-decoration: underline !default;\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom: 1rem !default;\n\n\n// Grid breakpoints\n//\n// Define the minimum dimensions at which your layout will change,\n// adapting to different screen sizes, for use in media queries.\n\n$grid-breakpoints: (\n xs: 0,\n sm: 576px,\n md: 768px,\n lg: 992px,\n xl: 1200px\n) !default;\n\n@include _assert-ascending($grid-breakpoints, \"$grid-breakpoints\");\n@include _assert-starts-at-zero($grid-breakpoints);\n\n\n// Grid containers\n//\n// Define the maximum width of `.container` for different screen sizes.\n\n$container-max-widths: (\n sm: 540px,\n md: 720px,\n lg: 960px,\n xl: 1140px\n) !default;\n\n@include _assert-ascending($container-max-widths, \"$container-max-widths\");\n\n\n// Grid columns\n//\n// Set the number of columns and specify the width of the gutters.\n\n$grid-columns: 12 !default;\n$grid-gutter-width: 30px !default;\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n$line-height-lg: 1.5 !default;\n$line-height-sm: 1.5 !default;\n\n$border-width: 1px !default;\n$border-color: $gray-300 !default;\n\n$border-radius: .25rem !default;\n$border-radius-lg: .3rem !default;\n$border-radius-sm: .2rem !default;\n\n$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;\n\n$component-active-color: $white !default;\n$component-active-bg: theme-color(\"primary\") !default;\n\n$caret-width: .3em !default;\n\n$transition-base: all .2s ease-in-out !default;\n$transition-fade: opacity .15s linear !default;\n$transition-collapse: height .35s ease !default;\n\n\n// Fonts\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// stylelint-disable value-keyword-case\n$font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n$font-family-base: $font-family-sans-serif !default;\n// stylelint-enable value-keyword-case\n\n$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`\n$font-size-lg: ($font-size-base * 1.25) !default;\n$font-size-sm: ($font-size-base * .875) !default;\n\n$font-weight-light: 300 !default;\n$font-weight-normal: 400 !default;\n$font-weight-bold: 700 !default;\n\n$font-weight-base: $font-weight-normal !default;\n$line-height-base: 1.5 !default;\n\n$h1-font-size: $font-size-base * 2.5 !default;\n$h2-font-size: $font-size-base * 2 !default;\n$h3-font-size: $font-size-base * 1.75 !default;\n$h4-font-size: $font-size-base * 1.5 !default;\n$h5-font-size: $font-size-base * 1.25 !default;\n$h6-font-size: $font-size-base !default;\n\n$headings-margin-bottom: ($spacer / 2) !default;\n$headings-font-family: inherit !default;\n$headings-font-weight: 500 !default;\n$headings-line-height: 1.2 !default;\n$headings-color: inherit !default;\n\n$display1-size: 6rem !default;\n$display2-size: 5.5rem !default;\n$display3-size: 4.5rem !default;\n$display4-size: 3.5rem !default;\n\n$display1-weight: 300 !default;\n$display2-weight: 300 !default;\n$display3-weight: 300 !default;\n$display4-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n\n$lead-font-size: ($font-size-base * 1.25) !default;\n$lead-font-weight: 300 !default;\n\n$small-font-size: 80% !default;\n\n$text-muted: $gray-600 !default;\n\n$blockquote-small-color: $gray-600 !default;\n$blockquote-font-size: ($font-size-base * 1.25) !default;\n\n$hr-border-color: rgba($black, .1) !default;\n$hr-border-width: $border-width !default;\n\n$mark-padding: .2em !default;\n\n$dt-font-weight: $font-weight-bold !default;\n\n$kbd-box-shadow: inset 0 -.1rem 0 rgba($black, .25) !default;\n$nested-kbd-font-weight: $font-weight-bold !default;\n\n$list-inline-padding: .5rem !default;\n\n$mark-bg: #fcf8e3 !default;\n\n$hr-margin-y: $spacer !default;\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n$table-cell-padding: .75rem !default;\n$table-cell-padding-sm: .3rem !default;\n\n$table-bg: transparent !default;\n$table-accent-bg: rgba($black, .05) !default;\n$table-hover-bg: rgba($black, .075) !default;\n$table-active-bg: $table-hover-bg !default;\n\n$table-border-width: $border-width !default;\n$table-border-color: $gray-300 !default;\n\n$table-head-bg: $gray-200 !default;\n$table-head-color: $gray-700 !default;\n\n$table-dark-bg: $gray-900 !default;\n$table-dark-accent-bg: rgba($white, .05) !default;\n$table-dark-hover-bg: rgba($white, .075) !default;\n$table-dark-border-color: lighten($gray-900, 7.5%) !default;\n$table-dark-color: $body-bg !default;\n\n$table-striped-order: odd !default;\n\n$table-caption-color: $text-muted !default;\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\n$input-btn-padding-y: .375rem !default;\n$input-btn-padding-x: .75rem !default;\n$input-btn-line-height: $line-height-base !default;\n\n$input-btn-focus-width: .2rem !default;\n$input-btn-focus-color: rgba($component-active-bg, .25) !default;\n$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color !default;\n\n$input-btn-padding-y-sm: .25rem !default;\n$input-btn-padding-x-sm: .5rem !default;\n$input-btn-line-height-sm: $line-height-sm !default;\n\n$input-btn-padding-y-lg: .5rem !default;\n$input-btn-padding-x-lg: 1rem !default;\n$input-btn-line-height-lg: $line-height-lg !default;\n\n$input-btn-border-width: $border-width !default;\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\n$btn-padding-y: $input-btn-padding-y !default;\n$btn-padding-x: $input-btn-padding-x !default;\n$btn-line-height: $input-btn-line-height !default;\n\n$btn-padding-y-sm: $input-btn-padding-y-sm !default;\n$btn-padding-x-sm: $input-btn-padding-x-sm !default;\n$btn-line-height-sm: $input-btn-line-height-sm !default;\n\n$btn-padding-y-lg: $input-btn-padding-y-lg !default;\n$btn-padding-x-lg: $input-btn-padding-x-lg !default;\n$btn-line-height-lg: $input-btn-line-height-lg !default;\n\n$btn-border-width: $input-btn-border-width !default;\n\n$btn-font-weight: $font-weight-normal !default;\n$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;\n$btn-focus-width: $input-btn-focus-width !default;\n$btn-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$btn-disabled-opacity: .65 !default;\n$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default;\n\n$btn-link-disabled-color: $gray-600 !default;\n\n$btn-block-spacing-y: .5rem !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius: $border-radius !default;\n$btn-border-radius-lg: $border-radius-lg !default;\n$btn-border-radius-sm: $border-radius-sm !default;\n\n$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n\n// Forms\n\n$label-margin-bottom: .5rem !default;\n\n$input-padding-y: $input-btn-padding-y !default;\n$input-padding-x: $input-btn-padding-x !default;\n$input-line-height: $input-btn-line-height !default;\n\n$input-padding-y-sm: $input-btn-padding-y-sm !default;\n$input-padding-x-sm: $input-btn-padding-x-sm !default;\n$input-line-height-sm: $input-btn-line-height-sm !default;\n\n$input-padding-y-lg: $input-btn-padding-y-lg !default;\n$input-padding-x-lg: $input-btn-padding-x-lg !default;\n$input-line-height-lg: $input-btn-line-height-lg !default;\n\n$input-bg: $white !default;\n$input-disabled-bg: $gray-200 !default;\n\n$input-color: $gray-700 !default;\n$input-border-color: $gray-400 !default;\n$input-border-width: $input-btn-border-width !default;\n$input-box-shadow: inset 0 1px 1px rgba($black, .075) !default;\n\n$input-border-radius: $border-radius !default;\n$input-border-radius-lg: $border-radius-lg !default;\n$input-border-radius-sm: $border-radius-sm !default;\n\n$input-focus-bg: $input-bg !default;\n$input-focus-border-color: lighten($component-active-bg, 25%) !default;\n$input-focus-color: $input-color !default;\n$input-focus-width: $input-btn-focus-width !default;\n$input-focus-box-shadow: $input-btn-focus-box-shadow !default;\n\n$input-placeholder-color: $gray-600 !default;\n$input-plaintext-color: $body-color !default;\n\n$input-height-border: $input-border-width * 2 !default;\n\n$input-height-inner: ($font-size-base * $input-btn-line-height) + ($input-btn-padding-y * 2) !default;\n$input-height: calc(#{$input-height-inner} + #{$input-height-border}) !default;\n\n$input-height-inner-sm: ($font-size-sm * $input-btn-line-height-sm) + ($input-btn-padding-y-sm * 2) !default;\n$input-height-sm: calc(#{$input-height-inner-sm} + #{$input-height-border}) !default;\n\n$input-height-inner-lg: ($font-size-lg * $input-btn-line-height-lg) + ($input-btn-padding-y-lg * 2) !default;\n$input-height-lg: calc(#{$input-height-inner-lg} + #{$input-height-border}) !default;\n\n$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$form-text-margin-top: .25rem !default;\n\n$form-check-input-gutter: 1.25rem !default;\n$form-check-input-margin-y: .3rem !default;\n$form-check-input-margin-x: .25rem !default;\n\n$form-check-inline-margin-x: .75rem !default;\n$form-check-inline-input-margin-x: .3125rem !default;\n\n$form-group-margin-bottom: 1rem !default;\n\n$input-group-addon-color: $input-color !default;\n$input-group-addon-bg: $gray-200 !default;\n$input-group-addon-border-color: $input-border-color !default;\n\n$custom-forms-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$custom-control-gutter: 1.5rem !default;\n$custom-control-spacer-x: 1rem !default;\n\n$custom-control-indicator-size: 1rem !default;\n$custom-control-indicator-bg: $gray-300 !default;\n$custom-control-indicator-bg-size: 50% 50% !default;\n$custom-control-indicator-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default;\n\n$custom-control-indicator-disabled-bg: $gray-200 !default;\n$custom-control-label-disabled-color: $gray-600 !default;\n\n$custom-control-indicator-checked-color: $component-active-color !default;\n$custom-control-indicator-checked-bg: $component-active-bg !default;\n$custom-control-indicator-checked-disabled-bg: rgba(theme-color(\"primary\"), .5) !default;\n$custom-control-indicator-checked-box-shadow: none !default;\n\n$custom-control-indicator-focus-box-shadow: 0 0 0 1px $body-bg, $input-btn-focus-box-shadow !default;\n\n$custom-control-indicator-active-color: $component-active-color !default;\n$custom-control-indicator-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-control-indicator-active-box-shadow: none !default;\n\n$custom-checkbox-indicator-border-radius: $border-radius !default;\n$custom-checkbox-indicator-icon-checked: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n\n$custom-checkbox-indicator-indeterminate-bg: $component-active-bg !default;\n$custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default;\n$custom-checkbox-indicator-icon-indeterminate: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n$custom-checkbox-indicator-indeterminate-box-shadow: none !default;\n\n$custom-radio-indicator-border-radius: 50% !default;\n$custom-radio-indicator-icon-checked: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='#{$custom-control-indicator-checked-color}'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n\n$custom-select-padding-y: .375rem !default;\n$custom-select-padding-x: .75rem !default;\n$custom-select-height: $input-height !default;\n$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator\n$custom-select-line-height: $input-btn-line-height !default;\n$custom-select-color: $input-color !default;\n$custom-select-disabled-color: $gray-600 !default;\n$custom-select-bg: $input-bg !default;\n$custom-select-disabled-bg: $gray-200 !default;\n$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions\n$custom-select-indicator-color: $gray-800 !default;\n$custom-select-indicator: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n$custom-select-border-width: $input-btn-border-width !default;\n$custom-select-border-color: $input-border-color !default;\n$custom-select-border-radius: $border-radius !default;\n$custom-select-box-shadow: inset 0 1px 2px rgba($black, .075) !default;\n\n$custom-select-focus-border-color: $input-focus-border-color !default;\n$custom-select-focus-width: $input-btn-focus-width !default;\n$custom-select-focus-box-shadow: 0 0 0 $custom-select-focus-width rgba($custom-select-focus-border-color, .5) !default;\n\n$custom-select-font-size-sm: 75% !default;\n$custom-select-height-sm: $input-height-sm !default;\n\n$custom-select-font-size-lg: 125% !default;\n$custom-select-height-lg: $input-height-lg !default;\n\n$custom-range-track-width: 100% !default;\n$custom-range-track-height: .5rem !default;\n$custom-range-track-cursor: pointer !default;\n$custom-range-track-bg: $gray-300 !default;\n$custom-range-track-border-radius: 1rem !default;\n$custom-range-track-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default;\n\n$custom-range-thumb-width: 1rem !default;\n$custom-range-thumb-height: $custom-range-thumb-width !default;\n$custom-range-thumb-bg: $component-active-bg !default;\n$custom-range-thumb-border: 0 !default;\n$custom-range-thumb-border-radius: 1rem !default;\n$custom-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;\n$custom-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-btn-focus-box-shadow !default;\n$custom-range-thumb-focus-box-shadow-width: $input-btn-focus-width !default; // For focus box shadow issue in IE/Edge\n$custom-range-thumb-active-bg: lighten($component-active-bg, 35%) !default;\n\n$custom-file-height: $input-height !default;\n$custom-file-height-inner: $input-height-inner !default;\n$custom-file-focus-border-color: $input-focus-border-color !default;\n$custom-file-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$custom-file-disabled-bg: $input-disabled-bg !default;\n\n$custom-file-padding-y: $input-btn-padding-y !default;\n$custom-file-padding-x: $input-btn-padding-x !default;\n$custom-file-line-height: $input-btn-line-height !default;\n$custom-file-color: $input-color !default;\n$custom-file-bg: $input-bg !default;\n$custom-file-border-width: $input-btn-border-width !default;\n$custom-file-border-color: $input-border-color !default;\n$custom-file-border-radius: $input-border-radius !default;\n$custom-file-box-shadow: $input-box-shadow !default;\n$custom-file-button-color: $custom-file-color !default;\n$custom-file-button-bg: $input-group-addon-bg !default;\n$custom-file-text: (\n en: \"Browse\"\n) !default;\n\n\n// Form validation\n$form-feedback-margin-top: $form-text-margin-top !default;\n$form-feedback-font-size: $small-font-size !default;\n$form-feedback-valid-color: theme-color(\"success\") !default;\n$form-feedback-invalid-color: theme-color(\"danger\") !default;\n\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\n$dropdown-min-width: 10rem !default;\n$dropdown-padding-y: .5rem !default;\n$dropdown-spacer: .125rem !default;\n$dropdown-bg: $white !default;\n$dropdown-border-color: rgba($black, .15) !default;\n$dropdown-border-radius: $border-radius !default;\n$dropdown-border-width: $border-width !default;\n$dropdown-divider-bg: $gray-200 !default;\n$dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default;\n\n$dropdown-link-color: $gray-900 !default;\n$dropdown-link-hover-color: darken($gray-900, 5%) !default;\n$dropdown-link-hover-bg: $gray-100 !default;\n\n$dropdown-link-active-color: $component-active-color !default;\n$dropdown-link-active-bg: $component-active-bg !default;\n\n$dropdown-link-disabled-color: $gray-600 !default;\n\n$dropdown-item-padding-y: .25rem !default;\n$dropdown-item-padding-x: 1.5rem !default;\n\n$dropdown-header-color: $gray-600 !default;\n\n\n// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n$zindex-dropdown: 1000 !default;\n$zindex-sticky: 1020 !default;\n$zindex-fixed: 1030 !default;\n$zindex-modal-backdrop: 1040 !default;\n$zindex-modal: 1050 !default;\n$zindex-popover: 1060 !default;\n$zindex-tooltip: 1070 !default;\n\n// Navs\n\n$nav-link-padding-y: .5rem !default;\n$nav-link-padding-x: 1rem !default;\n$nav-link-disabled-color: $gray-600 !default;\n\n$nav-tabs-border-color: $gray-300 !default;\n$nav-tabs-border-width: $border-width !default;\n$nav-tabs-border-radius: $border-radius !default;\n$nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default;\n$nav-tabs-link-active-color: $gray-700 !default;\n$nav-tabs-link-active-bg: $body-bg !default;\n$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default;\n\n$nav-pills-border-radius: $border-radius !default;\n$nav-pills-link-active-color: $component-active-color !default;\n$nav-pills-link-active-bg: $component-active-bg !default;\n\n$nav-divider-color: $gray-200 !default;\n$nav-divider-margin-y: ($spacer / 2) !default;\n\n// Navbar\n\n$navbar-padding-y: ($spacer / 2) !default;\n$navbar-padding-x: $spacer !default;\n\n$navbar-nav-link-padding-x: .5rem !default;\n\n$navbar-brand-font-size: $font-size-lg !default;\n// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link\n$nav-link-height: ($font-size-base * $line-height-base + $nav-link-padding-y * 2) !default;\n$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;\n$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) / 2 !default;\n\n$navbar-toggler-padding-y: .25rem !default;\n$navbar-toggler-padding-x: .75rem !default;\n$navbar-toggler-font-size: $font-size-lg !default;\n$navbar-toggler-border-radius: $btn-border-radius !default;\n\n$navbar-dark-color: rgba($white, .5) !default;\n$navbar-dark-hover-color: rgba($white, .75) !default;\n$navbar-dark-active-color: $white !default;\n$navbar-dark-disabled-color: rgba($white, .25) !default;\n$navbar-dark-toggler-icon-bg: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$navbar-dark-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n$navbar-dark-toggler-border-color: rgba($white, .1) !default;\n\n$navbar-light-color: rgba($black, .5) !default;\n$navbar-light-hover-color: rgba($black, .7) !default;\n$navbar-light-active-color: rgba($black, .9) !default;\n$navbar-light-disabled-color: rgba($black, .3) !default;\n$navbar-light-toggler-icon-bg: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$navbar-light-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n$navbar-light-toggler-border-color: rgba($black, .1) !default;\n\n// Pagination\n\n$pagination-padding-y: .5rem !default;\n$pagination-padding-x: .75rem !default;\n$pagination-padding-y-sm: .25rem !default;\n$pagination-padding-x-sm: .5rem !default;\n$pagination-padding-y-lg: .75rem !default;\n$pagination-padding-x-lg: 1.5rem !default;\n$pagination-line-height: 1.25 !default;\n\n$pagination-color: $link-color !default;\n$pagination-bg: $white !default;\n$pagination-border-width: $border-width !default;\n$pagination-border-color: $gray-300 !default;\n\n$pagination-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$pagination-focus-outline: 0 !default;\n\n$pagination-hover-color: $link-hover-color !default;\n$pagination-hover-bg: $gray-200 !default;\n$pagination-hover-border-color: $gray-300 !default;\n\n$pagination-active-color: $component-active-color !default;\n$pagination-active-bg: $component-active-bg !default;\n$pagination-active-border-color: $pagination-active-bg !default;\n\n$pagination-disabled-color: $gray-600 !default;\n$pagination-disabled-bg: $white !default;\n$pagination-disabled-border-color: $gray-300 !default;\n\n\n// Jumbotron\n\n$jumbotron-padding: 2rem !default;\n$jumbotron-bg: $gray-200 !default;\n\n\n// Cards\n\n$card-spacer-y: .75rem !default;\n$card-spacer-x: 1.25rem !default;\n$card-border-width: $border-width !default;\n$card-border-radius: $border-radius !default;\n$card-border-color: rgba($black, .125) !default;\n$card-inner-border-radius: calc(#{$card-border-radius} - #{$card-border-width}) !default;\n$card-cap-bg: rgba($black, .03) !default;\n$card-bg: $white !default;\n\n$card-img-overlay-padding: 1.25rem !default;\n\n$card-group-margin: ($grid-gutter-width / 2) !default;\n$card-deck-margin: $card-group-margin !default;\n\n$card-columns-count: 3 !default;\n$card-columns-gap: 1.25rem !default;\n$card-columns-margin: $card-spacer-y !default;\n\n\n// Tooltips\n\n$tooltip-font-size: $font-size-sm !default;\n$tooltip-max-width: 200px !default;\n$tooltip-color: $white !default;\n$tooltip-bg: $black !default;\n$tooltip-border-radius: $border-radius !default;\n$tooltip-opacity: .9 !default;\n$tooltip-padding-y: .25rem !default;\n$tooltip-padding-x: .5rem !default;\n$tooltip-margin: 0 !default;\n\n$tooltip-arrow-width: .8rem !default;\n$tooltip-arrow-height: .4rem !default;\n$tooltip-arrow-color: $tooltip-bg !default;\n\n\n// Popovers\n\n$popover-font-size: $font-size-sm !default;\n$popover-bg: $white !default;\n$popover-max-width: 276px !default;\n$popover-border-width: $border-width !default;\n$popover-border-color: rgba($black, .2) !default;\n$popover-border-radius: $border-radius-lg !default;\n$popover-box-shadow: 0 .25rem .5rem rgba($black, .2) !default;\n\n$popover-header-bg: darken($popover-bg, 3%) !default;\n$popover-header-color: $headings-color !default;\n$popover-header-padding-y: .5rem !default;\n$popover-header-padding-x: .75rem !default;\n\n$popover-body-color: $body-color !default;\n$popover-body-padding-y: $popover-header-padding-y !default;\n$popover-body-padding-x: $popover-header-padding-x !default;\n\n$popover-arrow-width: 1rem !default;\n$popover-arrow-height: .5rem !default;\n$popover-arrow-color: $popover-bg !default;\n\n$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default;\n\n\n// Badges\n\n$badge-font-size: 75% !default;\n$badge-font-weight: $font-weight-bold !default;\n$badge-padding-y: .25em !default;\n$badge-padding-x: .4em !default;\n$badge-border-radius: $border-radius !default;\n\n$badge-pill-padding-x: .6em !default;\n// Use a higher than normal value to ensure completely rounded edges when\n// customizing padding or font-size on labels.\n$badge-pill-border-radius: 10rem !default;\n\n\n// Modals\n\n// Padding applied to the modal body\n$modal-inner-padding: 1rem !default;\n\n$modal-dialog-margin: .5rem !default;\n$modal-dialog-margin-y-sm-up: 1.75rem !default;\n\n$modal-title-line-height: $line-height-base !default;\n\n$modal-content-bg: $white !default;\n$modal-content-border-color: rgba($black, .2) !default;\n$modal-content-border-width: $border-width !default;\n$modal-content-border-radius: $border-radius-lg !default;\n$modal-content-box-shadow-xs: 0 .25rem .5rem rgba($black, .5) !default;\n$modal-content-box-shadow-sm-up: 0 .5rem 1rem rgba($black, .5) !default;\n\n$modal-backdrop-bg: $black !default;\n$modal-backdrop-opacity: .5 !default;\n$modal-header-border-color: $gray-200 !default;\n$modal-footer-border-color: $modal-header-border-color !default;\n$modal-header-border-width: $modal-content-border-width !default;\n$modal-footer-border-width: $modal-header-border-width !default;\n$modal-header-padding: 1rem !default;\n\n$modal-lg: 800px !default;\n$modal-md: 500px !default;\n$modal-sm: 300px !default;\n\n$modal-transition: transform .3s ease-out !default;\n\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n$alert-padding-y: .75rem !default;\n$alert-padding-x: 1.25rem !default;\n$alert-margin-bottom: 1rem !default;\n$alert-border-radius: $border-radius !default;\n$alert-link-font-weight: $font-weight-bold !default;\n$alert-border-width: $border-width !default;\n\n$alert-bg-level: -10 !default;\n$alert-border-level: -9 !default;\n$alert-color-level: 6 !default;\n\n\n// Progress bars\n\n$progress-height: 1rem !default;\n$progress-font-size: ($font-size-base * .75) !default;\n$progress-bg: $gray-200 !default;\n$progress-border-radius: $border-radius !default;\n$progress-box-shadow: inset 0 .1rem .1rem rgba($black, .1) !default;\n$progress-bar-color: $white !default;\n$progress-bar-bg: theme-color(\"primary\") !default;\n$progress-bar-animation-timing: 1s linear infinite !default;\n$progress-bar-transition: width .6s ease !default;\n\n// List group\n\n$list-group-bg: $white !default;\n$list-group-border-color: rgba($black, .125) !default;\n$list-group-border-width: $border-width !default;\n$list-group-border-radius: $border-radius !default;\n\n$list-group-item-padding-y: .75rem !default;\n$list-group-item-padding-x: 1.25rem !default;\n\n$list-group-hover-bg: $gray-100 !default;\n$list-group-active-color: $component-active-color !default;\n$list-group-active-bg: $component-active-bg !default;\n$list-group-active-border-color: $list-group-active-bg !default;\n\n$list-group-disabled-color: $gray-600 !default;\n$list-group-disabled-bg: $list-group-bg !default;\n\n$list-group-action-color: $gray-700 !default;\n$list-group-action-hover-color: $list-group-action-color !default;\n\n$list-group-action-active-color: $body-color !default;\n$list-group-action-active-bg: $gray-200 !default;\n\n\n// Image thumbnails\n\n$thumbnail-padding: .25rem !default;\n$thumbnail-bg: $body-bg !default;\n$thumbnail-border-width: $border-width !default;\n$thumbnail-border-color: $gray-300 !default;\n$thumbnail-border-radius: $border-radius !default;\n$thumbnail-box-shadow: 0 1px 2px rgba($black, .075) !default;\n\n\n// Figures\n\n$figure-caption-font-size: 90% !default;\n$figure-caption-color: $gray-600 !default;\n\n\n// Breadcrumbs\n\n$breadcrumb-padding-y: .75rem !default;\n$breadcrumb-padding-x: 1rem !default;\n$breadcrumb-item-padding: .5rem !default;\n\n$breadcrumb-margin-bottom: 1rem !default;\n\n$breadcrumb-bg: $gray-200 !default;\n$breadcrumb-divider-color: $gray-600 !default;\n$breadcrumb-active-color: $gray-600 !default;\n$breadcrumb-divider: quote(\"/\") !default;\n\n$breadcrumb-border-radius: $border-radius !default;\n\n\n// Carousel\n\n$carousel-control-color: $white !default;\n$carousel-control-width: 15% !default;\n$carousel-control-opacity: .5 !default;\n\n$carousel-indicator-width: 30px !default;\n$carousel-indicator-height: 3px !default;\n$carousel-indicator-spacer: 3px !default;\n$carousel-indicator-active-bg: $white !default;\n\n$carousel-caption-width: 70% !default;\n$carousel-caption-color: $white !default;\n\n$carousel-control-icon-width: 20px !default;\n\n$carousel-control-prev-icon-bg: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n$carousel-control-next-icon-bg: str-replace(url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E\"), \"#\", \"%23\") !default;\n\n$carousel-transition: transform .6s ease !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)\n\n\n// Close\n\n$close-font-size: $font-size-base * 1.5 !default;\n$close-font-weight: $font-weight-bold !default;\n$close-color: $black !default;\n$close-text-shadow: 0 1px 0 $white !default;\n\n// Code\n\n$code-font-size: 87.5% !default;\n$code-color: $pink !default;\n\n$kbd-padding-y: .2rem !default;\n$kbd-padding-x: .4rem !default;\n$kbd-font-size: $code-font-size !default;\n$kbd-color: $white !default;\n$kbd-bg: $gray-900 !default;\n\n$pre-color: $gray-900 !default;\n$pre-scrollable-max-height: 340px !default;\n\n\n// Printing\n$print-page-size: a3 !default;\n$print-body-min-width: map-get($grid-breakpoints, \"lg\") !default;\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n // Common properties for all breakpoints\n %grid-column {\n position: relative;\n width: 100%;\n min-height: 1px; // Prevent columns from collapsing when empty\n padding-right: ($gutter / 2);\n padding-left: ($gutter / 2);\n }\n\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n // Allow columns to stretch full width below their breakpoints\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @extend %grid-column;\n }\n }\n .col#{$infix},\n .col#{$infix}-auto {\n @extend %grid-column;\n }\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col#{$infix}-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none; // Reset earlier grid tiers\n }\n\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n\n .order#{$infix}-first { order: -1; }\n\n .order#{$infix}-last { order: $columns + 1; }\n\n @for $i from 0 through $columns {\n .order#{$infix}-#{$i} { order: $i; }\n }\n\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Utilities for common `display` values\n//\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .d#{$infix}-none { display: none !important; }\n .d#{$infix}-inline { display: inline !important; }\n .d#{$infix}-inline-block { display: inline-block !important; }\n .d#{$infix}-block { display: block !important; }\n .d#{$infix}-table { display: table !important; }\n .d#{$infix}-table-row { display: table-row !important; }\n .d#{$infix}-table-cell { display: table-cell !important; }\n .d#{$infix}-flex { display: flex !important; }\n .d#{$infix}-inline-flex { display: inline-flex !important; }\n }\n}\n\n\n//\n// Utilities for toggling `display` in print\n//\n\n@media print {\n .d-print-none { display: none !important; }\n .d-print-inline { display: inline !important; }\n .d-print-inline-block { display: inline-block !important; }\n .d-print-block { display: block !important; }\n .d-print-table { display: table !important; }\n .d-print-table-row { display: table-row !important; }\n .d-print-table-cell { display: table-cell !important; }\n .d-print-flex { display: flex !important; }\n .d-print-inline-flex { display: inline-flex !important; }\n}\n","// stylelint-disable declaration-no-important\n\n// Flex variation\n//\n// Custom styles for additional flex alignment options.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .flex#{$infix}-row { flex-direction: row !important; }\n .flex#{$infix}-column { flex-direction: column !important; }\n .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }\n .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }\n\n .flex#{$infix}-wrap { flex-wrap: wrap !important; }\n .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }\n .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex#{$infix}-fill { flex: 1 1 auto !important; }\n .flex#{$infix}-grow-0 { flex-grow: 0 !important; }\n .flex#{$infix}-grow-1 { flex-grow: 1 !important; }\n .flex#{$infix}-shrink-0 { flex-shrink: 0 !important; }\n .flex#{$infix}-shrink-1 { flex-shrink: 1 !important; }\n\n .justify-content#{$infix}-start { justify-content: flex-start !important; }\n .justify-content#{$infix}-end { justify-content: flex-end !important; }\n .justify-content#{$infix}-center { justify-content: center !important; }\n .justify-content#{$infix}-between { justify-content: space-between !important; }\n .justify-content#{$infix}-around { justify-content: space-around !important; }\n\n .align-items#{$infix}-start { align-items: flex-start !important; }\n .align-items#{$infix}-end { align-items: flex-end !important; }\n .align-items#{$infix}-center { align-items: center !important; }\n .align-items#{$infix}-baseline { align-items: baseline !important; }\n .align-items#{$infix}-stretch { align-items: stretch !important; }\n\n .align-content#{$infix}-start { align-content: flex-start !important; }\n .align-content#{$infix}-end { align-content: flex-end !important; }\n .align-content#{$infix}-center { align-content: center !important; }\n .align-content#{$infix}-between { align-content: space-between !important; }\n .align-content#{$infix}-around { align-content: space-around !important; }\n .align-content#{$infix}-stretch { align-content: stretch !important; }\n\n .align-self#{$infix}-auto { align-self: auto !important; }\n .align-self#{$infix}-start { align-self: flex-start !important; }\n .align-self#{$infix}-end { align-self: flex-end !important; }\n .align-self#{$infix}-center { align-self: center !important; }\n .align-self#{$infix}-baseline { align-self: baseline !important; }\n .align-self#{$infix}-stretch { align-self: stretch !important; }\n }\n}\n"]}
\ No newline at end of file
diff --git a/dapps/demo/src/css/bootstrap-grid.min.css b/dapps/demo/src/css/bootstrap-grid.min.css
deleted file mode 100644
index 63e1bc6b0..000000000
--- a/dapps/demo/src/css/bootstrap-grid.min.css
+++ /dev/null
@@ -1,7 +0,0 @@
-/*!
- * Bootstrap Grid v4.1.3 (https://getbootstrap.com/)
- * Copyright 2011-2018 The Bootstrap Authors
- * Copyright 2011-2018 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */@-ms-viewport{width:device-width}html{box-sizing:border-box;-ms-overflow-style:scrollbar}*,::after,::before{box-sizing:inherit}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}
-/*# sourceMappingURL=bootstrap-grid.min.css.map */
\ No newline at end of file
diff --git a/dapps/demo/src/css/bootstrap-grid.min.css.map b/dapps/demo/src/css/bootstrap-grid.min.css.map
deleted file mode 100644
index 4cc3aa658..000000000
--- a/dapps/demo/src/css/bootstrap-grid.min.css.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["../../scss/bootstrap-grid.scss","dist/css/bootstrap-grid.css","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/mixins/_grid-framework.scss","../../scss/utilities/_display.scss","../../scss/utilities/_flex.scss"],"names":[],"mappings":"AAAA;;;;;AAQE,cAAgB,MAAA,aAGlB,KACE,WAAA,WACA,mBAAA,UAGF,ECCA,QADA,SDGE,WAAA,QEdA,WCAA,MAAA,KACA,cAAA,KACA,aAAA,KACA,aAAA,KACA,YAAA,KCmDE,yBFvDF,WCYI,UAAA,OC2CF,yBFvDF,WCYI,UAAA,OC2CF,yBFvDF,WCYI,UAAA,OC2CF,0BFvDF,WCYI,UAAA,QDAJ,iBCZA,MAAA,KACA,cAAA,KACA,aAAA,KACA,aAAA,KACA,YAAA,KDkBA,KCJA,QAAA,YAAA,QAAA,KACA,cAAA,KAAA,UAAA,KACA,aAAA,MACA,YAAA,MDOA,YACE,aAAA,EACA,YAAA,EAFF,iBD2CF,0BCrCM,cAAA,EACA,aAAA,EGjCJ,KAAA,OAAA,QAAA,QAAA,QAAA,OAAA,OAAA,OAAA,OAAA,OAAA,OAAA,OAAA,OJ2EF,UAEqJ,QAAvI,UAAmG,WAAY,WAAY,WAAhH,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UACtG,aAFqJ,QAAvI,UAAmG,WAAY,WAAY,WAAhH,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UACtG,aAFkJ,QAAvI,UAAmG,WAAY,WAAY,WAAhH,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UACnG,aAEqJ,QAAvI,UAAmG,WAAY,WAAY,WAAhH,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UACtG,aI9EI,SAAA,SACA,MAAA,KACA,WAAA,IACA,cAAA,KACA,aAAA,KAmBE,KACE,wBAAA,EAAA,WAAA,EACA,kBAAA,EAAA,UAAA,EACA,UAAA,KAEF,UACE,SAAA,EAAA,EAAA,KAAA,KAAA,EAAA,EAAA,KACA,MAAA,KACA,UAAA,KAIA,OFFN,SAAA,EAAA,EAAA,UAAA,KAAA,EAAA,EAAA,UAIA,UAAA,UEFM,OFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,OFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,OFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,OFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,OFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,OFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,OFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,OFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,QFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,QFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,QFFN,SAAA,EAAA,EAAA,KAAA,KAAA,EAAA,EAAA,KAIA,UAAA,KEGI,aAAwB,eAAA,GAAA,MAAA,GAExB,YAAuB,eAAA,GAAA,MAAA,GAGrB,SAAwB,eAAA,EAAA,MAAA,EAAxB,SAAwB,eAAA,EAAA,MAAA,EAAxB,SAAwB,eAAA,EAAA,MAAA,EAAxB,SAAwB,eAAA,EAAA,MAAA,EAAxB,SAAwB,eAAA,EAAA,MAAA,EAAxB,SAAwB,eAAA,EAAA,MAAA,EAAxB,SAAwB,eAAA,EAAA,MAAA,EAAxB,SAAwB,eAAA,EAAA,MAAA,EAAxB,SAAwB,eAAA,EAAA,MAAA,EAAxB,SAAwB,eAAA,EAAA,MAAA,EAAxB,UAAwB,eAAA,GAAA,MAAA,GAAxB,UAAwB,eAAA,GAAA,MAAA,GAAxB,UAAwB,eAAA,GAAA,MAAA,GAMtB,UFTR,YAAA,UESQ,UFTR,YAAA,WESQ,UFTR,YAAA,IESQ,UFTR,YAAA,WESQ,UFTR,YAAA,WESQ,UFTR,YAAA,IESQ,UFTR,YAAA,WESQ,UFTR,YAAA,WESQ,UFTR,YAAA,IESQ,WFTR,YAAA,WESQ,WFTR,YAAA,WCUE,yBC7BE,QACE,wBAAA,EAAA,WAAA,EACA,kBAAA,EAAA,UAAA,EACA,UAAA,KAEF,aACE,SAAA,EAAA,EAAA,KAAA,KAAA,EAAA,EAAA,KACA,MAAA,KACA,UAAA,KAIA,UFFN,SAAA,EAAA,EAAA,UAAA,KAAA,EAAA,EAAA,UAIA,UAAA,UEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,WFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,WFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,WFFN,SAAA,EAAA,EAAA,KAAA,KAAA,EAAA,EAAA,KAIA,UAAA,KEGI,gBAAwB,eAAA,GAAA,MAAA,GAExB,eAAuB,eAAA,GAAA,MAAA,GAGrB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,aAAwB,eAAA,GAAA,MAAA,GAAxB,aAAwB,eAAA,GAAA,MAAA,GAAxB,aAAwB,eAAA,GAAA,MAAA,GAMtB,aFTR,YAAA,EESQ,aFTR,YAAA,UESQ,aFTR,YAAA,WESQ,aFTR,YAAA,IESQ,aFTR,YAAA,WESQ,aFTR,YAAA,WESQ,aFTR,YAAA,IESQ,aFTR,YAAA,WESQ,aFTR,YAAA,WESQ,aFTR,YAAA,IESQ,cFTR,YAAA,WESQ,cFTR,YAAA,YCUE,yBC7BE,QACE,wBAAA,EAAA,WAAA,EACA,kBAAA,EAAA,UAAA,EACA,UAAA,KAEF,aACE,SAAA,EAAA,EAAA,KAAA,KAAA,EAAA,EAAA,KACA,MAAA,KACA,UAAA,KAIA,UFFN,SAAA,EAAA,EAAA,UAAA,KAAA,EAAA,EAAA,UAIA,UAAA,UEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,WFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,WFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,WFFN,SAAA,EAAA,EAAA,KAAA,KAAA,EAAA,EAAA,KAIA,UAAA,KEGI,gBAAwB,eAAA,GAAA,MAAA,GAExB,eAAuB,eAAA,GAAA,MAAA,GAGrB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,aAAwB,eAAA,GAAA,MAAA,GAAxB,aAAwB,eAAA,GAAA,MAAA,GAAxB,aAAwB,eAAA,GAAA,MAAA,GAMtB,aFTR,YAAA,EESQ,aFTR,YAAA,UESQ,aFTR,YAAA,WESQ,aFTR,YAAA,IESQ,aFTR,YAAA,WESQ,aFTR,YAAA,WESQ,aFTR,YAAA,IESQ,aFTR,YAAA,WESQ,aFTR,YAAA,WESQ,aFTR,YAAA,IESQ,cFTR,YAAA,WESQ,cFTR,YAAA,YCUE,yBC7BE,QACE,wBAAA,EAAA,WAAA,EACA,kBAAA,EAAA,UAAA,EACA,UAAA,KAEF,aACE,SAAA,EAAA,EAAA,KAAA,KAAA,EAAA,EAAA,KACA,MAAA,KACA,UAAA,KAIA,UFFN,SAAA,EAAA,EAAA,UAAA,KAAA,EAAA,EAAA,UAIA,UAAA,UEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,WFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,WFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,WFFN,SAAA,EAAA,EAAA,KAAA,KAAA,EAAA,EAAA,KAIA,UAAA,KEGI,gBAAwB,eAAA,GAAA,MAAA,GAExB,eAAuB,eAAA,GAAA,MAAA,GAGrB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,aAAwB,eAAA,GAAA,MAAA,GAAxB,aAAwB,eAAA,GAAA,MAAA,GAAxB,aAAwB,eAAA,GAAA,MAAA,GAMtB,aFTR,YAAA,EESQ,aFTR,YAAA,UESQ,aFTR,YAAA,WESQ,aFTR,YAAA,IESQ,aFTR,YAAA,WESQ,aFTR,YAAA,WESQ,aFTR,YAAA,IESQ,aFTR,YAAA,WESQ,aFTR,YAAA,WESQ,aFTR,YAAA,IESQ,cFTR,YAAA,WESQ,cFTR,YAAA,YCUE,0BC7BE,QACE,wBAAA,EAAA,WAAA,EACA,kBAAA,EAAA,UAAA,EACA,UAAA,KAEF,aACE,SAAA,EAAA,EAAA,KAAA,KAAA,EAAA,EAAA,KACA,MAAA,KACA,UAAA,KAIA,UFFN,SAAA,EAAA,EAAA,UAAA,KAAA,EAAA,EAAA,UAIA,UAAA,UEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,UFFN,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,IEFM,WFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,WFFN,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,WEFM,WFFN,SAAA,EAAA,EAAA,KAAA,KAAA,EAAA,EAAA,KAIA,UAAA,KEGI,gBAAwB,eAAA,GAAA,MAAA,GAExB,eAAuB,eAAA,GAAA,MAAA,GAGrB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,YAAwB,eAAA,EAAA,MAAA,EAAxB,aAAwB,eAAA,GAAA,MAAA,GAAxB,aAAwB,eAAA,GAAA,MAAA,GAAxB,aAAwB,eAAA,GAAA,MAAA,GAMtB,aFTR,YAAA,EESQ,aFTR,YAAA,UESQ,aFTR,YAAA,WESQ,aFTR,YAAA,IESQ,aFTR,YAAA,WESQ,aFTR,YAAA,WESQ,aFTR,YAAA,IESQ,aFTR,YAAA,WESQ,aFTR,YAAA,WESQ,aFTR,YAAA,IESQ,cFTR,YAAA,WESQ,cFTR,YAAA,YGxCE,QAA2B,QAAA,eAC3B,UAA2B,QAAA,iBAC3B,gBAA2B,QAAA,uBAC3B,SAA2B,QAAA,gBAC3B,SAA2B,QAAA,gBAC3B,aAA2B,QAAA,oBAC3B,cAA2B,QAAA,qBAC3B,QAA2B,QAAA,sBAAA,QAAA,eAC3B,eAA2B,QAAA,6BAAA,QAAA,sBF0C3B,yBElDA,WAA2B,QAAA,eAC3B,aAA2B,QAAA,iBAC3B,mBAA2B,QAAA,uBAC3B,YAA2B,QAAA,gBAC3B,YAA2B,QAAA,gBAC3B,gBAA2B,QAAA,oBAC3B,iBAA2B,QAAA,qBAC3B,WAA2B,QAAA,sBAAA,QAAA,eAC3B,kBAA2B,QAAA,6BAAA,QAAA,uBF0C3B,yBElDA,WAA2B,QAAA,eAC3B,aAA2B,QAAA,iBAC3B,mBAA2B,QAAA,uBAC3B,YAA2B,QAAA,gBAC3B,YAA2B,QAAA,gBAC3B,gBAA2B,QAAA,oBAC3B,iBAA2B,QAAA,qBAC3B,WAA2B,QAAA,sBAAA,QAAA,eAC3B,kBAA2B,QAAA,6BAAA,QAAA,uBF0C3B,yBElDA,WAA2B,QAAA,eAC3B,aAA2B,QAAA,iBAC3B,mBAA2B,QAAA,uBAC3B,YAA2B,QAAA,gBAC3B,YAA2B,QAAA,gBAC3B,gBAA2B,QAAA,oBAC3B,iBAA2B,QAAA,qBAC3B,WAA2B,QAAA,sBAAA,QAAA,eAC3B,kBAA2B,QAAA,6BAAA,QAAA,uBF0C3B,0BElDA,WAA2B,QAAA,eAC3B,aAA2B,QAAA,iBAC3B,mBAA2B,QAAA,uBAC3B,YAA2B,QAAA,gBAC3B,YAA2B,QAAA,gBAC3B,gBAA2B,QAAA,oBAC3B,iBAA2B,QAAA,qBAC3B,WAA2B,QAAA,sBAAA,QAAA,eAC3B,kBAA2B,QAAA,6BAAA,QAAA,uBAS/B,aACE,cAAwB,QAAA,eACxB,gBAAwB,QAAA,iBACxB,sBAAwB,QAAA,uBACxB,eAAwB,QAAA,gBACxB,eAAwB,QAAA,gBACxB,mBAAwB,QAAA,oBACxB,oBAAwB,QAAA,qBACxB,cAAwB,QAAA,sBAAA,QAAA,eACxB,qBAAwB,QAAA,6BAAA,QAAA,uBC1BtB,UAAgC,mBAAA,cAAA,eAAA,cAChC,aAAgC,mBAAA,iBAAA,eAAA,iBAChC,kBAAgC,mBAAA,sBAAA,eAAA,sBAChC,qBAAgC,mBAAA,yBAAA,eAAA,yBAEhC,WAA8B,cAAA,eAAA,UAAA,eAC9B,aAA8B,cAAA,iBAAA,UAAA,iBAC9B,mBAA8B,cAAA,uBAAA,UAAA,uBAC9B,WAA8B,SAAA,EAAA,EAAA,eAAA,KAAA,EAAA,EAAA,eAC9B,aAA8B,kBAAA,YAAA,UAAA,YAC9B,aAA8B,kBAAA,YAAA,UAAA,YAC9B,eAA8B,kBAAA,YAAA,YAAA,YAC9B,eAA8B,kBAAA,YAAA,YAAA,YAE9B,uBAAoC,cAAA,gBAAA,gBAAA,qBACpC,qBAAoC,cAAA,cAAA,gBAAA,mBACpC,wBAAoC,cAAA,iBAAA,gBAAA,iBACpC,yBAAoC,cAAA,kBAAA,gBAAA,wBACpC,wBAAoC,cAAA,qBAAA,gBAAA,uBAEpC,mBAAiC,eAAA,gBAAA,YAAA,qBACjC,iBAAiC,eAAA,cAAA,YAAA,mBACjC,oBAAiC,eAAA,iBAAA,YAAA,iBACjC,sBAAiC,eAAA,mBAAA,YAAA,mBACjC,qBAAiC,eAAA,kBAAA,YAAA,kBAEjC,qBAAkC,mBAAA,gBAAA,cAAA,qBAClC,mBAAkC,mBAAA,cAAA,cAAA,mBAClC,sBAAkC,mBAAA,iBAAA,cAAA,iBAClC,uBAAkC,mBAAA,kBAAA,cAAA,wBAClC,sBAAkC,mBAAA,qBAAA,cAAA,uBAClC,uBAAkC,mBAAA,kBAAA,cAAA,kBAElC,iBAAgC,oBAAA,eAAA,WAAA,eAChC,kBAAgC,oBAAA,gBAAA,WAAA,qBAChC,gBAAgC,oBAAA,cAAA,WAAA,mBAChC,mBAAgC,oBAAA,iBAAA,WAAA,iBAChC,qBAAgC,oBAAA,mBAAA,WAAA,mBAChC,oBAAgC,oBAAA,kBAAA,WAAA,kBHYhC,yBGlDA,aAAgC,mBAAA,cAAA,eAAA,cAChC,gBAAgC,mBAAA,iBAAA,eAAA,iBAChC,qBAAgC,mBAAA,sBAAA,eAAA,sBAChC,wBAAgC,mBAAA,yBAAA,eAAA,yBAEhC,cAA8B,cAAA,eAAA,UAAA,eAC9B,gBAA8B,cAAA,iBAAA,UAAA,iBAC9B,sBAA8B,cAAA,uBAAA,UAAA,uBAC9B,cAA8B,SAAA,EAAA,EAAA,eAAA,KAAA,EAAA,EAAA,eAC9B,gBAA8B,kBAAA,YAAA,UAAA,YAC9B,gBAA8B,kBAAA,YAAA,UAAA,YAC9B,kBAA8B,kBAAA,YAAA,YAAA,YAC9B,kBAA8B,kBAAA,YAAA,YAAA,YAE9B,0BAAoC,cAAA,gBAAA,gBAAA,qBACpC,wBAAoC,cAAA,cAAA,gBAAA,mBACpC,2BAAoC,cAAA,iBAAA,gBAAA,iBACpC,4BAAoC,cAAA,kBAAA,gBAAA,wBACpC,2BAAoC,cAAA,qBAAA,gBAAA,uBAEpC,sBAAiC,eAAA,gBAAA,YAAA,qBACjC,oBAAiC,eAAA,cAAA,YAAA,mBACjC,uBAAiC,eAAA,iBAAA,YAAA,iBACjC,yBAAiC,eAAA,mBAAA,YAAA,mBACjC,wBAAiC,eAAA,kBAAA,YAAA,kBAEjC,wBAAkC,mBAAA,gBAAA,cAAA,qBAClC,sBAAkC,mBAAA,cAAA,cAAA,mBAClC,yBAAkC,mBAAA,iBAAA,cAAA,iBAClC,0BAAkC,mBAAA,kBAAA,cAAA,wBAClC,yBAAkC,mBAAA,qBAAA,cAAA,uBAClC,0BAAkC,mBAAA,kBAAA,cAAA,kBAElC,oBAAgC,oBAAA,eAAA,WAAA,eAChC,qBAAgC,oBAAA,gBAAA,WAAA,qBAChC,mBAAgC,oBAAA,cAAA,WAAA,mBAChC,sBAAgC,oBAAA,iBAAA,WAAA,iBAChC,wBAAgC,oBAAA,mBAAA,WAAA,mBAChC,uBAAgC,oBAAA,kBAAA,WAAA,mBHYhC,yBGlDA,aAAgC,mBAAA,cAAA,eAAA,cAChC,gBAAgC,mBAAA,iBAAA,eAAA,iBAChC,qBAAgC,mBAAA,sBAAA,eAAA,sBAChC,wBAAgC,mBAAA,yBAAA,eAAA,yBAEhC,cAA8B,cAAA,eAAA,UAAA,eAC9B,gBAA8B,cAAA,iBAAA,UAAA,iBAC9B,sBAA8B,cAAA,uBAAA,UAAA,uBAC9B,cAA8B,SAAA,EAAA,EAAA,eAAA,KAAA,EAAA,EAAA,eAC9B,gBAA8B,kBAAA,YAAA,UAAA,YAC9B,gBAA8B,kBAAA,YAAA,UAAA,YAC9B,kBAA8B,kBAAA,YAAA,YAAA,YAC9B,kBAA8B,kBAAA,YAAA,YAAA,YAE9B,0BAAoC,cAAA,gBAAA,gBAAA,qBACpC,wBAAoC,cAAA,cAAA,gBAAA,mBACpC,2BAAoC,cAAA,iBAAA,gBAAA,iBACpC,4BAAoC,cAAA,kBAAA,gBAAA,wBACpC,2BAAoC,cAAA,qBAAA,gBAAA,uBAEpC,sBAAiC,eAAA,gBAAA,YAAA,qBACjC,oBAAiC,eAAA,cAAA,YAAA,mBACjC,uBAAiC,eAAA,iBAAA,YAAA,iBACjC,yBAAiC,eAAA,mBAAA,YAAA,mBACjC,wBAAiC,eAAA,kBAAA,YAAA,kBAEjC,wBAAkC,mBAAA,gBAAA,cAAA,qBAClC,sBAAkC,mBAAA,cAAA,cAAA,mBAClC,yBAAkC,mBAAA,iBAAA,cAAA,iBAClC,0BAAkC,mBAAA,kBAAA,cAAA,wBAClC,yBAAkC,mBAAA,qBAAA,cAAA,uBAClC,0BAAkC,mBAAA,kBAAA,cAAA,kBAElC,oBAAgC,oBAAA,eAAA,WAAA,eAChC,qBAAgC,oBAAA,gBAAA,WAAA,qBAChC,mBAAgC,oBAAA,cAAA,WAAA,mBAChC,sBAAgC,oBAAA,iBAAA,WAAA,iBAChC,wBAAgC,oBAAA,mBAAA,WAAA,mBAChC,uBAAgC,oBAAA,kBAAA,WAAA,mBHYhC,yBGlDA,aAAgC,mBAAA,cAAA,eAAA,cAChC,gBAAgC,mBAAA,iBAAA,eAAA,iBAChC,qBAAgC,mBAAA,sBAAA,eAAA,sBAChC,wBAAgC,mBAAA,yBAAA,eAAA,yBAEhC,cAA8B,cAAA,eAAA,UAAA,eAC9B,gBAA8B,cAAA,iBAAA,UAAA,iBAC9B,sBAA8B,cAAA,uBAAA,UAAA,uBAC9B,cAA8B,SAAA,EAAA,EAAA,eAAA,KAAA,EAAA,EAAA,eAC9B,gBAA8B,kBAAA,YAAA,UAAA,YAC9B,gBAA8B,kBAAA,YAAA,UAAA,YAC9B,kBAA8B,kBAAA,YAAA,YAAA,YAC9B,kBAA8B,kBAAA,YAAA,YAAA,YAE9B,0BAAoC,cAAA,gBAAA,gBAAA,qBACpC,wBAAoC,cAAA,cAAA,gBAAA,mBACpC,2BAAoC,cAAA,iBAAA,gBAAA,iBACpC,4BAAoC,cAAA,kBAAA,gBAAA,wBACpC,2BAAoC,cAAA,qBAAA,gBAAA,uBAEpC,sBAAiC,eAAA,gBAAA,YAAA,qBACjC,oBAAiC,eAAA,cAAA,YAAA,mBACjC,uBAAiC,eAAA,iBAAA,YAAA,iBACjC,yBAAiC,eAAA,mBAAA,YAAA,mBACjC,wBAAiC,eAAA,kBAAA,YAAA,kBAEjC,wBAAkC,mBAAA,gBAAA,cAAA,qBAClC,sBAAkC,mBAAA,cAAA,cAAA,mBAClC,yBAAkC,mBAAA,iBAAA,cAAA,iBAClC,0BAAkC,mBAAA,kBAAA,cAAA,wBAClC,yBAAkC,mBAAA,qBAAA,cAAA,uBAClC,0BAAkC,mBAAA,kBAAA,cAAA,kBAElC,oBAAgC,oBAAA,eAAA,WAAA,eAChC,qBAAgC,oBAAA,gBAAA,WAAA,qBAChC,mBAAgC,oBAAA,cAAA,WAAA,mBAChC,sBAAgC,oBAAA,iBAAA,WAAA,iBAChC,wBAAgC,oBAAA,mBAAA,WAAA,mBAChC,uBAAgC,oBAAA,kBAAA,WAAA,mBHYhC,0BGlDA,aAAgC,mBAAA,cAAA,eAAA,cAChC,gBAAgC,mBAAA,iBAAA,eAAA,iBAChC,qBAAgC,mBAAA,sBAAA,eAAA,sBAChC,wBAAgC,mBAAA,yBAAA,eAAA,yBAEhC,cAA8B,cAAA,eAAA,UAAA,eAC9B,gBAA8B,cAAA,iBAAA,UAAA,iBAC9B,sBAA8B,cAAA,uBAAA,UAAA,uBAC9B,cAA8B,SAAA,EAAA,EAAA,eAAA,KAAA,EAAA,EAAA,eAC9B,gBAA8B,kBAAA,YAAA,UAAA,YAC9B,gBAA8B,kBAAA,YAAA,UAAA,YAC9B,kBAA8B,kBAAA,YAAA,YAAA,YAC9B,kBAA8B,kBAAA,YAAA,YAAA,YAE9B,0BAAoC,cAAA,gBAAA,gBAAA,qBACpC,wBAAoC,cAAA,cAAA,gBAAA,mBACpC,2BAAoC,cAAA,iBAAA,gBAAA,iBACpC,4BAAoC,cAAA,kBAAA,gBAAA,wBACpC,2BAAoC,cAAA,qBAAA,gBAAA,uBAEpC,sBAAiC,eAAA,gBAAA,YAAA,qBACjC,oBAAiC,eAAA,cAAA,YAAA,mBACjC,uBAAiC,eAAA,iBAAA,YAAA,iBACjC,yBAAiC,eAAA,mBAAA,YAAA,mBACjC,wBAAiC,eAAA,kBAAA,YAAA,kBAEjC,wBAAkC,mBAAA,gBAAA,cAAA,qBAClC,sBAAkC,mBAAA,cAAA,cAAA,mBAClC,yBAAkC,mBAAA,iBAAA,cAAA,iBAClC,0BAAkC,mBAAA,kBAAA,cAAA,wBAClC,yBAAkC,mBAAA,qBAAA,cAAA,uBAClC,0BAAkC,mBAAA,kBAAA,cAAA,kBAElC,oBAAgC,oBAAA,eAAA,WAAA,eAChC,qBAAgC,oBAAA,gBAAA,WAAA,qBAChC,mBAAgC,oBAAA,cAAA,WAAA,mBAChC,sBAAgC,oBAAA,iBAAA,WAAA,iBAChC,wBAAgC,oBAAA,mBAAA,WAAA,mBAChC,uBAAgC,oBAAA,kBAAA,WAAA","sourcesContent":["/*!\n * Bootstrap Grid v4.1.3 (https://getbootstrap.com/)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n@at-root {\n @-ms-viewport { width: device-width; } // stylelint-disable-line at-rule-no-vendor-prefix\n}\n\nhtml {\n box-sizing: border-box;\n -ms-overflow-style: scrollbar;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit;\n}\n\n@import \"functions\";\n@import \"variables\";\n\n@import \"mixins/breakpoints\";\n@import \"mixins/grid-framework\";\n@import \"mixins/grid\";\n\n@import \"grid\";\n@import \"utilities/display\";\n@import \"utilities/flex\";\n","/*!\n * Bootstrap Grid v4.1.3 (https://getbootstrap.com/)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n@-ms-viewport {\n width: device-width;\n}\n\nhtml {\n box-sizing: border-box;\n -ms-overflow-style: scrollbar;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit;\n}\n\n.container {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container {\n max-width: 1140px;\n }\n}\n\n.container-fluid {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n.row {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.col-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n}\n\n.col-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n -ms-flex-order: -1;\n order: -1;\n}\n\n.order-last {\n -ms-flex-order: 13;\n order: 13;\n}\n\n.order-0 {\n -ms-flex-order: 0;\n order: 0;\n}\n\n.order-1 {\n -ms-flex-order: 1;\n order: 1;\n}\n\n.order-2 {\n -ms-flex-order: 2;\n order: 2;\n}\n\n.order-3 {\n -ms-flex-order: 3;\n order: 3;\n}\n\n.order-4 {\n -ms-flex-order: 4;\n order: 4;\n}\n\n.order-5 {\n -ms-flex-order: 5;\n order: 5;\n}\n\n.order-6 {\n -ms-flex-order: 6;\n order: 6;\n}\n\n.order-7 {\n -ms-flex-order: 7;\n order: 7;\n}\n\n.order-8 {\n -ms-flex-order: 8;\n order: 8;\n}\n\n.order-9 {\n -ms-flex-order: 9;\n order: 9;\n}\n\n.order-10 {\n -ms-flex-order: 10;\n order: 10;\n}\n\n.order-11 {\n -ms-flex-order: 11;\n order: 11;\n}\n\n.order-12 {\n -ms-flex-order: 12;\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-sm-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-sm-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-sm-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-sm-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-sm-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-sm-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-sm-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-sm-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-sm-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-sm-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-sm-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-sm-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-sm-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-sm-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-sm-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-sm-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-md-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-md-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-md-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-md-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-md-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-md-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-md-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-md-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-md-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-md-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-md-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-md-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-md-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-md-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-md-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-md-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-lg-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-lg-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-lg-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-lg-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-lg-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-lg-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-lg-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-lg-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-lg-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-lg-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-lg-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-lg-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-lg-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-lg-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-lg-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-lg-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-xl-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-xl-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-xl-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-xl-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-xl-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-xl-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-xl-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-xl-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-xl-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-xl-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-xl-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-xl-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-xl-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-xl-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-xl-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-xl-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n}\n\n.d-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-md-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-print-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n.flex-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n}\n\n.flex-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n}\n\n.justify-content-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n}\n\n.align-items-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n}\n\n.align-items-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n}\n\n.align-items-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n}\n\n.align-items-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n}\n\n.align-content-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n}\n\n.align-content-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n}\n\n.align-content-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n}\n\n.align-content-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n}\n\n.align-content-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n}\n\n.align-self-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n}\n\n.align-self-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n}\n\n.align-self-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n}\n\n.align-self-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n}\n\n.align-self-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-sm-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-sm-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-sm-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-sm-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-sm-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-sm-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-sm-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-sm-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-md-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-md-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-md-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-md-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-md-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-md-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-md-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-md-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-md-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-md-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-md-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-md-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-md-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-md-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-md-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-md-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-lg-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-lg-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-lg-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-lg-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-lg-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-lg-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-lg-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-lg-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-xl-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-xl-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-xl-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-xl-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-xl-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-xl-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-xl-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-xl-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n/*# sourceMappingURL=bootstrap-grid.css.map */","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n .container {\n @include make-container();\n @include make-container-max-widths();\n }\n}\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but with 100% width for\n// fluid, full width layouts.\n\n@if $enable-grid-classes {\n .container-fluid {\n @include make-container();\n }\n}\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n }\n\n // Remove the negative margin from default .row, then the horizontal padding\n // from all immediate children columns (to prevent runaway style inheritance).\n .no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n }\n}\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container() {\n width: 100%;\n padding-right: ($grid-gutter-width / 2);\n padding-left: ($grid-gutter-width / 2);\n margin-right: auto;\n margin-left: auto;\n}\n\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n}\n\n@mixin make-row() {\n display: flex;\n flex-wrap: wrap;\n margin-right: ($grid-gutter-width / -2);\n margin-left: ($grid-gutter-width / -2);\n}\n\n@mixin make-col-ready() {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n min-height: 1px; // Prevent collapsing\n padding-right: ($grid-gutter-width / 2);\n padding-left: ($grid-gutter-width / 2);\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02px, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n // Common properties for all breakpoints\n %grid-column {\n position: relative;\n width: 100%;\n min-height: 1px; // Prevent columns from collapsing when empty\n padding-right: ($gutter / 2);\n padding-left: ($gutter / 2);\n }\n\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n // Allow columns to stretch full width below their breakpoints\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @extend %grid-column;\n }\n }\n .col#{$infix},\n .col#{$infix}-auto {\n @extend %grid-column;\n }\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col#{$infix}-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none; // Reset earlier grid tiers\n }\n\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n\n .order#{$infix}-first { order: -1; }\n\n .order#{$infix}-last { order: $columns + 1; }\n\n @for $i from 0 through $columns {\n .order#{$infix}-#{$i} { order: $i; }\n }\n\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Utilities for common `display` values\n//\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .d#{$infix}-none { display: none !important; }\n .d#{$infix}-inline { display: inline !important; }\n .d#{$infix}-inline-block { display: inline-block !important; }\n .d#{$infix}-block { display: block !important; }\n .d#{$infix}-table { display: table !important; }\n .d#{$infix}-table-row { display: table-row !important; }\n .d#{$infix}-table-cell { display: table-cell !important; }\n .d#{$infix}-flex { display: flex !important; }\n .d#{$infix}-inline-flex { display: inline-flex !important; }\n }\n}\n\n\n//\n// Utilities for toggling `display` in print\n//\n\n@media print {\n .d-print-none { display: none !important; }\n .d-print-inline { display: inline !important; }\n .d-print-inline-block { display: inline-block !important; }\n .d-print-block { display: block !important; }\n .d-print-table { display: table !important; }\n .d-print-table-row { display: table-row !important; }\n .d-print-table-cell { display: table-cell !important; }\n .d-print-flex { display: flex !important; }\n .d-print-inline-flex { display: inline-flex !important; }\n}\n","// stylelint-disable declaration-no-important\n\n// Flex variation\n//\n// Custom styles for additional flex alignment options.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .flex#{$infix}-row { flex-direction: row !important; }\n .flex#{$infix}-column { flex-direction: column !important; }\n .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }\n .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }\n\n .flex#{$infix}-wrap { flex-wrap: wrap !important; }\n .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }\n .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex#{$infix}-fill { flex: 1 1 auto !important; }\n .flex#{$infix}-grow-0 { flex-grow: 0 !important; }\n .flex#{$infix}-grow-1 { flex-grow: 1 !important; }\n .flex#{$infix}-shrink-0 { flex-shrink: 0 !important; }\n .flex#{$infix}-shrink-1 { flex-shrink: 1 !important; }\n\n .justify-content#{$infix}-start { justify-content: flex-start !important; }\n .justify-content#{$infix}-end { justify-content: flex-end !important; }\n .justify-content#{$infix}-center { justify-content: center !important; }\n .justify-content#{$infix}-between { justify-content: space-between !important; }\n .justify-content#{$infix}-around { justify-content: space-around !important; }\n\n .align-items#{$infix}-start { align-items: flex-start !important; }\n .align-items#{$infix}-end { align-items: flex-end !important; }\n .align-items#{$infix}-center { align-items: center !important; }\n .align-items#{$infix}-baseline { align-items: baseline !important; }\n .align-items#{$infix}-stretch { align-items: stretch !important; }\n\n .align-content#{$infix}-start { align-content: flex-start !important; }\n .align-content#{$infix}-end { align-content: flex-end !important; }\n .align-content#{$infix}-center { align-content: center !important; }\n .align-content#{$infix}-between { align-content: space-between !important; }\n .align-content#{$infix}-around { align-content: space-around !important; }\n .align-content#{$infix}-stretch { align-content: stretch !important; }\n\n .align-self#{$infix}-auto { align-self: auto !important; }\n .align-self#{$infix}-start { align-self: flex-start !important; }\n .align-self#{$infix}-end { align-self: flex-end !important; }\n .align-self#{$infix}-center { align-self: center !important; }\n .align-self#{$infix}-baseline { align-self: baseline !important; }\n .align-self#{$infix}-stretch { align-self: stretch !important; }\n }\n}\n"]}
\ No newline at end of file
diff --git a/dapps/demo/src/css/bootstrap-reboot.css b/dapps/demo/src/css/bootstrap-reboot.css
deleted file mode 100644
index b3d7f4c6a..000000000
--- a/dapps/demo/src/css/bootstrap-reboot.css
+++ /dev/null
@@ -1,331 +0,0 @@
-/*!
- * Bootstrap Reboot v4.1.3 (https://getbootstrap.com/)
- * Copyright 2011-2018 The Bootstrap Authors
- * Copyright 2011-2018 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
- */
-*,
-*::before,
-*::after {
- box-sizing: border-box;
-}
-
-html {
- font-family: sans-serif;
- line-height: 1.15;
- -webkit-text-size-adjust: 100%;
- -ms-text-size-adjust: 100%;
- -ms-overflow-style: scrollbar;
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-}
-
-@-ms-viewport {
- width: device-width;
-}
-
-article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
- display: block;
-}
-
-body {
- margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
- font-size: 1rem;
- font-weight: 400;
- line-height: 1.5;
- color: #212529;
- text-align: left;
- background-color: #fff;
-}
-
-[tabindex="-1"]:focus {
- outline: 0 !important;
-}
-
-hr {
- box-sizing: content-box;
- height: 0;
- overflow: visible;
-}
-
-h1, h2, h3, h4, h5, h6 {
- margin-top: 0;
- margin-bottom: 0.5rem;
-}
-
-p {
- margin-top: 0;
- margin-bottom: 1rem;
-}
-
-abbr[title],
-abbr[data-original-title] {
- text-decoration: underline;
- -webkit-text-decoration: underline dotted;
- text-decoration: underline dotted;
- cursor: help;
- border-bottom: 0;
-}
-
-address {
- margin-bottom: 1rem;
- font-style: normal;
- line-height: inherit;
-}
-
-ol,
-ul,
-dl {
- margin-top: 0;
- margin-bottom: 1rem;
-}
-
-ol ol,
-ul ul,
-ol ul,
-ul ol {
- margin-bottom: 0;
-}
-
-dt {
- font-weight: 700;
-}
-
-dd {
- margin-bottom: .5rem;
- margin-left: 0;
-}
-
-blockquote {
- margin: 0 0 1rem;
-}
-
-dfn {
- font-style: italic;
-}
-
-b,
-strong {
- font-weight: bolder;
-}
-
-small {
- font-size: 80%;
-}
-
-sub,
-sup {
- position: relative;
- font-size: 75%;
- line-height: 0;
- vertical-align: baseline;
-}
-
-sub {
- bottom: -.25em;
-}
-
-sup {
- top: -.5em;
-}
-
-a {
- color: #007bff;
- text-decoration: none;
- background-color: transparent;
- -webkit-text-decoration-skip: objects;
-}
-
-a:hover {
- color: #0056b3;
- text-decoration: underline;
-}
-
-a:not([href]):not([tabindex]) {
- color: inherit;
- text-decoration: none;
-}
-
-a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
- color: inherit;
- text-decoration: none;
-}
-
-a:not([href]):not([tabindex]):focus {
- outline: 0;
-}
-
-pre,
-code,
-kbd,
-samp {
- font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
- font-size: 1em;
-}
-
-pre {
- margin-top: 0;
- margin-bottom: 1rem;
- overflow: auto;
- -ms-overflow-style: scrollbar;
-}
-
-figure {
- margin: 0 0 1rem;
-}
-
-img {
- vertical-align: middle;
- border-style: none;
-}
-
-svg {
- overflow: hidden;
- vertical-align: middle;
-}
-
-table {
- border-collapse: collapse;
-}
-
-caption {
- padding-top: 0.75rem;
- padding-bottom: 0.75rem;
- color: #6c757d;
- text-align: left;
- caption-side: bottom;
-}
-
-th {
- text-align: inherit;
-}
-
-label {
- display: inline-block;
- margin-bottom: 0.5rem;
-}
-
-button {
- border-radius: 0;
-}
-
-button:focus {
- outline: 1px dotted;
- outline: 5px auto -webkit-focus-ring-color;
-}
-
-input,
-button,
-select,
-optgroup,
-textarea {
- margin: 0;
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
-}
-
-button,
-input {
- overflow: visible;
-}
-
-button,
-select {
- text-transform: none;
-}
-
-button,
-html [type="button"],
-[type="reset"],
-[type="submit"] {
- -webkit-appearance: button;
-}
-
-button::-moz-focus-inner,
-[type="button"]::-moz-focus-inner,
-[type="reset"]::-moz-focus-inner,
-[type="submit"]::-moz-focus-inner {
- padding: 0;
- border-style: none;
-}
-
-input[type="radio"],
-input[type="checkbox"] {
- box-sizing: border-box;
- padding: 0;
-}
-
-input[type="date"],
-input[type="time"],
-input[type="datetime-local"],
-input[type="month"] {
- -webkit-appearance: listbox;
-}
-
-textarea {
- overflow: auto;
- resize: vertical;
-}
-
-fieldset {
- min-width: 0;
- padding: 0;
- margin: 0;
- border: 0;
-}
-
-legend {
- display: block;
- width: 100%;
- max-width: 100%;
- padding: 0;
- margin-bottom: .5rem;
- font-size: 1.5rem;
- line-height: inherit;
- color: inherit;
- white-space: normal;
-}
-
-progress {
- vertical-align: baseline;
-}
-
-[type="number"]::-webkit-inner-spin-button,
-[type="number"]::-webkit-outer-spin-button {
- height: auto;
-}
-
-[type="search"] {
- outline-offset: -2px;
- -webkit-appearance: none;
-}
-
-[type="search"]::-webkit-search-cancel-button,
-[type="search"]::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-
-::-webkit-file-upload-button {
- font: inherit;
- -webkit-appearance: button;
-}
-
-output {
- display: inline-block;
-}
-
-summary {
- display: list-item;
- cursor: pointer;
-}
-
-template {
- display: none;
-}
-
-[hidden] {
- display: none !important;
-}
-/*# sourceMappingURL=bootstrap-reboot.css.map */
\ No newline at end of file
diff --git a/dapps/demo/src/css/bootstrap-reboot.css.map b/dapps/demo/src/css/bootstrap-reboot.css.map
deleted file mode 100644
index 3a17ed962..000000000
--- a/dapps/demo/src/css/bootstrap-reboot.css.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["../../scss/bootstrap-reboot.scss","../../scss/_reboot.scss","../../scss/_variables.scss","bootstrap-reboot.css","../../scss/mixins/_hover.scss"],"names":[],"mappings":"AAAA;;;;;;GAMG;ACcH;;;EAGE,uBAAsB;CACvB;;AAED;EACE,wBAAuB;EACvB,kBAAiB;EACjB,+BAA8B;EAC9B,2BAA0B;EAC1B,8BAA6B;EAC7B,8CCZa;CDad;;AAIC;EACE,oBAAmB;CEdtB;;AFoBD;EACE,eAAc;CACf;;AAUD;EACE,UAAS;EACT,sLCgMoM;ED/LpM,gBCoMgC;EDnMhC,iBCwM+B;EDvM/B,iBC2M+B;ED1M/B,eC3CgB;ED4ChB,iBAAgB;EAChB,uBCtDa;CDuDd;;AExBD;EFgCE,sBAAqB;CACtB;;AAQD;EACE,wBAAuB;EACvB,UAAS;EACT,kBAAiB;CAClB;;AAYD;EACE,cAAa;EACb,sBC6KyC;CD5K1C;;AAOD;EACE,cAAa;EACb,oBCkE8B;CDjE/B;;AASD;;EAEE,2BAA0B;EAC1B,0CAAiC;EAAjC,kCAAiC;EACjC,aAAY;EACZ,iBAAgB;CACjB;;AAED;EACE,oBAAmB;EACnB,mBAAkB;EAClB,qBAAoB;CACrB;;AAED;;;EAGE,cAAa;EACb,oBAAmB;CACpB;;AAED;;;;EAIE,iBAAgB;CACjB;;AAED;EACE,iBCgH+B;CD/GhC;;AAED;EACE,qBAAoB;EACpB,eAAc;CACf;;AAED;EACE,iBAAgB;CACjB;;AAED;EACE,mBAAkB;CACnB;;AAGD;;EAEE,oBAAmB;CACpB;;AAGD;EACE,eAAc;CACf;;AAOD;;EAEE,mBAAkB;EAClB,eAAc;EACd,eAAc;EACd,yBAAwB;CACzB;;AAED;EAAM,eAAc;CAAI;;AACxB;EAAM,WAAU;CAAI;;AAOpB;EACE,eC9Je;ED+Jf,sBC/B8B;EDgC9B,8BAA6B;EAC7B,sCAAqC;CAMtC;;AGnMC;EHgME,eCnCgD;EDoChD,2BCnCiC;CE9Jb;;AH2MxB;EACE,eAAc;EACd,sBAAqB;CAUtB;;AGnNC;EH4ME,eAAc;EACd,sBAAqB;CG1MtB;;AHoMH;EAUI,WAAU;CACX;;AAQH;;;;EAIE,kGCagH;EDZhH,eAAc;CACf;;AAED;EAEE,cAAa;EAEb,oBAAmB;EAEnB,eAAc;EAGd,8BAA6B;CAC9B;;AAOD;EAEE,iBAAgB;CACjB;;AAOD;EACE,uBAAsB;EACtB,mBAAkB;CACnB;;AAED;EAGE,iBAAgB;EAChB,uBAAsB;CACvB;;AAOD;EACE,0BAAyB;CAC1B;;AAED;EACE,qBC8BkC;ED7BlC,wBC6BkC;ED5BlC,eCrRgB;EDsRhB,iBAAgB;EAChB,qBAAoB;CACrB;;AAED;EAGE,oBAAmB;CACpB;;AAOD;EAEE,sBAAqB;EACrB,sBC+F2C;CD9F5C;;AAKD;EACE,iBAAgB;CACjB;;AAMD;EACE,oBAAmB;EACnB,2CAA0C;CAC3C;;AAED;;;;;EAKE,UAAS;EACT,qBAAoB;EACpB,mBAAkB;EAClB,qBAAoB;CACrB;;AAED;;EAEE,kBAAiB;CAClB;;AAED;;EAEE,qBAAoB;CACrB;;AAKD;;;;EAIE,2BAA0B;CAC3B;;AAGD;;;;EAIE,WAAU;EACV,mBAAkB;CACnB;;AAED;;EAEE,uBAAsB;EACtB,WAAU;CACX;;AAGD;;;;EASE,4BAA2B;CAC5B;;AAED;EACE,eAAc;EAEd,iBAAgB;CACjB;;AAED;EAME,aAAY;EAEZ,WAAU;EACV,UAAS;EACT,UAAS;CACV;;AAID;EACE,eAAc;EACd,YAAW;EACX,gBAAe;EACf,WAAU;EACV,qBAAoB;EACpB,kBAAiB;EACjB,qBAAoB;EACpB,eAAc;EACd,oBAAmB;CACpB;;AAED;EACE,yBAAwB;CACzB;;AEpID;;EFyIE,aAAY;CACb;;AErID;EF4IE,qBAAoB;EACpB,yBAAwB;CACzB;;AEzID;;EFiJE,yBAAwB;CACzB;;AAOD;EACE,cAAa;EACb,2BAA0B;CAC3B;;AAMD;EACE,sBAAqB;CACtB;;AAED;EACE,mBAAkB;EAClB,gBAAe;CAChB;;AAED;EACE,cAAa;CACd;;AEtJD;EF2JE,yBAAwB;CACzB","file":"bootstrap-reboot.css","sourcesContent":["/*!\n * Bootstrap Reboot v4.1.3 (https://getbootstrap.com/)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"reboot\";\n","// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Setting @viewport causes scrollbars to overlap content in IE11 and Edge, so\n// we force a non-overlapping, non-auto-hiding scrollbar to counteract.\n// 6. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -ms-text-size-adjust: 100%; // 4\n -ms-overflow-style: scrollbar; // 5\n -webkit-tap-highlight-color: rgba($black, 0); // 6\n}\n\n// IE10+ doesn't honor `` in some cases.\n@at-root {\n @-ms-viewport {\n width: device-width;\n }\n}\n\n// stylelint-disable selector-list-comma-newline-after\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n// stylelint-enable selector-list-comma-newline-after\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use the\n// the `inherit` value on things like `` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n font-size: $font-size-base;\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Suppress the focus outline on elements that cannot be accessed via keyboard.\n// This prevents an unwanted focus outline from appearing around elements that\n// might still respond to pointer events.\n//\n// Credit: https://github.com/suitcss/base\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, ``-`` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n// stylelint-enable selector-list-comma-newline-after\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on ``s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Remove the bottom border in Firefox 39-.\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Duplicate behavior to the data-* attribute for our tooltip plugin\n\nabbr[title],\nabbr[data-original-title] { // 4\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 1\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic; // Add the correct font style in Android 4.3-\n}\n\n// stylelint-disable font-weight-notation\nb,\nstrong {\n font-weight: bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n// stylelint-enable font-weight-notation\n\nsmall {\n font-size: 80%; // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n -webkit-text-decoration-skip: objects; // Remove gaps in links underline in iOS 8+ and Safari 8+.\n\n @include hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href)\n// which have not been made explicitly keyboard-focusable (without tabindex).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n\n @include hover-focus {\n color: inherit;\n text-decoration: none;\n }\n\n &:focus {\n outline: 0;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n font-size: 1em; // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // We have @viewport set which causes scrollbars to overlap content in IE11 and Edge, so\n // we force a non-overlapping, non-auto-hiding scrollbar to counteract.\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n // Matches default ` | ` alignment by inheriting from the ``, or the\n // closest parent with a set `text-align`.\n text-align: inherit;\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n border-radius: 0;\n}\n\n// Work around a Firefox/IE bug where the transparent `button` background\n// results in a loss of the default `button` focus styles.\n//\n// Credit: https://github.com/suitcss/base/\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\nhtml [type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n // Remove the default appearance of temporal inputs to avoid a Mobile Safari\n // bug where setting a custom line-height prevents text from being vertically\n // centered within the input.\n // See https://bugs.webkit.org/show_bug.cgi?id=139848\n // and https://github.com/twbs/bootstrap/issues/11266\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. ` |